1 /* libnfnetlink.h: Header file for generic netfilter netlink interface
2  *
3  * (C) 2002 Harald Welte <laforge@gnumonks.org>
4  *
5  * 2005-10-29 Pablo Neira Ayuso <pablo@netfilter.org>:
6  * 	Fix NFNL_HEADER_LEN
7  * 2005-11-13 Pablo Neira Ayuso <pablo@netfilter.org>:
8  * 	Define NETLINK_NETFILTER if it's undefined
9  */
10 
11 #ifndef __LIBNFNETLINK_H
12 #define __LIBNFNETLINK_H
13 
14 #ifndef aligned_u64
15 #define aligned_u64 unsigned long long __attribute__((aligned(8)))
16 #endif
17 
18 #include <sys/socket.h>	/* for sa_family_t */
19 #include <linux/netlink.h>
20 #include <libnfnetlink/linux_nfnetlink.h>
21 #include <stdbool.h>
22 
23 #ifndef NETLINK_NETFILTER
24 #define NETLINK_NETFILTER 12
25 #endif
26 
27 #ifndef SOL_NETLINK
28 #define SOL_NETLINK	270
29 #endif
30 
31 #ifndef NETLINK_BROADCAST_SEND_ERROR
32 #define NETLINK_BROADCAST_SEND_ERROR 4
33 #endif
34 
35 #ifndef NETLINK_NO_ENOBUFS
36 #define NETLINK_NO_ENOBUFS 5
37 #endif
38 
39 #define NLMSG_TAIL(nlh) \
40 	(((void *) (nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len))
41 
42 #define NFNL_HEADER_LEN	(NLMSG_ALIGN(sizeof(struct nlmsghdr))	\
43 			 +NLMSG_ALIGN(sizeof(struct nfgenmsg)))
44 
45 #define NFNL_BUFFSIZE		8192
46 
47 #ifdef __cplusplus
48 extern "C" {
49 #endif
50 
51 struct nfnlhdr {
52 	struct nlmsghdr nlh;
53 	struct nfgenmsg nfmsg;
54 };
55 
56 struct nfnl_callback {
57 	int (*call)(struct nlmsghdr *nlh, struct nfattr *nfa[], void *data);
58 	void *data;
59 	u_int16_t attr_count;
60 };
61 
62 struct nfnl_handle;
63 struct nfnl_subsys_handle;
64 
65 extern int nfnl_fd(struct nfnl_handle *h);
66 extern unsigned int nfnl_portid(const struct nfnl_handle *h);
67 
68 /* get a new library handle */
69 extern struct nfnl_handle *nfnl_open(void);
70 extern struct nfnl_handle *nfnl_open2(int fd, bool bind);
71 extern int nfnl_close(struct nfnl_handle *);
72 extern int nfnl_close2(struct nfnl_handle *);
73 
74 extern struct nfnl_subsys_handle *nfnl_subsys_open(struct nfnl_handle *,
75 						   u_int8_t, u_int8_t,
76 						   unsigned int);
77 extern struct nfnl_subsys_handle *nfnl_subsys_open2(struct nfnl_handle *,
78 						   u_int8_t, u_int8_t,
79 						   unsigned int,
80 						   bool bind);
81 extern void nfnl_subsys_close(struct nfnl_subsys_handle *);
82 
83 /* set and unset sequence tracking */
84 void nfnl_set_sequence_tracking(struct nfnl_handle *h);
85 void nfnl_unset_sequence_tracking(struct nfnl_handle *h);
86 
87 /* set receive buffer size (for nfnl_catch) */
88 extern void nfnl_set_rcv_buffer_size(struct nfnl_handle *h, unsigned int size);
89 
90 /* sending of data */
91 extern int nfnl_send(struct nfnl_handle *, struct nlmsghdr *);
92 extern int nfnl_sendmsg(const struct nfnl_handle *, const struct msghdr *msg,
93 			unsigned int flags);
94 extern int nfnl_sendiov(const struct nfnl_handle *nfnlh,
95 			const struct iovec *iov, unsigned int num,
96 			unsigned int flags);
97 extern void nfnl_fill_hdr(struct nfnl_subsys_handle *, struct nlmsghdr *,
98 			  unsigned int, u_int8_t, u_int16_t, u_int16_t,
99 			  u_int16_t);
100 extern __attribute__((deprecated)) int
101 nfnl_talk(struct nfnl_handle *, struct nlmsghdr *, pid_t,
102           unsigned, struct nlmsghdr *,
103           int (*)(struct sockaddr_nl *, struct nlmsghdr *, void *), void *);
104 
105 /* simple challenge/response */
106 extern __attribute__((deprecated)) int
107 nfnl_listen(struct nfnl_handle *,
108             int (*)(struct sockaddr_nl *, struct nlmsghdr *, void *), void *);
109 
110 /* receiving */
111 extern ssize_t nfnl_recv(const struct nfnl_handle *h, unsigned char *buf, size_t len);
112 extern int nfnl_callback_register(struct nfnl_subsys_handle *,
113 				  u_int8_t type, struct nfnl_callback *cb);
114 extern int nfnl_callback_unregister(struct nfnl_subsys_handle *, u_int8_t type);
115 extern int nfnl_handle_packet(struct nfnl_handle *, char *buf, int len);
116 
117 /* parsing */
118 extern struct nfattr *nfnl_parse_hdr(const struct nfnl_handle *nfnlh,
119 				     const struct nlmsghdr *nlh,
120 				     struct nfgenmsg **genmsg);
121 extern int nfnl_check_attributes(const struct nfnl_handle *nfnlh,
122 				 const struct nlmsghdr *nlh,
123 				 struct nfattr *tb[]);
124 extern struct nlmsghdr *nfnl_get_msg_first(struct nfnl_handle *h,
125 					   const unsigned char *buf,
126 					   size_t len);
127 extern struct nlmsghdr *nfnl_get_msg_next(struct nfnl_handle *h,
128 					  const unsigned char *buf,
129 					  size_t len);
130 
131 /* callback verdict */
132 enum {
133 	NFNL_CB_FAILURE = -1,   /* failure */
134 	NFNL_CB_STOP = 0,       /* stop the query */
135 	NFNL_CB_CONTINUE = 1,   /* keep iterating */
136 };
137 
138 /* join a certain netlink multicast group */
139 extern int nfnl_join(const struct nfnl_handle *nfnlh, unsigned int group);
140 
141 /* process a netlink message */
142 extern int nfnl_process(struct nfnl_handle *h,
143 			const unsigned char *buf,
144 			size_t len);
145 
146 /* iterator API */
147 
148 extern struct nfnl_iterator *
149 nfnl_iterator_create(const struct nfnl_handle *h,
150 		     const char *buf,
151 		     size_t len);
152 
153 extern void nfnl_iterator_destroy(struct nfnl_iterator *it);
154 
155 extern int nfnl_iterator_process(struct nfnl_handle *h,
156 				 struct nfnl_iterator *it);
157 
158 extern int nfnl_iterator_next(const struct nfnl_handle *h,
159 			      struct nfnl_iterator *it);
160 
161 /* replacement for nfnl_listen */
162 extern int nfnl_catch(struct nfnl_handle *h);
163 
164 /* replacement for nfnl_talk */
165 extern int nfnl_query(struct nfnl_handle *h, struct nlmsghdr *nlh);
166 
167 #define nfnl_attr_present(tb, attr)			\
168 	(tb[attr-1])
169 
170 #define nfnl_get_data(tb, attr, type)			\
171 	({	type __ret = 0;				\
172 	 if (tb[attr-1])				\
173 	 __ret = *(type *)NFA_DATA(tb[attr-1]);		\
174 	 __ret;						\
175 	 })
176 
177 #define nfnl_get_pointer_to_data(tb, attr, type)	\
178 	({	type *__ret = NULL;			\
179 	 if (tb[attr-1])				\
180 	 __ret = NFA_DATA(tb[attr-1]);			\
181 	 __ret;						\
182 	 })
183 
184 #ifndef NLA_F_NESTED
185 #define NLA_F_NESTED            (1 << 15)
186 #endif
187 
188 /* nfnl attribute handling functions */
189 extern int nfnl_addattr_l(struct nlmsghdr *, int, int, const void *, int);
190 extern int nfnl_addattr8(struct nlmsghdr *, int, int, u_int8_t);
191 extern int nfnl_addattr16(struct nlmsghdr *, int, int, u_int16_t);
192 extern int nfnl_addattr32(struct nlmsghdr *, int, int, u_int32_t);
193 extern int nfnl_nfa_addattr_l(struct nfattr *, int, int, const void *, int);
194 extern int nfnl_nfa_addattr16(struct nfattr *, int, int, u_int16_t);
195 extern int nfnl_nfa_addattr32(struct nfattr *, int, int, u_int32_t);
196 extern int nfnl_parse_attr(struct nfattr **, int, struct nfattr *, int);
197 #define nfnl_parse_nested(tb, max, nfa) \
198 	nfnl_parse_attr((tb), (max), NFA_DATA((nfa)), NFA_PAYLOAD((nfa)))
199 #define nfnl_nest(nlh, bufsize, type) 				\
200 ({	struct nfattr *__start = NLMSG_TAIL(nlh);		\
201 	nfnl_addattr_l(nlh, bufsize, (NLA_F_NESTED | type), NULL, 0); 	\
202 	__start; })
203 #define nfnl_nest_end(nlh, tail) 				\
204 ({	(tail)->nfa_len = (void *) NLMSG_TAIL(nlh) - (void *) tail; })
205 
206 extern void nfnl_build_nfa_iovec(struct iovec *iov, struct nfattr *nfa,
207 				 u_int16_t type, u_int32_t len,
208 				 unsigned char *val);
209 extern unsigned int nfnl_rcvbufsiz(const struct nfnl_handle *h,
210 				   unsigned int size);
211 
212 
213 extern void nfnl_dump_packet(struct nlmsghdr *, int, char *);
214 
215 /*
216  * index to interface name API
217  */
218 
219 #ifndef IFNAMSIZ
220 #define IFNAMSIZ 16
221 #endif
222 
223 struct nlif_handle;
224 
225 struct nlif_handle *nlif_open(void);
226 void nlif_close(struct nlif_handle *orig);
227 int nlif_fd(struct nlif_handle *nlif_handle);
228 int nlif_query(struct nlif_handle *nlif_handle);
229 int nlif_catch(struct nlif_handle *nlif_handle);
230 int nlif_index2name(struct nlif_handle *nlif_handle,
231 		    unsigned int if_index,
232 		    char *name);
233 int nlif_get_ifflags(const struct nlif_handle *h,
234 		     unsigned int index,
235 		     unsigned int *flags);
236 
237 #ifdef __cplusplus
238 } /* extern "C" */
239 #endif
240 
241 /* Pablo: What is the equivalence of be64_to_cpu in userspace?
242  *
243  * Harald: Good question.  I don't think there's a standard way [yet?],
244  * so I'd suggest manually implementing it by "#if little endian" bitshift
245  * operations in C (at least for now).
246  *
247  * All the payload of any nfattr will always be in network byte order.
248  * This would allow easy transport over a real network in the future
249  * (e.g. jamal's netlink2).
250  *
251  * Pablo: I've called it __be64_to_cpu instead of be64_to_cpu, since maybe
252  * there will one in the userspace headers someday. We don't want to
253  * pollute POSIX space naming,
254  */
255 
256 #include <byteswap.h>
257 #if __BYTE_ORDER == __BIG_ENDIAN
258 #  ifndef __be64_to_cpu
259 #  define __be64_to_cpu(x)	(x)
260 #  endif
261 # else
262 # if __BYTE_ORDER == __LITTLE_ENDIAN
263 #  ifndef __be64_to_cpu
264 #  define __be64_to_cpu(x)	__bswap_64(x)
265 #  endif
266 # endif
267 #endif
268 
269 #endif /* __LIBNFNETLINK_H */
270