Browse Source

Internal refactoring (#5)

Signed-off-by: Lehner Florian <dev@der-flo.net>
tags/v2.0.0^0
Florian Lehner 2 years ago
committed by GitHub
parent
commit
327225dbfd
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 89 additions and 70 deletions
  1. +1
    -1
      .travis.yml
  2. +46
    -26
      attribute.go
  3. +3
    -3
      example_test.go
  4. +4
    -4
      nfqueue.go
  5. +3
    -3
      nfqueue_linux_gteq_1.12_integration_test.go
  6. +4
    -3
      nfqueue_linux_integration_test.go
  7. +28
    -30
      types.go

+ 1
- 1
.travis.yml View File

@@ -13,7 +13,7 @@ install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq update ; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo modprobe nfnetlink_queue ; fi
- go get golang.org/x/lint/golint
- go get -d ./...
- go get -d -t ./...

before_script:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo ip6tables -I OUTPUT -p ipv6-icmp -j NFQUEUE --queue-num 100 ; fi


+ 46
- 26
attribute.go View File

@@ -12,7 +12,7 @@ import (
"golang.org/x/sys/unix"
)

func extractAttribute(log *log.Logger, m Msg, data []byte) error {
func extractAttribute(log *log.Logger, a *Attribute, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data)
if err != nil {
return err
@@ -21,11 +21,15 @@ func extractAttribute(log *log.Logger, m Msg, data []byte) error {
for ad.Next() {
switch ad.Type() {
case nfQaPacketHdr:
m[AttrPacketID] = binary.BigEndian.Uint32(ad.Bytes()[:4])
m[AttrHwProtocol] = binary.BigEndian.Uint16(ad.Bytes()[4:6])
m[AttrHook] = ad.Bytes()[6]
packetID := binary.BigEndian.Uint32(ad.Bytes()[:4])
a.PacketID = &packetID
hwProto := binary.BigEndian.Uint16(ad.Bytes()[4:6])
a.HwProtocol = &hwProto
hook := uint8(ad.Bytes()[6])
a.Hook = &hook
case nfQaMark:
m[AttrMark] = ad.Uint32()
mark := ad.Uint32()
a.Mark = &mark
case nfQaTimestamp:
var sec, usec int64
r := bytes.NewReader(ad.Bytes()[:8])
@@ -36,38 +40,54 @@ func extractAttribute(log *log.Logger, m Msg, data []byte) error {
if err := binary.Read(r, binary.BigEndian, &usec); err != nil {
return err
}
m[AttrTimestamp] = time.Unix(sec, usec*1000)
timestamp := time.Unix(sec, usec*1000)
a.Timestamp = &timestamp
case nfQaIfIndexInDev:
m[AttrIfIndexInDev] = ad.Uint32()
inDev := ad.Uint32()
a.InDev = &inDev
case nfQaIfIndexOutDev:
m[AttrIfIndexOutDev] = ad.Uint32()
outDev := ad.Uint32()
a.OutDev = &outDev
case nfQaIfIndexPhysInDev:
m[AttrIfIndexPhysInDev] = ad.Uint32()
physInDev := ad.Uint32()
a.PhysInDev = &physInDev
case nfQaIfIndexPhysOutDev:
m[AttrIfIndexPhysOutDev] = ad.Uint32()
physOutDev := ad.Uint32()
a.PhysOutDev = &physOutDev
case nfQaHwAddr:
hwAddrLen := binary.BigEndian.Uint16(ad.Bytes()[:2])
m[AttrHwAddr] = (ad.Bytes())[4 : 4+hwAddrLen]
hwAddr := (ad.Bytes())[4 : 4+hwAddrLen]
a.HwAddr = &hwAddr
case nfQaPayload:
m[AttrPayload] = ad.Bytes()
payload := ad.Bytes()
a.Payload = &payload
case nfQaCt:
m[AttrCt] = ad.Bytes()
ct := ad.Bytes()
a.Ct = &ct
case nfQaCtInfo:
m[AttrCtInfo] = ad.Bytes()
ctInfo := ad.Uint32()
a.CtInfo = &ctInfo
case nfQaCapLen:
m[AttrCapLen] = ad.Uint32()
capLen := ad.Uint32()
a.CapLen = &capLen
case nfQaSkbInfo:
m[AttrSkbInfo] = ad.Bytes()
skbInfo := ad.Bytes()
a.SkbInfo = &skbInfo
case nfQaExp:
m[AttrExp] = ad.Bytes()
exp := ad.Bytes()
a.Exp = &exp
case nfQaUID:
m[AttrUID] = ad.Uint32()
uid := ad.Uint32()
a.UID = &uid
case nfQaGID:
m[AttrGID] = ad.Uint32()
gid := ad.Uint32()
a.GID = &gid
case nfQaSecCtx:
m[AttrSecCtx] = ad.String()
secCtx := ad.String()
a.SecCtx = &secCtx
case nfQaL2HDR:
m[AttrL2HDR] = ad.Bytes()
l2hdr := ad.Bytes()
a.L2Hdr = &l2hdr
default:
log.Printf("Unknown attribute Type: 0x%x\tData: %v\n", ad.Type(), ad.Bytes())
}
@@ -83,12 +103,12 @@ func checkHeader(data []byte) int {
return 0
}

func extractAttributes(log *log.Logger, msg []byte) (Msg, error) {
var data = make(Msg)
func extractAttributes(log *log.Logger, msg []byte) (Attribute, error) {
attrs := Attribute{}

offset := checkHeader(msg[:2])
if err := extractAttribute(log, data, msg[offset:]); err != nil {
return nil, err
if err := extractAttribute(log, &attrs, msg[offset:]); err != nil {
return attrs, err
}
return data, nil
return attrs, nil
}

+ 3
- 3
example_test.go View File

@@ -34,10 +34,10 @@ func ExampleNfqueue_Register() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

fn := func(m nfqueue.Msg) int {
id := m[nfqueue.AttrPacketID].(uint32)
fn := func(a nfqueue.Attribute) int {
id := *a.PacketID
// Just print out the id and payload of the nfqueue packet
fmt.Printf("[%d]\t%v\n", id, m[nfqueue.AttrPayload])
fmt.Printf("[%d]\t%v\n", id, *a.Payload)
nf.SetVerdict(id, nfqueue.NfAccept)
return 0
}


+ 4
- 4
nfqueue.go View File

@@ -148,10 +148,10 @@ func (nfqueue *Nfqueue) execute(req netlink.Message) (uint32, error) {
return seq, nil
}

func parseMsg(log *log.Logger, msg netlink.Message) (Msg, error) {
m, err := extractAttributes(log, msg.Data)
func parseMsg(log *log.Logger, msg netlink.Message) (Attribute, error) {
a, err := extractAttributes(log, msg.Data)
if err != nil {
return nil, err
return a, err
}
return m, nil
return a, nil
}

+ 3
- 3
nfqueue_linux_gteq_1.12_integration_test.go View File

@@ -30,10 +30,10 @@ func TestTimeout(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()

fn := func(m Msg) int {
id := m[AttrPacketID].(uint32)
fn := func(a Attribute) int {
id := *a.PacketID
// Just print out the id and payload of the nfqueue packet
t.Logf("[%d]\t%v\n", id, m[AttrPayload])
t.Logf("[%d]\t%v\n", id, *a.Payload)
nfq.SetVerdict(id, NfAccept)
return 0
}


+ 4
- 3
nfqueue_linux_integration_test.go View File

@@ -15,6 +15,7 @@ func TestLinuxNfqueue(t *testing.T) {
MaxPacketLen: 0xFFFF,
MaxQueueLen: 0xFF,
Copymode: NfQnlCopyPacket,
ReadTimeout: 10 * time.Millisecond,
}
// Open a socket to the netfilter log subsystem
nfq, err := Open(&config)
@@ -26,10 +27,10 @@ func TestLinuxNfqueue(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

fn := func(m Msg) int {
id := m[AttrPacketID].(uint32)
fn := func(a Attribute) int {
id := *a.PacketID
// Just print out the id and payload of the nfqueue packet
t.Logf("[%d]\t%v\n", id, m[AttrPayload])
t.Logf("[%d]\t%v\n", id, *a.Payload)
nfq.SetVerdict(id, NfAccept)
return 0
}


+ 28
- 30
types.go View File

@@ -6,9 +6,36 @@ import (
"time"
)

// Attribute contains various elements for nfqueue elements.
// As not every value is contained in every nfqueue message,
// the elements inside Attribute are pointers to these values
// or nil, if not present.
type Attribute struct {
PacketID *uint32
Hook *uint8
Timestamp *time.Time
Mark *uint32
InDev *uint32
PhysInDev *uint32
OutDev *uint32
PhysOutDev *uint32
Payload *[]byte
CapLen *uint32
UID *uint32
GID *uint32
SecCtx *string
L2Hdr *[]byte
HwAddr *[]byte
HwProtocol *uint16
Ct *[]byte
CtInfo *uint32
SkbInfo *[]byte
Exp *[]byte
}

// HookFunc is a function, that receives events from a Netlinkgroup
// To stop receiving messages on this HookFunc, return something different than 0
type HookFunc func(m Msg) int
type HookFunc func(a Attribute) int

// Config contains options for a Conn.
type Config struct {
@@ -52,38 +79,9 @@ var (
ErrInvalidVerdict = errors.New("Invalid verdict")
)

// Msg contains all the information of a connection
type Msg map[int]interface{}

// nfLogSubSysQueue the netlink subsystem we will query
const nfnlSubSysQueue = 0x03

// Various identifier,that can be the key of Msg map
const (
AttrPacketID = iota
AttrHook
AttrHwProtocol
AttrIfIndexInDev
AttrIfIndexOutDev
AttrIfIndexPhysInDev
AttrIfIndexPhysOutDev
AttrPayload
AttrCapLen
AttrTimestamp
AttrHwAddr
AttrMark
AttrUID
AttrGID
AttrL2HDR
AttrCt
AttrCtInfo
AttrSkbInfo
AttrExp
AttrSecCtx
AttrVlanProto
AttrVlanTCI
)

const (
nfQaUnspec = iota
nfQaPacketHdr


Loading…
Cancel
Save