attr.h

00001 /*
00002  * netlink/attr.h               Netlink Attributes
00003  *
00004  *      This library is free software; you can redistribute it and/or
00005  *      modify it under the terms of the GNU Lesser General Public
00006  *      License as published by the Free Software Foundation version 2.1
00007  *      of the License.
00008  *
00009  * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
00010  */
00011 
00012 #ifndef NETLINK_ATTR_H_
00013 #define NETLINK_ATTR_H_
00014 
00015 #include <netlink/netlink.h>
00016 #include <netlink/object.h>
00017 #include <netlink/addr.h>
00018 #include <netlink/data.h>
00019 
00020 #ifdef __cplusplus
00021 extern "C" {
00022 #endif
00023 
00024 struct nl_msg;
00025 
00026 /**
00027  * @name Basic Attribute Data Types
00028  * @{
00029  */
00030 
00031  /**
00032   * @ingroup attr
00033   * Basic attribute data types
00034   *
00035   * See \ref attr_datatypes for more details.
00036   */
00037 enum {
00038         NLA_UNSPEC,     /**< Unspecified type, binary data chunk */
00039         NLA_U8,         /**< 8 bit integer */
00040         NLA_U16,        /**< 16 bit integer */
00041         NLA_U32,        /**< 32 bit integer */
00042         NLA_U64,        /**< 64 bit integer */
00043         NLA_STRING,     /**< NUL terminated character string */
00044         NLA_FLAG,       /**< Flag */
00045         NLA_MSECS,      /**< Micro seconds (64bit) */
00046         NLA_NESTED,     /**< Nested attributes */
00047         __NLA_TYPE_MAX,
00048 };
00049 
00050 #define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
00051 
00052 /** @} */
00053 
00054 /**
00055  * @ingroup attr
00056  * Attribute validation policy.
00057  *
00058  * See \ref attr_datatypes for more details.
00059  */
00060 struct nla_policy {
00061         /** Type of attribute or NLA_UNSPEC */
00062         uint16_t        type;
00063 
00064         /** Minimal length of payload required */
00065         uint16_t        minlen;
00066 
00067         /** Maximal length of payload allowed */
00068         uint16_t        maxlen;
00069 };
00070 
00071 /* Size calculations */
00072 extern int              nla_attr_size(int payload);
00073 extern int              nla_total_size(int payload);
00074 extern int              nla_padlen(int payload);
00075 
00076 /* Attribute parsing */
00077 extern int              nla_type(const struct nlattr *);
00078 extern void *           nla_data(const struct nlattr *);
00079 extern int              nla_len(const struct nlattr *);
00080 extern int              nla_ok(const struct nlattr *, int);
00081 extern struct nlattr *  nla_next(const struct nlattr *, int *);
00082 extern int              nla_parse(struct nlattr **, int, struct nlattr *,
00083                                   int, struct nla_policy *);
00084 extern int              nla_validate(struct nlattr *, int, int,
00085                                      struct nla_policy *);
00086 extern struct nlattr *  nla_find(struct nlattr *, int, int);
00087 
00088 /* Helper Functions */
00089 extern int              nla_memcpy(void *, struct nlattr *, int);
00090 extern size_t           nla_strlcpy(char *, const struct nlattr *, size_t);
00091 extern int              nla_memcmp(const struct nlattr *, const void *, size_t);
00092 extern int              nla_strcmp(const struct nlattr *, const char *);
00093 
00094 /* Unspecific attribute */
00095 extern struct nlattr *  nla_reserve(struct nl_msg *, int, int);
00096 extern int              nla_put(struct nl_msg *, int, int, const void *);
00097 extern int              nla_put_data(struct nl_msg *, int, struct nl_data *);
00098 extern int              nla_put_addr(struct nl_msg *, int, struct nl_addr *);
00099 
00100 /* Integer attribute */
00101 extern uint8_t          nla_get_u8(struct nlattr *);
00102 extern int              nla_put_u8(struct nl_msg *, int, uint8_t);
00103 extern uint16_t         nla_get_u16(struct nlattr *);
00104 extern int              nla_put_u16(struct nl_msg *, int, uint16_t);
00105 extern uint32_t         nla_get_u32(struct nlattr *);
00106 extern int              nla_put_u32(struct nl_msg *, int, uint32_t);
00107 extern uint64_t         nla_get_u64(struct nlattr *);
00108 extern int              nla_put_u64(struct nl_msg *, int, uint64_t);
00109 
00110 /* String attribute */
00111 extern char *           nla_get_string(struct nlattr *);
00112 extern char *           nla_strdup(struct nlattr *);
00113 extern int              nla_put_string(struct nl_msg *, int, const char *);
00114 
00115 /* Flag attribute */
00116 extern int              nla_get_flag(struct nlattr *);
00117 extern int              nla_put_flag(struct nl_msg *, int);
00118 
00119 /* Msec attribute */
00120 extern unsigned long    nla_get_msecs(struct nlattr *);
00121 extern int              nla_put_msecs(struct nl_msg *, int, unsigned long);
00122 
00123 /* Attribute nesting */
00124 extern int              nla_put_nested(struct nl_msg *, int, struct nl_msg *);
00125 extern struct nlattr *  nla_nest_start(struct nl_msg *, int);
00126 extern int              nla_nest_end(struct nl_msg *, struct nlattr *);
00127 extern int              nla_parse_nested(struct nlattr **, int, struct nlattr *,
00128                                          struct nla_policy *);
00129 
00130 /**
00131  * @name Attribute Construction (Exception Based)
00132  * @{
00133  */
00134 
00135 /**
00136  * @ingroup attr
00137  * Add unspecific attribute to netlink message.
00138  * @arg msg             Netlink message.
00139  * @arg attrtype        Attribute type.
00140  * @arg attrlen         Length of attribute payload.
00141  * @arg data            Head of attribute payload.
00142  */
00143 #define NLA_PUT(msg, attrtype, attrlen, data) \
00144         do { \
00145                 if (nla_put(msg, attrtype, attrlen, data) < 0) \
00146                         goto nla_put_failure; \
00147         } while(0)
00148 
00149 /**
00150  * @ingroup attr
00151  * Add atomic type attribute to netlink message.
00152  * @arg msg             Netlink message.
00153  * @arg type            Atomic type.
00154  * @arg attrtype        Attribute type.
00155  * @arg value           Head of attribute payload.
00156  */
00157 #define NLA_PUT_TYPE(msg, type, attrtype, value) \
00158         do { \
00159                 type __tmp = value; \
00160                 NLA_PUT(msg, attrtype, sizeof(type), &__tmp); \
00161         } while(0)
00162 
00163 /**
00164  * Add 8 bit integer attribute to netlink message.
00165  * @arg msg             Netlink message.
00166  * @arg attrtype        Attribute type.
00167  * @arg value           Numeric value.
00168  */
00169 #define NLA_PUT_U8(msg, attrtype, value) \
00170         NLA_PUT_TYPE(msg, uint8_t, attrtype, value)
00171 
00172 /**
00173  * Add 16 bit integer attribute to netlink message.
00174  * @arg msg             Netlink message.
00175  * @arg attrtype        Attribute type.
00176  * @arg value           Numeric value.
00177  */
00178 #define NLA_PUT_U16(msg, attrtype, value) \
00179         NLA_PUT_TYPE(msg, uint16_t, attrtype, value)
00180 
00181 /**
00182  * Add 32 bit integer attribute to netlink message.
00183  * @arg msg             Netlink message.
00184  * @arg attrtype        Attribute type.
00185  * @arg value           Numeric value.
00186  */
00187 #define NLA_PUT_U32(msg, attrtype, value) \
00188         NLA_PUT_TYPE(msg, uint32_t, attrtype, value)
00189 
00190 /**
00191  * Add 64 bit integer attribute to netlink message.
00192  * @arg msg             Netlink message.
00193  * @arg attrtype        Attribute type.
00194  * @arg value           Numeric value.
00195  */
00196 #define NLA_PUT_U64(msg, attrtype, value) \
00197         NLA_PUT_TYPE(msg, uint64_t, attrtype, value)
00198 
00199 /**
00200  * Add string attribute to netlink message.
00201  * @arg msg             Netlink message.
00202  * @arg attrtype        Attribute type.
00203  * @arg value           NUL terminated character string.
00204  */
00205 #define NLA_PUT_STRING(msg, attrtype, value) \
00206         NLA_PUT(msg, attrtype, strlen(value) + 1, value)
00207 
00208 /**
00209  * Add flag attribute to netlink message.
00210  * @arg msg             Netlink message.
00211  * @arg attrtype        Attribute type.
00212  */
00213 #define NLA_PUT_FLAG(msg, attrtype) \
00214         NLA_PUT(msg, attrtype, 0, NULL)
00215 
00216 /**
00217  * Add msecs attribute to netlink message.
00218  * @arg msg             Netlink message.
00219  * @arg attrtype        Attribute type.
00220  * @arg msecs           Numeric value in micro seconds.
00221  */
00222 #define NLA_PUT_MSECS(msg, attrtype, msecs) \
00223         NLA_PUT_U64(msg, attrtype, msecs)
00224 
00225 /**
00226  * Add address attribute to netlink message.
00227  * @arg msg             Netlink message.
00228  * @arg attrtype        Attribute type.
00229  * @arg addr            Abstract address object.
00230  */
00231 #define NLA_PUT_ADDR(msg, attrtype, addr) \
00232         NLA_PUT(msg, attrtype, nl_addr_get_len(addr), \
00233                 nl_addr_get_binary_addr(addr))
00234 
00235 /**
00236  * Add abstract data attribute to netlink message.
00237  * @arg msg             Netlink message.
00238  * @arg attrtype        Attribute type.
00239  * @arg data            Abstract data object.
00240  */
00241 #define NLA_PUT_DATA(msg, attrtype, data) \
00242         NLA_PUT(msg, attrtype, nl_data_get_size(data), \
00243                 nl_data_get(data))
00244 
00245 /** @} */
00246 
00247 /**
00248  * @name Iterators
00249  * @{
00250  */
00251 
00252 /**
00253  * @ingroup attr
00254  * Iterate over a stream of attributes
00255  * @arg pos     loop counter, set to current attribute
00256  * @arg head    head of attribute stream
00257  * @arg len     length of attribute stream
00258  * @arg rem     initialized to len, holds bytes currently remaining in stream
00259  */
00260 #define nla_for_each_attr(pos, head, len, rem) \
00261         for (pos = head, rem = len; \
00262              nla_ok(pos, rem); \
00263              pos = nla_next(pos, &(rem)))
00264 
00265 /**
00266  * @ingroup attr
00267  * Iterate over a stream of nested attributes
00268  * @arg pos     loop counter, set to current attribute
00269  * @arg nla     attribute containing the nested attributes
00270  * @arg rem     initialized to len, holds bytes currently remaining in stream
00271  */
00272 #define nla_for_each_nested(pos, nla, rem) \
00273         for (pos = nla_data(nla), rem = nla_len(nla); \
00274              nla_ok(pos, rem); \
00275              pos = nla_next(pos, &(rem)))
00276 
00277 /** @} */
00278 
00279 #ifdef __cplusplus
00280 }
00281 #endif
00282 
00283 #endif