12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- package nl
- import (
- "encoding/binary"
- "fmt"
- "log"
- )
- type Attribute struct {
- Type uint16
- Value []byte
- }
- func ParseAttributes(data []byte) <-chan Attribute {
- native := NativeEndian()
- result := make(chan Attribute)
- go func() {
- i := 0
- for i+4 < len(data) {
- length := int(native.Uint16(data[i : i+2]))
- attrType := native.Uint16(data[i+2 : i+4])
- if length < 4 {
- log.Printf("attribute 0x%02x has invalid length of %d bytes", attrType, length)
- break
- }
- if len(data) < i+length {
- log.Printf("attribute 0x%02x of length %d is truncated, only %d bytes remaining", attrType, length, len(data)-i)
- break
- }
- result <- Attribute{
- Type: attrType,
- Value: data[i+4 : i+length],
- }
- i += rtaAlignOf(length)
- }
- close(result)
- }()
- return result
- }
- func PrintAttributes(data []byte) {
- printAttributes(data, 0)
- }
- func printAttributes(data []byte, level int) {
- for attr := range ParseAttributes(data) {
- for i := 0; i < level; i++ {
- print("> ")
- }
- nested := attr.Type&NLA_F_NESTED != 0
- fmt.Printf("type=%d nested=%v len=%v %v\n", attr.Type&NLA_TYPE_MASK, nested, len(attr.Value), attr.Value)
- if nested {
- printAttributes(attr.Value, level+1)
- }
- }
- }
- // Uint32 returns the uint32 value respecting the NET_BYTEORDER flag
- func (attr *Attribute) Uint32() uint32 {
- if attr.Type&NLA_F_NET_BYTEORDER != 0 {
- return binary.BigEndian.Uint32(attr.Value)
- } else {
- return NativeEndian().Uint32(attr.Value)
- }
- }
- // Uint64 returns the uint64 value respecting the NET_BYTEORDER flag
- func (attr *Attribute) Uint64() uint64 {
- if attr.Type&NLA_F_NET_BYTEORDER != 0 {
- return binary.BigEndian.Uint64(attr.Value)
- } else {
- return NativeEndian().Uint64(attr.Value)
- }
- }
|