attribute.go 17 KB

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