message.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package genetlink
  2. import "errors"
  3. // errInvalidMessage is returned when a Message is malformed.
  4. var errInvalidMessage = errors.New("generic netlink message is invalid or too short")
  5. // A Header is a generic netlink header. A Header is sent and received with
  6. // each generic netlink message to indicate metadata regarding a Message.
  7. type Header struct {
  8. // Command specifies a command to issue to netlink.
  9. Command uint8
  10. // Version specifies the version of a command to use.
  11. Version uint8
  12. }
  13. // headerLen is the length of a Header.
  14. const headerLen = 4 // unix.GENL_HDRLEN
  15. // A Message is a generic netlink message. It contains a Header and an
  16. // arbitrary byte payload, which may be decoded using information from the
  17. // Header.
  18. //
  19. // Data is encoded using the native endianness of the host system. Use
  20. // the netlink.AttributeDecoder and netlink.AttributeEncoder types to decode
  21. // and encode data.
  22. type Message struct {
  23. Header Header
  24. Data []byte
  25. }
  26. // MarshalBinary marshals a Message into a byte slice.
  27. func (m Message) MarshalBinary() ([]byte, error) {
  28. b := make([]byte, headerLen)
  29. b[0] = m.Header.Command
  30. b[1] = m.Header.Version
  31. // b[2] and b[3] are padding bytes and set to zero
  32. return append(b, m.Data...), nil
  33. }
  34. // UnmarshalBinary unmarshals the contents of a byte slice into a Message.
  35. func (m *Message) UnmarshalBinary(b []byte) error {
  36. if len(b) < headerLen {
  37. return errInvalidMessage
  38. }
  39. // Don't allow reserved pad bytes to be set
  40. if b[2] != 0 || b[3] != 0 {
  41. return errInvalidMessage
  42. }
  43. m.Header.Command = b[0]
  44. m.Header.Version = b[1]
  45. m.Data = b[4:]
  46. return nil
  47. }