libnl: /data/src/libnl/lib/attr.c Source File

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