attribute.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. package netlink
  2. import (
  3. "encoding/binary"
  4. "errors"
  5. "fmt"
  6. "github.com/mdlayher/netlink/nlenc"
  7. )
  8. // errInvalidAttribute specifies if an Attribute's length is incorrect.
  9. var errInvalidAttribute = errors.New("invalid attribute; length too short or too large")
  10. // An Attribute is a netlink attribute. Attributes are packed and unpacked
  11. // to and from the Data field of Message for some netlink families.
  12. type Attribute struct {
  13. // Length of an Attribute, including this field and Type.
  14. Length uint16
  15. // The type of this Attribute, typically matched to a constant. Note that
  16. // flags such as Nested and NetByteOrder must be handled manually when
  17. // working with Attribute structures directly.
  18. Type uint16
  19. // An arbitrary payload which is specified by Type.
  20. Data []byte
  21. }
  22. // marshal marshals the contents of a into b and returns the number of bytes
  23. // written to b, including attribute alignment padding.
  24. func (a *Attribute) marshal(b []byte) (int, error) {
  25. if int(a.Length) < nlaHeaderLen {
  26. return 0, errInvalidAttribute
  27. }
  28. nlenc.PutUint16(b[0:2], a.Length)
  29. nlenc.PutUint16(b[2:4], a.Type)
  30. n := copy(b[nlaHeaderLen:], a.Data)
  31. return nlaHeaderLen + nlaAlign(n), nil
  32. }
  33. // unmarshal unmarshals the contents of a byte slice into an Attribute.
  34. func (a *Attribute) unmarshal(b []byte) error {
  35. if len(b) < nlaHeaderLen {
  36. return errInvalidAttribute
  37. }
  38. a.Length = nlenc.Uint16(b[0:2])
  39. a.Type = nlenc.Uint16(b[2:4])
  40. if int(a.Length) > len(b) {
  41. return errInvalidAttribute
  42. }
  43. switch {
  44. // No length, no data
  45. case a.Length == 0:
  46. a.Data = make([]byte, 0)
  47. // Not enough length for any data
  48. case int(a.Length) < nlaHeaderLen:
  49. return errInvalidAttribute
  50. // Data present
  51. case int(a.Length) >= nlaHeaderLen:
  52. a.Data = make([]byte, len(b[nlaHeaderLen:a.Length]))
  53. copy(a.Data, b[nlaHeaderLen:a.Length])
  54. }
  55. return nil
  56. }
  57. // MarshalAttributes packs a slice of Attributes into a single byte slice.
  58. // In most cases, the Length field of each Attribute should be set to 0, so it
  59. // can be calculated and populated automatically for each Attribute.
  60. //
  61. // It is recommend to use the AttributeEncoder type where possible instead of
  62. // calling MarshalAttributes and using package nlenc functions directly.
  63. func MarshalAttributes(attrs []Attribute) ([]byte, error) {
  64. // Count how many bytes we should allocate to store each attribute's contents.
  65. var c int
  66. for _, a := range attrs {
  67. c += nlaHeaderLen + nlaAlign(len(a.Data))
  68. }
  69. // Advance through b with idx to place attribute data at the correct offset.
  70. var idx int
  71. b := make([]byte, c)
  72. for _, a := range attrs {
  73. // Infer the length of attribute if zero.
  74. if a.Length == 0 {
  75. a.Length = uint16(nlaHeaderLen + len(a.Data))
  76. }
  77. // Marshal a into b and advance idx to show many bytes are occupied.
  78. n, err := a.marshal(b[idx:])
  79. if err != nil {
  80. return nil, err
  81. }
  82. idx += n
  83. }
  84. return b, nil
  85. }
  86. // UnmarshalAttributes unpacks a slice of Attributes from a single byte slice.
  87. //
  88. // It is recommend to use the AttributeDecoder type where possible instead of calling
  89. // UnmarshalAttributes and using package nlenc functions directly.
  90. func UnmarshalAttributes(b []byte) ([]Attribute, error) {
  91. ad, err := NewAttributeDecoder(b)
  92. if err != nil {
  93. return nil, err
  94. }
  95. // Return a nil slice when there are no attributes to decode.
  96. if ad.Len() == 0 {
  97. return nil, nil
  98. }
  99. attrs := make([]Attribute, 0, ad.Len())
  100. for ad.Next() {
  101. if ad.attr().Length != 0 {
  102. attrs = append(attrs, ad.attr())
  103. }
  104. }
  105. if err := ad.Err(); err != nil {
  106. return nil, err
  107. }
  108. return attrs, nil
  109. }
  110. // An AttributeDecoder provides a safe, iterator-like, API around attribute
  111. // decoding.
  112. //
  113. // It is recommend to use an AttributeDecoder where possible instead of calling
  114. // UnmarshalAttributes and using package nlenc functions directly.
  115. //
  116. // The Err method must be called after the Next method returns false to determine
  117. // if any errors occurred during iteration.
  118. type AttributeDecoder struct {
  119. // ByteOrder defines a specific byte order to use when processing integer
  120. // attributes. ByteOrder should be set immediately after creating the
  121. // AttributeDecoder: before any attributes are parsed.
  122. //
  123. // If not set, the native byte order will be used.
  124. ByteOrder binary.ByteOrder
  125. // The current attribute being worked on.
  126. a Attribute
  127. // The slice of input bytes and its iterator index.
  128. b []byte
  129. i int
  130. length int
  131. // Any error encountered while decoding attributes.
  132. err error
  133. }
  134. // NewAttributeDecoder creates an AttributeDecoder that unpacks Attributes
  135. // from b and prepares the decoder for iteration.
  136. func NewAttributeDecoder(b []byte) (*AttributeDecoder, error) {
  137. ad := &AttributeDecoder{
  138. // By default, use native byte order.
  139. ByteOrder: nlenc.NativeEndian(),
  140. b: b,
  141. }
  142. var err error
  143. ad.length, err = ad.available()
  144. if err != nil {
  145. return nil, err
  146. }
  147. return ad, nil
  148. }
  149. // Next advances the decoder to the next netlink attribute. It returns false
  150. // when no more attributes are present, or an error was encountered.
  151. func (ad *AttributeDecoder) Next() bool {
  152. if ad.err != nil {
  153. // Hit an error, stop iteration.
  154. return false
  155. }
  156. // Exit if array pointer is at or beyond the end of the slice.
  157. if ad.i >= len(ad.b) {
  158. return false
  159. }
  160. if err := ad.a.unmarshal(ad.b[ad.i:]); err != nil {
  161. ad.err = err
  162. return false
  163. }
  164. // Advance the pointer by at least one header's length.
  165. if int(ad.a.Length) < nlaHeaderLen {
  166. ad.i += nlaHeaderLen
  167. } else {
  168. ad.i += nlaAlign(int(ad.a.Length))
  169. }
  170. return true
  171. }
  172. // Type returns the Attribute.Type field of the current netlink attribute
  173. // pointed to by the decoder.
  174. //
  175. // Type masks off the high bits of the netlink attribute type which may contain
  176. // the Nested and NetByteOrder flags. These can be obtained by calling TypeFlags.
  177. func (ad *AttributeDecoder) Type() uint16 {
  178. // Mask off any flags stored in the high bits.
  179. return ad.a.Type & attrTypeMask
  180. }
  181. // TypeFlags returns the two high bits of the Attribute.Type field of the current
  182. // netlink attribute pointed to by the decoder.
  183. //
  184. // These bits of the netlink attribute type are used for the Nested and NetByteOrder
  185. // flags, available as the Nested and NetByteOrder constants in this package.
  186. func (ad *AttributeDecoder) TypeFlags() uint16 {
  187. return ad.a.Type & ^attrTypeMask
  188. }
  189. // Len returns the number of netlink attributes pointed to by the decoder.
  190. func (ad *AttributeDecoder) Len() int { return ad.length }
  191. // count scans the input slice to count the number of netlink attributes
  192. // that could be decoded by Next().
  193. func (ad *AttributeDecoder) available() (int, error) {
  194. var i, count int
  195. for {
  196. // No more data to read.
  197. if i >= len(ad.b) {
  198. break
  199. }
  200. // Make sure there's at least a header's worth
  201. // of data to read on each iteration.
  202. if len(ad.b[i:]) < nlaHeaderLen {
  203. return 0, errInvalidAttribute
  204. }
  205. // Extract the length of the attribute.
  206. l := int(nlenc.Uint16(ad.b[i : i+2]))
  207. // Ignore zero-length attributes.
  208. if l != 0 {
  209. count++
  210. }
  211. // Advance by at least a header's worth of bytes.
  212. if l < nlaHeaderLen {
  213. l = nlaHeaderLen
  214. }
  215. i += nlaAlign(l)
  216. }
  217. return count, nil
  218. }
  219. // attr returns the current Attribute pointed to by the decoder.
  220. func (ad *AttributeDecoder) attr() Attribute {
  221. return ad.a
  222. }
  223. // data returns the Data field of the current Attribute pointed to by the decoder.
  224. func (ad *AttributeDecoder) data() []byte {
  225. return ad.a.Data
  226. }
  227. // Err returns the first error encountered by the decoder.
  228. func (ad *AttributeDecoder) Err() error {
  229. return ad.err
  230. }
  231. // Bytes returns the raw bytes of the current Attribute's data.
  232. func (ad *AttributeDecoder) Bytes() []byte {
  233. src := ad.data()
  234. dest := make([]byte, len(src))
  235. copy(dest, src)
  236. return dest
  237. }
  238. // String returns the string representation of the current Attribute's data.
  239. func (ad *AttributeDecoder) String() string {
  240. if ad.err != nil {
  241. return ""
  242. }
  243. return nlenc.String(ad.data())
  244. }
  245. // Uint8 returns the uint8 representation of the current Attribute's data.
  246. func (ad *AttributeDecoder) Uint8() uint8 {
  247. if ad.err != nil {
  248. return 0
  249. }
  250. b := ad.data()
  251. if len(b) != 1 {
  252. ad.err = fmt.Errorf("netlink: attribute %d is not a uint8; length: %d", ad.Type(), len(b))
  253. return 0
  254. }
  255. return uint8(b[0])
  256. }
  257. // Uint16 returns the uint16 representation of the current Attribute's data.
  258. func (ad *AttributeDecoder) Uint16() uint16 {
  259. if ad.err != nil {
  260. return 0
  261. }
  262. b := ad.data()
  263. if len(b) != 2 {
  264. ad.err = fmt.Errorf("netlink: attribute %d is not a uint16; length: %d", ad.Type(), len(b))
  265. return 0
  266. }
  267. return ad.ByteOrder.Uint16(b)
  268. }
  269. // Uint32 returns the uint32 representation of the current Attribute's data.
  270. func (ad *AttributeDecoder) Uint32() uint32 {
  271. if ad.err != nil {
  272. return 0
  273. }
  274. b := ad.data()
  275. if len(b) != 4 {
  276. ad.err = fmt.Errorf("netlink: attribute %d is not a uint32; length: %d", ad.Type(), len(b))
  277. return 0
  278. }
  279. return ad.ByteOrder.Uint32(b)
  280. }
  281. // Uint64 returns the uint64 representation of the current Attribute's data.
  282. func (ad *AttributeDecoder) Uint64() uint64 {
  283. if ad.err != nil {
  284. return 0
  285. }
  286. b := ad.data()
  287. if len(b) != 8 {
  288. ad.err = fmt.Errorf("netlink: attribute %d is not a uint64; length: %d", ad.Type(), len(b))
  289. return 0
  290. }
  291. return ad.ByteOrder.Uint64(b)
  292. }
  293. // Flag returns a boolean representing the Attribute.
  294. func (ad *AttributeDecoder) Flag() bool {
  295. if ad.err != nil {
  296. return false
  297. }
  298. b := ad.data()
  299. if len(b) != 0 {
  300. ad.err = fmt.Errorf("netlink: attribute %d is not a flag; length: %d", ad.Type(), len(b))
  301. return false
  302. }
  303. return true
  304. }
  305. // Do is a general purpose function which allows access to the current data
  306. // pointed to by the AttributeDecoder.
  307. //
  308. // Do can be used to allow parsing arbitrary data within the context of the
  309. // decoder. Do is most useful when dealing with nested attributes, attribute
  310. // arrays, or decoding arbitrary types (such as C structures) which don't fit
  311. // cleanly into a typical unsigned integer value.
  312. //
  313. // The function fn should not retain any reference to the data b outside of the
  314. // scope of the function.
  315. func (ad *AttributeDecoder) Do(fn func(b []byte) error) {
  316. if ad.err != nil {
  317. return
  318. }
  319. b := ad.data()
  320. if err := fn(b); err != nil {
  321. ad.err = err
  322. }
  323. }
  324. // Nested decodes data into a nested AttributeDecoder to handle nested netlink
  325. // attributes. When calling Nested, the Err method does not need to be called on
  326. // the nested AttributeDecoder.
  327. //
  328. // The nested AttributeDecoder nad inherits the same ByteOrder setting as the
  329. // top-level AttributeDecoder ad.
  330. func (ad *AttributeDecoder) Nested(fn func(nad *AttributeDecoder) error) {
  331. // Because we are wrapping Do, there is no need to check ad.err immediately.
  332. ad.Do(func(b []byte) error {
  333. nad, err := NewAttributeDecoder(b)
  334. if err != nil {
  335. return err
  336. }
  337. nad.ByteOrder = ad.ByteOrder
  338. if err := fn(nad); err != nil {
  339. return err
  340. }
  341. return nad.Err()
  342. })
  343. }
  344. // An AttributeEncoder provides a safe way to encode attributes.
  345. //
  346. // It is recommended to use an AttributeEncoder where possible instead of
  347. // calling MarshalAttributes or using package nlenc directly.
  348. //
  349. // Errors from intermediate encoding steps are returned in the call to
  350. // Encode.
  351. type AttributeEncoder struct {
  352. // ByteOrder defines a specific byte order to use when processing integer
  353. // attributes. ByteOrder should be set immediately after creating the
  354. // AttributeEncoder: before any attributes are encoded.
  355. //
  356. // If not set, the native byte order will be used.
  357. ByteOrder binary.ByteOrder
  358. attrs []Attribute
  359. err error
  360. }
  361. // NewAttributeEncoder creates an AttributeEncoder that encodes Attributes.
  362. func NewAttributeEncoder() *AttributeEncoder {
  363. return &AttributeEncoder{
  364. ByteOrder: nlenc.NativeEndian(),
  365. }
  366. }
  367. // Uint8 encodes uint8 data into an Attribute specified by typ.
  368. func (ae *AttributeEncoder) Uint8(typ uint16, v uint8) {
  369. if ae.err != nil {
  370. return
  371. }
  372. ae.attrs = append(ae.attrs, Attribute{
  373. Type: typ,
  374. Data: []byte{v},
  375. })
  376. }
  377. // Uint16 encodes uint16 data into an Attribute specified by typ.
  378. func (ae *AttributeEncoder) Uint16(typ uint16, v uint16) {
  379. if ae.err != nil {
  380. return
  381. }
  382. b := make([]byte, 2)
  383. ae.ByteOrder.PutUint16(b, v)
  384. ae.attrs = append(ae.attrs, Attribute{
  385. Type: typ,
  386. Data: b,
  387. })
  388. }
  389. // Uint32 encodes uint32 data into an Attribute specified by typ.
  390. func (ae *AttributeEncoder) Uint32(typ uint16, v uint32) {
  391. if ae.err != nil {
  392. return
  393. }
  394. b := make([]byte, 4)
  395. ae.ByteOrder.PutUint32(b, v)
  396. ae.attrs = append(ae.attrs, Attribute{
  397. Type: typ,
  398. Data: b,
  399. })
  400. }
  401. // Uint64 encodes uint64 data into an Attribute specified by typ.
  402. func (ae *AttributeEncoder) Uint64(typ uint16, v uint64) {
  403. if ae.err != nil {
  404. return
  405. }
  406. b := make([]byte, 8)
  407. ae.ByteOrder.PutUint64(b, v)
  408. ae.attrs = append(ae.attrs, Attribute{
  409. Type: typ,
  410. Data: b,
  411. })
  412. }
  413. // Flag encodes a flag into an Attribute specidied by typ.
  414. func (ae *AttributeEncoder) Flag(typ uint16, v bool) {
  415. // Only set flag on no previous error or v == true.
  416. if ae.err != nil || !v {
  417. return
  418. }
  419. // Flags have no length or data fields.
  420. ae.attrs = append(ae.attrs, Attribute{Type: typ})
  421. }
  422. // String encodes string s as a null-terminated string into an Attribute
  423. // specified by typ.
  424. func (ae *AttributeEncoder) String(typ uint16, s string) {
  425. if ae.err != nil {
  426. return
  427. }
  428. ae.attrs = append(ae.attrs, Attribute{
  429. Type: typ,
  430. Data: nlenc.Bytes(s),
  431. })
  432. }
  433. // Bytes embeds raw byte data into an Attribute specified by typ.
  434. func (ae *AttributeEncoder) Bytes(typ uint16, b []byte) {
  435. if ae.err != nil {
  436. return
  437. }
  438. ae.attrs = append(ae.attrs, Attribute{
  439. Type: typ,
  440. Data: b,
  441. })
  442. }
  443. // Do is a general purpose function to encode arbitrary data into an attribute
  444. // specified by typ.
  445. //
  446. // Do is especially helpful in encoding nested attributes, attribute arrays,
  447. // or encoding arbitrary types (such as C structures) which don't fit cleanly
  448. // into an unsigned integer value.
  449. func (ae *AttributeEncoder) Do(typ uint16, fn func() ([]byte, error)) {
  450. if ae.err != nil {
  451. return
  452. }
  453. b, err := fn()
  454. if err != nil {
  455. ae.err = err
  456. return
  457. }
  458. ae.attrs = append(ae.attrs, Attribute{
  459. Type: typ,
  460. Data: b,
  461. })
  462. }
  463. // Nested embeds data produced by a nested AttributeEncoder and flags that data
  464. // with the Nested flag. When calling Nested, the Encode method should not be
  465. // called on the nested AttributeEncoder.
  466. //
  467. // The nested AttributeEncoder nae inherits the same ByteOrder setting as the
  468. // top-level AttributeEncoder ae.
  469. func (ae *AttributeEncoder) Nested(typ uint16, fn func(nae *AttributeEncoder) error) {
  470. // Because we are wrapping Do, there is no need to check ae.err immediately.
  471. ae.Do(Nested|typ, func() ([]byte, error) {
  472. nae := NewAttributeEncoder()
  473. nae.ByteOrder = ae.ByteOrder
  474. if err := fn(nae); err != nil {
  475. return nil, err
  476. }
  477. return nae.Encode()
  478. })
  479. }
  480. // Encode returns the encoded bytes representing the attributes.
  481. func (ae *AttributeEncoder) Encode() ([]byte, error) {
  482. if ae.err != nil {
  483. return nil, ae.err
  484. }
  485. return MarshalAttributes(ae.attrs)
  486. }