Skip to content

Commit

Permalink
Add NByte ematch
Browse files Browse the repository at this point in the history
Signed-off-by: Florian Lehner <[email protected]>
  • Loading branch information
florianl committed Jan 6, 2024
1 parent 664c554 commit 0550966
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 0 deletions.
8 changes: 8 additions & 0 deletions ematch.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ type EmatchMatch struct {
IPSetMatch *IPSetMatch
IptMatch *IptMatch
ContainerMatch *ContainerMatch
NByteMatch *NByteMatch
}

// unmarshalEmatch parses the Ematch-encoded data and stores the result in the value pointed to by info.
Expand Down Expand Up @@ -221,6 +222,11 @@ func unmarshalEmatchTreeList(data []byte, info *[]EmatchMatch) error {
err := unmarshalContainerMatch(tmp[8:], expr)
multiError = concatError(multiError, err)
match.ContainerMatch = expr
case EmatchNByte:
expr := &NByteMatch{}
err := unmarshalNByteMatch(tmp[8:], expr)
multiError = concatError(multiError, err)
match.NByteMatch = expr
default:
return fmt.Errorf("unmarshalEmatchTreeList() kind %d is not yet implemented", match.Hdr.Kind)
}
Expand Down Expand Up @@ -249,6 +255,8 @@ func marshalEmatchTreeList(info *[]EmatchMatch) ([]byte, error) {
expr, err = marshalIptMatch(m.IptMatch)
case EmatchContainer:
expr, err = marshalContainerMatch(m.ContainerMatch)
case EmatchNByte:
expr, err = marshalNByteMatch(m.NByteMatch)
default:
return []byte{}, fmt.Errorf("marshalEmatchTreeList() kind %d is not yet implemented", m.Hdr.Kind)
}
Expand Down
51 changes: 51 additions & 0 deletions ematch_nbyte.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package tc

import (
"fmt"
)

type NByteMatch struct {

Check failure on line 7 in ematch_nbyte.go

View workflow job for this annotation

GitHub Actions / code-check (1.20.x)

exported type NByteMatch should have comment or be unexported

Check failure on line 7 in ematch_nbyte.go

View workflow job for this annotation

GitHub Actions / code-check (1.21.x)

exported type NByteMatch should have comment or be unexported
Offset uint16
Layer uint8
Needle []byte
}

type tcfEmNByte struct {
off uint16
len uint16
layer uint8
}

func unmarshalNByteMatch(data []byte, info *NByteMatch) error {
if len(data) < 8 {
return fmt.Errorf("unmarshalNByteMatch: incomplete data")
}

nbyte := tcfEmNByte{}
if err := unmarshalStruct(data[:5], nbyte); err != nil {
return err
}
info.Offset = nbyte.off
info.Layer = nbyte.layer
info.Needle = data[8:]

return nil
}

func marshalNByteMatch(info *NByteMatch) ([]byte, error) {
if info == nil {
return []byte{}, fmt.Errorf("marshalNByteMatch: %w", ErrNoArg)
}
nbyte := tcfEmNByte{
off: info.Offset,
len: uint16(len(info.Needle)),
layer: info.Layer,
}

tmp, err := marshalAndAlignStruct(nbyte)
if err != nil {
return []byte{}, err
}
tmp = append(tmp, info.Needle...)
return tmp, nil
}
46 changes: 46 additions & 0 deletions ematch_nbyte_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package tc

import (
"errors"
"testing"

"github.com/google/go-cmp/cmp"
)

func TestNByteMatch(t *testing.T) {
t.Skip()
tests := map[string]struct {
val NByteMatch
err1 error
err2 error
}{
"simple": {
val: NByteMatch{Needle: []byte("helloWorld"),
Offset: 42,
Layer: 7},
},
}

for name, testcase := range tests {
t.Run(name, func(t *testing.T) {
data, err1 := marshalNByteMatch(&testcase.val)
if !errors.Is(err1, testcase.err1) {
t.Fatalf("Unexpected error: %v", err1)
}
val := NByteMatch{}
err2 := unmarshalNByteMatch(data, &val)
if !errors.Is(err2, testcase.err2) {
t.Fatalf("Unexpected error: %v", err2)
}
if diff := cmp.Diff(val, testcase.val); diff != "" {
t.Fatalf("NByteMatch missmatch (want +got):\n%s", diff)
}
})
}
t.Run("nil", func(t *testing.T) {
_, err := marshalNByteMatch(nil)
if !errors.Is(err, ErrNoArg) {
t.Fatalf("unexpected error: %v", err)
}
})
}

0 comments on commit 0550966

Please sign in to comment.