libnl 1.1
|
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