• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/libnl-tiny/include/netlink/attr.h

  1 /*
  2  * netlink/attr.h               Netlink Attributes
  3  *
  4  *      This library is free software; you can redistribute it and/or
  5  *      modify it under the terms of the GNU Lesser General Public
  6  *      License as published by the Free Software Foundation version 2.1
  7  *      of the License.
  8  *
  9  * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
 10  */
 11 
 12 #ifndef NETLINK_ATTR_H_
 13 #define NETLINK_ATTR_H_
 14 
 15 #include <netlink/netlink.h>
 16 #include <netlink/object.h>
 17 #include <netlink/addr.h>
 18 #include <netlink/data.h>
 19 #include <netlink/msg.h>
 20 
 21 #ifdef __cplusplus
 22 extern "C" {
 23 #endif
 24 
 25 struct nl_msg;
 26 
 27 /**
 28  * @name Basic Attribute Data Types
 29  * @{
 30  */
 31 
 32  /**
 33   * @ingroup attr
 34   * Basic attribute data types
 35   *
 36   * See \ref attr_datatypes for more details.
 37   */
 38 enum {
 39         NLA_UNSPEC,     /**< Unspecified type, binary data chunk */
 40         NLA_U8,         /**< 8 bit integer */
 41         NLA_U16,        /**< 16 bit integer */
 42         NLA_U32,        /**< 32 bit integer */
 43         NLA_U64,        /**< 64 bit integer */
 44         NLA_STRING,     /**< NUL terminated character string */
 45         NLA_FLAG,       /**< Flag */
 46         NLA_MSECS,      /**< Micro seconds (64bit) */
 47         NLA_NESTED,     /**< Nested attributes */
 48         __NLA_TYPE_MAX,
 49 };
 50 
 51 #define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
 52 
 53 /** @} */
 54 
 55 /**
 56  * @ingroup attr
 57  * Attribute validation policy.
 58  *
 59  * See \ref attr_datatypes for more details.
 60  */
 61 struct nla_policy {
 62         /** Type of attribute or NLA_UNSPEC */
 63         uint16_t        type;
 64 
 65         /** Minimal length of payload required */
 66         uint16_t        minlen;
 67 
 68         /** Maximal length of payload allowed */
 69         uint16_t        maxlen;
 70 };
 71 
 72 /* Attribute parsing */
 73 extern int              nla_ok(const struct nlattr *, int);
 74 extern struct nlattr *  nla_next(const struct nlattr *, int *);
 75 extern int              nla_parse(struct nlattr **, int, struct nlattr *,
 76                                   int, struct nla_policy *);
 77 extern int              nla_validate(struct nlattr *, int, int,
 78                                      struct nla_policy *);
 79 extern struct nlattr *  nla_find(struct nlattr *, int, int);
 80 
 81 /* Unspecific attribute */
 82 extern struct nlattr *  nla_reserve(struct nl_msg *, int, int);
 83 extern int              nla_put(struct nl_msg *, int, int, const void *);
 84 
 85 /**
 86  * nlmsg_find_attr - find a specific attribute in a netlink message
 87  * @arg nlh             netlink message header
 88  * @arg hdrlen          length of familiy specific header
 89  * @arg attrtype        type of attribute to look for
 90  *
 91  * Returns the first attribute which matches the specified type.
 92  */
 93 static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh, int hdrlen, int attrtype)
 94 {
 95         return nla_find(nlmsg_attrdata(nlh, hdrlen),
 96                         nlmsg_attrlen(nlh, hdrlen), attrtype);
 97 }
 98 
 99 
100 /**
101  * Return size of attribute whithout padding.
102  * @arg payload         Payload length of attribute.
103  *
104  * @code
105  *    <-------- nla_attr_size(payload) --------->
106  *   +------------------+- - -+- - - - - - - - - +- - -+
107  *   | Attribute Header | Pad |     Payload      | Pad |
108  *   +------------------+- - -+- - - - - - - - - +- - -+
109  * @endcode
110  *
111  * @return Size of attribute in bytes without padding.
112  */
113 static inline int nla_attr_size(int payload)
114 {
115         return NLA_HDRLEN + payload;
116 }
117 
118 /**
119  * Return size of attribute including padding.
120  * @arg payload         Payload length of attribute.
121  *
122  * @code
123  *    <----------- nla_total_size(payload) ----------->
124  *   +------------------+- - -+- - - - - - - - - +- - -+
125  *   | Attribute Header | Pad |     Payload      | Pad |
126  *   +------------------+- - -+- - - - - - - - - +- - -+
127  * @endcode
128  *
129  * @return Size of attribute in bytes.
130  */
131 static inline int nla_total_size(int payload)
132 {
133         return NLA_ALIGN(nla_attr_size(payload));
134 }
135 
136 /**
137  * Return length of padding at the tail of the attribute.
138  * @arg payload         Payload length of attribute.
139  *
140  * @code
141  *   +------------------+- - -+- - - - - - - - - +- - -+
142  *   | Attribute Header | Pad |     Payload      | Pad |
143  *   +------------------+- - -+- - - - - - - - - +- - -+
144  *                                                <--->  
145  * @endcode
146  *
147  * @return Length of padding in bytes.
148  */
149 static inline int nla_padlen(int payload)
150 {
151         return nla_total_size(payload) - nla_attr_size(payload);
152 }
153 
154 /**
155  * Return type of the attribute.
156  * @arg nla             Attribute.
157  *
158  * @return Type of attribute.
159  */
160 static inline int nla_type(const struct nlattr *nla)
161 {
162         return nla->nla_type & NLA_TYPE_MASK;
163 }
164 
165 /**
166  * Return pointer to the payload section.
167  * @arg nla             Attribute.
168  *
169  * @return Pointer to start of payload section.
170  */
171 static inline void *nla_data(const struct nlattr *nla)
172 {
173         return (char *) nla + NLA_HDRLEN;
174 }
175 
176 /**
177  * Return length of the payload .
178  * @arg nla             Attribute
179  *
180  * @return Length of payload in bytes.
181  */
182 static inline int nla_len(const struct nlattr *nla)
183 {
184         return nla->nla_len - NLA_HDRLEN;
185 }
186 
187 /**
188  * Copy attribute payload to another memory area.
189  * @arg dest            Pointer to destination memory area.
190  * @arg src             Attribute
191  * @arg count           Number of bytes to copy at most.
192  *
193  * Note: The number of bytes copied is limited by the length of
194  *       the attribute payload.
195  *
196  * @return The number of bytes copied to dest.
197  */
198 static inline int nla_memcpy(void *dest, struct nlattr *src, int count)
199 {
200         int minlen;
201 
202         if (!src)
203                 return 0;
204         
205         minlen = min_t(int, count, nla_len(src));
206         memcpy(dest, nla_data(src), minlen);
207 
208         return minlen;
209 }
210 
211 
212 /**
213  * Add abstract data as unspecific attribute to netlink message.
214  * @arg msg             Netlink message.
215  * @arg attrtype        Attribute type.
216  * @arg data            Abstract data object.
217  *
218  * Equivalent to nla_put() except that the length of the payload is
219  * derived from the abstract data object.
220  *
221  * @see nla_put
222  * @return 0 on success or a negative error code.
223  */
224 static inline int nla_put_data(struct nl_msg *msg, int attrtype, struct nl_data *data)
225 {
226         return nla_put(msg, attrtype, nl_data_get_size(data),
227                        nl_data_get(data));
228 }
229 
230 /**
231  * Add abstract address as unspecific attribute to netlink message.
232  * @arg msg             Netlink message.
233  * @arg attrtype        Attribute type.
234  * @arg addr            Abstract address object.
235  *
236  * @see nla_put
237  * @return 0 on success or a negative error code.
238  */
239 static inline int nla_put_addr(struct nl_msg *msg, int attrtype, struct nl_addr *addr)
240 {
241         return nla_put(msg, attrtype, nl_addr_get_len(addr),
242                        nl_addr_get_binary_addr(addr));
243 }
244 
245 /** @} */
246 
247 /**
248  * @name Integer Attributes
249  */
250 
251 /**
252  * Add 8 bit integer attribute to netlink message.
253  * @arg msg             Netlink message.
254  * @arg attrtype        Attribute type.
255  * @arg value           Numeric value to store as payload.
256  *
257  * @see nla_put
258  * @return 0 on success or a negative error code.
259  */
260 static inline int nla_put_u8(struct nl_msg *msg, int attrtype, uint8_t value)
261 {
262         return nla_put(msg, attrtype, sizeof(uint8_t), &value);
263 }
264 
265 /**
266  * Return value of 8 bit integer attribute.
267  * @arg nla             8 bit integer attribute
268  *
269  * @return Payload as 8 bit integer.
270  */
271 static inline uint8_t nla_get_u8(struct nlattr *nla)
272 {
273         return *(uint8_t *) nla_data(nla);
274 }
275 
276 /**
277  * Add 16 bit integer attribute to netlink message.
278  * @arg msg             Netlink message.
279  * @arg attrtype        Attribute type.
280  * @arg value           Numeric value to store as payload.
281  *
282  * @see nla_put
283  * @return 0 on success or a negative error code.
284  */
285 static inline int nla_put_u16(struct nl_msg *msg, int attrtype, uint16_t value)
286 {
287         return nla_put(msg, attrtype, sizeof(uint16_t), &value);
288 }
289 
290 /**
291  * Return payload of 16 bit integer attribute.
292  * @arg nla             16 bit integer attribute
293  *
294  * @return Payload as 16 bit integer.
295  */
296 static inline uint16_t nla_get_u16(struct nlattr *nla)
297 {
298         return *(uint16_t *) nla_data(nla);
299 }
300 
301 /**
302  * Add 32 bit signed integer attribute to netlink message.
303  * @arg msg             Netlink message.
304  * @arg attrtype        Attribute type.
305  * @arg value           Numeric value to store as payload.
306  *
307  * @see nla_put
308  * @return 0 on success or a negative error code.
309  */
310 static inline int nla_put_s32(struct nl_msg *msg, int attrtype, int32_t value)
311 {
312         return nla_put(msg, attrtype, sizeof(int32_t), &value);
313 }
314 
315 /**
316  * Return payload of 32 bit signed integer attribute.
317  * @arg nla             32 bit integer attribute.
318  *
319  * @return Payload as 32 bit integer.
320  */
321 static inline int32_t nla_get_s32(struct nlattr *nla)
322 {
323         return *(int32_t *) nla_data(nla);
324 }
325 
326 /**
327  * Add 32 bit integer attribute to netlink message.
328  * @arg msg             Netlink message.
329  * @arg attrtype        Attribute type.
330  * @arg value           Numeric value to store as payload.
331  *
332  * @see nla_put
333  * @return 0 on success or a negative error code.
334  */
335 static inline int nla_put_u32(struct nl_msg *msg, int attrtype, uint32_t value)
336 {
337         return nla_put(msg, attrtype, sizeof(uint32_t), &value);
338 }
339 
340 /**
341  * Return payload of 32 bit integer attribute.
342  * @arg nla             32 bit integer attribute.
343  *
344  * @return Payload as 32 bit integer.
345  */
346 static inline uint32_t nla_get_u32(struct nlattr *nla)
347 {
348         return *(uint32_t *) nla_data(nla);
349 }
350 
351 /**
352  * Add 64 bit integer attribute to netlink message.
353  * @arg msg             Netlink message.
354  * @arg attrtype        Attribute type.
355  * @arg value           Numeric value to store as payload.
356  *
357  * @see nla_put
358  * @return 0 on success or a negative error code.
359  */
360 static inline int nla_put_u64(struct nl_msg *msg, int attrtype, uint64_t value)
361 {
362         return nla_put(msg, attrtype, sizeof(uint64_t), &value);
363 }
364 
365 /**
366  * Return payload of u64 attribute
367  * @arg nla             u64 netlink attribute
368  *
369  * @return Payload as 64 bit integer.
370  */
371 static inline uint64_t nla_get_u64(struct nlattr *nla)
372 {
373         uint64_t tmp;
374 
375         nla_memcpy(&tmp, nla, sizeof(tmp));
376 
377         return tmp;
378 }
379 
380 /**
381  * Add string attribute to netlink message.
382  * @arg msg             Netlink message.
383  * @arg attrtype        Attribute type.
384  * @arg str             NUL terminated string.
385  *
386  * @see nla_put
387  * @return 0 on success or a negative error code.
388  */
389 static inline int nla_put_string(struct nl_msg *msg, int attrtype, const char *str)
390 {
391         return nla_put(msg, attrtype, strlen(str) + 1, str);
392 }
393 
394 /**
395  * Return payload of string attribute.
396  * @arg nla             String attribute.
397  *
398  * @return Pointer to attribute payload.
399  */
400 static inline char *nla_get_string(struct nlattr *nla)
401 {
402         return (char *) nla_data(nla);
403 }
404 
405 static inline char *nla_strdup(struct nlattr *nla)
406 {
407         return strdup(nla_get_string(nla));
408 }
409 
410 /** @} */
411 
412 /**
413  * @name Flag Attribute
414  */
415 
416 /**
417  * Add flag netlink attribute to netlink message.
418  * @arg msg             Netlink message.
419  * @arg attrtype        Attribute type.
420  *
421  * @see nla_put
422  * @return 0 on success or a negative error code.
423  */
424 static inline int nla_put_flag(struct nl_msg *msg, int attrtype)
425 {
426         return nla_put(msg, attrtype, 0, NULL);
427 }
428 
429 /**
430  * Return true if flag attribute is set.
431  * @arg nla             Flag netlink attribute.
432  *
433  * @return True if flag is set, otherwise false.
434  */
435 static inline int nla_get_flag(struct nlattr *nla)
436 {
437         return !!nla;
438 }
439 
440 /** @} */
441 
442 /**
443  * @name Microseconds Attribute
444  */
445 
446 /**
447  * Add a msecs netlink attribute to a netlink message
448  * @arg n               netlink message
449  * @arg attrtype        attribute type
450  * @arg msecs           number of msecs
451  */
452 static inline int nla_put_msecs(struct nl_msg *n, int attrtype, unsigned long msecs)
453 {
454         return nla_put_u64(n, attrtype, msecs);
455 }
456 
457 /**
458  * Return payload of msecs attribute
459  * @arg nla             msecs netlink attribute
460  *
461  * @return the number of milliseconds.
462  */
463 static inline unsigned long nla_get_msecs(struct nlattr *nla)
464 {
465         return nla_get_u64(nla);
466 }
467 
468 /**
469  * Add nested attributes to netlink message.
470  * @arg msg             Netlink message.
471  * @arg attrtype        Attribute type.
472  * @arg nested          Message containing attributes to be nested.
473  *
474  * Takes the attributes found in the \a nested message and appends them
475  * to the message \a msg nested in a container of the type \a attrtype.
476  * The \a nested message may not have a family specific header.
477  *
478  * @see nla_put
479  * @return 0 on success or a negative error code.
480  */
481 static inline int nla_put_nested(struct nl_msg *msg, int attrtype, struct nl_msg *nested)
482 {
483         return nla_put(msg, attrtype, nlmsg_len(nested->nm_nlh),
484                        nlmsg_data(nested->nm_nlh));
485 }
486 
487 /**
488  * Start a new level of nested attributes.
489  * @arg msg             Netlink message.
490  * @arg attrtype        Attribute type of container.
491  *
492  * @return Pointer to container attribute.
493  */
494 static inline struct nlattr *nla_nest_start(struct nl_msg *msg, int attrtype)
495 {
496         struct nlattr *start = (struct nlattr *) nlmsg_tail(msg->nm_nlh);
497 
498         if (nla_put(msg, attrtype | NLA_F_NESTED, 0, NULL) < 0)
499                 return NULL;
500 
501         return start;
502 }
503 
504 /**
505  * Finalize nesting of attributes.
506  * @arg msg             Netlink message.
507  * @arg start           Container attribute as returned from nla_nest_start().
508  *
509  * Corrects the container attribute header to include the appeneded attributes.
510  *
511  * @return 0
512  */
513 static inline int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
514 {
515         start->nla_len = (unsigned char *) nlmsg_tail(msg->nm_nlh) -
516                                 (unsigned char *) start;
517         return 0;
518 }
519 
520 /**
521  * Create attribute index based on nested attribute
522  * @arg tb              Index array to be filled (maxtype+1 elements).
523  * @arg maxtype         Maximum attribute type expected and accepted.
524  * @arg nla             Nested Attribute.
525  * @arg policy          Attribute validation policy.
526  *
527  * Feeds the stream of attributes nested into the specified attribute
528  * to nla_parse().
529  *
530  * @see nla_parse
531  * @return 0 on success or a negative error code.
532  */
533 static inline int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
534                      struct nla_policy *policy)
535 {
536         return nla_parse(tb, maxtype, (struct nlattr *)nla_data(nla), nla_len(nla), policy);
537 }
538 
539 /**
540  * Compare attribute payload with memory area.
541  * @arg nla             Attribute.
542  * @arg data            Memory area to compare to.
543  * @arg size            Number of bytes to compare.
544  *
545  * @see memcmp(3)
546  * @return An integer less than, equal to, or greater than zero.
547  */
548 static inline int nla_memcmp(const struct nlattr *nla, const void *data, size_t size)
549 {
550         int d = nla_len(nla) - size;
551 
552         if (d == 0)
553                 d = memcmp(nla_data(nla), data, size);
554 
555         return d;
556 }
557 
558 /**
559  * Compare string attribute payload with string
560  * @arg nla             Attribute of type NLA_STRING.
561  * @arg str             NUL terminated string.
562  *
563  * @see strcmp(3)
564  * @return An integer less than, equal to, or greater than zero.
565  */
566 static inline int nla_strcmp(const struct nlattr *nla, const char *str)
567 {
568         int len = strlen(str) + 1;
569         int d = nla_len(nla) - len;
570 
571         if (d == 0)
572                 d = memcmp(nla_data(nla), str, len);
573 
574         return d;
575 }
576 
577 /**
578  * Copy string attribute payload to a buffer.
579  * @arg dst             Pointer to destination buffer.
580  * @arg nla             Attribute of type NLA_STRING.
581  * @arg dstsize         Size of destination buffer in bytes.
582  *
583  * Copies at most dstsize - 1 bytes to the destination buffer.
584  * The result is always a valid NUL terminated string. Unlike
585  * strlcpy the destination buffer is always padded out.
586  *
587  * @return The length of string attribute without the terminating NUL.
588  */
589 static inline size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
590 {
591         size_t srclen = (size_t)nla_len(nla);
592         char *src = (char*)nla_data(nla);
593 
594         if (srclen > 0 && src[srclen - 1] == '\0')
595                 srclen--;
596 
597         if (dstsize > 0) {
598                 size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
599 
600                 memset(dst, 0, dstsize);
601                 memcpy(dst, src, len);
602         }
603 
604         return srclen;
605 }
606 
607 
608 /**
609  * @name Attribute Construction (Exception Based)
610  * @{
611  */
612 
613 /**
614  * @ingroup attr
615  * Add unspecific attribute to netlink message.
616  * @arg msg             Netlink message.
617  * @arg attrtype        Attribute type.
618  * @arg attrlen         Length of attribute payload.
619  * @arg data            Head of attribute payload.
620  */
621 #define NLA_PUT(msg, attrtype, attrlen, data) \
622         do { \
623                 if (nla_put(msg, attrtype, attrlen, data) < 0) \
624                         goto nla_put_failure; \
625         } while(0)
626 
627 /**
628  * @ingroup attr
629  * Add atomic type attribute to netlink message.
630  * @arg msg             Netlink message.
631  * @arg type            Atomic type.
632  * @arg attrtype        Attribute type.
633  * @arg value           Head of attribute payload.
634  */
635 #define NLA_PUT_TYPE(msg, type, attrtype, value) \
636         do { \
637                 type __tmp = value; \
638                 NLA_PUT(msg, attrtype, sizeof(type), &__tmp); \
639         } while(0)
640 
641 /**
642  * Add 8 bit integer attribute to netlink message.
643  * @arg msg             Netlink message.
644  * @arg attrtype        Attribute type.
645  * @arg value           Numeric value.
646  */
647 #define NLA_PUT_U8(msg, attrtype, value) \
648         NLA_PUT_TYPE(msg, uint8_t, attrtype, value)
649 
650 /**
651  * Add 16 bit integer attribute to netlink message.
652  * @arg msg             Netlink message.
653  * @arg attrtype        Attribute type.
654  * @arg value           Numeric value.
655  */
656 #define NLA_PUT_U16(msg, attrtype, value) \
657         NLA_PUT_TYPE(msg, uint16_t, attrtype, value)
658 
659 /**
660  * Add 32 bit signed integer attribute to netlink message.
661  * @arg msg             Netlink message.
662  * @arg attrtype        Attribute type.
663  * @arg value           Numeric value.
664  */
665 #define NLA_PUT_S32(msg, attrtype, value) \
666         NLA_PUT_TYPE(msg, int32_t, attrtype, value)
667 
668 /**
669  * Add 32 bit integer attribute to netlink message.
670  * @arg msg             Netlink message.
671  * @arg attrtype        Attribute type.
672  * @arg value           Numeric value.
673  */
674 #define NLA_PUT_U32(msg, attrtype, value) \
675         NLA_PUT_TYPE(msg, uint32_t, attrtype, value)
676 
677 /**
678  * Add 64 bit integer attribute to netlink message.
679  * @arg msg             Netlink message.
680  * @arg attrtype        Attribute type.
681  * @arg value           Numeric value.
682  */
683 #define NLA_PUT_U64(msg, attrtype, value) \
684         NLA_PUT_TYPE(msg, uint64_t, attrtype, value)
685 
686 /**
687  * Add string attribute to netlink message.
688  * @arg msg             Netlink message.
689  * @arg attrtype        Attribute type.
690  * @arg value           NUL terminated character string.
691  */
692 #define NLA_PUT_STRING(msg, attrtype, value) \
693         NLA_PUT(msg, attrtype, strlen(value) + 1, value)
694 
695 /**
696  * Add flag attribute to netlink message.
697  * @arg msg             Netlink message.
698  * @arg attrtype        Attribute type.
699  */
700 #define NLA_PUT_FLAG(msg, attrtype) \
701         NLA_PUT(msg, attrtype, 0, NULL)
702 
703 /**
704  * Add msecs attribute to netlink message.
705  * @arg msg             Netlink message.
706  * @arg attrtype        Attribute type.
707  * @arg msecs           Numeric value in micro seconds.
708  */
709 #define NLA_PUT_MSECS(msg, attrtype, msecs) \
710         NLA_PUT_U64(msg, attrtype, msecs)
711 
712 /**
713  * Add address attribute to netlink message.
714  * @arg msg             Netlink message.
715  * @arg attrtype        Attribute type.
716  * @arg addr            Abstract address object.
717  */
718 #define NLA_PUT_ADDR(msg, attrtype, addr) \
719         NLA_PUT(msg, attrtype, nl_addr_get_len(addr), \
720                 nl_addr_get_binary_addr(addr))
721 
722 /** @} */
723 
724 /**
725  * @name Iterators
726  * @{
727  */
728 
729 /**
730  * @ingroup attr
731  * Iterate over a stream of attributes
732  * @arg pos     loop counter, set to current attribute
733  * @arg head    head of attribute stream
734  * @arg len     length of attribute stream
735  * @arg rem     initialized to len, holds bytes currently remaining in stream
736  */
737 #define nla_for_each_attr(pos, head, len, rem) \
738         for (pos = head, rem = len; \
739              nla_ok(pos, rem); \
740              pos = nla_next(pos, &(rem)))
741 
742 /**
743  * @ingroup attr
744  * Iterate over a stream of nested attributes
745  * @arg pos     loop counter, set to current attribute
746  * @arg nla     attribute containing the nested attributes
747  * @arg rem     initialized to len, holds bytes currently remaining in stream
748  */
749 #define nla_for_each_nested(pos, nla, rem) \
750         for (pos = (struct nlattr *)nla_data(nla), rem = nla_len(nla); \
751              nla_ok(pos, rem); \
752              pos = nla_next(pos, &(rem)))
753 
754 /** @} */
755 
756 #ifdef __cplusplus
757 }
758 #endif
759 
760 #endif
761 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt