Skip to content

Commit

Permalink
conntrack - rename Bitfield to Binary, move errors & err consts to er…
Browse files Browse the repository at this point in the history
…rors, Tuple error output

Also:
- TupleType stringer
- Fixes in child attr length logic
- TODO for missing attribute type implementations
- Tuple test suite for new error output
  • Loading branch information
ti-mo committed Aug 24, 2018
1 parent ac01f5a commit bdf55f7
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 64 deletions.
40 changes: 15 additions & 25 deletions attribute_types.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,17 @@
package conntrack

import (
"errors"
"fmt"
"time"

"github.com/ti-mo/netfilter"
)

var (
errNotImplemented = errors.New("sorry, not implemented yet")
errNested = errors.New("unexpected Nested attribute")
errNotNested = errors.New("need a Nested attribute to decode this structure")
errNeedSingleChild = errors.New("need (at least) 1 child attribute")
errNeedChildren = errors.New("need at least 2 child attributes")
errIncorrectSize = errors.New("binary attribute data has incorrect size")

ctaCountersOrigReplyCat = fmt.Sprintf("%s/%s", CTACountersOrig, CTACountersReply)
ctaSeqAdjOrigReplyCat = fmt.Sprintf("%s/%s", CTASeqAdjOrig, CTASeqAdjReply)
)

const (
errAttributeWrongType = "attribute type '%d' is not a %s"
errAttributeChild = "child Type '%d' unknown for attribute type %s"
errAttributeUnknown = "attribute type '%d' unknown"
errExactChildren = "need exactly %d child attributes for attribute type %s"
)

// Attribute is an interface implemented by all Conntrack attribute types.
type Attribute interface {
UnmarshalAttribute(netfilter.Attribute) error
Expand Down Expand Up @@ -90,19 +75,19 @@ func (i *Num32) UnmarshalAttribute(attr netfilter.Attribute) error {
return nil
}

// Bitfield is an attribute that contains a bitfield of any size.
type Bitfield struct {
// Binary is a binary attribute that is backed by a byte slice.
type Binary struct {
Type AttributeType
Data []byte
}

// Filled returns true if the bitfield's values are non-zero.
func (b Bitfield) Filled() bool {
func (b Binary) Filled() bool {
return len(b.Data) != 0
}

// UnmarshalAttribute unmarshals a netfilter.Attribute into a Bitfield.
func (b *Bitfield) UnmarshalAttribute(attr netfilter.Attribute) error {
// UnmarshalAttribute unmarshals a netfilter.Attribute into a Binary struct.
func (b *Binary) UnmarshalAttribute(attr netfilter.Attribute) error {

b.Type = AttributeType(attr.Type)
b.Data = attr.Data
Expand Down Expand Up @@ -209,8 +194,7 @@ func (tpi *ProtoInfoTCP) UnmarshalAttribute(attr netfilter.Attribute) error {
return errNotNested
}

// A ProtoInfoTCP has at least 3 members,
// TCP_STATE and TCP_FLAGS_ORIG/REPLY
// A ProtoInfoTCP has at least 3 members, TCP_STATE and TCP_FLAGS_ORIG/REPLY.
if len(attr.Children) < 3 {
return errNeedChildren
}
Expand Down Expand Up @@ -314,7 +298,7 @@ func (ts *Timestamp) UnmarshalAttribute(attr netfilter.Attribute) error {
}

// A Timestamp will always have at least a start time
if len(attr.Children) < 1 {
if len(attr.Children) == 0 {
return errNeedSingleChild
}

Expand Down Expand Up @@ -350,7 +334,7 @@ func (ctx *Security) UnmarshalAttribute(attr netfilter.Attribute) error {
}

// A SecurityContext has at least a name
if len(attr.Children) < 1 {
if len(attr.Children) == 0 {
return errNeedChildren
}

Expand Down Expand Up @@ -407,7 +391,7 @@ func (seq *SequenceAdjust) UnmarshalAttribute(attr netfilter.Attribute) error {
}

// A SequenceAdjust message should come with at least 1 child.
if len(attr.Children) < 1 {
if len(attr.Children) == 0 {
return errNeedSingleChild
}

Expand All @@ -429,3 +413,9 @@ func (seq *SequenceAdjust) UnmarshalAttribute(attr netfilter.Attribute) error {

return nil
}

// TODO: CTASynProxy
// TODO: CTAExpect
// TODO: CTAStats
// TODO: CTAStatsGlobal
// TODO: CTAStatsExp
2 changes: 1 addition & 1 deletion attribute_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func TestAttribute_Num32(t *testing.T) {
}

func TestAttribute_Bitfield(t *testing.T) {
bf := Bitfield{}
bf := Binary{}

assert.Nil(t, bf.UnmarshalAttribute(netfilter.Attribute{}))
}
Expand Down
20 changes: 15 additions & 5 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,22 @@ var (
errNotConntrack = errors.New("trying to decode a non-conntrack or conntrack-exp message")
errConnHasListeners = errors.New("Conn has existing listeners, open another to listen on more groups")
errMultipartEvent = errors.New("received multicast event with more than one Netlink message")
errNotImplemented = errors.New("sorry, not implemented yet")
errNested = errors.New("unexpected Nested attribute")
errNotNested = errors.New("need a Nested attribute to decode this structure")
errNeedSingleChild = errors.New("need (at least) 1 child attribute")
errNeedChildren = errors.New("need (at least) 2 child attributes")
errIncorrectSize = errors.New("binary attribute data has incorrect size")
)

const (
errUnknownEventType = "unknown event type %d"
errWorkerCount = "invalid worker count %s"
errMessageTypeRange = "message (event) type %x out of range for Netlink subscription"
errRecover = "recovered from panic in function %s: %s"
errWorkerReceive = "netlink.Receive error in listenWorker %d, exiting"
errUnknownEventType = "unknown event type %d"
errWorkerCount = "invalid worker count %s"
errMessageTypeRange = "message (event) type %x out of range for Netlink subscription"
errRecover = "recovered from panic in function %s: %s"
errWorkerReceive = "netlink.Receive error in listenWorker %d, exiting"
errAttributeWrongType = "attribute type '%d' is not a %s"
errAttributeChild = "child Type '%d' unknown for attribute type %s"
errAttributeUnknown = "attribute type '%d' unknown"
errExactChildren = "need exactly %d child attributes for attribute type %s"
)
2 changes: 1 addition & 1 deletion flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type Flow struct {

SeqAdjOrig, SeqAdjReply SequenceAdjust

Labels, LabelsMask Bitfield
Labels, LabelsMask Binary

Mark, MarkMask, Use Num32
}
Expand Down
62 changes: 49 additions & 13 deletions tuple.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
package conntrack

import (
"errors"
"fmt"
"net"

"github.com/pkg/errors"

"github.com/ti-mo/netfilter"
)

var (
ctaTupleOrigReplyMasterCat = fmt.Sprintf("%s/%s/%s", CTATupleOrig, CTATupleReply, CTATupleMaster)
)

const (
opUnTup = "Tuple unmarshal"
opUnIPTup = "IPTuple unmarshal"
opUnPTup = "ProtoTuple unmarshal"
)

// A Tuple holds an IPTuple, ProtoTuple and a Zone.
type Tuple struct {
IP IPTuple
Expand All @@ -18,13 +29,19 @@ type Tuple struct {
// UnmarshalAttribute unmarshals a netfilter.Attribute into a Tuple.
func (t *Tuple) UnmarshalAttribute(attr netfilter.Attribute) error {

if AttributeType(attr.Type) != CTATupleOrig &&
AttributeType(attr.Type) != CTATupleReply &&
AttributeType(attr.Type) != CTATupleMaster {
return errors.Wrap(fmt.Errorf(errAttributeWrongType, attr.Type, ctaTupleOrigReplyMasterCat), opUnTup)
}

if !attr.Nested {
return errNotNested
return errors.Wrap(errNotNested, opUnTup)
}

// A Tuple will always consist of more than one child attribute
if len(attr.Children) < 2 {
return errNeedChildren
return errors.Wrap(errNeedChildren, opUnTup)
}

for _, iattr := range attr.Children {
Expand All @@ -47,7 +64,7 @@ func (t *Tuple) UnmarshalAttribute(attr netfilter.Attribute) error {
}
t.Zone = iattr.Uint16()
default:
return fmt.Errorf("error: UnmarshalAttribute - unknown TupleType %v", iattr.Type)
return errors.Wrap(fmt.Errorf(errAttributeChild, iattr.Type, AttributeType(attr.Type)), opUnTup)
}
}

Expand All @@ -68,15 +85,15 @@ type IPTuple struct {
func (ipt *IPTuple) UnmarshalAttribute(attr netfilter.Attribute) error {

if TupleType(attr.Type) != CTATupleIP {
return fmt.Errorf("error: UnmarshalAttribute - %v is not a CTA_TUPLE_IP", attr.Type)
return fmt.Errorf(errAttributeWrongType, attr.Type, CTATupleIP)
}

if !attr.Nested {
return errNotNested
return errors.Wrap(errNotNested, opUnIPTup)
}

if len(attr.Children) != 2 {
return errors.New("error: UnmarshalAttribute - IPTuple expects exactly two children")
return errors.Wrap(errNeedChildren, opUnIPTup)
}

for _, iattr := range attr.Children {
Expand All @@ -91,7 +108,7 @@ func (ipt *IPTuple) UnmarshalAttribute(attr netfilter.Attribute) error {
case CTAIPv4Dst, CTAIPv6Dst:
ipt.DestinationAddress = net.IP(iattr.Data)
default:
return fmt.Errorf("error: UnmarshalAttribute - unknown IPTupleType %v", iattr.Type)
return errors.Wrap(fmt.Errorf(errAttributeChild, iattr.Type, CTATupleIP), opUnIPTup)
}
}

Expand All @@ -103,21 +120,28 @@ type ProtoTuple struct {
Protocol uint8
SourcePort uint16
DestinationPort uint16

ICMPv4 bool
ICMPv6 bool

ICMPID uint16
ICMPType uint8
ICMPCode uint8
}

// UnmarshalAttribute unmarshals a netfilter.Attribute into a ProtoTuple.
func (pt *ProtoTuple) UnmarshalAttribute(attr netfilter.Attribute) error {

if TupleType(attr.Type) != CTATupleProto {
return fmt.Errorf("error: UnmarshalAttribute - %v is not a CTA_TUPLE_PROTO", attr.Type)
return fmt.Errorf(errAttributeWrongType, attr.Type, CTATupleProto)
}

if !attr.Nested {
return errNotNested
return errors.Wrap(errNotNested, opUnPTup)
}

if len(attr.Children) != 3 {
return errors.New("error: UnmarshalAttribute - ProtoTuple expects exactly three children")
if len(attr.Children) == 0 {
return errors.Wrap(errNeedSingleChild, opUnPTup)
}

for _, iattr := range attr.Children {
Expand All @@ -128,8 +152,20 @@ func (pt *ProtoTuple) UnmarshalAttribute(attr netfilter.Attribute) error {
pt.SourcePort = iattr.Uint16()
case CTAProtoDstPort:
pt.DestinationPort = iattr.Uint16()
case CTAProtoICMPID:
pt.ICMPv4 = true
pt.ICMPID = iattr.Uint16()
case CTAProtoICMPv6ID:
pt.ICMPv6 = true
pt.ICMPID = iattr.Uint16()
case CTAProtoICMPType:
case CTAProtoICMPv6Type:
pt.ICMPType = iattr.Data[0]
case CTAProtoICMPCode:
case CTAProtoICMPv6Code:
pt.ICMPCode = iattr.Data[0]
default:
return fmt.Errorf("error: UnmarshalAttribute - unknown ProtoTupleType %v", iattr.Type)
return errors.Wrap(fmt.Errorf(errAttributeChild, iattr.Type, CTATupleProto), opUnPTup)
}
}

Expand Down
Loading

0 comments on commit bdf55f7

Please sign in to comment.