libnl 1.1

include/netlink/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-2006 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 Validation Policy Types
00028  * @{
00029  */
00030 
00031  /**
00032   * @ingroup attr
00033   * Standard attribute types to specify validation policy
00034   */
00035 enum {
00036         NLA_UNSPEC,     /**< Unspecified type */
00037         NLA_U8,         /**< 8bit integer */
00038         NLA_U16,        /**< 16bit integer */
00039         NLA_U32,        /**< 32bit integer */
00040         NLA_U64,        /**< 64bit integer */
00041         NLA_STRING,     /**< character string */
00042         NLA_FLAG,       /**< flag */
00043         NLA_MSECS,      /**< micro seconds (64bit) */
00044         NLA_NESTED,     /**< nested attributes */
00045         __NLA_TYPE_MAX,
00046 };
00047 
00048 /**
00049  * @ingroup attr
00050  * Maximum netlink validation policy type
00051  */
00052 #define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
00053 
00054 /** @} */
00055 
00056 /**
00057  * @ingroup attr
00058  * attribute validation policy
00059  *
00060  * Policies are defined as arrays of this struct, the array must
00061  * be accessible by attribute type up to the highest identifier
00062  * to be expected.
00063  *
00064  * Example:
00065  * @code
00066  * static struct nla_policy my_policy[ATTR_MAX+1] __read_mostly = {
00067  *      [ATTR_FOO] = { .type = NLA_U16 },
00068  *      [ATTR_BAR] = { .type = NLA_STRING },
00069  *      [ATTR_BAZ] = { .minlen = sizeof(struct mystruct) },
00070  * };
00071  * @endcode
00072  */
00073 struct nla_policy {
00074         /** Type of attribute or NLA_UNSPEC */
00075         uint16_t        type;
00076 
00077         /** Minimal length of payload required to be available */
00078         uint16_t        minlen;
00079 
00080         /** Maximal length of payload required to be available */
00081         uint16_t        maxlen;
00082 };
00083 
00084 /* size calculations */
00085 extern int              nla_attr_size(int payload);
00086 extern int              nla_total_size(int payload);
00087 extern int              nla_padlen(int payload);
00088 
00089 /* payload access */
00090 extern int              nla_type(const struct nlattr *);
00091 extern void *           nla_data(const struct nlattr *);
00092 extern int              nla_len(const struct nlattr *);
00093 
00094 /* attribute parsing */
00095 extern int              nla_ok(const struct nlattr *, int);
00096 extern struct nlattr *  nla_next(const struct nlattr *, int *);
00097 extern int              nla_parse(struct nlattr **, int, struct nlattr *,
00098                                   int, struct nla_policy *);
00099 extern int              nla_parse_nested(struct nlattr **, int, struct nlattr *,
00100                                          struct nla_policy *);
00101 extern int              nla_validate(struct nlattr *, int, int,
00102                                      struct nla_policy *);
00103 extern struct nlattr *  nla_find(struct nlattr *, int, int);
00104 
00105 /* utilities */
00106 extern int              nla_memcpy(void *, struct nlattr *, int);
00107 extern size_t           nla_strlcpy(char *, const struct nlattr *, size_t);
00108 extern int              nla_memcmp(const struct nlattr *, const void *, size_t);
00109 extern int              nla_strcmp(const struct nlattr *, const char *);
00110 
00111 /* attribute construction */
00112 extern struct nlattr *  nla_reserve(struct nl_msg *, int, int);
00113 extern int              nla_put(struct nl_msg *, int, int, const void *);
00114 extern int              nla_put_nested(struct nl_msg *, int, struct nl_msg *);
00115 extern int              nla_put_u8(struct nl_msg *, int, uint8_t);
00116 extern int              nla_put_u16(struct nl_msg *, int, uint16_t);
00117 extern int              nla_put_u32(struct nl_msg *, int, uint32_t);
00118 extern int              nla_put_u64(struct nl_msg *, int, uint64_t);
00119 extern int              nla_put_string(struct nl_msg *, int, const char *);
00120 extern int              nla_put_flag(struct nl_msg *, int);
00121 extern int              nla_put_msecs(struct nl_msg *, int, unsigned long);
00122 extern int              nla_put_data(struct nl_msg *, int, struct nl_data *);
00123 extern int              nla_put_addr(struct nl_msg *, int, struct nl_addr *);
00124 
00125 /* attribute nesting */
00126 extern struct nlattr *  nla_nest_start(struct nl_msg *, int);
00127 extern int              nla_nest_end(struct nl_msg *, struct nlattr *);
00128 
00129 /* attribute reading */
00130 extern uint8_t          nla_get_u8(struct nlattr *);
00131 extern uint16_t         nla_get_u16(struct nlattr *);
00132 extern uint32_t         nla_get_u32(struct nlattr *);
00133 extern uint64_t         nla_get_u64(struct nlattr *);
00134 extern char *           nla_get_string(struct nlattr *);
00135 extern int              nla_get_flag(struct nlattr *);
00136 extern unsigned long    nla_get_msecs(struct nlattr *);
00137 extern struct nl_data * nla_get_data(struct nlattr *);
00138 extern struct nl_addr * nla_get_addr(struct nlattr *, int);
00139 
00140 /**
00141  * @name Attribute Construction (Exception Based)
00142  *
00143  * All these functions jump to nla_put_failure in case of a failure
00144  * instead of returning an error code.
00145  * 
00146  * @{
00147  */
00148 
00149 /**
00150  * @ingroup attr
00151  * Add a netlink attribute to a netlink message
00152  * @arg n               netlink message
00153  * @arg attrtype        attribute type
00154  * @arg attrlen         length of attribute payload
00155  * @arg data            head of attribute payload
00156  */
00157 #define NLA_PUT(n, attrtype, attrlen, data) \
00158         do { \
00159                 if (nla_put(n, attrtype, attrlen, data) < 0) \
00160                         goto nla_put_failure; \
00161         } while(0)
00162 
00163 /**
00164  * @ingroup attr
00165  * Add a basic netlink attribute to a netlink message
00166  * @arg n               netlink message
00167  * @arg type            atomic type
00168  * @arg attrtype        attribute type
00169  * @arg value           head of attribute payload
00170  */
00171 #define NLA_PUT_TYPE(n, type, attrtype, value) \
00172         do { \
00173                 type __tmp = value; \
00174                 NLA_PUT(n, attrtype, sizeof(type), &__tmp); \
00175         } while(0)
00176 
00177 /**
00178  * Add a u8 netlink attribute to a netlink message
00179  * @arg n               netlink message
00180  * @arg attrtype        attribute type
00181  * @arg value           numeric value
00182  */
00183 #define NLA_PUT_U8(n, attrtype, value) \
00184         NLA_PUT_TYPE(n, uint8_t, attrtype, value)
00185 
00186 /**
00187  * Add a u16 netlink attribute to a netlink message
00188  * @arg n               netlink message
00189  * @arg attrtype        attribute type
00190  * @arg value           numeric value
00191  */
00192 #define NLA_PUT_U16(n, attrtype, value) \
00193         NLA_PUT_TYPE(n, uint16_t, attrtype, value)
00194 
00195 /**
00196  * Add a u32 netlink attribute to a netlink message
00197  * @arg n               netlink message
00198  * @arg attrtype        attribute type
00199  * @arg value           numeric value
00200  */
00201 #define NLA_PUT_U32(n, attrtype, value) \
00202         NLA_PUT_TYPE(n, uint32_t, attrtype, value)
00203 
00204 /**
00205  * Add a u64 netlink attribute to a netlink message
00206  * @arg n               netlink message
00207  * @arg attrtype        attribute type
00208  * @arg value           numeric value
00209  */
00210 #define NLA_PUT_U64(n, attrtype, value) \
00211         NLA_PUT_TYPE(n, uint64_t, attrtype, value)
00212 
00213 /**
00214  * Add a character string netlink attribute to a netlink message
00215  * @arg n               netlink message
00216  * @arg attrtype        attribute type
00217  * @arg value           character string
00218  */
00219 #define NLA_PUT_STRING(n, attrtype, value) \
00220         NLA_PUT(n, attrtype, strlen(value) + 1, value)
00221 
00222 /**
00223  * Add a flag netlink attribute to a netlink message
00224  * @arg n               netlink message
00225  * @arg attrtype        attribute type
00226  */
00227 #define NLA_PUT_FLAG(n, attrtype) \
00228         NLA_PUT(n, attrtype, 0, NULL)
00229 
00230 /**
00231  * Add a msecs netlink attribute to a netlink message
00232  * @arg n               netlink message
00233  * @arg attrtype        attribute type
00234  * @arg msecs           numeric value in micro seconds
00235  */
00236 #define NLA_PUT_MSECS(n, attrtype, msecs) \
00237         NLA_PUT_U64(n, attrtype, msecs)
00238 
00239 /**
00240  * Add a address attribute to a netlink message
00241  * @arg n               netlink message
00242  * @arg attrtype        attribute type
00243  * @arg addr            abstract address object
00244  */
00245 #define NLA_PUT_ADDR(n, attrtype, addr) \
00246         NLA_PUT(n, attrtype, nl_addr_get_len(addr), \
00247                 nl_addr_get_binary_addr(addr))
00248 
00249 /** @} */
00250 
00251 /**
00252  * @name Iterators
00253  * @{
00254  */
00255 
00256 /**
00257  * @ingroup attr
00258  * iterate over a stream of attributes
00259  * @arg pos     loop counter, set to current attribute
00260  * @arg head    head of attribute stream
00261  * @arg len     length of attribute stream
00262  * @arg rem     initialized to len, holds bytes currently remaining in stream
00263  */
00264 #define nla_for_each_attr(pos, head, len, rem) \
00265         for (pos = head, rem = len; \
00266              nla_ok(pos, rem); \
00267              pos = nla_next(pos, &(rem)))
00268 
00269 /**
00270  * @ingroup attr
00271  * iterate over a stream of nested attributes
00272  * @arg pos     loop counter, set to current attribute
00273  * @arg nla     attribute containing the nested attributes
00274  * @arg rem     initialized to len, holds bytes currently remaining in stream
00275  */
00276 #define nla_for_each_nested(pos, nla, rem) \
00277         for (pos = nla_data(nla), rem = nla_len(nla); \
00278              nla_ok(pos, rem); \
00279              pos = nla_next(pos, &(rem)))
00280 
00281 /** @} */
00282 
00283 #ifdef __cplusplus
00284 }
00285 #endif
00286 
00287 #endif