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