// UnmarshalBinary unmarshals the contents of a byte slice into an Attribute. func (a *Attribute) UnmarshalBinary(b []byte) error { if len(b) < nlaHeaderLen { return errInvalidAttribute } a.Length = nlenc.Uint16(b[0:2]) a.Type = nlenc.Uint16(b[2:4]) if nlaAlign(int(a.Length)) > len(b) { return errInvalidAttribute } switch { // No length, no data case a.Length == 0: a.Data = make([]byte, 0) // Not enough length for any data case a.Length < 4: return errInvalidAttribute // Data present case a.Length >= 4: a.Data = make([]byte, len(b[4:a.Length])) copy(a.Data, b[4:a.Length]) } return nil }
// parseAttributes parses netlink attributes into a Family's fields. func (f *Family) parseAttributes(attrs []netlink.Attribute) error { for _, a := range attrs { switch a.Type { case attrFamilyID: f.ID = nlenc.Uint16(a.Data) case attrFamilyName: f.Name = nlenc.String(a.Data) case attrVersion: v := nlenc.Uint32(a.Data) if v > math.MaxUint8 { return errInvalidFamilyVersion } f.Version = uint8(v) case attrMulticastGroups: groups, err := parseMulticastGroups(a.Data) if err != nil { return err } f.Groups = groups } } return nil }
// parseRateInfo parses a rateInfo from netlink attributes. func parseRateInfo(b []byte) (*rateInfo, error) { attrs, err := netlink.UnmarshalAttributes(b) if err != nil { return nil, err } var info rateInfo for _, a := range attrs { switch a.Type { case nl80211.RateInfoBitrate32: info.Bitrate = int(nlenc.Uint32(a.Data)) } // Only use 16-bit counters if the 32-bit counters are not present. // If the 32-bit counters appear later in the slice, they will overwrite // these values. if info.Bitrate == 0 && a.Type == nl80211.RateInfoBitrate { info.Bitrate = int(nlenc.Uint16(a.Data)) } } // Scale bitrate to bits/second as base unit instead of 100kbits/second. // * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) info.Bitrate *= 100 * 1000 return &info, nil }
// UnmarshalBinary unmarshals the contents of a byte slice into a Message. func (m *Message) UnmarshalBinary(b []byte) error { if len(b) < nlmsgHeaderLen { return errShortMessage } if len(b) != nlmsgAlign(len(b)) { return errUnalignedMessage } // Don't allow misleading length m.Header.Length = nlenc.Uint32(b[0:4]) if int(m.Header.Length) != len(b) { return errShortMessage } m.Header.Type = HeaderType(nlenc.Uint16(b[4:6])) m.Header.Flags = HeaderFlags(nlenc.Uint16(b[6:8])) m.Header.Sequence = nlenc.Uint32(b[8:12]) m.Header.PID = nlenc.Uint32(b[12:16]) m.Data = b[16:] return nil }