• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  
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