attribute.go 17 KB

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