Home | History | Annotate | Download | only in netlink
      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 (at) 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 
     20 #ifdef __cplusplus
     21 extern "C" {
     22 #endif
     23 
     24 struct nl_msg;
     25 
     26 /**
     27  * @name Basic Attribute Data Types
     28  * @{
     29  */
     30 
     31  /**
     32   * @ingroup attr
     33   * Basic attribute data types
     34   *
     35   * See \ref attr_datatypes for more details.
     36   */
     37 enum {
     38 	NLA_UNSPEC,	/**< Unspecified type, binary data chunk */
     39 	NLA_U8,		/**< 8 bit integer */
     40 	NLA_U16,	/**< 16 bit integer */
     41 	NLA_U32,	/**< 32 bit integer */
     42 	NLA_U64,	/**< 64 bit integer */
     43 	NLA_STRING,	/**< NUL terminated character string */
     44 	NLA_FLAG,	/**< Flag */
     45 	NLA_MSECS,	/**< Micro seconds (64bit) */
     46 	NLA_NESTED,	/**< Nested attributes */
     47 	__NLA_TYPE_MAX,
     48 };
     49 
     50 #define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
     51 
     52 /** @} */
     53 
     54 /**
     55  * @ingroup attr
     56  * Attribute validation policy.
     57  *
     58  * See \ref attr_datatypes for more details.
     59  */
     60 struct nla_policy {
     61 	/** Type of attribute or NLA_UNSPEC */
     62 	uint16_t	type;
     63 
     64 	/** Minimal length of payload required */
     65 	uint16_t	minlen;
     66 
     67 	/** Maximal length of payload allowed */
     68 	uint16_t	maxlen;
     69 };
     70 
     71 /* Size calculations */
     72 extern int		nla_attr_size(int payload);
     73 extern int		nla_total_size(int payload);
     74 extern int		nla_padlen(int payload);
     75 
     76 /* Attribute parsing */
     77 extern int		nla_type(const struct nlattr *);
     78 extern void *		nla_data(const struct nlattr *);
     79 extern int		nla_len(const struct nlattr *);
     80 extern int		nla_ok(const struct nlattr *, int);
     81 extern struct nlattr *	nla_next(const struct nlattr *, int *);
     82 extern int		nla_parse(struct nlattr **, int, struct nlattr *,
     83 				  int, struct nla_policy *);
     84 extern int		nla_validate(struct nlattr *, int, int,
     85 				     struct nla_policy *);
     86 extern struct nlattr *	nla_find(struct nlattr *, int, int);
     87 
     88 /* Helper Functions */
     89 extern int		nla_memcpy(void *, struct nlattr *, int);
     90 extern size_t		nla_strlcpy(char *, const struct nlattr *, size_t);
     91 extern int		nla_memcmp(const struct nlattr *, const void *, size_t);
     92 extern int		nla_strcmp(const struct nlattr *, const char *);
     93 
     94 /* Unspecific attribute */
     95 extern struct nlattr *	nla_reserve(struct nl_msg *, int, int);
     96 extern int		nla_put(struct nl_msg *, int, int, const void *);
     97 extern int		nla_put_data(struct nl_msg *, int, struct nl_data *);
     98 extern int		nla_put_addr(struct nl_msg *, int, struct nl_addr *);
     99 
    100 /* Integer attribute */
    101 extern uint8_t		nla_get_u8(struct nlattr *);
    102 extern int		nla_put_u8(struct nl_msg *, int, uint8_t);
    103 extern uint16_t		nla_get_u16(struct nlattr *);
    104 extern int		nla_put_u16(struct nl_msg *, int, uint16_t);
    105 extern uint32_t		nla_get_u32(struct nlattr *);
    106 extern int		nla_put_u32(struct nl_msg *, int, uint32_t);
    107 extern uint64_t		nla_get_u64(struct nlattr *);
    108 extern int		nla_put_u64(struct nl_msg *, int, uint64_t);
    109 
    110 /* String attribute */
    111 extern char *		nla_get_string(struct nlattr *);
    112 extern char *		nla_strdup(struct nlattr *);
    113 extern int		nla_put_string(struct nl_msg *, int, const char *);
    114 
    115 /* Flag attribute */
    116 extern int		nla_get_flag(struct nlattr *);
    117 extern int		nla_put_flag(struct nl_msg *, int);
    118 
    119 /* Msec attribute */
    120 extern unsigned long	nla_get_msecs(struct nlattr *);
    121 extern int		nla_put_msecs(struct nl_msg *, int, unsigned long);
    122 
    123 /* Attribute nesting */
    124 extern int		nla_put_nested(struct nl_msg *, int, struct nl_msg *);
    125 extern struct nlattr *	nla_nest_start(struct nl_msg *, int);
    126 extern int		nla_nest_end(struct nl_msg *, struct nlattr *);
    127 extern int		nla_parse_nested(struct nlattr **, int, struct nlattr *,
    128 					 struct nla_policy *);
    129 
    130 /**
    131  * @name Attribute Construction (Exception Based)
    132  * @{
    133  */
    134 
    135 /**
    136  * @ingroup attr
    137  * Add unspecific attribute to netlink message.
    138  * @arg msg		Netlink message.
    139  * @arg attrtype	Attribute type.
    140  * @arg attrlen		Length of attribute payload.
    141  * @arg data		Head of attribute payload.
    142  */
    143 #define NLA_PUT(msg, attrtype, attrlen, data) \
    144 	do { \
    145 		if (nla_put(msg, attrtype, attrlen, data) < 0) \
    146 			goto nla_put_failure; \
    147 	} while(0)
    148 
    149 /**
    150  * @ingroup attr
    151  * Add atomic type attribute to netlink message.
    152  * @arg msg		Netlink message.
    153  * @arg type		Atomic type.
    154  * @arg attrtype	Attribute type.
    155  * @arg value		Head of attribute payload.
    156  */
    157 #define NLA_PUT_TYPE(msg, type, attrtype, value) \
    158 	do { \
    159 		type __tmp = value; \
    160 		NLA_PUT(msg, attrtype, sizeof(type), &__tmp); \
    161 	} while(0)
    162 
    163 /**
    164  * Add 8 bit integer attribute to netlink message.
    165  * @arg msg		Netlink message.
    166  * @arg attrtype	Attribute type.
    167  * @arg value		Numeric value.
    168  */
    169 #define NLA_PUT_U8(msg, attrtype, value) \
    170 	NLA_PUT_TYPE(msg, uint8_t, attrtype, value)
    171 
    172 /**
    173  * Add 16 bit integer attribute to netlink message.
    174  * @arg msg		Netlink message.
    175  * @arg attrtype	Attribute type.
    176  * @arg value		Numeric value.
    177  */
    178 #define NLA_PUT_U16(msg, attrtype, value) \
    179 	NLA_PUT_TYPE(msg, uint16_t, attrtype, value)
    180 
    181 /**
    182  * Add 32 bit integer attribute to netlink message.
    183  * @arg msg		Netlink message.
    184  * @arg attrtype	Attribute type.
    185  * @arg value		Numeric value.
    186  */
    187 #define NLA_PUT_U32(msg, attrtype, value) \
    188 	NLA_PUT_TYPE(msg, uint32_t, attrtype, value)
    189 
    190 /**
    191  * Add 64 bit integer attribute to netlink message.
    192  * @arg msg		Netlink message.
    193  * @arg attrtype	Attribute type.
    194  * @arg value		Numeric value.
    195  */
    196 #define NLA_PUT_U64(msg, attrtype, value) \
    197 	NLA_PUT_TYPE(msg, uint64_t, attrtype, value)
    198 
    199 /**
    200  * Add string attribute to netlink message.
    201  * @arg msg		Netlink message.
    202  * @arg attrtype	Attribute type.
    203  * @arg value		NUL terminated character string.
    204  */
    205 #define NLA_PUT_STRING(msg, attrtype, value) \
    206 	NLA_PUT(msg, attrtype, strlen(value) + 1, value)
    207 
    208 /**
    209  * Add flag attribute to netlink message.
    210  * @arg msg		Netlink message.
    211  * @arg attrtype	Attribute type.
    212  */
    213 #define NLA_PUT_FLAG(msg, attrtype) \
    214 	NLA_PUT(msg, attrtype, 0, NULL)
    215 
    216 /**
    217  * Add msecs attribute to netlink message.
    218  * @arg msg		Netlink message.
    219  * @arg attrtype	Attribute type.
    220  * @arg msecs		Numeric value in micro seconds.
    221  */
    222 #define NLA_PUT_MSECS(msg, attrtype, msecs) \
    223 	NLA_PUT_U64(msg, attrtype, msecs)
    224 
    225 /**
    226  * Add address attribute to netlink message.
    227  * @arg msg		Netlink message.
    228  * @arg attrtype	Attribute type.
    229  * @arg addr		Abstract address object.
    230  */
    231 #define NLA_PUT_ADDR(msg, attrtype, addr) \
    232 	NLA_PUT(msg, attrtype, nl_addr_get_len(addr), \
    233 		nl_addr_get_binary_addr(addr))
    234 
    235 /**
    236  * Add abstract data attribute to netlink message.
    237  * @arg msg		Netlink message.
    238  * @arg attrtype	Attribute type.
    239  * @arg data		Abstract data object.
    240  */
    241 #define NLA_PUT_DATA(msg, attrtype, data) \
    242 	NLA_PUT(msg, attrtype, nl_data_get_size(data), \
    243 		nl_data_get(data))
    244 
    245 /** @} */
    246 
    247 /**
    248  * @name Iterators
    249  * @{
    250  */
    251 
    252 /**
    253  * @ingroup attr
    254  * Iterate over a stream of attributes
    255  * @arg pos	loop counter, set to current attribute
    256  * @arg head	head of attribute stream
    257  * @arg len	length of attribute stream
    258  * @arg rem	initialized to len, holds bytes currently remaining in stream
    259  */
    260 #define nla_for_each_attr(pos, head, len, rem) \
    261 	for (pos = head, rem = len; \
    262 	     nla_ok(pos, rem); \
    263 	     pos = nla_next(pos, &(rem)))
    264 
    265 /**
    266  * @ingroup attr
    267  * Iterate over a stream of nested attributes
    268  * @arg pos	loop counter, set to current attribute
    269  * @arg nla	attribute containing the nested attributes
    270  * @arg rem	initialized to len, holds bytes currently remaining in stream
    271  */
    272 #define nla_for_each_nested(pos, nla, rem) \
    273 	for (pos = nla_data(nla), rem = nla_len(nla); \
    274 	     nla_ok(pos, rem); \
    275 	     pos = nla_next(pos, &(rem)))
    276 
    277 /** @} */
    278 
    279 #ifdef __cplusplus
    280 }
    281 #endif
    282 
    283 #endif
    284