Created
March 14, 2017 16:42
-
-
Save ti-mo/513aadd02922062e0a265b64876294bc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"errors" | |
"encoding/binary" | |
"syscall" | |
) | |
func main() { | |
dump1 := []byte{52, 0, 1, 128, 20, 0, 1, 128, 8, 0, 1, 0, 172, 17, 0, 2, 8, 0, 2, 0, 192, 168, 65, 1, 28, 0, 2, 128, 5, 0, 1, 0, 17, 0, 0, 0, 6, 0, 2, 0, 215, 32, 0, 0, 6, 0, 3, 0, 0, 53, 0, 0, 52, 0, 2, 128, 20, 0, 1, 128, 8, 0, 1, 0, 192, 168, 65, 1, 8, 0, 2, 0, 172, 17, 0, 2, 28, 0, 2, 128, 5, 0, 1, 0, 17, 0, 0, 0, 6, 0, 2, 0, 0, 53, 0, 0, 6, 0, 3, 0, 215, 32, 0, 0, 8, 0, 12, 0, 239, 175, 148, 0, 8, 0, 3, 0, 0, 0, 0, 8, 8, 0, 7, 0, 0, 0, 0, 30} | |
dump2 := []byte{52, 0, 1, 128, 20, 0, 1, 128, 8, 0, 1, 0, 172, 17, 0, 2, 8, 0, 2, 0, 192, 168, 65, 1, 28, 0, 2, 128, 5, 0, 1, 0, 17, 0, 0, 0, 6, 0, 2, 0, 183, 16, 0, 0, 6, 0, 3, 0, 0, 53, 0, 0, 52, 0, 2, 128, 20, 0, 1, 128, 8, 0, 1, 0, 192, 168, 65, 1, 8, 0, 2, 0, 172, 17, 0, 2, 28, 0, 2, 128, 5, 0, 1, 0, 17, 0, 0, 0, 6, 0, 2, 0, 0, 53, 0, 0, 6, 0, 3, 0, 183, 16, 0, 0, 8, 0, 12, 0, 239, 177, 130, 0, 8, 0, 3, 0, 0, 0, 0, 10, 8, 0, 7, 0, 0, 0, 0, 30} | |
dump3 := []byte{60, 0, 1, 128, 20, 0, 1, 128, 8, 0, 1, 0, 172, 17, 0, 2, 8, 0, 2, 0, 172, 217, 0, 14, 36, 0, 2, 128, 5, 0, 1, 0, 1, 0, 0, 0, 6, 0, 4, 0, 12, 155, 0, 0, 5, 0, 5, 0, 8, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 60, 0, 2, 128, 20, 0, 1, 128, 8, 0, 1, 0, 172, 217, 0, 14, 8, 0, 2, 0, 172, 17, 0, 2, 36, 0, 2, 128, 5, 0, 1, 0, 1, 0, 0, 0, 6, 0, 4, 0, 12, 155, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 8, 0, 12, 0, 239, 177, 139, 0, 8, 0, 3, 0, 0, 0, 0, 8, 8, 0, 7, 0, 0, 0, 0, 30} | |
dump4 := []byte{60, 0, 1, 128, 20, 0, 1, 128, 8, 0, 1, 0, 172, 17, 0, 2, 8, 0, 2, 0, 172, 217, 0, 14, 36, 0, 2, 128, 5, 0, 1, 0, 1, 0, 0, 0, 6, 0, 4, 0, 12, 155, 0, 0, 5, 0, 5, 0, 8, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 60, 0, 2, 128, 20, 0, 1, 128, 8, 0, 1, 0, 172, 217, 0, 14, 8, 0, 2, 0, 172, 17, 0, 2, 36, 0, 2, 128, 5, 0, 1, 0, 1, 0, 0, 0, 6, 0, 4, 0, 12, 155, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 8, 0, 12, 0, 239, 177, 139, 0, 8, 0, 3, 0, 0, 0, 0, 10, 8, 0, 7, 0, 0, 0, 0, 30} | |
dump5 := []byte{60, 0, 1, 128, 20, 0, 1, 128, 8, 0, 1, 0, 172, 17, 0, 2, 8, 0, 2, 0, 172, 217, 0, 14, 36, 0, 2, 128, 5, 0, 1, 0, 1, 0, 0, 0, 6, 0, 4, 0, 12, 155, 0, 0, 5, 0, 5, 0, 8, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 60, 0, 2, 128, 20, 0, 1, 128, 8, 0, 1, 0, 172, 217, 0, 14, 8, 0, 2, 0, 172, 17, 0, 2, 36, 0, 2, 128, 5, 0, 1, 0, 1, 0, 0, 0, 6, 0, 4, 0, 12, 155, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 8, 0, 12, 0, 239, 177, 139, 0, 8, 0, 3, 0, 0, 0, 2, 10} | |
dump6 := []byte{52, 0, 1, 128, 20, 0, 1, 128, 8, 0, 1, 0, 172, 17, 0, 2, 8, 0, 2, 0, 192, 168, 65, 1, 28, 0, 2, 128, 5, 0, 1, 0, 17, 0, 0, 0, 6, 0, 2, 0, 183, 16, 0, 0, 6, 0, 3, 0, 0, 53, 0, 0, 52, 0, 2, 128, 20, 0, 1, 128, 8, 0, 1, 0, 192, 168, 65, 1, 8, 0, 2, 0, 172, 17, 0, 2, 28, 0, 2, 128, 5, 0, 1, 0, 17, 0, 0, 0, 6, 0, 2, 0, 0, 53, 0, 0, 6, 0, 3, 0, 183, 16, 0, 0, 8, 0, 12, 0, 239, 177, 130, 0, 8, 0, 3, 0, 0, 0, 2, 10} | |
parse1, _ := parseAttrs(dump1) | |
fmt.Printf("%v\n", parse1) | |
parse2, _ := parseAttrs(dump2) | |
fmt.Printf("%v\n", parse2) | |
parse3, _ := parseAttrs(dump3) | |
fmt.Printf("%v\n", parse3) | |
parse4, _ := parseAttrs(dump4) | |
fmt.Printf("%v\n", parse4) | |
parse5, _ := parseAttrs(dump5) | |
fmt.Printf("%v\n", parse5) | |
parse6, _ := parseAttrs(dump6) | |
fmt.Printf("%v\n", parse6) | |
} | |
const ( | |
// #defined in libnfnetlink/include/libnfnetlink/libnfnetlink.h | |
NLA_F_NESTED = uint16(1 << 15) | |
NLA_F_NET_BYTEORDER = uint16(1 << 14) | |
NLA_TYPE_MASK = ^(NLA_F_NESTED | NLA_F_NET_BYTEORDER) | |
NLM_F_EXCL = 0x200 | |
NLM_F_CREATE = 0x400 | |
) | |
const attrHdrLength = 4 | |
type Attr struct { | |
Msg []byte | |
Typ int | |
IsNested bool | |
IsNetByteorder bool | |
Attrs []Attr | |
} | |
func parseAttrs(b []byte) ([]Attr, error) { | |
var attrs []Attr | |
for len(b) >= attrHdrLength { | |
var attr Attr | |
attr, b = parseAttr(b) | |
attrs = append(attrs, attr) | |
} | |
if len(b) != 0 { | |
return nil, errors.New("leftover attr bytes") | |
} | |
return attrs, nil | |
} | |
func parseAttr(b []byte) (Attr, []byte) { | |
attrLen := binary.LittleEndian.Uint16(b[0:2]) | |
// length is header + payload | |
attrLen -= uint16(attrHdrLength) | |
typ := binary.LittleEndian.Uint16(b[2:4]) | |
attr := Attr{ | |
Msg: b[attrHdrLength : attrHdrLength+int(attrLen)], | |
Typ: int(typ & NLA_TYPE_MASK), | |
IsNested: typ&NLA_F_NESTED > 0, | |
IsNetByteorder: typ&NLA_F_NET_BYTEORDER > 0, | |
} | |
if attr.IsNested { | |
attr.Attrs, _ = parseAttrs(attr.Msg) | |
} | |
return attr, b[rtaAlignOf(attrHdrLength+int(attrLen)):] | |
} | |
// Round the length of a netlink route attribute up to align it | |
// properly. | |
func rtaAlignOf(attrlen int) int { | |
return (attrlen + syscall.RTA_ALIGNTO - 1) & ^(syscall.RTA_ALIGNTO - 1) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment