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