package nflog import ( "encoding/binary" "testing" "golang.org/x/sys/unix" ) // message builds an nfnetlink_log packet message as the kernel sends it. func message(family byte, attrs ...[]byte) []byte { body := []byte{family, 0, 0x10, 0x4b} // nfgenmsg: family, version, group 4171 for _, a := range attrs { body = append(body, a...) } msg := make([]byte, headerLen, headerLen+len(body)) binary.LittleEndian.PutUint32(msg, uint32(headerLen+len(body))) binary.LittleEndian.PutUint16(msg[4:], subsysULOG<<8|msgPacket) return append(msg, body...) } func be32(v uint32) []byte { b := make([]byte, 4); binary.BigEndian.PutUint32(b, v); return b } func TestParse(t *testing.T) { // An IPv4 TCP SYN from 203.0.113.9:40000 to 217.155.8.194:22. ip := []byte{0x45, 0, 0, 60, 0, 0, 0, 0, 64, 6, 0, 0, 203, 0, 113, 9, 217, 155, 8, 194} tcp := []byte{0x9c, 0x40, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0x50, 0x02, 0, 0, 0, 0, 0, 0} m1 := message(unix.AF_INET, attr(attrPrefix, []byte("hc input #12 drop: \x00")), attr(attrInDev, be32(3)), attr(attrPayload, append(ip, tcp...))) // An IPv6 echo request, logged by the forward policy. ip6 := make([]byte, 40) ip6[0], ip6[6] = 0x60, 58 ip6[8], ip6[9], ip6[23] = 0x2a, 0x02, 0x01 // source 2a02::1 ip6[24], ip6[25], ip6[39] = 0x20, 0x01, 0x57 // destination 2001::57 m2 := message(unix.AF_INET6, attr(attrPrefix, []byte("hc forward policy drop: \x00")), attr(attrOutDev, be32(4)), attr(attrPayload, append(ip6, 128, 0, 0, 0))) names := map[uint32]string{3: "wan", 4: "enp2s0"} es := Parse(append(m1, m2...), func(i uint32) string { return names[i] }) if len(es) != 2 { t.Fatalf("%d entries", len(es)) } e := es[0] if e.Family != "ipv4" || e.Source != "203.0.113.9" || e.Dest != "217.155.8.194" || e.Protocol != "tcp" || e.SrcPort != 40000 || e.DestPort != 22 || e.TCPFlags != "syn" || e.In != "wan" || e.RuleMark != "r12" || e.Verdict != "drop" || e.Length != 60 { t.Errorf("v4 entry %+v", e) } e = es[1] if e.Family != "ipv6" || e.Source != "2a02::1" || e.Dest != "2001::57" || e.Protocol != "icmpv6" || e.ICMPType != "echo-request" || e.Out != "enp2s0" || e.RuleMark != "p-forward" { t.Errorf("v6 entry %+v", e) } }