2 * lib/attr.c Netlink Attributes
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
9 * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
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>
22 * @defgroup attr Attributes
23 * Netlink Attributes Construction/Parsing Interface
24 * @par 0) Introduction
25 * Netlink attributes are chained together following each other:
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)-----------------------------'
38 * The attribute header and payload must be aligned properly:
40 * <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
41 * +---------------------+- - -+- - - - - - - - - -+- - -+
42 * | Header | Pad | Payload | Pad |
43 * | (struct nlattr) | ing | | ing |
44 * +---------------------+- - -+- - - - - - - - - -+- - -+
45 * <-------------- nlattr->nla_len -------------->
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.
54 * <-------------------- NLA_ALIGN(...) ------------------->
55 * +---------------+- - - - - - - - - - - - - - - - - -+- - -+
56 * | |+---------+---------+- - -+-------+| |
57 * | TLV Header || TLV 1 | TLV 2 | | TLV n || Pad |
58 * | |+---------+---------+- - -+-------+| |
59 * +---------------+- - - - - - - - - - - - - - - - - -+- - -+
60 * <--------- nla_data(nla) --------->
63 * @par 1) Constructing a message with attributes
66 * char *param2 = "parameter text";
67 * struct nlmsghdr hdr = {
68 * .nlmsg_type = MY_ACTION,
70 * struct nl_msg *m = nlmsg_build(&hdr);
71 * nla_put_u32(m, 1, param1);
72 * nla_put_string(m, 2, param2);
74 * nl_send_auto_complete(handle, nl_msg_get(m));
78 * @par 2) Constructing nested attributes
80 * struct nl_msg * nested_config(void)
82 * int a = 5, int b = 10;
83 * struct nl_msg *n = nlmsg_build(NULL);
84 * nla_put_u32(n, 10, a);
85 * nla_put_u32(n, 20, b);
90 * struct nl_msg *m = nlmsg_build(&hdr);
91 * struct nl_msg *nest = nested_config();
92 * nla_put_nested(m, 1, nest);
94 * nl_send_auto_complete(handle, nl_msg_get(m));
102 * @name Size Calculations
107 * length of attribute not including padding
108 * @arg payload length of payload
110 int nla_attr_size(int payload)
112 return NLA_HDRLEN + payload;
116 * total length of attribute including padding
117 * @arg payload length of payload
119 int nla_total_size(int payload)
121 return NLA_ALIGN(nla_attr_size(payload));
125 * length of padding at the tail of the attribute
126 * @arg payload length of payload
128 int nla_padlen(int payload)
130 return nla_total_size(payload) - nla_attr_size(payload);
136 * @name Payload Access
142 * @arg nla netlink attribute
144 void *nla_data(const struct nlattr *nla)
146 return (char *) nla + NLA_HDRLEN;
151 * @arg nla netlink attribute
153 int nla_len(const struct nlattr *nla)
155 return nla->nla_len - NLA_HDRLEN;
161 * @name Attribute Parsing
166 * check if the netlink attribute fits into the remaining bytes
167 * @arg nla netlink attribute
168 * @arg remaining number of bytes remaining in attribute stream
170 int nla_ok(const struct nlattr *nla, int remaining)
172 return remaining >= sizeof(*nla) &&
173 nla->nla_len >= sizeof(*nla) &&
174 nla->nla_len <= remaining;
178 * next netlink attribte in attribute stream
179 * @arg nla netlink attribute
180 * @arg remaining number of bytes remaining in attribute stream
182 * @return the next netlink attribute in the attribute stream and
183 * decrements remaining by the size of the current attribute.
185 struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
187 int totlen = NLA_ALIGN(nla->nla_len);
189 *remaining -= totlen;
190 return (struct nlattr *) ((char *) nla + totlen);
193 static uint16_t nla_attr_minlen[NLA_TYPE_MAX+1] = {
194 [NLA_U8] = sizeof(uint8_t),
195 [NLA_U16] = sizeof(uint16_t),
196 [NLA_U32] = sizeof(uint32_t),
197 [NLA_U64] = sizeof(uint64_t),
199 [NLA_NESTED] = NLA_HDRLEN,
202 static int validate_nla(struct nlattr *nla, int maxtype,
203 struct nla_policy *policy)
205 struct nla_policy *pt;
208 if (nla->nla_type <= 0 || nla->nla_type > maxtype)
211 pt = &policy[nla->nla_type];
213 if (pt->type > NLA_TYPE_MAX)
218 else if (pt->type != NLA_UNSPEC)
219 minlen = nla_attr_minlen[pt->type];
221 if (pt->type == NLA_FLAG && nla_len(nla) > 0)
224 if (nla_len(nla) < minlen)
227 if (pt->maxlen && nla_len(nla) > pt->maxlen)
230 if (pt->type == NLA_STRING) {
231 char *data = nla_data(nla);
232 if (data[nla_len(nla) - 1] != '\0')
241 * Parse a stream of attributes into a tb buffer
242 * @arg tb destination array with maxtype+1 elements
243 * @arg maxtype maximum attribute type to be expected
244 * @arg head head of attribute stream
245 * @arg len length of attribute stream
246 * @arg policy validation policy
248 * Parses a stream of attributes and stores a pointer to each attribute in
249 * the tb array accessable via the attribute type. Attributes with a type
250 * exceeding maxtype will be silently ignored for backwards compatibility
251 * reasons. policy may be set to NULL if no validation is required.
253 * @return 0 on success or a negative error code.
255 int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
256 struct nla_policy *policy)
261 memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
263 nla_for_each_attr(nla, head, len, rem) {
264 uint16_t type = nla->nla_type;
267 fprintf(stderr, "Illegal nla->nla_type == 0\n");
271 if (type <= maxtype) {
273 err = validate_nla(nla, maxtype, policy);
283 fprintf(stderr, "netlink: %d bytes leftover after parsing "
284 "attributes.\n", rem);
293 * parse nested attributes
294 * @arg tb destination array with maxtype+1 elements
295 * @arg maxtype maximum attribute type to be expected
296 * @arg nla attribute containing the nested attributes
297 * @arg policy validation policy
301 int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
302 struct nla_policy *policy)
304 return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
308 * Validate a stream of attributes
309 * @arg head head of attribute stream
310 * @arg len length of attribute stream
311 * @arg maxtype maximum attribute type to be expected
312 * @arg policy validation policy
314 * Validates all attributes in the specified attribute stream
315 * against the specified policy. Attributes with a type exceeding
316 * maxtype will be ignored. See documenation of struct nla_policy
319 * @return 0 on success or a negative error code.
321 int nla_validate(struct nlattr *head, int len, int maxtype,
322 struct nla_policy *policy)
327 nla_for_each_attr(nla, head, len, rem) {
328 err = validate_nla(nla, maxtype, policy);
339 * Find a specific attribute in a stream of attributes
340 * @arg head head of attribute stream
341 * @arg len length of attribute stream
342 * @arg attrtype type of attribute to look for
344 * @return the first attribute in the stream matching the specified type.
346 struct nlattr *nla_find(struct nlattr *head, int len, int attrtype)
351 nla_for_each_attr(nla, head, len, rem)
352 if (nla->nla_type == attrtype)
366 * Copy a netlink attribute into another memory area
367 * @arg dest where to copy to memcpy
368 * @arg src netlink attribute to copy from
369 * @arg count size of the destination area
371 * Note: The number of bytes copied is limited by the length of
372 * attribute's payload. memcpy
374 * @return the number of bytes copied.
376 int nla_memcpy(void *dest, struct nlattr *src, int count)
383 minlen = min_t(int, count, nla_len(src));
384 memcpy(dest, nla_data(src), minlen);
390 * Copy string attribute payload into a sized buffer
391 * @arg dst where to copy the string to
392 * @arg nla attribute to copy the string from
393 * @arg dstsize size of destination buffer
395 * Copies at most dstsize - 1 bytes into the destination buffer.
396 * The result is always a valid NUL-terminated string. Unlike
397 * strlcpy the destination buffer is always padded out.
399 * @return the length of the source buffer.
401 size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
403 size_t srclen = nla_len(nla);
404 char *src = nla_data(nla);
406 if (srclen > 0 && src[srclen - 1] == '\0')
410 size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
412 memset(dst, 0, dstsize);
413 memcpy(dst, src, len);
420 * Compare an attribute with sized memory area
421 * @arg nla netlink attribute
422 * @arg data memory area
423 * @arg size size of memory area
425 int nla_memcmp(const struct nlattr *nla, const void *data,
428 int d = nla_len(nla) - size;
431 d = memcmp(nla_data(nla), data, size);
437 * Compare a string attribute against a string
438 * @arg nla netlink string attribute
439 * @arg str another string
441 int nla_strcmp(const struct nlattr *nla, const char *str)
443 int len = strlen(str) + 1;
444 int d = nla_len(nla) - len;
447 d = memcmp(nla_data(nla), str, len);
455 * @name Attribute Construction
460 * reserve room for attribute on the skb
461 * @arg n netlink message
462 * @arg attrtype attribute type
463 * @arg attrlen length of attribute payload
465 * Adds a netlink attribute header to a netlink message and reserves
466 * room for the payload but does not copy it.
468 struct nlattr *nla_reserve(struct nl_msg *n, int attrtype, int attrlen)
473 tlen = NLMSG_ALIGN(n->nm_nlh->nlmsg_len) + nla_total_size(attrlen);
475 n->nm_nlh = realloc(n->nm_nlh, tlen);
481 nla = (struct nlattr *) nlmsg_tail(n->nm_nlh);
482 nla->nla_type = attrtype;
483 nla->nla_len = nla_attr_size(attrlen);
485 memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen));
486 n->nm_nlh->nlmsg_len = tlen;
492 * Add a netlink attribute to a netlink message
493 * @arg n netlink message
494 * @arg attrtype attribute type
495 * @arg attrlen length of attribute payload
496 * @arg data head of attribute payload
498 * @return -1 if the tailroom of the skb is insufficient to store
499 * the attribute header and payload.
501 int nla_put(struct nl_msg *n, int attrtype, int attrlen, const void *data)
505 nla = nla_reserve(n, attrtype, attrlen);
507 return nl_errno(ENOMEM);
509 memcpy(nla_data(nla), data, attrlen);
515 * Add a nested netlink attribute to a netlink message
516 * @arg n netlink message
517 * @arg attrtype attribute type
518 * @arg nested netlink attribute to nest
520 * @return -1 if the tailroom of the skb is insufficient to store
521 * the attribute header and payload.
523 int nla_put_nested(struct nl_msg *n, int attrtype, struct nl_msg *nested)
525 return nla_put(n, attrtype, nlmsg_len(nested->nm_nlh),
526 nlmsg_data(nested->nm_nlh));
530 * Add a u16 netlink attribute to a netlink message
531 * @arg n netlink message
532 * @arg attrtype attribute type
533 * @arg value numeric value
535 int nla_put_u8(struct nl_msg *n, int attrtype, uint8_t value)
537 return nla_put(n, attrtype, sizeof(uint8_t), &value);
541 * Add a u16 netlink attribute to a netlink message
542 * @arg n netlink message
543 * @arg attrtype attribute type
544 * @arg value numeric value
546 int nla_put_u16(struct nl_msg *n, int attrtype, uint16_t value)
548 return nla_put(n, attrtype, sizeof(uint16_t), &value);
552 * Add a u32 netlink attribute to a netlink message
553 * @arg n netlink message
554 * @arg attrtype attribute type
555 * @arg value numeric value
557 int nla_put_u32(struct nl_msg *n, int attrtype, uint32_t value)
559 return nla_put(n, attrtype, sizeof(uint32_t), &value);
563 * Add a u64 netlink attribute to a netlink message
564 * @arg n netlink message
565 * @arg attrtype attribute type
566 * @arg value numeric value
568 int nla_put_u64(struct nl_msg *n, int attrtype, uint64_t value)
570 return nla_put(n, attrtype, sizeof(uint64_t), &value);
574 * Add a string netlink attribute to a netlink message
575 * @arg n netlink message
576 * @arg attrtype attribute type
577 * @arg str NUL terminated string
579 int nla_put_string(struct nl_msg *n, int attrtype, const char *str)
581 return nla_put(n, attrtype, strlen(str) + 1, str);
585 * Add a flag netlink attribute to a netlink message
586 * @arg n netlink message
587 * @arg attrtype attribute type
589 int nla_put_flag(struct nl_msg *n, int attrtype)
591 return nla_put(n, attrtype, 0, NULL);
595 * Add a msecs netlink attribute to a netlink message
596 * @arg n netlink message
597 * @arg attrtype attribute type
598 * @arg msecs number of msecs
600 int nla_put_msecs(struct nl_msg *n, int attrtype, unsigned long msecs)
602 return nla_put_u64(n, attrtype, msecs);
606 * Add an abstract data netlink attribute to a netlink message
607 * @arg n netlink message
608 * @arg attrtype attribute type
609 * @arg data abstract data
611 int nla_put_data(struct nl_msg *n, int attrtype, struct nl_data *data)
613 return nla_put(n, attrtype, nl_data_get_size(data),
618 * Add an abstract address netlink attribute to a netlink message
619 * @arg n netlink message
620 * @arg attrtype attribute type
621 * @arg addr abstract address
623 int nla_put_addr(struct nl_msg *n, int attrtype, struct nl_addr *addr)
625 return nla_put(n, attrtype, nl_addr_get_len(addr),
626 nl_addr_get_binary_addr(addr));
632 * @name Attribute Nesting
637 * Start a new level of nested attributes
638 * @arg n netlink message
639 * @arg attrtype attribute type of container
641 * @return the container attribute
643 struct nlattr *nla_nest_start(struct nl_msg *n, int attrtype)
645 struct nlattr *start = (struct nlattr *) nlmsg_tail(n->nm_nlh);
647 if (nla_put(n, attrtype, 0, NULL) < 0)
654 * Finalize nesting of attributes
655 * @arg n netlink message
656 * @arg start container attribute
658 * Corrects the container attribute header to include the all
659 * appeneded attributes.
661 * @return the total data length of the skb.
663 int nla_nest_end(struct nl_msg *n, struct nlattr *start)
665 start->nla_len = (unsigned char *) nlmsg_tail(n->nm_nlh) -
666 (unsigned char *) start;
673 * @name Attribute Reading
678 * Return payload of u32 attribute
679 * @arg nla u32 netlink attribute
681 uint32_t nla_get_u32(struct nlattr *nla)
683 return *(uint32_t *) nla_data(nla);
687 * Return payload of u16 attribute
688 * @arg nla u16 netlink attribute
690 uint16_t nla_get_u16(struct nlattr *nla)
692 return *(uint16_t *) nla_data(nla);
696 * Return payload of u8 attribute
697 * @arg nla u8 netlink attribute
699 uint8_t nla_get_u8(struct nlattr *nla)
701 return *(uint8_t *) nla_data(nla);
705 * Return payload of u64 attribute
706 * @arg nla u64 netlink attribute
708 uint64_t nla_get_u64(struct nlattr *nla)
712 nla_memcpy(&tmp, nla, sizeof(tmp));
718 * Return payload of flag attribute
719 * @arg nla flag netlink attribute
721 int nla_get_flag(struct nlattr *nla)
727 * Return payload of msecs attribute
728 * @arg nla msecs netlink attribute
730 * @return the number of milliseconds.
732 unsigned long nla_get_msecs(struct nlattr *nla)
734 return nla_get_u64(nla);
738 * Return payload of address attribute
739 * @arg nla address netlink attribute
740 * @arg family address family
742 * @return Newly allocated address handle or NULL
744 struct nl_addr *nla_get_addr(struct nlattr *nla, int family)
746 return nl_addr_build(family, nla_data(nla), nla_len(nla));
750 * Return payload of abstract data attribute
751 * @arg nla abstract data netlink attribute
753 * @return Newly allocated abstract data handle or NULL
755 struct nl_data *nla_get_data(struct nlattr *nla)
757 return nl_data_alloc(nla_data(nla), nla_len(nla));