libnl  3.5.0
attr.c
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * lib/attr.c Netlink Attributes
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation version 2.1
8  * of the License.
9  *
10  * Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
11  */
12 
13 #include <netlink-private/netlink.h>
14 #include <netlink/netlink.h>
15 #include <netlink/utils.h>
16 #include <netlink/addr.h>
17 #include <netlink/attr.h>
18 #include <netlink/msg.h>
19 #include <linux/socket.h>
20 
21 /**
22  * @ingroup msg
23  * @defgroup attr Attributes
24  * Netlink Attributes Construction/Parsing Interface
25  *
26  * Related sections in the development guide:
27  * - @core_doc{core_attr,Netlink Attributes}
28  *
29  * @{
30  *
31  * Header
32  * ------
33  * ~~~~{.c}
34  * #include <netlink/attr.h>
35  * ~~~~
36  */
37 
38 /**
39  * @name Attribute Size Calculation
40  * @{
41  */
42 
43 /**
44  * Return size of attribute whithout padding.
45  * @arg payload Payload length of attribute.
46  *
47  * @code
48  * <-------- nla_attr_size(payload) --------->
49  * +------------------+- - -+- - - - - - - - - +- - -+
50  * | Attribute Header | Pad | Payload | Pad |
51  * +------------------+- - -+- - - - - - - - - +- - -+
52  * @endcode
53  *
54  * @return Size of attribute in bytes without padding.
55  */
56 int nla_attr_size(int payload)
57 {
58  return NLA_HDRLEN + payload;
59 }
60 
61 /**
62  * Return size of attribute including padding.
63  * @arg payload Payload length of attribute.
64  *
65  * @code
66  * <----------- nla_total_size(payload) ----------->
67  * +------------------+- - -+- - - - - - - - - +- - -+
68  * | Attribute Header | Pad | Payload | Pad |
69  * +------------------+- - -+- - - - - - - - - +- - -+
70  * @endcode
71  *
72  * @return Size of attribute in bytes.
73  */
74 int nla_total_size(int payload)
75 {
76  return NLA_ALIGN(nla_attr_size(payload));
77 }
78 
79 /**
80  * Return length of padding at the tail of the attribute.
81  * @arg payload Payload length of attribute.
82  *
83  * @code
84  * +------------------+- - -+- - - - - - - - - +- - -+
85  * | Attribute Header | Pad | Payload | Pad |
86  * +------------------+- - -+- - - - - - - - - +- - -+
87  * <--->
88  * @endcode
89  *
90  * @return Length of padding in bytes.
91  */
92 int nla_padlen(int payload)
93 {
94  return nla_total_size(payload) - nla_attr_size(payload);
95 }
96 
97 /** @} */
98 
99 /**
100  * @name Parsing Attributes
101  * @{
102  */
103 
104 /**
105  * Return type of the attribute.
106  * @arg nla Attribute.
107  *
108  * @return Type of attribute.
109  */
110 int nla_type(const struct nlattr *nla)
111 {
112  return nla->nla_type & NLA_TYPE_MASK;
113 }
114 
115 /**
116  * Return pointer to the payload section.
117  * @arg nla Attribute.
118  *
119  * @return Pointer to start of payload section.
120  */
121 void *nla_data(const struct nlattr *nla)
122 {
123  return (char *) nla + NLA_HDRLEN;
124 }
125 
126 /**
127  * Return length of the payload .
128  * @arg nla Attribute
129  *
130  * @return Length of payload in bytes.
131  */
132 int nla_len(const struct nlattr *nla)
133 {
134  return nla->nla_len - NLA_HDRLEN;
135 }
136 
137 /**
138  * Check if the attribute header and payload can be accessed safely.
139  * @arg nla Attribute of any kind.
140  * @arg remaining Number of bytes remaining in attribute stream.
141  *
142  * Verifies that the header and payload do not exceed the number of
143  * bytes left in the attribute stream. This function must be called
144  * before access the attribute header or payload when iterating over
145  * the attribute stream using nla_next().
146  *
147  * @return True if the attribute can be accessed safely, false otherwise.
148  */
149 int nla_ok(const struct nlattr *nla, int remaining)
150 {
151  return remaining >= (int) sizeof(*nla) &&
152  nla->nla_len >= sizeof(*nla) &&
153  nla->nla_len <= remaining;
154 }
155 
156 /**
157  * Return next attribute in a stream of attributes.
158  * @arg nla Attribute of any kind.
159  * @arg remaining Variable to count remaining bytes in stream.
160  *
161  * Calculates the offset to the next attribute based on the attribute
162  * given. The attribute provided is assumed to be accessible, the
163  * caller is responsible to use nla_ok() beforehand. The offset (length
164  * of specified attribute including padding) is then subtracted from
165  * the remaining bytes variable and a pointer to the next attribute is
166  * returned.
167  *
168  * nla_next() can be called as long as remainig is >0.
169  *
170  * @return Pointer to next attribute.
171  */
172 struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
173 {
174  int totlen = NLA_ALIGN(nla->nla_len);
175 
176  *remaining -= totlen;
177  return (struct nlattr *) ((char *) nla + totlen);
178 }
179 
180 static uint16_t nla_attr_minlen[NLA_TYPE_MAX+1] = {
181  [NLA_U8] = sizeof(uint8_t),
182  [NLA_U16] = sizeof(uint16_t),
183  [NLA_U32] = sizeof(uint32_t),
184  [NLA_U64] = sizeof(uint64_t),
185  [NLA_STRING] = 1,
186  [NLA_FLAG] = 0,
187 };
188 
189 static int validate_nla(const struct nlattr *nla, int maxtype,
190  const struct nla_policy *policy)
191 {
192  const struct nla_policy *pt;
193  unsigned int minlen = 0;
194  int type = nla_type(nla);
195 
196  if (type < 0 || type > maxtype)
197  return 0;
198 
199  pt = &policy[type];
200 
201  if (pt->type > NLA_TYPE_MAX)
202  BUG();
203 
204  if (pt->minlen)
205  minlen = pt->minlen;
206  else if (pt->type != NLA_UNSPEC)
207  minlen = nla_attr_minlen[pt->type];
208 
209  if (nla_len(nla) < minlen)
210  return -NLE_RANGE;
211 
212  if (pt->maxlen && nla_len(nla) > pt->maxlen)
213  return -NLE_RANGE;
214 
215  if (pt->type == NLA_STRING) {
216  const char *data = nla_data(nla);
217  if (data[nla_len(nla) - 1] != '\0')
218  return -NLE_INVAL;
219  }
220 
221  return 0;
222 }
223 
224 
225 /**
226  * Create attribute index based on a stream of attributes.
227  * @arg tb Index array to be filled (maxtype+1 elements).
228  * @arg maxtype Maximum attribute type expected and accepted.
229  * @arg head Head of attribute stream.
230  * @arg len Length of attribute stream.
231  * @arg policy Attribute validation policy.
232  *
233  * Iterates over the stream of attributes and stores a pointer to each
234  * attribute in the index array using the attribute type as index to
235  * the array. Attribute with a type greater than the maximum type
236  * specified will be silently ignored in order to maintain backwards
237  * compatibility. If \a policy is not NULL, the attribute will be
238  * validated using the specified policy.
239  *
240  * @see nla_validate
241  * @return 0 on success or a negative error code.
242  */
243 int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
244  const struct nla_policy *policy)
245 {
246  struct nlattr *nla;
247  int rem, err;
248 
249  memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
250 
251  nla_for_each_attr(nla, head, len, rem) {
252  int type = nla_type(nla);
253 
254  if (type > maxtype)
255  continue;
256 
257  if (policy) {
258  err = validate_nla(nla, maxtype, policy);
259  if (err < 0)
260  goto errout;
261  }
262 
263  if (tb[type])
264  NL_DBG(1, "Attribute of type %#x found multiple times in message, "
265  "previous attribute is being ignored.\n", type);
266 
267  tb[type] = nla;
268  }
269 
270  if (rem > 0)
271  NL_DBG(1, "netlink: %d bytes leftover after parsing "
272  "attributes.\n", rem);
273 
274  err = 0;
275 errout:
276  return err;
277 }
278 
279 /**
280  * Validate a stream of attributes.
281  * @arg head Head of attributes stream.
282  * @arg len Length of attributes stream.
283  * @arg maxtype Maximum attribute type expected and accepted.
284  * @arg policy Validation policy.
285  *
286  * Iterates over the stream of attributes and validates each attribute
287  * one by one using the specified policy. Attributes with a type greater
288  * than the maximum type specified will be silently ignored in order to
289  * maintain backwards compatibility.
290  *
291  * See section @core_doc{core_attr_parse,Attribute Parsing} for more details.
292  *
293  * @return 0 on success or a negative error code.
294  */
295 int nla_validate(const struct nlattr *head, int len, int maxtype,
296  const struct nla_policy *policy)
297 {
298  const struct nlattr *nla;
299  int rem, err;
300 
301  nla_for_each_attr(nla, head, len, rem) {
302  err = validate_nla(nla, maxtype, policy);
303  if (err < 0)
304  goto errout;
305  }
306 
307  err = 0;
308 errout:
309  return err;
310 }
311 
312 /**
313  * Find a single attribute in a stream of attributes.
314  * @arg head Head of attributes stream.
315  * @arg len Length of attributes stream.
316  * @arg attrtype Attribute type to look for.
317  *
318  * Iterates over the stream of attributes and compares each type with
319  * the type specified. Returns the first attribute which matches the
320  * type.
321  *
322  * @return Pointer to attribute found or NULL.
323  */
324 struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype)
325 {
326  const struct nlattr *nla;
327  int rem;
328 
329  nla_for_each_attr(nla, head, len, rem)
330  if (nla_type(nla) == attrtype)
331  return (struct nlattr*)nla;
332 
333  return NULL;
334 }
335 
336 /** @} */
337 
338 /**
339  * @name Helper Functions
340  * @{
341  */
342 
343 /**
344  * Copy attribute payload to another memory area.
345  * @arg dest Pointer to destination memory area.
346  * @arg src Attribute
347  * @arg count Number of bytes to copy at most.
348  *
349  * Note: The number of bytes copied is limited by the length of
350  * the attribute payload.
351  *
352  * @return The number of bytes copied to dest.
353  */
354 int nla_memcpy(void *dest, const struct nlattr *src, int count)
355 {
356  int minlen;
357 
358  if (!src)
359  return 0;
360 
361  minlen = min_t(int, count, nla_len(src));
362  memcpy(dest, nla_data(src), minlen);
363 
364  return minlen;
365 }
366 
367 /**
368  * Copy string attribute payload to a buffer.
369  * @arg dst Pointer to destination buffer.
370  * @arg nla Attribute of type NLA_STRING.
371  * @arg dstsize Size of destination buffer in bytes.
372  *
373  * Copies at most dstsize - 1 bytes to the destination buffer.
374  * The result is always a valid NUL terminated string. Unlike
375  * strlcpy the destination buffer is always padded out.
376  *
377  * @return The length of string attribute without the terminating NUL.
378  */
379 size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
380 {
381  size_t srclen = nla_len(nla);
382  const char *src = nla_data(nla);
383 
384  if (srclen > 0 && src[srclen - 1] == '\0')
385  srclen--;
386 
387  if (dstsize > 0) {
388  size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
389 
390  memset(dst, 0, dstsize);
391  memcpy(dst, src, len);
392  }
393 
394  return srclen;
395 }
396 
397 /**
398  * Compare attribute payload with memory area.
399  * @arg nla Attribute.
400  * @arg data Memory area to compare to.
401  * @arg size Number of bytes to compare.
402  *
403  * @see memcmp(3)
404  * @return An integer less than, equal to, or greater than zero.
405  */
406 int nla_memcmp(const struct nlattr *nla, const void *data, size_t size)
407 {
408  int d = nla_len(nla) - size;
409 
410  if (d == 0)
411  d = memcmp(nla_data(nla), data, size);
412 
413  return d;
414 }
415 
416 /**
417  * Compare string attribute payload with string
418  * @arg nla Attribute of type NLA_STRING.
419  * @arg str NUL terminated string.
420  *
421  * @see strcmp(3)
422  * @return An integer less than, equal to, or greater than zero.
423  */
424 int nla_strcmp(const struct nlattr *nla, const char *str)
425 {
426  int len = strlen(str) + 1;
427  int d = nla_len(nla) - len;
428 
429  if (d == 0)
430  d = memcmp(nla_data(nla), str, len);
431 
432  return d;
433 }
434 
435 /** @} */
436 
437 /**
438  * @name Unspecific Attribute
439  * @{
440  */
441 
442 /**
443  * Reserve space for a attribute.
444  * @arg msg Netlink Message.
445  * @arg attrtype Attribute Type.
446  * @arg attrlen Length of payload.
447  *
448  * Reserves room for a attribute in the specified netlink message and
449  * fills in the attribute header (type, length). Returns NULL if there
450  * is unsuficient space for the attribute.
451  *
452  * Any padding between payload and the start of the next attribute is
453  * zeroed out.
454  *
455  * @return Pointer to start of attribute or NULL on failure.
456  */
457 struct nlattr *nla_reserve(struct nl_msg *msg, int attrtype, int attrlen)
458 {
459  struct nlattr *nla;
460  int tlen;
461 
462  if (attrlen < 0)
463  return NULL;
464 
465  tlen = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) + nla_total_size(attrlen);
466 
467  if (tlen > msg->nm_size)
468  return NULL;
469 
470  nla = (struct nlattr *) nlmsg_tail(msg->nm_nlh);
471  nla->nla_type = attrtype;
472  nla->nla_len = nla_attr_size(attrlen);
473 
474  if (attrlen)
475  memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen));
476  msg->nm_nlh->nlmsg_len = tlen;
477 
478  NL_DBG(2, "msg %p: attr <%p> %d: Reserved %d (%d) bytes at offset +%td "
479  "nlmsg_len=%d\n", msg, nla, nla->nla_type,
480  nla_total_size(attrlen), attrlen,
481  (char *) nla - (char *) nlmsg_data(msg->nm_nlh),
482  msg->nm_nlh->nlmsg_len);
483 
484  return nla;
485 }
486 
487 /**
488  * Add a unspecific attribute to netlink message.
489  * @arg msg Netlink message.
490  * @arg attrtype Attribute type.
491  * @arg datalen Length of data to be used as payload.
492  * @arg data Pointer to data to be used as attribute payload.
493  *
494  * Reserves room for a unspecific attribute and copies the provided data
495  * into the message as payload of the attribute. Returns an error if there
496  * is insufficient space for the attribute.
497  *
498  * @see nla_reserve
499  * @return 0 on success or a negative error code.
500  */
501 int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data)
502 {
503  struct nlattr *nla;
504 
505  nla = nla_reserve(msg, attrtype, datalen);
506  if (!nla) {
507  if (datalen < 0)
508  return -NLE_INVAL;
509 
510  return -NLE_NOMEM;
511  }
512 
513  if (datalen > 0) {
514  memcpy(nla_data(nla), data, datalen);
515  NL_DBG(2, "msg %p: attr <%p> %d: Wrote %d bytes at offset +%td\n",
516  msg, nla, nla->nla_type, datalen,
517  (char *) nla - (char *) nlmsg_data(msg->nm_nlh));
518  }
519 
520  return 0;
521 }
522 
523 /**
524  * Add abstract data as unspecific attribute to netlink message.
525  * @arg msg Netlink message.
526  * @arg attrtype Attribute type.
527  * @arg data Abstract data object.
528  *
529  * Equivalent to nla_put() except that the length of the payload is
530  * derived from the abstract data object.
531  *
532  * @see nla_put
533  * @return 0 on success or a negative error code.
534  */
535 int nla_put_data(struct nl_msg *msg, int attrtype, const struct nl_data *data)
536 {
537  return nla_put(msg, attrtype, nl_data_get_size(data),
538  nl_data_get(data));
539 }
540 
541 /**
542  * Add abstract address as unspecific attribute to netlink message.
543  * @arg msg Netlink message.
544  * @arg attrtype Attribute type.
545  * @arg addr Abstract address object.
546  *
547  * @see nla_put
548  * @return 0 on success or a negative error code.
549  */
550 int nla_put_addr(struct nl_msg *msg, int attrtype, struct nl_addr *addr)
551 {
552  return nla_put(msg, attrtype, nl_addr_get_len(addr),
554 }
555 
556 /** @} */
557 
558 /**
559  * @name Integer Attributes
560  */
561 
562 /**
563  * Add 8 bit signed integer attribute to netlink message.
564  * @arg msg Netlink message.
565  * @arg attrtype Attribute type.
566  * @arg value Numeric value to store as payload.
567  *
568  * @see nla_put
569  * @return 0 on success or a negative error code.
570  */
571 int nla_put_s8(struct nl_msg *msg, int attrtype, int8_t value)
572 {
573  return nla_put(msg, attrtype, sizeof(int8_t), &value);
574 }
575 
576 /**
577  * Return value of 8 bit signed integer attribute.
578  * @arg nla 8 bit integer attribute
579  *
580  * @return Payload as 8 bit integer.
581  */
582 int8_t nla_get_s8(const struct nlattr *nla)
583 {
584  return *(const int8_t *) nla_data(nla);
585 }
586 
587 /**
588  * Add 8 bit integer attribute to netlink message.
589  * @arg msg Netlink message.
590  * @arg attrtype Attribute type.
591  * @arg value Numeric value to store as payload.
592  *
593  * @see nla_put
594  * @return 0 on success or a negative error code.
595  */
596 int nla_put_u8(struct nl_msg *msg, int attrtype, uint8_t value)
597 {
598  return nla_put(msg, attrtype, sizeof(uint8_t), &value);
599 }
600 
601 /**
602  * Return value of 8 bit integer attribute.
603  * @arg nla 8 bit integer attribute
604  *
605  * @return Payload as 8 bit integer.
606  */
607 uint8_t nla_get_u8(const struct nlattr *nla)
608 {
609  return *(const uint8_t *) nla_data(nla);
610 }
611 
612 /**
613  * Add 16 bit signed integer attribute to netlink message.
614  * @arg msg Netlink message.
615  * @arg attrtype Attribute type.
616  * @arg value Numeric value to store as payload.
617  *
618  * @see nla_put
619  * @return 0 on success or a negative error code.
620  */
621 int nla_put_s16(struct nl_msg *msg, int attrtype, int16_t value)
622 {
623  return nla_put(msg, attrtype, sizeof(int16_t), &value);
624 }
625 
626 /**
627  * Return payload of 16 bit signed integer attribute.
628  * @arg nla 16 bit integer attribute
629  *
630  * @return Payload as 16 bit integer.
631  */
632 int16_t nla_get_s16(const struct nlattr *nla)
633 {
634  return *(const int16_t *) nla_data(nla);
635 }
636 
637 /**
638  * Add 16 bit integer attribute to netlink message.
639  * @arg msg Netlink message.
640  * @arg attrtype Attribute type.
641  * @arg value Numeric value to store as payload.
642  *
643  * @see nla_put
644  * @return 0 on success or a negative error code.
645  */
646 int nla_put_u16(struct nl_msg *msg, int attrtype, uint16_t value)
647 {
648  return nla_put(msg, attrtype, sizeof(uint16_t), &value);
649 }
650 
651 /**
652  * Return payload of 16 bit integer attribute.
653  * @arg nla 16 bit integer attribute
654  *
655  * @return Payload as 16 bit integer.
656  */
657 uint16_t nla_get_u16(const struct nlattr *nla)
658 {
659  return *(const uint16_t *) nla_data(nla);
660 }
661 
662 /**
663  * Add 32 bit signed integer attribute to netlink message.
664  * @arg msg Netlink message.
665  * @arg attrtype Attribute type.
666  * @arg value Numeric value to store as payload.
667  *
668  * @see nla_put
669  * @return 0 on success or a negative error code.
670  */
671 int nla_put_s32(struct nl_msg *msg, int attrtype, int32_t value)
672 {
673  return nla_put(msg, attrtype, sizeof(int32_t), &value);
674 }
675 
676 /**
677  * Return payload of 32 bit signed integer attribute.
678  * @arg nla 32 bit integer attribute.
679  *
680  * @return Payload as 32 bit integer.
681  */
682 int32_t nla_get_s32(const struct nlattr *nla)
683 {
684  return *(const int32_t *) nla_data(nla);
685 }
686 
687 /**
688  * Add 32 bit integer attribute to netlink message.
689  * @arg msg Netlink message.
690  * @arg attrtype Attribute type.
691  * @arg value Numeric value to store as payload.
692  *
693  * @see nla_put
694  * @return 0 on success or a negative error code.
695  */
696 int nla_put_u32(struct nl_msg *msg, int attrtype, uint32_t value)
697 {
698  return nla_put(msg, attrtype, sizeof(uint32_t), &value);
699 }
700 
701 /**
702  * Return payload of 32 bit integer attribute.
703  * @arg nla 32 bit integer attribute.
704  *
705  * @return Payload as 32 bit integer.
706  */
707 uint32_t nla_get_u32(const struct nlattr *nla)
708 {
709  return *(const uint32_t *) nla_data(nla);
710 }
711 
712 /**
713  * Add 64 bit signed integer attribute to netlink message.
714  * @arg msg Netlink message.
715  * @arg attrtype Attribute type.
716  * @arg value Numeric value to store as payload.
717  *
718  * @see nla_put
719  * @return 0 on success or a negative error code.
720  */
721 int nla_put_s64(struct nl_msg *msg, int attrtype, int64_t value)
722 {
723  return nla_put(msg, attrtype, sizeof(int64_t), &value);
724 }
725 
726 /**
727  * Return payload of s64 attribute
728  * @arg nla s64 netlink attribute
729  *
730  * @return Payload as 64 bit integer.
731  */
732 int64_t nla_get_s64(const struct nlattr *nla)
733 {
734  int64_t tmp = 0;
735 
736  if (nla && nla_len(nla) >= sizeof(tmp))
737  memcpy(&tmp, nla_data(nla), sizeof(tmp));
738 
739  return tmp;
740 }
741 
742 /**
743  * Add 64 bit integer attribute to netlink message.
744  * @arg msg Netlink message.
745  * @arg attrtype Attribute type.
746  * @arg value Numeric value to store as payload.
747  *
748  * @see nla_put
749  * @return 0 on success or a negative error code.
750  */
751 int nla_put_u64(struct nl_msg *msg, int attrtype, uint64_t value)
752 {
753  return nla_put(msg, attrtype, sizeof(uint64_t), &value);
754 }
755 
756 /**
757  * Return payload of u64 attribute
758  * @arg nla u64 netlink attribute
759  *
760  * @return Payload as 64 bit integer.
761  */
762 uint64_t nla_get_u64(const struct nlattr *nla)
763 {
764  uint64_t tmp = 0;
765 
766  if (nla && nla_len(nla) >= sizeof(tmp))
767  memcpy(&tmp, nla_data(nla), sizeof(tmp));
768 
769  return tmp;
770 }
771 
772 /** @} */
773 
774 /**
775  * @name String Attribute
776  */
777 
778 /**
779  * Add string attribute to netlink message.
780  * @arg msg Netlink message.
781  * @arg attrtype Attribute type.
782  * @arg str NUL terminated string.
783  *
784  * @see nla_put
785  * @return 0 on success or a negative error code.
786  */
787 int nla_put_string(struct nl_msg *msg, int attrtype, const char *str)
788 {
789  return nla_put(msg, attrtype, strlen(str) + 1, str);
790 }
791 
792 /**
793  * Return payload of string attribute.
794  * @arg nla String attribute.
795  *
796  * @return Pointer to attribute payload.
797  */
798 char *nla_get_string(const struct nlattr *nla)
799 {
800  return (char *) nla_data(nla);
801 }
802 
803 char *nla_strdup(const struct nlattr *nla)
804 {
805  return strdup(nla_get_string(nla));
806 }
807 
808 /** @} */
809 
810 /**
811  * @name Flag Attribute
812  */
813 
814 /**
815  * Add flag netlink attribute to netlink message.
816  * @arg msg Netlink message.
817  * @arg attrtype Attribute type.
818  *
819  * @see nla_put
820  * @return 0 on success or a negative error code.
821  */
822 int nla_put_flag(struct nl_msg *msg, int attrtype)
823 {
824  return nla_put(msg, attrtype, 0, NULL);
825 }
826 
827 /**
828  * Return true if flag attribute is set.
829  * @arg nla Flag netlink attribute.
830  *
831  * @return True if flag is set, otherwise false.
832  */
833 int nla_get_flag(const struct nlattr *nla)
834 {
835  return !!nla;
836 }
837 
838 /** @} */
839 
840 /**
841  * @name Microseconds Attribute
842  */
843 
844 /**
845  * Add a msecs netlink attribute to a netlink message
846  * @arg n netlink message
847  * @arg attrtype attribute type
848  * @arg msecs number of msecs
849  */
850 int nla_put_msecs(struct nl_msg *n, int attrtype, unsigned long msecs)
851 {
852  return nla_put_u64(n, attrtype, msecs);
853 }
854 
855 /**
856  * Return payload of msecs attribute
857  * @arg nla msecs netlink attribute
858  *
859  * @return the number of milliseconds.
860  */
861 unsigned long nla_get_msecs(const struct nlattr *nla)
862 {
863  return nla_get_u64(nla);
864 }
865 
866 /** @} */
867 
868 /**
869  * @name Nested Attribute
870  */
871 
872 /**
873  * Add nested attributes to netlink message.
874  * @arg msg Netlink message.
875  * @arg attrtype Attribute type.
876  * @arg nested Message containing attributes to be nested.
877  *
878  * Takes the attributes found in the \a nested message and appends them
879  * to the message \a msg nested in a container of the type \a attrtype.
880  * The \a nested message may not have a family specific header.
881  *
882  * @see nla_put
883  * @return 0 on success or a negative error code.
884  */
885 int nla_put_nested(struct nl_msg *msg, int attrtype,
886  const struct nl_msg *nested)
887 {
888  NL_DBG(2, "msg %p: attr <> %d: adding msg %p as nested attribute\n",
889  msg, attrtype, nested);
890 
891  return nla_put(msg, attrtype, nlmsg_datalen(nested->nm_nlh),
892  nlmsg_data(nested->nm_nlh));
893 }
894 
895 
896 /**
897  * Start a new level of nested attributes.
898  * @arg msg Netlink message.
899  * @arg attrtype Attribute type of container.
900  *
901  * @return Pointer to container attribute.
902  */
903 struct nlattr *nla_nest_start(struct nl_msg *msg, int attrtype)
904 {
905  struct nlattr *start = (struct nlattr *) nlmsg_tail(msg->nm_nlh);
906 
907  if (nla_put(msg, NLA_F_NESTED | attrtype, 0, NULL) < 0)
908  return NULL;
909 
910  NL_DBG(2, "msg %p: attr <%p> %d: starting nesting\n",
911  msg, start, start->nla_type);
912 
913  return start;
914 }
915 
916 static int _nest_end(struct nl_msg *msg, struct nlattr *start, int keep_empty)
917 {
918  size_t pad, len;
919 
920  len = (char *) nlmsg_tail(msg->nm_nlh) - (char *) start;
921 
922  if ( len > USHRT_MAX
923  || (!keep_empty && len == NLA_HDRLEN)) {
924  /*
925  * Max nlattr size exceeded or empty nested attribute, trim the
926  * attribute header again
927  */
928  nla_nest_cancel(msg, start);
929 
930  /* Return error only if nlattr size was exceeded */
931  return (len == NLA_HDRLEN) ? 0 : -NLE_ATTRSIZE;
932  }
933 
934  start->nla_len = len;
935 
936  pad = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) - msg->nm_nlh->nlmsg_len;
937  if (pad > 0) {
938  /*
939  * Data inside attribute does not end at a alignment boundry.
940  * Pad accordingly and accoun for the additional space in
941  * the message. nlmsg_reserve() may never fail in this situation,
942  * the allocate message buffer must be a multiple of NLMSG_ALIGNTO.
943  */
944  if (!nlmsg_reserve(msg, pad, 0))
945  BUG();
946 
947  NL_DBG(2, "msg %p: attr <%p> %d: added %zu bytes of padding\n",
948  msg, start, start->nla_type, pad);
949  }
950 
951  NL_DBG(2, "msg %p: attr <%p> %d: closing nesting, len=%u\n",
952  msg, start, start->nla_type, start->nla_len);
953 
954  return 0;
955 }
956 
957 /**
958  * Finalize nesting of attributes.
959  * @arg msg Netlink message.
960  * @arg start Container attribute as returned from nla_nest_start().
961  *
962  * Corrects the container attribute header to include the appeneded attributes.
963  *
964  * @return 0 on success or a negative error code.
965  */
966 int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
967 {
968  return _nest_end (msg, start, 0);
969 }
970 
971 /**
972  * Finalize nesting of attributes without stripping off empty attributes.
973  * @arg msg Netlink message.
974  * @arg start Container attribute as returned from nla_nest_start().
975  *
976  * Corrects the container attribute header to include the appeneded attributes.
977  * Keep empty attribute if NO actual attribute payload exists.
978  *
979  * @return 0 on success or a negative error code.
980  */
981 int nla_nest_end_keep_empty(struct nl_msg *msg, struct nlattr *start)
982 {
983  return _nest_end (msg, start, 1);
984 }
985 
986 /**
987  * Cancel the addition of a nested attribute
988  * @arg msg Netlink message
989  * @arg attr Nested netlink attribute
990  *
991  * Removes any partially added nested Netlink attribute from the message
992  * by resetting the message to the size before the call to nla_nest_start()
993  * and by overwriting any potentially touched message segments with 0.
994  */
995 void nla_nest_cancel(struct nl_msg *msg, const struct nlattr *attr)
996 {
997  ssize_t len;
998 
999  len = (char *) nlmsg_tail(msg->nm_nlh) - (char *) attr;
1000  if (len < 0)
1001  BUG();
1002  else if (len > 0) {
1003  msg->nm_nlh->nlmsg_len -= len;
1004  memset(nlmsg_tail(msg->nm_nlh), 0, len);
1005  }
1006 }
1007 
1008 /**
1009  * Create attribute index based on nested attribute
1010  * @arg tb Index array to be filled (maxtype+1 elements).
1011  * @arg maxtype Maximum attribute type expected and accepted.
1012  * @arg nla Nested Attribute.
1013  * @arg policy Attribute validation policy.
1014  *
1015  * Feeds the stream of attributes nested into the specified attribute
1016  * to nla_parse().
1017  *
1018  * @see nla_parse
1019  * @return 0 on success or a negative error code.
1020  */
1021 int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
1022  const struct nla_policy *policy)
1023 {
1024  return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
1025 }
1026 
1027 /**
1028  * Return true if attribute has NLA_F_NESTED flag set
1029  * @arg attr Netlink attribute
1030  *
1031  * @return True if attribute has NLA_F_NESTED flag set, oterhwise False.
1032  */
1033 int nla_is_nested(const struct nlattr *attr)
1034 {
1035  return !!(attr->nla_type & NLA_F_NESTED);
1036 }
1037 
1038 /** @} */
1039 
1040 /** @} */
8 bit integer
Definition: attr.h:41
int nla_ok(const struct nlattr *nla, int remaining)
Check if the attribute header and payload can be accessed safely.
Definition: attr.c:149
int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, const struct nla_policy *policy)
Create attribute index based on a stream of attributes.
Definition: attr.c:243
int32_t nla_get_s32(const struct nlattr *nla)
Return payload of 32 bit signed integer attribute.
Definition: attr.c:682
int nla_padlen(int payload)
Return length of padding at the tail of the attribute.
Definition: attr.c:92
int nla_put_u16(struct nl_msg *msg, int attrtype, uint16_t value)
Add 16 bit integer attribute to netlink message.
Definition: attr.c:646
struct nlattr * nla_find(const struct nlattr *head, int len, int attrtype)
Find a single attribute in a stream of attributes.
Definition: attr.c:324
void * nlmsg_data(const struct nlmsghdr *nlh)
Return pointer to message payload.
Definition: msg.c:107
int nla_get_flag(const struct nlattr *nla)
Return true if flag attribute is set.
Definition: attr.c:833
void * nl_data_get(const struct nl_data *data)
Get data buffer of abstract data object.
Definition: data.c:155
int16_t nla_get_s16(const struct nlattr *nla)
Return payload of 16 bit signed integer attribute.
Definition: attr.c:632
int nla_put_addr(struct nl_msg *msg, int attrtype, struct nl_addr *addr)
Add abstract address as unspecific attribute to netlink message.
Definition: attr.c:550
int nla_put_s8(struct nl_msg *msg, int attrtype, int8_t value)
Add 8 bit signed integer attribute to netlink message.
Definition: attr.c:571
void * nlmsg_reserve(struct nl_msg *n, size_t len, int pad)
Reserve room for additional data in a netlink message.
Definition: msg.c:411
Attribute validation policy.
Definition: attr.h:69
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
Definition: attr.c:607
Unspecified type, binary data chunk.
Definition: attr.h:40
int nla_strcmp(const struct nlattr *nla, const char *str)
Compare string attribute payload with string.
Definition: attr.c:424
char * nla_get_string(const struct nlattr *nla)
Return payload of string attribute.
Definition: attr.c:798
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:707
size_t nl_data_get_size(const struct nl_data *data)
Get size of data buffer of abstract data object.
Definition: data.c:167
struct nlattr * nla_reserve(struct nl_msg *msg, int attrtype, int attrlen)
Reserve space for a attribute.
Definition: attr.c:457
int nla_nest_end_keep_empty(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes without stripping off empty attributes.
Definition: attr.c:981
int8_t nla_get_s8(const struct nlattr *nla)
Return value of 8 bit signed integer attribute.
Definition: attr.c:582
int nla_put_s32(struct nl_msg *msg, int attrtype, int32_t value)
Add 32 bit signed integer attribute to netlink message.
Definition: attr.c:671
NUL terminated character string.
Definition: attr.h:45
int nla_is_nested(const struct nlattr *attr)
Return true if attribute has NLA_F_NESTED flag set.
Definition: attr.c:1033
int nla_total_size(int payload)
Return size of attribute including padding.
Definition: attr.c:74
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
Definition: attr.c:966
int nla_put_flag(struct nl_msg *msg, int attrtype)
Add flag netlink attribute to netlink message.
Definition: attr.c:822
int64_t nla_get_s64(const struct nlattr *nla)
Return payload of s64 attribute.
Definition: attr.c:732
struct nlattr * nla_next(const struct nlattr *nla, int *remaining)
Return next attribute in a stream of attributes.
Definition: attr.c:172
int nlmsg_datalen(const struct nlmsghdr *nlh)
Return length of message payload.
Definition: msg.c:123
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, const struct nla_policy *policy)
Create attribute index based on nested attribute.
Definition: attr.c:1021
int nla_put_data(struct nl_msg *msg, int attrtype, const struct nl_data *data)
Add abstract data as unspecific attribute to netlink message.
Definition: attr.c:535
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
Definition: attr.c:354
int nla_type(const struct nlattr *nla)
Return type of the attribute.
Definition: attr.c:110
16 bit integer
Definition: attr.h:42
int nla_put_msecs(struct nl_msg *n, int attrtype, unsigned long msecs)
Add a msecs netlink attribute to a netlink message.
Definition: attr.c:850
int nla_attr_size(int payload)
Return size of attribute whithout padding.
Definition: attr.c:56
int nla_put_u64(struct nl_msg *msg, int attrtype, uint64_t value)
Add 64 bit integer attribute to netlink message.
Definition: attr.c:751
int nla_put_nested(struct nl_msg *msg, int attrtype, const struct nl_msg *nested)
Add nested attributes to netlink message.
Definition: attr.c:885
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
Definition: attr.c:121
uint16_t maxlen
Maximal length of payload allowed.
Definition: attr.h:77
int nla_len(const struct nlattr *nla)
Return length of the payload .
Definition: attr.c:132
unsigned long nla_get_msecs(const struct nlattr *nla)
Return payload of msecs attribute.
Definition: attr.c:861
uint16_t minlen
Minimal length of payload required.
Definition: attr.h:74
64 bit integer
Definition: attr.h:44
int nla_put_s16(struct nl_msg *msg, int attrtype, int16_t value)
Add 16 bit signed integer attribute to netlink message.
Definition: attr.c:621
void nla_nest_cancel(struct nl_msg *msg, const struct nlattr *attr)
Cancel the addition of a nested attribute.
Definition: attr.c:995
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:71
int nla_memcmp(const struct nlattr *nla, const void *data, size_t size)
Compare attribute payload with memory area.
Definition: attr.c:406
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
Definition: attr.c:657
int nla_put_u32(struct nl_msg *msg, int attrtype, uint32_t value)
Add 32 bit integer attribute to netlink message.
Definition: attr.c:696
32 bit integer
Definition: attr.h:43
Flag.
Definition: attr.h:46
int nla_put_u8(struct nl_msg *msg, int attrtype, uint8_t value)
Add 8 bit integer attribute to netlink message.
Definition: attr.c:596
uint64_t nla_get_u64(const struct nlattr *nla)
Return payload of u64 attribute.
Definition: attr.c:762
int nla_put_string(struct nl_msg *msg, int attrtype, const char *str)
Add string attribute to netlink message.
Definition: attr.c:787
int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data)
Add a unspecific attribute to netlink message.
Definition: attr.c:501
unsigned int nl_addr_get_len(const struct nl_addr *addr)
Get length of binary address of abstract address object.
Definition: addr.c:954
int nla_put_s64(struct nl_msg *msg, int attrtype, int64_t value)
Add 64 bit signed integer attribute to netlink message.
Definition: attr.c:721
void * nl_addr_get_binary_addr(const struct nl_addr *addr)
Get binary address of abstract address object.
Definition: addr.c:942
size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
Copy string attribute payload to a buffer.
Definition: attr.c:379
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
Definition: attr.c:903
#define nla_for_each_attr(pos, head, len, rem)
Iterate over a stream of attributes.
Definition: attr.h:318
int nla_validate(const struct nlattr *head, int len, int maxtype, const struct nla_policy *policy)
Validate a stream of attributes.
Definition: attr.c:295