Add bitwise decoder logic (#71)
This commit is contained in:
parent
dc8c451012
commit
e0f4f3f8f8
|
@ -15,7 +15,7 @@
|
||||||
package expr
|
package expr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"encoding/binary"
|
||||||
|
|
||||||
"github.com/google/nftables/binaryutil"
|
"github.com/google/nftables/binaryutil"
|
||||||
"github.com/mdlayher/netlink"
|
"github.com/mdlayher/netlink"
|
||||||
|
@ -61,5 +61,42 @@ func (e *Bitwise) marshal() ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Bitwise) unmarshal(data []byte) error {
|
func (e *Bitwise) unmarshal(data []byte) error {
|
||||||
return fmt.Errorf("not yet implemented")
|
ad, err := netlink.NewAttributeDecoder(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ad.ByteOrder = binary.BigEndian
|
||||||
|
for ad.Next() {
|
||||||
|
switch ad.Type() {
|
||||||
|
case unix.NFTA_BITWISE_SREG:
|
||||||
|
e.SourceRegister = ad.Uint32()
|
||||||
|
case unix.NFTA_BITWISE_DREG:
|
||||||
|
e.DestRegister = ad.Uint32()
|
||||||
|
case unix.NFTA_BITWISE_LEN:
|
||||||
|
e.Len = ad.Uint32()
|
||||||
|
case unix.NFTA_BITWISE_MASK:
|
||||||
|
// Since NFTA_BITWISE_MASK is nested, it requires additional decoding
|
||||||
|
ad.Nested(func(nad *netlink.AttributeDecoder) error {
|
||||||
|
for nad.Next() {
|
||||||
|
switch nad.Type() {
|
||||||
|
case unix.NFTA_DATA_VALUE:
|
||||||
|
e.Mask = nad.Bytes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
case unix.NFTA_BITWISE_XOR:
|
||||||
|
// Since NFTA_BITWISE_XOR is nested, it requires additional decoding
|
||||||
|
ad.Nested(func(nad *netlink.AttributeDecoder) error {
|
||||||
|
for nad.Next() {
|
||||||
|
switch nad.Type() {
|
||||||
|
case unix.NFTA_DATA_VALUE:
|
||||||
|
e.Xor = nad.Bytes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ad.Err()
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package expr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mdlayher/netlink"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBitwise(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
bw Bitwise
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Unmarshal Bitwise IPv4 case",
|
||||||
|
bw: Bitwise{
|
||||||
|
SourceRegister: 1,
|
||||||
|
DestRegister: 2,
|
||||||
|
Len: 4,
|
||||||
|
// By specifying Xor to 0x0,0x0,0x0,0x0 and Mask to 0xff,0xff,0x0,0x0
|
||||||
|
// an expression will match /16 IPv4 address.
|
||||||
|
Xor: []byte{0x0, 0x0, 0x0, 0x0},
|
||||||
|
Mask: []byte{0xff, 0xff, 0x0, 0x0},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
nbw := Bitwise{}
|
||||||
|
data, err := tt.bw.marshal()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("marshal error: %+v", err)
|
||||||
|
|
||||||
|
}
|
||||||
|
ad, err := netlink.NewAttributeDecoder(data)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewAttributeDecoder() error: %+v", err)
|
||||||
|
}
|
||||||
|
ad.ByteOrder = binary.BigEndian
|
||||||
|
for ad.Next() {
|
||||||
|
if ad.Type() == unix.NFTA_EXPR_DATA {
|
||||||
|
if err := nbw.unmarshal(ad.Bytes()); err != nil {
|
||||||
|
t.Errorf("unmarshal error: %+v", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(tt.bw, nbw) {
|
||||||
|
t.Fatalf("original %+v and recovered %+v Bitwise structs are different", tt.bw, nbw)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
5
go.mod
5
go.mod
|
@ -4,7 +4,8 @@ go 1.12
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/koneu/natend v0.0.0-20150829182554-ec0926ea948d
|
github.com/koneu/natend v0.0.0-20150829182554-ec0926ea948d
|
||||||
github.com/mdlayher/netlink v0.0.0-20190516121005-0087c778e469
|
github.com/mdlayher/netlink v0.0.0-20191009155606-de872b0d824b
|
||||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc
|
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc
|
||||||
golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5
|
golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20191029155521-f43be2a4598c
|
||||||
)
|
)
|
||||||
|
|
28
go.sum
28
go.sum
|
@ -1,16 +1,26 @@
|
||||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
||||||
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
|
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a h1:84IpUNXj4mCR9CuCEvSiCArMbzr/TMbuPIadKDwypkI=
|
||||||
|
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
|
||||||
github.com/koneu/natend v0.0.0-20150829182554-ec0926ea948d h1:MFX8DxRnKMY/2M3H61iSsVbo/n3h0MWGmWNN1UViOU0=
|
github.com/koneu/natend v0.0.0-20150829182554-ec0926ea948d h1:MFX8DxRnKMY/2M3H61iSsVbo/n3h0MWGmWNN1UViOU0=
|
||||||
github.com/koneu/natend v0.0.0-20150829182554-ec0926ea948d/go.mod h1:QHb4k4cr1fQikUahfcRVPcEXiUgFsdIstGqlurL0XL4=
|
github.com/koneu/natend v0.0.0-20150829182554-ec0926ea948d/go.mod h1:QHb4k4cr1fQikUahfcRVPcEXiUgFsdIstGqlurL0XL4=
|
||||||
github.com/mdlayher/netlink v0.0.0-20190516121005-0087c778e469 h1:6XwSkpIirmRxmstYmbL5PshChpqazkNfFNJ+Uj1iJlU=
|
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
||||||
github.com/mdlayher/netlink v0.0.0-20190516121005-0087c778e469/go.mod h1:gOrA34zDL0K3RsACQe54bDYLF/CeFspQ9m5DOycycQ8=
|
github.com/mdlayher/netlink v0.0.0-20191009155606-de872b0d824b h1:W3er9pI7mt2gOqOWzwvx20iJ8Akiqz1mUMTxU6wdvl8=
|
||||||
|
github.com/mdlayher/netlink v0.0.0-20191009155606-de872b0d824b/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
|
||||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc h1:R83G5ikgLMxrBvLh22JhdfI8K6YXEPHx5P03Uu3DRs4=
|
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc h1:R83G5ikgLMxrBvLh22JhdfI8K6YXEPHx5P03Uu3DRs4=
|
||||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
||||||
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 h1:N66aaryRB3Ax92gH0v3hp1QYZ3zWWCCUR/j8Ifh45Ss=
|
||||||
|
golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5 h1:sM3evRHxE/1RuMe1FYAL3j7C7fUfIjkbE+NiDAYUF8U=
|
golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg=
|
||||||
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191029155521-f43be2a4598c h1:S/FtSvpNLtFBgjTqcKsRpsa6aVsI6iztaz1bQd9BJwE=
|
||||||
|
golang.org/x/sys v0.0.0-20191029155521-f43be2a4598c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
|
2
rule.go
2
rule.go
|
@ -190,6 +190,8 @@ func exprsFromMsg(b []byte) ([]expr.Any, error) {
|
||||||
e = &expr.Lookup{}
|
e = &expr.Lookup{}
|
||||||
case "immediate":
|
case "immediate":
|
||||||
e = &expr.Immediate{}
|
e = &expr.Immediate{}
|
||||||
|
case "bitwise":
|
||||||
|
e = &expr.Bitwise{}
|
||||||
}
|
}
|
||||||
if e == nil {
|
if e == nil {
|
||||||
// TODO: introduce an opaque expression type so that users know
|
// TODO: introduce an opaque expression type so that users know
|
||||||
|
|
Loading…
Reference in New Issue