libnl  1.1.4
attr.c
1 /*
2  * lib/attr.c Netlink Attributes
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation version 2.1
7  * of the License.
8  *
9  * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
10  */
11 
12 #include <netlink-local.h>
13 #include <netlink/netlink.h>
14 #include <netlink/utils.h>
15 #include <netlink/addr.h>
16 #include <netlink/attr.h>
17 #include <netlink/msg.h>
18 #include <linux/socket.h>
19 
20 /**
21  * @ingroup msg
22  * @defgroup attr Attributes
23  * Netlink Attributes Construction/Parsing Interface
24  * @par 0) Introduction
25  * Netlink attributes are chained together following each other:
26  * @code
27  * <------- nla_total_size(payload) ------->
28  * <---- nla_attr_size(payload) ----->
29  * +----------+- - -+- - - - - - - - - +- - -+-------- - -
30  * | Header | Pad | Payload | Pad | Header
31  * +----------+- - -+- - - - - - - - - +- - -+-------- - -
32  * <- nla_len(nla) -> ^
33  * nla_data(nla)----^ |
34  * nla_next(nla)-----------------------------'
35  * @endcode
36  *
37  * @par
38  * The attribute header and payload must be aligned properly:
39  * @code
40  * <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
41  * +---------------------+- - -+- - - - - - - - - -+- - -+
42  * | Header | Pad | Payload | Pad |
43  * | (struct nlattr) | ing | | ing |
44  * +---------------------+- - -+- - - - - - - - - -+- - -+
45  * <-------------- nlattr->nla_len -------------->
46  * @endcode
47  *
48  * @par Nested TLVs:
49  * Nested TLVs are an array of TLVs nested into another TLV. This can be useful
50  * to allow subsystems to have their own formatting rules without the need to
51  * make the underlying layer be aware of it. It can also be useful to transfer
52  * arrays, lists and flattened trees.
53  * \code
54  * <-------------------- NLA_ALIGN(...) ------------------->
55  * +---------------+- - - - - - - - - - - - - - - - - -+- - -+
56  * | |+---------+---------+- - -+-------+| |
57  * | TLV Header || TLV 1 | TLV 2 | | TLV n || Pad |
58  * | |+---------+---------+- - -+-------+| |
59  * +---------------+- - - - - - - - - - - - - - - - - -+- - -+
60  * <--------- nla_data(nla) --------->
61  * \endcode
62  *
63  * @par 1) Constructing a message with attributes
64  * @code
65  * int param1 = 10;
66  * char *param2 = "parameter text";
67  *
68  * struct nl_msg *msg = nlmsg_alloc();
69  * nla_put_u32(msg, 1, param1);
70  * nla_put_string(msg, 2, param2);
71  *
72  * nl_send_auto_complete(handle, nl_msg_get(msg));
73  * nlmsg_free(msg);
74  * @endcode
75  *
76  * @par 2) Constructing nested attributes
77  * @code
78  * struct nl_msg * nested_config(void)
79  * {
80  * int a = 5, int b = 10;
81  * struct nl_msg *n = nlmsg_alloc();
82  * nla_put_u32(n, 10, a);
83  * nla_put_u32(n, 20, b);
84  * return n;
85  * }
86  *
87  * ...
88  * struct nl_msg *m = nlmsg_alloc();
89  * struct nl_msg *nest = nested_config();
90  * nla_put_nested(m, 1, nest);
91  *
92  * nl_send_auto_complete(handle, nl_msg_get(m));
93  * nlmsg_free(nest);
94  * nlmsg_free(m);
95  * @endcode
96  * @{
97  */
98 
99 /**
100  * @name Size Calculations
101  * @{
102  */
103 
104 /**
105  * length of attribute not including padding
106  * @arg payload length of payload
107  */
108 int nla_attr_size(int payload)
109 {
110  return NLA_HDRLEN + payload;
111 }
112 
113 /**
114  * total length of attribute including padding
115  * @arg payload length of payload
116  */
117 int nla_total_size(int payload)
118 {
119  return NLA_ALIGN(nla_attr_size(payload));
120 }
121 
122 /**
123  * length of padding at the tail of the attribute
124  * @arg payload length of payload
125  */
126 int nla_padlen(int payload)
127 {
128  return nla_total_size(payload) - nla_attr_size(payload);
129 }
130 
131 /** @} */
132 
133 /**
134  * @name Payload Access
135  * @{
136  */
137 
138 /**
139  * attribute type
140  * @arg nla netlink attribute
141  */
142 int nla_type(const struct nlattr *nla)
143 {
144  return nla->nla_type & NLA_TYPE_MASK;
145 }
146 
147 /**
148  * head of payload
149  * @arg nla netlink attribute
150  */
151 void *nla_data(const struct nlattr *nla)
152 {
153  return (char *) nla + NLA_HDRLEN;
154 }
155 
156 /**
157  * length of payload
158  * @arg nla netlink attribute
159  */
160 int nla_len(const struct nlattr *nla)
161 {
162  return nla->nla_len - NLA_HDRLEN;
163 }
164 
165 /** @} */
166 
167 /**
168  * @name Attribute Parsing
169  * @{
170  */
171 
172 /**
173  * check if the netlink attribute fits into the remaining bytes
174  * @arg nla netlink attribute
175  * @arg remaining number of bytes remaining in attribute stream
176  */
177 int nla_ok(const struct nlattr *nla, int remaining)
178 {
179  return remaining >= sizeof(*nla) &&
180  nla->nla_len >= sizeof(*nla) &&
181  nla->nla_len <= remaining;
182 }
183 
184 /**
185  * next netlink attribte in attribute stream
186  * @arg nla netlink attribute
187  * @arg remaining number of bytes remaining in attribute stream
188  *
189  * @return the next netlink attribute in the attribute stream and
190  * decrements remaining by the size of the current attribute.
191  */
192 struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
193 {
194  int totlen = NLA_ALIGN(nla->nla_len);
195 
196  *remaining -= totlen;
197  return (struct nlattr *) ((char *) nla + totlen);
198 }
199 
200 static uint16_t nla_attr_minlen[NLA_TYPE_MAX+1] = {
201  [NLA_U8] = sizeof(uint8_t),
202  [NLA_U16] = sizeof(uint16_t),
203  [NLA_U32] = sizeof(uint32_t),
204  [NLA_U64] = sizeof(uint64_t),
205  [NLA_STRING] = 1,
206  [NLA_NESTED] = NLA_HDRLEN,
207 };
208 
209 static int validate_nla(struct nlattr *nla, int maxtype,
210  struct nla_policy *policy)
211 {
212  struct nla_policy *pt;
213  int minlen = 0, type = nla_type(nla);
214 
215  if (type <= 0 || type > maxtype)
216  return 0;
217 
218  pt = &policy[type];
219 
220  if (pt->type > NLA_TYPE_MAX)
221  BUG();
222 
223  if (pt->minlen)
224  minlen = pt->minlen;
225  else if (pt->type != NLA_UNSPEC)
226  minlen = nla_attr_minlen[pt->type];
227 
228  if (pt->type == NLA_FLAG && nla_len(nla) > 0)
229  return nl_errno(ERANGE);
230 
231  if (nla_len(nla) < minlen)
232  return nl_errno(ERANGE);
233 
234  if (pt->maxlen && nla_len(nla) > pt->maxlen)
235  return nl_errno(ERANGE);
236 
237  if (pt->type == NLA_STRING) {
238  char *data = nla_data(nla);
239  if (data[nla_len(nla) - 1] != '\0')
240  return nl_errno(EINVAL);
241  }
242 
243  return 0;
244 }
245 
246 
247 /**
248  * Parse a stream of attributes into a tb buffer
249  * @arg tb destination array with maxtype+1 elements
250  * @arg maxtype maximum attribute type to be expected
251  * @arg head head of attribute stream
252  * @arg len length of attribute stream
253  * @arg policy validation policy
254  *
255  * Parses a stream of attributes and stores a pointer to each attribute in
256  * the tb array accessable via the attribute type. Attributes with a type
257  * exceeding maxtype will be silently ignored for backwards compatibility
258  * reasons. policy may be set to NULL if no validation is required.
259  *
260  * @return 0 on success or a negative error code.
261  */
262 int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
263  struct nla_policy *policy)
264 {
265  struct nlattr *nla;
266  int rem, err;
267 
268  memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
269 
270  nla_for_each_attr(nla, head, len, rem) {
271  int type = nla_type(nla);
272 
273  /* Padding attributes */
274  if (type == 0)
275  continue;
276 
277  if (type <= maxtype) {
278  if (policy) {
279  err = validate_nla(nla, maxtype, policy);
280  if (err < 0)
281  goto errout;
282  }
283 
284  tb[type] = nla;
285  }
286  }
287 
288  if (rem > 0)
289  fprintf(stderr, "netlink: %d bytes leftover after parsing "
290  "attributes.\n", rem);
291 
292  err = 0;
293 errout:
294  return err;
295 }
296 
297 
298 /**
299  * parse nested attributes
300  * @arg tb destination array with maxtype+1 elements
301  * @arg maxtype maximum attribute type to be expected
302  * @arg nla attribute containing the nested attributes
303  * @arg policy validation policy
304  *
305  * @see nla_parse()
306  */
307 int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
308  struct nla_policy *policy)
309 {
310  return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
311 }
312 
313 /**
314  * Validate a stream of attributes
315  * @arg head head of attribute stream
316  * @arg len length of attribute stream
317  * @arg maxtype maximum attribute type to be expected
318  * @arg policy validation policy
319  *
320  * Validates all attributes in the specified attribute stream
321  * against the specified policy. Attributes with a type exceeding
322  * maxtype will be ignored. See documenation of struct nla_policy
323  * for more details.
324  *
325  * @return 0 on success or a negative error code.
326  */
327 int nla_validate(struct nlattr *head, int len, int maxtype,
328  struct nla_policy *policy)
329 {
330  struct nlattr *nla;
331  int rem, err;
332 
333  nla_for_each_attr(nla, head, len, rem) {
334  err = validate_nla(nla, maxtype, policy);
335  if (err < 0)
336  goto errout;
337  }
338 
339  err = 0;
340 errout:
341  return err;
342 }
343 
344 /**
345  * Find a specific attribute in a stream of attributes
346  * @arg head head of attribute stream
347  * @arg len length of attribute stream
348  * @arg attrtype type of attribute to look for
349  *
350  * @return the first attribute in the stream matching the specified type.
351  */
352 struct nlattr *nla_find(struct nlattr *head, int len, int attrtype)
353 {
354  struct nlattr *nla;
355  int rem;
356 
357  nla_for_each_attr(nla, head, len, rem)
358  if (nla_type(nla) == attrtype)
359  return nla;
360 
361  return NULL;
362 }
363 
364 /** @} */
365 
366 /**
367  * @name Utilities
368  * @{
369  */
370 
371 /**
372  * Copy a netlink attribute into another memory area
373  * @arg dest where to copy to memcpy
374  * @arg src netlink attribute to copy from
375  * @arg count size of the destination area
376  *
377  * Note: The number of bytes copied is limited by the length of
378  * attribute's payload. memcpy
379  *
380  * @return the number of bytes copied.
381  */
382 int nla_memcpy(void *dest, struct nlattr *src, int count)
383 {
384  int minlen;
385 
386  if (!src)
387  return 0;
388 
389  minlen = min_t(int, count, nla_len(src));
390  memcpy(dest, nla_data(src), minlen);
391 
392  return minlen;
393 }
394 
395 /**
396  * Copy string attribute payload into a sized buffer
397  * @arg dst where to copy the string to
398  * @arg nla attribute to copy the string from
399  * @arg dstsize size of destination buffer
400  *
401  * Copies at most dstsize - 1 bytes into the destination buffer.
402  * The result is always a valid NUL-terminated string. Unlike
403  * strlcpy the destination buffer is always padded out.
404  *
405  * @return the length of the source buffer.
406  */
407 size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
408 {
409  size_t srclen = nla_len(nla);
410  char *src = nla_data(nla);
411 
412  if (srclen > 0 && src[srclen - 1] == '\0')
413  srclen--;
414 
415  if (dstsize > 0) {
416  size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
417 
418  memset(dst, 0, dstsize);
419  memcpy(dst, src, len);
420  }
421 
422  return srclen;
423 }
424 
425 /**
426  * Compare an attribute with sized memory area
427  * @arg nla netlink attribute
428  * @arg data memory area
429  * @arg size size of memory area
430  */
431 int nla_memcmp(const struct nlattr *nla, const void *data,
432  size_t size)
433 {
434  int d = nla_len(nla) - size;
435 
436  if (d == 0)
437  d = memcmp(nla_data(nla), data, size);
438 
439  return d;
440 }
441 
442 /**
443  * Compare a string attribute against a string
444  * @arg nla netlink string attribute
445  * @arg str another string
446  */
447 int nla_strcmp(const struct nlattr *nla, const char *str)
448 {
449  int len = strlen(str) + 1;
450  int d = nla_len(nla) - len;
451 
452  if (d == 0)
453  d = memcmp(nla_data(nla), str, len);
454 
455  return d;
456 }
457 
458 /** @} */
459 
460 /**
461  * @name Attribute Construction
462  * @{
463  */
464 
465 /**
466  * reserve room for attribute on the skb
467  * @arg n netlink message
468  * @arg attrtype attribute type
469  * @arg attrlen length of attribute payload
470  *
471  * Adds a netlink attribute header to a netlink message and reserves
472  * room for the payload but does not copy it.
473  */
474 struct nlattr *nla_reserve(struct nl_msg *n, int attrtype, int attrlen)
475 {
476  struct nlattr *nla;
477  int tlen;
478 
479  tlen = NLMSG_ALIGN(n->nm_nlh->nlmsg_len) + nla_total_size(attrlen);
480 
481  if (tlen > n->nm_size) {
482  nl_errno(ENOBUFS);
483  return NULL;
484  }
485 
486  nla = (struct nlattr *) nlmsg_tail(n->nm_nlh);
487  nla->nla_type = attrtype;
488  nla->nla_len = nla_attr_size(attrlen);
489 
490  memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen));
491  n->nm_nlh->nlmsg_len = tlen;
492 
493  NL_DBG(2, "msg %p: Reserved %d bytes at offset +%td for attr %d "
494  "nlmsg_len=%d\n", n, attrlen,
495  (void *) nla - nlmsg_data(n->nm_nlh),
496  attrtype, n->nm_nlh->nlmsg_len);
497 
498  return nla;
499 }
500 
501 /**
502  * Add a netlink attribute to a netlink message
503  * @arg n netlink message
504  * @arg attrtype attribute type
505  * @arg attrlen length of attribute payload
506  * @arg data head of attribute payload
507  *
508  * @return -1 if the tailroom of the skb is insufficient to store
509  * the attribute header and payload.
510  */
511 int nla_put(struct nl_msg *n, int attrtype, int attrlen, const void *data)
512 {
513  struct nlattr *nla;
514 
515  nla = nla_reserve(n, attrtype, attrlen);
516  if (!nla)
517  return nl_errno(ENOMEM);
518 
519  memcpy(nla_data(nla), data, attrlen);
520  NL_DBG(2, "msg %p: Wrote %d bytes at offset +%td for attr %d\n",
521  n, attrlen, (void *) nla - nlmsg_data(n->nm_nlh), attrtype);
522 
523  return 0;
524 }
525 
526 /**
527  * Add a nested netlink attribute to a netlink message
528  * @arg n netlink message
529  * @arg attrtype attribute type
530  * @arg nested netlink attribute to nest
531  *
532  * @return -1 if the tailroom of the skb is insufficient to store
533  * the attribute header and payload.
534  */
535 int nla_put_nested(struct nl_msg *n, int attrtype, struct nl_msg *nested)
536 {
537  return nla_put(n, attrtype, nlmsg_len(nested->nm_nlh),
538  nlmsg_data(nested->nm_nlh));
539 }
540 
541 /**
542  * Add a u16 netlink attribute to a netlink message
543  * @arg n netlink message
544  * @arg attrtype attribute type
545  * @arg value numeric value
546  */
547 int nla_put_u8(struct nl_msg *n, int attrtype, uint8_t value)
548 {
549  return nla_put(n, attrtype, sizeof(uint8_t), &value);
550 }
551 
552 /**
553  * Add a u16 netlink attribute to a netlink message
554  * @arg n netlink message
555  * @arg attrtype attribute type
556  * @arg value numeric value
557  */
558 int nla_put_u16(struct nl_msg *n, int attrtype, uint16_t value)
559 {
560  return nla_put(n, attrtype, sizeof(uint16_t), &value);
561 }
562 
563 /**
564  * Add a u32 netlink attribute to a netlink message
565  * @arg n netlink message
566  * @arg attrtype attribute type
567  * @arg value numeric value
568  */
569 int nla_put_u32(struct nl_msg *n, int attrtype, uint32_t value)
570 {
571  return nla_put(n, attrtype, sizeof(uint32_t), &value);
572 }
573 
574 /**
575  * Add a u64 netlink attribute to a netlink message
576  * @arg n netlink message
577  * @arg attrtype attribute type
578  * @arg value numeric value
579  */
580 int nla_put_u64(struct nl_msg *n, int attrtype, uint64_t value)
581 {
582  return nla_put(n, attrtype, sizeof(uint64_t), &value);
583 }
584 
585 /**
586  * Add a string netlink attribute to a netlink message
587  * @arg n netlink message
588  * @arg attrtype attribute type
589  * @arg str NUL terminated string
590  */
591 int nla_put_string(struct nl_msg *n, int attrtype, const char *str)
592 {
593  return nla_put(n, attrtype, strlen(str) + 1, str);
594 }
595 
596 /**
597  * Add a flag netlink attribute to a netlink message
598  * @arg n netlink message
599  * @arg attrtype attribute type
600  */
601 int nla_put_flag(struct nl_msg *n, int attrtype)
602 {
603  return nla_put(n, attrtype, 0, NULL);
604 }
605 
606 /**
607  * Add a msecs netlink attribute to a netlink message
608  * @arg n netlink message
609  * @arg attrtype attribute type
610  * @arg msecs number of msecs
611  */
612 int nla_put_msecs(struct nl_msg *n, int attrtype, unsigned long msecs)
613 {
614  return nla_put_u64(n, attrtype, msecs);
615 }
616 
617 /**
618  * Add an abstract data netlink attribute to a netlink message
619  * @arg n netlink message
620  * @arg attrtype attribute type
621  * @arg data abstract data
622  */
623 int nla_put_data(struct nl_msg *n, int attrtype, struct nl_data *data)
624 {
625  return nla_put(n, attrtype, nl_data_get_size(data),
626  nl_data_get(data));
627 }
628 
629 /**
630  * Add an abstract address netlink attribute to a netlink message
631  * @arg n netlink message
632  * @arg attrtype attribute type
633  * @arg addr abstract address
634  */
635 int nla_put_addr(struct nl_msg *n, int attrtype, struct nl_addr *addr)
636 {
637  return nla_put(n, attrtype, nl_addr_get_len(addr),
639 }
640 
641 /** @} */
642 
643 /**
644  * @name Attribute Nesting
645  * @{
646  */
647 
648 /**
649  * Start a new level of nested attributes
650  * @arg n netlink message
651  * @arg attrtype attribute type of container
652  *
653  * @return the container attribute
654  */
655 struct nlattr *nla_nest_start(struct nl_msg *n, int attrtype)
656 {
657  struct nlattr *start = (struct nlattr *) nlmsg_tail(n->nm_nlh);
658 
659  if (nla_put(n, attrtype, 0, NULL) < 0)
660  return NULL;
661 
662  return start;
663 }
664 
665 /**
666  * Finalize nesting of attributes
667  * @arg n netlink message
668  * @arg start container attribute
669  *
670  * Corrects the container attribute header to include the all
671  * appeneded attributes.
672  *
673  * @return the total data length of the skb.
674  */
675 int nla_nest_end(struct nl_msg *n, struct nlattr *start)
676 {
677  start->nla_len = (unsigned char *) nlmsg_tail(n->nm_nlh) -
678  (unsigned char *) start;
679  return 0;
680 }
681 
682 /** @} */
683 
684 /**
685  * @name Attribute Reading
686  * @{
687  */
688 
689 /**
690  * Return payload of u32 attribute
691  * @arg nla u32 netlink attribute
692  */
693 uint32_t nla_get_u32(struct nlattr *nla)
694 {
695  return *(uint32_t *) nla_data(nla);
696 }
697 
698 /**
699  * Return payload of u16 attribute
700  * @arg nla u16 netlink attribute
701  */
702 uint16_t nla_get_u16(struct nlattr *nla)
703 {
704  return *(uint16_t *) nla_data(nla);
705 }
706 
707 /**
708  * Return payload of u8 attribute
709  * @arg nla u8 netlink attribute
710  */
711 uint8_t nla_get_u8(struct nlattr *nla)
712 {
713  return *(uint8_t *) nla_data(nla);
714 }
715 
716 /**
717  * Return payload of u64 attribute
718  * @arg nla u64 netlink attribute
719  */
720 uint64_t nla_get_u64(struct nlattr *nla)
721 {
722  uint64_t tmp;
723 
724  nla_memcpy(&tmp, nla, sizeof(tmp));
725 
726  return tmp;
727 }
728 
729 /**
730  * return payload of string attribute
731  * @arg nla string netlink attribute
732  */
733 char *nla_get_string(struct nlattr *nla)
734 {
735  return (char *) nla_data(nla);
736 }
737 
738 /**
739  * Return payload of flag attribute
740  * @arg nla flag netlink attribute
741  */
742 int nla_get_flag(struct nlattr *nla)
743 {
744  return !!nla;
745 }
746 
747 /**
748  * Return payload of msecs attribute
749  * @arg nla msecs netlink attribute
750  *
751  * @return the number of milliseconds.
752  */
753 unsigned long nla_get_msecs(struct nlattr *nla)
754 {
755  return nla_get_u64(nla);
756 }
757 
758 /**
759  * Return payload of address attribute
760  * @arg nla address netlink attribute
761  * @arg family address family
762  *
763  * @return Newly allocated address handle or NULL
764  */
765 struct nl_addr *nla_get_addr(struct nlattr *nla, int family)
766 {
767  return nl_addr_build(family, nla_data(nla), nla_len(nla));
768 }
769 
770 /**
771  * Return payload of abstract data attribute
772  * @arg nla abstract data netlink attribute
773  *
774  * @return Newly allocated abstract data handle or NULL
775  */
776 struct nl_data *nla_get_data(struct nlattr *nla)
777 {
778  return nl_data_alloc(nla_data(nla), nla_len(nla));
779 }
780 
781 /** @} */
782 
783 /** @} */