1 /*
2 * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9
10 #include <stdlib.h>
11 #include <stdbool.h>
12 #include <string.h> /* for memset */
13 #include <errno.h>
14 #include <assert.h>
15
16 #include "internal/internal.h"
17
18 /**
19 * \mainpage
20 *
21 * libnetfilter_conntrack is a userspace library providing a programming
22 * interface (API) to the in-kernel connection tracking state table. The
23 * library libnetfilter_conntrack has been previously known as
24 * libnfnetlink_conntrack and libctnetlink. This library is currently used by
25 * conntrack-tools among many other applications.
26 *
27 * libnetfilter_conntrack homepage is:
28 * http://netfilter.org/projects/libnetfilter_conntrack/
29 *
30 * \section Dependencies
31 * libnetfilter_conntrack requires libnfnetlink and a kernel that includes the
32 * nf_conntrack_netlink subsystem (i.e. 2.6.14 or later, >= 2.6.18 recommended).
33 *
34 * \section Main Features
35 * - listing/retrieving entries from the kernel connection tracking table.
36 * - inserting/modifying/deleting entries from the kernel connection tracking
37 * table.
38 * - listing/retrieving entries from the kernel expect table.
39 * - inserting/modifying/deleting entries from the kernel expect table.
40 * \section Git Tree
41 * The current development version of libnetfilter_conntrack can be accessed at
42 * https://git.netfilter.org/cgi-bin/gitweb.cgi?p=libnetfilter_conntrack.git
43 *
44 * \section Privileges
45 * You need the CAP_NET_ADMIN capability in order to allow your application
46 * to receive events from and to send commands to kernel-space, excepting
47 * the conntrack table dumping operation.
48 *
49 * \section using Using libnetfilter_conntrack
50 * To write your own program using libnetfilter_conntrack, you should start by
51 * reading the doxygen documentation (start by \link LibrarySetup \endlink page)
52 * and check examples available under utils/ in the libnetfilter_conntrack
53 * source code tree. You can compile these examples by invoking `make check'.
54 *
55 * \section Authors
56 * libnetfilter_conntrack has been almost entirely written by Pablo Neira Ayuso.
57 *
58 * \section python Python Binding
59 * pynetfilter_conntrack is a Python binding of libnetfilter_conntrack written
60 * by Victor Stinner. You can visit his official web site at
61 * http://software.inl.fr/trac/trac.cgi/wiki/pynetfilter_conntrack.
62 */
63
64 /**
65 * \defgroup ct Conntrack object handling
66 * @{
67 */
68
69 /**
70 * nfct_conntrack_new - allocate a new conntrack
71 *
72 * In case of success, this function returns a valid pointer to a memory blob,
73 * otherwise NULL is returned and errno is set appropiately.
74 */
nfct_new(void)75 struct nf_conntrack *nfct_new(void)
76 {
77 struct nf_conntrack *ct;
78
79 ct = malloc(sizeof(struct nf_conntrack));
80 if (!ct)
81 return NULL;
82
83 memset(ct, 0, sizeof(struct nf_conntrack));
84
85 return ct;
86 }
87
88 /**
89 * nf_conntrack_destroy - release a conntrack object
90 * \param ct pointer to the conntrack object
91 */
nfct_destroy(struct nf_conntrack * ct)92 void nfct_destroy(struct nf_conntrack *ct)
93 {
94 assert(ct != NULL);
95 if (ct->secctx)
96 free(ct->secctx);
97 if (ct->helper_info)
98 free(ct->helper_info);
99 if (ct->connlabels)
100 nfct_bitmask_destroy(ct->connlabels);
101 if (ct->connlabels_mask)
102 nfct_bitmask_destroy(ct->connlabels_mask);
103 free(ct);
104 ct = NULL; /* bugtrap */
105 }
106
107 /**
108 * nf_sizeof - return the size in bytes of a certain conntrack object
109 * \param ct pointer to the conntrack object
110 *
111 * This function is DEPRECATED, don't use it in your code.
112 */
nfct_sizeof(const struct nf_conntrack * ct)113 size_t nfct_sizeof(const struct nf_conntrack *ct)
114 {
115 assert(ct != NULL);
116 return sizeof(*ct);
117 }
118
119 /**
120 * nfct_maxsize - return the maximum size in bytes of a conntrack object
121 *
122 * Use this function if you want to allocate a conntrack object in the stack
123 * instead of the heap. For example:
124 * \verbatim
125 char buf[nfct_maxsize()];
126 struct nf_conntrack *ct = (struct nf_conntrack *) buf;
127 memset(ct, 0, nfct_maxsize());
128 \endverbatim
129 * Note: As for now this function returns the same size that nfct_sizeof(ct)
130 * does although _this could change in the future_. Therefore, do not assume
131 * that nfct_sizeof(ct) == nfct_maxsize().
132 *
133 * This function is DEPRECATED, don't use it in your code.
134 */
nfct_maxsize(void)135 size_t nfct_maxsize(void)
136 {
137 return sizeof(struct nf_conntrack);
138 }
139
140 /**
141 * nfct_clone - clone a conntrack object
142 * \param ct pointer to a valid conntrack object
143 *
144 * On error, NULL is returned and errno is appropiately set. Otherwise,
145 * a valid pointer to the clone conntrack is returned.
146 */
nfct_clone(const struct nf_conntrack * ct)147 struct nf_conntrack *nfct_clone(const struct nf_conntrack *ct)
148 {
149 struct nf_conntrack *clone;
150
151 assert(ct != NULL);
152
153 if ((clone = nfct_new()) == NULL)
154 return NULL;
155 nfct_copy(clone, ct, NFCT_CP_OVERRIDE);
156
157 return clone;
158 }
159
160 /**
161 * nfct_setobjopt - set a certain option for a conntrack object
162 * \param ct conntrack object
163 * \param option option parameter
164 *
165 * In case of error, -1 is returned and errno is appropiately set. On success,
166 * 0 is returned.
167 */
nfct_setobjopt(struct nf_conntrack * ct,unsigned int option)168 int nfct_setobjopt(struct nf_conntrack *ct, unsigned int option)
169 {
170 assert(ct != NULL);
171
172 if (unlikely(option > NFCT_SOPT_MAX)) {
173 errno = EOPNOTSUPP;
174 return -1;
175 }
176
177 return __setobjopt(ct, option);
178 }
179
180 /**
181 * nfct_getobjopt - get a certain option for a conntrack object
182 * \param ct conntrack object
183 * \param option option parameter
184 *
185 * In case of error, -1 is returned and errno is appropiately set. On success,
186 * 0 is returned.
187 */
nfct_getobjopt(const struct nf_conntrack * ct,unsigned int option)188 int nfct_getobjopt(const struct nf_conntrack *ct, unsigned int option)
189 {
190 assert(ct != NULL);
191
192 if (unlikely(option > NFCT_GOPT_MAX)) {
193 errno = EOPNOTSUPP;
194 return -1;
195 }
196
197 return __getobjopt(ct, option);
198 }
199
200 /**
201 * @}
202 */
203
204 /**
205 * \defgroup LibrarySetup Library setup
206 * @{
207 */
208
209 /**
210 * nf_callback_register - register a callback
211 * \param h library handler
212 * \param type message type (see enum nf_conntrack_msg_type definition)
213 * \param cb callback used to process conntrack received
214 * \param data data used by the callback, if any.
215 *
216 * This function register a callback to handle the conntrack received,
217 * in case of error -1 is returned and errno is set appropiately, otherwise
218 * 0 is returned.
219 *
220 * Note that the data parameter is optional, if you do not want to pass any
221 * data to your callback, then use NULL.
222 */
nfct_callback_register(struct nfct_handle * h,enum nf_conntrack_msg_type type,int (* cb)(enum nf_conntrack_msg_type type,struct nf_conntrack * ct,void * data),void * data)223 int nfct_callback_register(struct nfct_handle *h,
224 enum nf_conntrack_msg_type type,
225 int (*cb)(enum nf_conntrack_msg_type type,
226 struct nf_conntrack *ct,
227 void *data),
228 void *data)
229 {
230 struct __data_container *container;
231
232 assert(h != NULL);
233
234 container = malloc(sizeof(struct __data_container));
235 if (!container)
236 return -1;
237 memset(container, 0, sizeof(struct __data_container));
238
239 h->cb = cb;
240 container->h = h;
241 container->type = type;
242 container->data = data;
243
244 h->nfnl_cb_ct.call = __callback;
245 h->nfnl_cb_ct.data = container;
246 h->nfnl_cb_ct.attr_count = CTA_MAX;
247
248 nfnl_callback_register(h->nfnlssh_ct,
249 IPCTNL_MSG_CT_NEW,
250 &h->nfnl_cb_ct);
251
252 nfnl_callback_register(h->nfnlssh_ct,
253 IPCTNL_MSG_CT_DELETE,
254 &h->nfnl_cb_ct);
255
256 return 0;
257 }
258
259 /**
260 * nfct_callback_unregister - unregister a callback
261 * \param h library handler
262 */
nfct_callback_unregister(struct nfct_handle * h)263 void nfct_callback_unregister(struct nfct_handle *h)
264 {
265 assert(h != NULL);
266
267 nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_NEW);
268 nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_DELETE);
269
270 h->cb = NULL;
271 free(h->nfnl_cb_ct.data);
272
273 h->nfnl_cb_ct.call = NULL;
274 h->nfnl_cb_ct.data = NULL;
275 h->nfnl_cb_ct.attr_count = 0;
276 }
277
278 /**
279 * nf_callback_register2 - register a callback
280 * \param h library handler
281 * \param cb callback used to process conntrack received
282 * \param data data used by the callback, if any.
283 *
284 * This function register a callback to handle the conntrack received,
285 * in case of error -1 is returned and errno is set appropiately, otherwise
286 * 0 is returned.
287 *
288 * Note that the data parameter is optional, if you do not want to pass any
289 * data to your callback, then use NULL.
290 *
291 * NOTICE: The difference with nf_callback_register() is that this function
292 * uses the new callback interface that includes the Netlink header.
293 *
294 * WARNING: Don't mix nf_callback_register() and nf_callback_register2()
295 * calls, use only once at a time.
296 */
nfct_callback_register2(struct nfct_handle * h,enum nf_conntrack_msg_type type,int (* cb)(const struct nlmsghdr * nlh,enum nf_conntrack_msg_type type,struct nf_conntrack * ct,void * data),void * data)297 int nfct_callback_register2(struct nfct_handle *h,
298 enum nf_conntrack_msg_type type,
299 int (*cb)(const struct nlmsghdr *nlh,
300 enum nf_conntrack_msg_type type,
301 struct nf_conntrack *ct,
302 void *data),
303 void *data)
304 {
305 struct __data_container *container;
306
307 assert(h != NULL);
308
309 container = calloc(sizeof(struct __data_container), 1);
310 if (container == NULL)
311 return -1;
312
313 h->cb2 = cb;
314 container->h = h;
315 container->type = type;
316 container->data = data;
317
318 h->nfnl_cb_ct.call = __callback;
319 h->nfnl_cb_ct.data = container;
320 h->nfnl_cb_ct.attr_count = CTA_MAX;
321
322 nfnl_callback_register(h->nfnlssh_ct,
323 IPCTNL_MSG_CT_NEW,
324 &h->nfnl_cb_ct);
325
326 nfnl_callback_register(h->nfnlssh_ct,
327 IPCTNL_MSG_CT_DELETE,
328 &h->nfnl_cb_ct);
329
330 return 0;
331 }
332
333 /**
334 * nfct_callback_unregister2 - unregister a callback
335 * \param h library handler
336 */
nfct_callback_unregister2(struct nfct_handle * h)337 void nfct_callback_unregister2(struct nfct_handle *h)
338 {
339 assert(h != NULL);
340
341 nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_NEW);
342 nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_DELETE);
343
344 h->cb2 = NULL;
345 free(h->nfnl_cb_ct.data);
346
347 h->nfnl_cb_ct.call = NULL;
348 h->nfnl_cb_ct.data = NULL;
349 h->nfnl_cb_ct.attr_count = 0;
350 }
351
352 /**
353 * @}
354 */
355
356 /**
357 * \defgroup ct Conntrack object handling
358 * @{
359 */
360
361 /**
362 * nfct_set_attr_l - set the value of a certain conntrack attribute
363 * \param ct pointer to a valid conntrack
364 * \param type attribute type
365 * \param pointer to attribute value
366 * \param length of attribute value (in bytes)
367 */
368 void
nfct_set_attr_l(struct nf_conntrack * ct,const enum nf_conntrack_attr type,const void * value,size_t len)369 nfct_set_attr_l(struct nf_conntrack *ct, const enum nf_conntrack_attr type,
370 const void *value, size_t len)
371 {
372 assert(ct != NULL);
373 assert(value != NULL);
374
375 if (unlikely(type >= ATTR_MAX))
376 return;
377
378 if (set_attr_array[type]) {
379 set_attr_array[type](ct, value, len);
380 set_bit(type, ct->head.set);
381 }
382 }
383
384 /**
385 * nfct_set_attr - set the value of a certain conntrack attribute
386 * \param ct pointer to a valid conntrack
387 * \param type attribute type
388 * \param value pointer to the attribute value
389 *
390 * Note that certain attributes are unsettable:
391 * - ATTR_USE
392 * - ATTR_ID
393 * - ATTR_*_COUNTER_*
394 * - ATTR_SECCTX
395 * - ATTR_TIMESTAMP_*
396 * The call of this function for such attributes do nothing.
397 */
nfct_set_attr(struct nf_conntrack * ct,const enum nf_conntrack_attr type,const void * value)398 void nfct_set_attr(struct nf_conntrack *ct,
399 const enum nf_conntrack_attr type,
400 const void *value)
401 {
402 /* We assume the setter knows the size of the passed pointer. */
403 nfct_set_attr_l(ct, type, value, 0);
404 }
405
406 /**
407 * nfct_set_attr_u8 - set the value of a certain conntrack attribute
408 * \param ct pointer to a valid conntrack
409 * \param type attribute type
410 * \param value unsigned 8 bits attribute value
411 */
nfct_set_attr_u8(struct nf_conntrack * ct,const enum nf_conntrack_attr type,uint8_t value)412 void nfct_set_attr_u8(struct nf_conntrack *ct,
413 const enum nf_conntrack_attr type,
414 uint8_t value)
415 {
416 nfct_set_attr_l(ct, type, &value, sizeof(uint8_t));
417 }
418
419 /**
420 * nfct_set_attr_u16 - set the value of a certain conntrack attribute
421 * \param ct pointer to a valid conntrack
422 * \param type attribute type
423 * \param value unsigned 16 bits attribute value
424 */
nfct_set_attr_u16(struct nf_conntrack * ct,const enum nf_conntrack_attr type,uint16_t value)425 void nfct_set_attr_u16(struct nf_conntrack *ct,
426 const enum nf_conntrack_attr type,
427 uint16_t value)
428 {
429 nfct_set_attr_l(ct, type, &value, sizeof(uint16_t));
430 }
431
432 /**
433 * nfct_set_attr_u32 - set the value of a certain conntrack attribute
434 * \param ct pointer to a valid conntrack
435 * \param type attribute type
436 * \param value unsigned 32 bits attribute value
437 */
nfct_set_attr_u32(struct nf_conntrack * ct,const enum nf_conntrack_attr type,uint32_t value)438 void nfct_set_attr_u32(struct nf_conntrack *ct,
439 const enum nf_conntrack_attr type,
440 uint32_t value)
441 {
442 nfct_set_attr_l(ct, type, &value, sizeof(uint32_t));
443 }
444
445 /**
446 * nfct_set_attr_u64 - set the value of a certain conntrack attribute
447 * \param ct pointer to a valid conntrack
448 * \param type attribute type
449 * \param value unsigned 64 bits attribute value
450 */
nfct_set_attr_u64(struct nf_conntrack * ct,const enum nf_conntrack_attr type,uint64_t value)451 void nfct_set_attr_u64(struct nf_conntrack *ct,
452 const enum nf_conntrack_attr type,
453 uint64_t value)
454 {
455 nfct_set_attr_l(ct, type, &value, sizeof(uint64_t));
456 }
457
458 /**
459 * nfct_get_attr - get a conntrack attribute
460 * \param ct pointer to a valid conntrack
461 * \param type attribute type
462 *
463 * In case of success a valid pointer to the attribute requested is returned,
464 * on error NULL is returned and errno is set appropiately.
465 */
nfct_get_attr(const struct nf_conntrack * ct,const enum nf_conntrack_attr type)466 const void *nfct_get_attr(const struct nf_conntrack *ct,
467 const enum nf_conntrack_attr type)
468 {
469 assert(ct != NULL);
470
471 if (unlikely(type >= ATTR_MAX)) {
472 errno = EINVAL;
473 return NULL;
474 }
475
476 if (!test_bit(type, ct->head.set)) {
477 errno = ENODATA;
478 return NULL;
479 }
480
481 assert(get_attr_array[type]);
482
483 return get_attr_array[type](ct);
484 }
485
486 /**
487 * nfct_get_attr_u8 - get attribute of unsigned 8-bits long
488 * \param ct pointer to a valid conntrack
489 * \param type attribute type
490 *
491 * Returns the value of the requested attribute, if the attribute is not
492 * set, 0 is returned. In order to check if the attribute is set or not,
493 * use nfct_attr_is_set.
494 */
nfct_get_attr_u8(const struct nf_conntrack * ct,const enum nf_conntrack_attr type)495 uint8_t nfct_get_attr_u8(const struct nf_conntrack *ct,
496 const enum nf_conntrack_attr type)
497 {
498 const uint8_t *ret = nfct_get_attr(ct, type);
499 return ret == NULL ? 0 : *ret;
500 }
501
502 /**
503 * nfct_get_attr_u16 - get attribute of unsigned 16-bits long
504 * \param ct pointer to a valid conntrack
505 * \param type attribute type
506 *
507 * Returns the value of the requested attribute, if the attribute is not
508 * set, 0 is returned. In order to check if the attribute is set or not,
509 * use nfct_attr_is_set.
510 */
nfct_get_attr_u16(const struct nf_conntrack * ct,const enum nf_conntrack_attr type)511 uint16_t nfct_get_attr_u16(const struct nf_conntrack *ct,
512 const enum nf_conntrack_attr type)
513 {
514 const uint16_t *ret = nfct_get_attr(ct, type);
515 return ret == NULL ? 0 : *ret;
516 }
517
518 /**
519 * nfct_get_attr_u32 - get attribute of unsigned 32-bits long
520 * \param ct pointer to a valid conntrack
521 * \param type attribute type
522 *
523 * Returns the value of the requested attribute, if the attribute is not
524 * set, 0 is returned. In order to check if the attribute is set or not,
525 * use nfct_attr_is_set.
526 */
nfct_get_attr_u32(const struct nf_conntrack * ct,const enum nf_conntrack_attr type)527 uint32_t nfct_get_attr_u32(const struct nf_conntrack *ct,
528 const enum nf_conntrack_attr type)
529 {
530 const uint32_t *ret = nfct_get_attr(ct, type);
531 return ret == NULL ? 0 : *ret;
532 }
533
534 /**
535 * nfct_get_attr_u64 - get attribute of unsigned 32-bits long
536 * \param ct pointer to a valid conntrack
537 * \param type attribute type
538 *
539 * Returns the value of the requested attribute, if the attribute is not
540 * set, 0 is returned. In order to check if the attribute is set or not,
541 * use nfct_attr_is_set.
542 */
nfct_get_attr_u64(const struct nf_conntrack * ct,const enum nf_conntrack_attr type)543 uint64_t nfct_get_attr_u64(const struct nf_conntrack *ct,
544 const enum nf_conntrack_attr type)
545 {
546 const uint64_t *ret = nfct_get_attr(ct, type);
547 return ret == NULL ? 0 : *ret;
548 }
549
550 /**
551 * nfct_attr_is_set - check if a certain attribute is set
552 * \param ct pointer to a valid conntrack object
553 * \param type attribute type
554 *
555 * On error, -1 is returned and errno is set appropiately, otherwise
556 * the value of the attribute is returned.
557 */
nfct_attr_is_set(const struct nf_conntrack * ct,const enum nf_conntrack_attr type)558 int nfct_attr_is_set(const struct nf_conntrack *ct,
559 const enum nf_conntrack_attr type)
560 {
561 assert(ct != NULL);
562
563 if (unlikely(type >= ATTR_MAX)) {
564 errno = EINVAL;
565 return -1;
566 }
567 return test_bit(type, ct->head.set);
568 }
569
570 /**
571 * nfct_attr_is_set_array - check if an array of attribute types is set
572 * \param ct pointer to a valid conntrack object
573 * \param array attribute type array
574 * \param size size of the array
575 *
576 * On error, -1 is returned and errno is set appropiately, otherwise
577 * the value of the attribute is returned.
578 */
nfct_attr_is_set_array(const struct nf_conntrack * ct,const enum nf_conntrack_attr * type_array,int size)579 int nfct_attr_is_set_array(const struct nf_conntrack *ct,
580 const enum nf_conntrack_attr *type_array,
581 int size)
582 {
583 int i;
584
585 assert(ct != NULL);
586
587 for (i=0; i<size; i++) {
588 if (unlikely(type_array[i] >= ATTR_MAX)) {
589 errno = EINVAL;
590 return -1;
591 }
592 if (!test_bit(type_array[i], ct->head.set))
593 return 0;
594 }
595 return 1;
596 }
597
598 /**
599 * nfct_attr_unset - unset a certain attribute
600 * \param type attribute type
601 * \param ct pointer to a valid conntrack object
602 *
603 * On error, -1 is returned and errno is set appropiately, otherwise
604 * 0 is returned.
605 */
nfct_attr_unset(struct nf_conntrack * ct,const enum nf_conntrack_attr type)606 int nfct_attr_unset(struct nf_conntrack *ct,
607 const enum nf_conntrack_attr type)
608 {
609 assert(ct != NULL);
610
611 if (unlikely(type >= ATTR_MAX)) {
612 errno = EINVAL;
613 return -1;
614 }
615 unset_bit(type, ct->head.set);
616
617 return 0;
618 }
619
620 /**
621 * nfct_set_attr_grp - set a group of attributes
622 * \param ct pointer to a valid conntrack object
623 * \param type attribute group (see ATTR_GRP_*)
624 * \param data pointer to struct (see struct nfct_attr_grp_*)
625 *
626 * Note that calling this function for ATTR_GRP_COUNTER_* and ATTR_GRP_ADDR_*
627 * have no effect.
628 */
nfct_set_attr_grp(struct nf_conntrack * ct,const enum nf_conntrack_attr_grp type,const void * data)629 void nfct_set_attr_grp(struct nf_conntrack *ct,
630 const enum nf_conntrack_attr_grp type,
631 const void *data)
632 {
633 assert(ct != NULL);
634
635 if (unlikely(type >= ATTR_GRP_MAX))
636 return;
637
638 if (set_attr_grp_array[type]) {
639 set_attr_grp_array[type](ct, data);
640 set_bitmask_u32(ct->head.set,
641 attr_grp_bitmask[type].bitmask, __NFCT_BITSET);
642 }
643 }
644
645 /**
646 * nfct_get_attr_grp - get an attribute group
647 * \param ct pointer to a valid conntrack object
648 * \param type attribute group (see ATTR_GRP_*)
649 * \param data pointer to struct (see struct nfct_attr_grp_*)
650 *
651 * On error, it returns -1 and errno is appropriately set. On success, the
652 * data pointer contains the attribute group.
653 */
nfct_get_attr_grp(const struct nf_conntrack * ct,const enum nf_conntrack_attr_grp type,void * data)654 int nfct_get_attr_grp(const struct nf_conntrack *ct,
655 const enum nf_conntrack_attr_grp type,
656 void *data)
657 {
658 assert(ct != NULL);
659
660 if (unlikely(type >= ATTR_GRP_MAX)) {
661 errno = EINVAL;
662 return -1;
663 }
664 switch(attr_grp_bitmask[type].type) {
665 case NFCT_BITMASK_AND:
666 if (!test_bitmask_u32(ct->head.set,
667 attr_grp_bitmask[type].bitmask,
668 __NFCT_BITSET)) {
669 errno = ENODATA;
670 return -1;
671 }
672 break;
673 case NFCT_BITMASK_OR:
674 if (!test_bitmask_u32_or(ct->head.set,
675 attr_grp_bitmask[type].bitmask,
676 __NFCT_BITSET)) {
677 errno = ENODATA;
678 return -1;
679 }
680 break;
681 }
682 assert(get_attr_grp_array[type]);
683 get_attr_grp_array[type](ct, data);
684 return 0;
685 }
686
687 /**
688 * nfct_attr_grp_is_set - check if an attribute group is set
689 * \param ct pointer to a valid conntrack object
690 * \param type attribute group (see ATTR_GRP_*)
691 *
692 * If the attribute group is set, this function returns 1, otherwise 0.
693 */
nfct_attr_grp_is_set(const struct nf_conntrack * ct,const enum nf_conntrack_attr_grp type)694 int nfct_attr_grp_is_set(const struct nf_conntrack *ct,
695 const enum nf_conntrack_attr_grp type)
696 {
697 assert(ct != NULL);
698
699 if (unlikely(type >= ATTR_GRP_MAX)) {
700 errno = EINVAL;
701 return -1;
702 }
703 switch(attr_grp_bitmask[type].type) {
704 case NFCT_BITMASK_AND:
705 if (test_bitmask_u32(ct->head.set,
706 attr_grp_bitmask[type].bitmask,
707 __NFCT_BITSET)) {
708 return 1;
709 }
710 break;
711 case NFCT_BITMASK_OR:
712 if (test_bitmask_u32_or(ct->head.set,
713 attr_grp_bitmask[type].bitmask,
714 __NFCT_BITSET)) {
715 return 1;
716 }
717 break;
718 }
719 return 0;
720 }
721
722 /**
723 * nfct_attr_grp_unset - unset an attribute group
724 * \param ct pointer to a valid conntrack object
725 * \param type attribute group (see ATTR_GRP_*)
726 *
727 * On error, it returns -1 and errno is appropriately set. On success,
728 * this function returns 0.
729 */
nfct_attr_grp_unset(struct nf_conntrack * ct,const enum nf_conntrack_attr_grp type)730 int nfct_attr_grp_unset(struct nf_conntrack *ct,
731 const enum nf_conntrack_attr_grp type)
732 {
733 assert(ct != NULL);
734
735 if (unlikely(type >= ATTR_GRP_MAX)) {
736 errno = EINVAL;
737 return -1;
738 }
739 unset_bitmask_u32(ct->head.set, attr_grp_bitmask[type].bitmask,
740 __NFCT_BITSET);
741
742 return 0;
743 }
744
745 /**
746 * @}
747 */
748
749 /**
750 * \defgroup nl Low level object to Netlink message
751 * @{
752 */
753
754 /**
755 * nfct_build_conntrack - build a netlink message from a conntrack object
756 * \param ssh nfnetlink subsystem handler
757 * \param req buffer used to build the netlink message
758 * \param size size of the buffer passed
759 * \param type netlink message type
760 * \param flags netlink flags
761 * \param ct pointer to a conntrack object
762 *
763 * This is a low level function for those that require to be close to
764 * netlink details via libnfnetlink. If you do want to obviate the netlink
765 * details then we suggest you to use nfct_query.
766 *
767 * On error, -1 is returned and errno is appropiately set.
768 * On success, 0 is returned.
769 */
nfct_build_conntrack(struct nfnl_subsys_handle * ssh,void * req,size_t size,uint16_t type,uint16_t flags,const struct nf_conntrack * ct)770 int nfct_build_conntrack(struct nfnl_subsys_handle *ssh,
771 void *req,
772 size_t size,
773 uint16_t type,
774 uint16_t flags,
775 const struct nf_conntrack *ct)
776 {
777 assert(ssh != NULL);
778 assert(req != NULL);
779 assert(ct != NULL);
780
781 return __build_conntrack(ssh, req, size, type, flags, ct);
782 }
783
784 static int
__build_query_ct(struct nfnl_subsys_handle * ssh,const enum nf_conntrack_query qt,const void * data,void * buffer,unsigned int size)785 __build_query_ct(struct nfnl_subsys_handle *ssh,
786 const enum nf_conntrack_query qt,
787 const void *data, void *buffer, unsigned int size)
788 {
789 struct nfnlhdr *req = buffer;
790 const uint32_t *family = data;
791
792 assert(ssh != NULL);
793 assert(data != NULL);
794 assert(req != NULL);
795
796 memset(req, 0, size);
797
798 switch(qt) {
799 case NFCT_Q_CREATE:
800 __build_conntrack(ssh, req, size, IPCTNL_MSG_CT_NEW, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK|NLM_F_EXCL, data);
801 break;
802 case NFCT_Q_UPDATE:
803 __build_conntrack(ssh, req, size, IPCTNL_MSG_CT_NEW, NLM_F_REQUEST|NLM_F_ACK, data);
804 break;
805 case NFCT_Q_DESTROY:
806 __build_conntrack(ssh, req, size, IPCTNL_MSG_CT_DELETE, NLM_F_REQUEST|NLM_F_ACK, data);
807 break;
808 case NFCT_Q_GET:
809 __build_conntrack(ssh, req, size, IPCTNL_MSG_CT_GET, NLM_F_REQUEST|NLM_F_ACK, data);
810 break;
811 case NFCT_Q_FLUSH:
812 nfnl_fill_hdr(ssh, &req->nlh, 0, *family, 0, IPCTNL_MSG_CT_DELETE, NLM_F_REQUEST|NLM_F_ACK);
813 break;
814 case NFCT_Q_DUMP:
815 nfnl_fill_hdr(ssh, &req->nlh, 0, *family, 0, IPCTNL_MSG_CT_GET, NLM_F_REQUEST|NLM_F_DUMP);
816 break;
817 case NFCT_Q_DUMP_RESET:
818 nfnl_fill_hdr(ssh, &req->nlh, 0, *family, 0, IPCTNL_MSG_CT_GET_CTRZERO, NLM_F_REQUEST|NLM_F_DUMP);
819 break;
820 case NFCT_Q_CREATE_UPDATE:
821 __build_conntrack(ssh, req, size, IPCTNL_MSG_CT_NEW, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK, data);
822 break;
823 case NFCT_Q_DUMP_FILTER:
824 nfnl_fill_hdr(ssh, &req->nlh, 0, AF_UNSPEC, 0, IPCTNL_MSG_CT_GET, NLM_F_REQUEST|NLM_F_DUMP);
825 __build_filter_dump(req, size, data);
826 break;
827 case NFCT_Q_DUMP_FILTER_RESET:
828 nfnl_fill_hdr(ssh, &req->nlh, 0, AF_UNSPEC, 0, IPCTNL_MSG_CT_GET_CTRZERO, NLM_F_REQUEST|NLM_F_DUMP);
829 __build_filter_dump(req, size, data);
830 break;
831 default:
832 errno = ENOTSUP;
833 return -1;
834 }
835 return 1;
836 }
837
838 /**
839 * nfct_build_query - build a query in netlink message format for ctnetlink
840 * \param ssh nfnetlink subsystem handler
841 * \param qt query type
842 * \param data data required to build the query
843 * \param req buffer to build the netlink message
844 * \param size size of the buffer passed
845 *
846 * This is a low level function, use it if you want to require to work
847 * with netlink details via libnfnetlink, otherwise we suggest you to
848 * use nfct_query.
849 *
850 * The pointer to data can be a conntrack object or the protocol family
851 * depending on the request.
852 *
853 * For query types:
854 * - NFCT_Q_CREATE: add a new conntrack, if it exists, fail
855 * - NFCT_O_CREATE_UPDATE: add a new conntrack, if it exists, update it
856 * - NFCT_Q_UPDATE: update a conntrack
857 * - NFCT_Q_DESTROY: destroy a conntrack
858 * - NFCT_Q_GET: get a conntrack
859 *
860 * Pass a valid pointer to a conntrack object.
861 *
862 * For query types:
863 * - NFCT_Q_FLUSH: flush the conntrack table
864 * - NFCT_Q_DUMP: dump the conntrack table
865 * - NFCT_Q_DUMP_RESET: dump the conntrack table and reset counters
866 * - NFCT_Q_DUMP_FILTER: dump the conntrack table
867 * - NFCT_Q_DUMP_FILTER_RESET: dump the conntrack table and reset counters
868 *
869 * Pass a valid pointer to the protocol family (uint32_t)
870 *
871 * On success, 0 is returned. On error, -1 is returned and errno is set
872 * appropiately.
873 */
nfct_build_query(struct nfnl_subsys_handle * ssh,const enum nf_conntrack_query qt,const void * data,void * buffer,unsigned int size)874 int nfct_build_query(struct nfnl_subsys_handle *ssh,
875 const enum nf_conntrack_query qt,
876 const void *data,
877 void *buffer,
878 unsigned int size)
879 {
880 return __build_query_ct(ssh, qt, data, buffer, size);
881 }
882
883 /**
884 * nfct_parse_conntrack - translate a netlink message to a conntrack object
885 * \param type do the translation iif the message type is of a certain type
886 * \param nlh pointer to the netlink message
887 * \param ct pointer to the conntrack object
888 *
889 * This is a low level function, use it in case that you require to work
890 * with netlink details via libnfnetlink. Otherwise, we suggest you to
891 * use the high level API.
892 *
893 * The message types are:
894 *
895 * - NFCT_T_NEW: parse messages with new conntracks
896 * - NFCT_T_UPDATE: parse messages with conntrack updates
897 * - NFCT_T_DESTROY: parse messages with conntrack destroy
898 * - NFCT_T_ALL: all message types
899 *
900 * The message type is a flag, therefore the can be combined, ie.
901 * NFCT_T_NEW | NFCT_T_DESTROY to parse only new and destroy messages
902 *
903 * On error, NFCT_T_ERROR is returned and errno is set appropiately. If
904 * the message received is not of the requested type then 0 is returned,
905 * otherwise this function returns the message type parsed.
906 */
nfct_parse_conntrack(enum nf_conntrack_msg_type type,const struct nlmsghdr * nlh,struct nf_conntrack * ct)907 int nfct_parse_conntrack(enum nf_conntrack_msg_type type,
908 const struct nlmsghdr *nlh,
909 struct nf_conntrack *ct)
910 {
911 unsigned int flags;
912 int len = nlh->nlmsg_len;
913 struct nfgenmsg *nfhdr = NLMSG_DATA(nlh);
914 struct nfattr *cda[CTA_MAX];
915
916 assert(nlh != NULL);
917 assert(ct != NULL);
918
919 len -= NLMSG_LENGTH(sizeof(struct nfgenmsg));
920 if (len < 0) {
921 errno = EINVAL;
922 return NFCT_T_ERROR;
923 }
924
925 flags = __parse_message_type(nlh);
926 if (!(flags & type))
927 return 0;
928
929 nfnl_parse_attr(cda, CTA_MAX, NFA_DATA(nfhdr), len);
930
931 __parse_conntrack(nlh, cda, ct);
932
933 return flags;
934 }
935
936 /**
937 * @}
938 */
939
940 /**
941 * \defgroup cmd Send commands to kernel-space and receive replies
942 * @{
943 */
944
945 /**
946 * nfct_query - send a query to ctnetlink and handle the reply
947 * \param h library handler
948 * \param qt query type
949 * \param data data required to send the query
950 *
951 * On error, -1 is returned and errno is explicitely set. On success, 0
952 * is returned.
953 */
nfct_query(struct nfct_handle * h,const enum nf_conntrack_query qt,const void * data)954 int nfct_query(struct nfct_handle *h,
955 const enum nf_conntrack_query qt,
956 const void *data)
957 {
958 const size_t size = 4096; /* enough for now */
959 union {
960 char buffer[size];
961 struct nfnlhdr req;
962 } u;
963
964 assert(h != NULL);
965 assert(data != NULL);
966
967 if (__build_query_ct(h->nfnlssh_ct, qt, data, &u.req, size) == -1)
968 return -1;
969
970 return nfnl_query(h->nfnlh, &u.req.nlh);
971 }
972
973 /**
974 * nfct_send - send a query to ctnetlink
975 * \param h library handler
976 * \param qt query type
977 * \param data data required to send the query
978 *
979 * Like nfct_query but we do not wait for the reply from ctnetlink.
980 * You can use nfct_send() and nfct_catch() to emulate nfct_query().
981 * This is particularly useful when the socket is non-blocking.
982 *
983 * On error, -1 is returned and errno is explicitely set. On success, 0
984 * is returned.
985 */
nfct_send(struct nfct_handle * h,const enum nf_conntrack_query qt,const void * data)986 int nfct_send(struct nfct_handle *h,
987 const enum nf_conntrack_query qt,
988 const void *data)
989 {
990 const size_t size = 4096; /* enough for now */
991 union {
992 char buffer[size];
993 struct nfnlhdr req;
994 } u;
995
996 assert(h != NULL);
997 assert(data != NULL);
998
999 if (__build_query_ct(h->nfnlssh_ct, qt, data, &u.req, size) == -1)
1000 return -1;
1001
1002 return nfnl_send(h->nfnlh, &u.req.nlh);
1003 }
1004
1005
1006 /**
1007 * nfct_catch - catch events
1008 * \param h library handler
1009 *
1010 * This function receives the event from the kernel and it invokes the
1011 * callback that was registered to this handle.
1012 *
1013 * On error, -1 is returned and errno is set appropiately. On success,
1014 * a value greater or equal to 0 is returned indicating the callback
1015 * verdict: NFCT_CB_STOP, NFCT_CB_CONTINUE or NFCT_CB_STOLEN.
1016 *
1017 * Beware that this function also handles expectation events, in case they are
1018 * received through this handle.
1019 */
nfct_catch(struct nfct_handle * h)1020 int nfct_catch(struct nfct_handle *h)
1021 {
1022 assert(h != NULL);
1023
1024 return nfnl_catch(h->nfnlh);
1025 }
1026
1027 /**
1028 * @}
1029 */
1030
1031 /**
1032 * \defgroup ct Conntrack object handling
1033 * @{
1034 */
1035
1036 /**
1037 * nfct_snprintf - print a conntrack object to a buffer
1038 * \param buf buffer used to build the printable conntrack
1039 * \param size size of the buffer
1040 * \param ct pointer to a valid conntrack object
1041 * \param message_type print message type (NFCT_T_UNKNOWN, NFCT_T_NEW,...)
1042 * \param output_type print type (NFCT_O_DEFAULT, NFCT_O_XML, ...)
1043 * \param flags extra flags for the output type (NFCT_OF_LAYER3)
1044 *
1045 * If you are listening to events, probably you want to display the message
1046 * type as well. In that case, set the message type parameter to any of the
1047 * known existing types, ie. NFCT_T_NEW, NFCT_T_UPDATE, NFCT_T_DESTROY.
1048 * If you pass NFCT_T_UNKNOWN, the message type will not be output.
1049 *
1050 * Currently, the output available are:
1051 * - NFCT_O_DEFAULT: default /proc-like output
1052 * - NFCT_O_XML: XML output
1053 *
1054 * The output flags are:
1055 * - NFCT_OF_SHOW_LAYER3: include layer 3 information in the output,
1056 * this is *only* required by NFCT_O_DEFAULT.
1057 * - NFCT_OF_TIME: display current time.
1058 * - NFCT_OF_ID: display the ID number.
1059 * - NFCT_OF_TIMESTAMP: display creation and (if exists) deletion time.
1060 *
1061 * To use NFCT_OF_TIMESTAMP, you have to:
1062 * \verbatim
1063 * $ echo 1 > /proc/sys/net/netfilter/nf_conntrack_timestamp
1064 \endverbatim
1065 * This requires a Linux kernel >= 2.6.38.
1066 *
1067 * Note that NFCT_OF_TIME displays the current time when nfct_snprintf() has
1068 * been called. Thus, it can be used to know when a flow was destroy if you
1069 * print the message just after you receive the destroy event. If you want
1070 * more accurate timestamping, use NFCT_OF_TIMESTAMP.
1071 *
1072 * This function returns the size of the information that _would_ have been
1073 * written to the buffer, even if there was no room for it. Thus, the
1074 * behaviour is similar to snprintf.
1075 */
nfct_snprintf(char * buf,unsigned int size,const struct nf_conntrack * ct,unsigned int msg_type,unsigned int out_type,unsigned int flags)1076 int nfct_snprintf(char *buf,
1077 unsigned int size,
1078 const struct nf_conntrack *ct,
1079 unsigned int msg_type,
1080 unsigned int out_type,
1081 unsigned int flags)
1082 {
1083 assert(buf != NULL);
1084 assert(size > 0);
1085 assert(ct != NULL);
1086
1087 return __snprintf_conntrack(buf, size, ct, msg_type, out_type, flags, NULL);
1088 }
1089
1090 /**
1091 * nfct_snprintf_labels - print a bitmask object to a buffer including labels
1092 * \param buf buffer used to build the printable conntrack
1093 * \param size size of the buffer
1094 * \param ct pointer to a valid conntrack object
1095 * \param message_type print message type (NFCT_T_UNKNOWN, NFCT_T_NEW,...)
1096 * \param output_type print type (NFCT_O_DEFAULT, NFCT_O_XML, ...)
1097 * \param flags extra flags for the output type (NFCT_OF_LAYER3)
1098 * \param map nfct_labelmap describing the connlabel translation, or NULL.
1099 *
1100 * When map is NULL, the function is equal to nfct_snprintf().
1101 * Otherwise, if the conntrack object has a connlabel attribute, the active
1102 * labels are translated using the label map and added to the buffer.
1103 */
nfct_snprintf_labels(char * buf,unsigned int size,const struct nf_conntrack * ct,unsigned int msg_type,unsigned int out_type,unsigned int flags,struct nfct_labelmap * map)1104 int nfct_snprintf_labels(char *buf,
1105 unsigned int size,
1106 const struct nf_conntrack *ct,
1107 unsigned int msg_type,
1108 unsigned int out_type,
1109 unsigned int flags,
1110 struct nfct_labelmap *map)
1111 {
1112 return __snprintf_conntrack(buf, size, ct, msg_type, out_type, flags, map);
1113 }
1114
1115 /**
1116 * nfct_compare - compare two conntrack objects
1117 * \param ct1 pointer to a valid conntrack object
1118 * \param ct2 pointer to a valid conntrack object
1119 *
1120 * This function only compare attribute set in both objects, ie. if a certain
1121 * attribute is not set in ct1 but it is in ct2, then the value of such
1122 * attribute is not used in the comparison.
1123 *
1124 * If both conntrack object are equal, this function returns 1, otherwise
1125 * 0 is returned.
1126 *
1127 * NOTICE: The use nfct_cmp is preferred.
1128 */
nfct_compare(const struct nf_conntrack * ct1,const struct nf_conntrack * ct2)1129 int nfct_compare(const struct nf_conntrack *ct1,
1130 const struct nf_conntrack *ct2)
1131 {
1132 assert(ct1 != NULL);
1133 assert(ct2 != NULL);
1134
1135 return __compare(ct1, ct2, NFCT_CMP_ALL);
1136 }
1137
1138 /**
1139 * nfct_cmp - compare two conntrack objects
1140 * \param ct1 pointer to a valid conntrack object
1141 * \param ct2 pointer to a valid conntrack object
1142 * \param flags flags
1143 *
1144 * This function only compare attribute set in both objects, by default
1145 * the comparison is not strict, ie. if a certain attribute is not set in one
1146 * of the objects, then such attribute is not used in the comparison.
1147 * If you want more strict comparisons, you can use the appropriate flags
1148 * to modify this behaviour (see NFCT_CMP_STRICT and NFCT_CMP_MASK).
1149 *
1150 * The available flags are:
1151 *
1152 * - NFCT_CMP_STRICT: the compared objects must have the same attributes
1153 * and the same values, otherwise it returns that the objects are
1154 * different.
1155 * - NFCT_CMP_MASK: the first object is used as mask, this means that
1156 * if an attribute is present in ct1 but not in ct2, this function
1157 * returns that the objects are different.
1158 * - NFCT_CMP_ALL: full comparison of both objects
1159 * - NFCT_CMP_ORIG: it only compares the source and destination address;
1160 * source and destination ports; the layer 3 and 4 protocol numbers
1161 * of the original direction; and the id (if present).
1162 * - NFCT_CMP_REPL: like NFCT_CMP_REPL but it compares the flow
1163 * information that goes in the reply direction.
1164 * - NFCT_CMP_TIMEOUT_EQ: timeout(ct1) == timeout(ct2)
1165 * - NFCT_CMP_TIMEOUT_GT: timeout(ct1) > timeout(ct2)
1166 * - NFCT_CMP_TIMEOUT_LT: timeout(ct1) < timeout(ct2)
1167 * - NFCT_CMP_TIMEOUT_GE: timeout(ct1) >= timeout(ct2)
1168 * - NFCT_CMP_TIMEOUT_LE: timeout(ct1) <= timeout(ct2)
1169 *
1170 * The status bits comparison is status(ct1) & status(ct2) == status(ct1).
1171 *
1172 * If both conntrack object are equal, this function returns 1, otherwise
1173 * 0 is returned.
1174 */
nfct_cmp(const struct nf_conntrack * ct1,const struct nf_conntrack * ct2,unsigned int flags)1175 int nfct_cmp(const struct nf_conntrack *ct1,
1176 const struct nf_conntrack *ct2,
1177 unsigned int flags)
1178 {
1179 assert(ct1 != NULL);
1180 assert(ct2 != NULL);
1181
1182 return __compare(ct1, ct2, flags);
1183 }
1184
1185 /**
1186 * nfct_copy - copy part of one source object to another
1187 * \param ct1 destination object
1188 * \param ct2 source object
1189 * \param flags flags
1190 *
1191 * This function copies one part of the source object to the target.
1192 * It behaves like clone but:
1193 *
1194 * 1) You have to pass an already allocated space for the target object
1195 * 2) You can copy only a part of the source object to the target
1196 *
1197 * The current supported flags are:
1198 * - NFCT_CP_ALL: that copies the object entirely.
1199 * - NFCT_CP_ORIG and NFCT_CP_REPL: that can be used to copy the
1200 * information that identifies a flow in the original and the reply
1201 * direction. This information is usually composed of: source and
1202 * destination IP address; source and destination ports; layer 3
1203 * and 4 protocol number.
1204 * - NFCT_CP_META: that copies the metainformation
1205 * (all the attributes >= ATTR_TCP_STATE)
1206 * - NFCT_CP_OVERRIDE: changes the default behaviour of nfct_copy() since
1207 * it overrides the destination object. After the copy, the destination
1208 * is a clone of the origin. This flag provides faster copying.
1209 */
nfct_copy(struct nf_conntrack * ct1,const struct nf_conntrack * ct2,unsigned int flags)1210 void nfct_copy(struct nf_conntrack *ct1,
1211 const struct nf_conntrack *ct2,
1212 unsigned int flags)
1213 {
1214 int i;
1215
1216 assert(ct1 != NULL);
1217 assert(ct2 != NULL);
1218
1219 if (flags & NFCT_CP_OVERRIDE) {
1220 __copy_fast(ct1, ct2);
1221 return;
1222 }
1223 if (flags == NFCT_CP_ALL) {
1224 for (i=0; i<ATTR_MAX; i++) {
1225 if (test_bit(i, ct2->head.set)) {
1226 assert(copy_attr_array[i]);
1227 copy_attr_array[i](ct1, ct2);
1228 set_bit(i, ct1->head.set);
1229 }
1230 }
1231 return;
1232 }
1233
1234 static const int cp_orig_mask[] = {
1235 ATTR_ORIG_IPV4_SRC,
1236 ATTR_ORIG_IPV4_DST,
1237 ATTR_ORIG_IPV6_SRC,
1238 ATTR_ORIG_IPV6_DST,
1239 ATTR_ORIG_PORT_SRC,
1240 ATTR_ORIG_PORT_DST,
1241 ATTR_ICMP_TYPE,
1242 ATTR_ICMP_CODE,
1243 ATTR_ICMP_ID,
1244 ATTR_ORIG_L3PROTO,
1245 ATTR_ORIG_L4PROTO,
1246 };
1247 #define __CP_ORIG_MAX sizeof(cp_orig_mask)/sizeof(int)
1248
1249 if (flags & NFCT_CP_ORIG) {
1250 for (i=0; i<__CP_ORIG_MAX; i++) {
1251 if (test_bit(cp_orig_mask[i], ct2->head.set)) {
1252 assert(copy_attr_array[i]);
1253 copy_attr_array[cp_orig_mask[i]](ct1, ct2);
1254 set_bit(cp_orig_mask[i], ct1->head.set);
1255 }
1256 }
1257 }
1258
1259 static const int cp_repl_mask[] = {
1260 ATTR_REPL_IPV4_SRC,
1261 ATTR_REPL_IPV4_DST,
1262 ATTR_REPL_IPV6_SRC,
1263 ATTR_REPL_IPV6_DST,
1264 ATTR_REPL_PORT_SRC,
1265 ATTR_REPL_PORT_DST,
1266 ATTR_REPL_L3PROTO,
1267 ATTR_REPL_L4PROTO,
1268 };
1269 #define __CP_REPL_MAX sizeof(cp_repl_mask)/sizeof(int)
1270
1271 if (flags & NFCT_CP_REPL) {
1272 for (i=0; i<__CP_REPL_MAX; i++) {
1273 if (test_bit(cp_repl_mask[i], ct2->head.set)) {
1274 assert(copy_attr_array[i]);
1275 copy_attr_array[cp_repl_mask[i]](ct1, ct2);
1276 set_bit(cp_repl_mask[i], ct1->head.set);
1277 }
1278 }
1279 }
1280
1281 if (flags & NFCT_CP_META) {
1282 for (i=ATTR_TCP_STATE; i<ATTR_MAX; i++) {
1283 if (test_bit(i, ct2->head.set)) {
1284 assert(copy_attr_array[i]),
1285 copy_attr_array[i](ct1, ct2);
1286 set_bit(i, ct1->head.set);
1287 }
1288 }
1289 }
1290 }
1291
1292 /**
1293 * nfct_copy_attr - copy an attribute of one source object to another
1294 * \param ct1 destination object
1295 * \param ct2 source object
1296 * \param flags flags
1297 *
1298 * This function copies one attribute (if present) to another object.
1299 */
nfct_copy_attr(struct nf_conntrack * ct1,const struct nf_conntrack * ct2,const enum nf_conntrack_attr type)1300 void nfct_copy_attr(struct nf_conntrack *ct1,
1301 const struct nf_conntrack *ct2,
1302 const enum nf_conntrack_attr type)
1303 {
1304 if (test_bit(type, ct2->head.set)) {
1305 assert(copy_attr_array[type]);
1306 copy_attr_array[type](ct1, ct2);
1307 set_bit(type, ct1->head.set);
1308 }
1309 }
1310
1311 /**
1312 * @}
1313 */
1314
1315 /**
1316 * \defgroup bsf Kernel-space filtering for events
1317 *
1318 * @{
1319 */
1320
1321 /**
1322 * nfct_filter_create - create a filter
1323 *
1324 * This function returns a valid pointer on success, otherwise NULL is
1325 * returned and errno is appropriately set.
1326 */
nfct_filter_create(void)1327 struct nfct_filter *nfct_filter_create(void)
1328 {
1329 return calloc(sizeof(struct nfct_filter), 1);
1330 }
1331
1332 /**
1333 * nfct_filter_destroy - destroy a filter
1334 * \param filter filter that we want to destroy
1335 *
1336 * This function releases the memory that is used by the filter object.
1337 * However, please note that this function does *not* detach an already
1338 * attached filter.
1339 */
nfct_filter_destroy(struct nfct_filter * filter)1340 void nfct_filter_destroy(struct nfct_filter *filter)
1341 {
1342 assert(filter != NULL);
1343 free(filter);
1344 filter = NULL;
1345 }
1346
1347 /**
1348 * nfct_filter_add_attr - add a filter attribute of the filter object
1349 * \param filter filter object that we want to modify
1350 * \param type filter attribute type
1351 * \param value pointer to the value of the filter attribute
1352 *
1353 * Limitations: You can add up to 127 IPv4 addresses and masks for
1354 * NFCT_FILTER_SRC_IPV4 and, similarly, 127 for NFCT_FILTER_DST_IPV4.
1355 */
nfct_filter_add_attr(struct nfct_filter * filter,const enum nfct_filter_attr type,const void * value)1356 void nfct_filter_add_attr(struct nfct_filter *filter,
1357 const enum nfct_filter_attr type,
1358 const void *value)
1359 {
1360 assert(filter != NULL);
1361 assert(value != NULL);
1362
1363 if (unlikely(type >= NFCT_FILTER_MAX))
1364 return;
1365
1366 if (filter_attr_array[type]) {
1367 filter_attr_array[type](filter, value);
1368 set_bit(type, filter->set);
1369 }
1370 }
1371
1372 /**
1373 * nfct_filter_add_attr_u32 - add an u32 filter attribute of the filter object
1374 * \param filter filter object that we want to modify
1375 * \param type filter attribute type
1376 * \param value value of the filter attribute using unsigned int (32 bits).
1377 *
1378 * Limitations: You can add up to 255 protocols which is a reasonable limit.
1379 */
nfct_filter_add_attr_u32(struct nfct_filter * filter,const enum nfct_filter_attr type,uint32_t value)1380 void nfct_filter_add_attr_u32(struct nfct_filter *filter,
1381 const enum nfct_filter_attr type,
1382 uint32_t value)
1383 {
1384 nfct_filter_add_attr(filter, type, &value);
1385 }
1386
1387 /**
1388 * nfct_filter_set_logic - set the filter logic for an attribute type
1389 * \param filter filter object that we want to modify
1390 * \param type filter attribute type
1391 * \param logic filter logic that we want to use
1392 *
1393 * You can only use this function once to set the filtering logic for
1394 * one attribute. You can define two logics: NFCT_FILTER_LOGIC_POSITIVE
1395 * that accept events that match the filter, and NFCT_FILTER_LOGIC_NEGATIVE
1396 * that rejects events that match the filter. Default filtering logic is
1397 * NFCT_FILTER_LOGIC_POSITIVE.
1398 *
1399 * On error, it returns -1 and errno is appropriately set. On success, it
1400 * returns 0.
1401 */
nfct_filter_set_logic(struct nfct_filter * filter,const enum nfct_filter_attr type,const enum nfct_filter_logic logic)1402 int nfct_filter_set_logic(struct nfct_filter *filter,
1403 const enum nfct_filter_attr type,
1404 const enum nfct_filter_logic logic)
1405 {
1406 if (unlikely(type >= NFCT_FILTER_MAX)) {
1407 errno = ENOTSUP;
1408 return -1;
1409 }
1410
1411 if (filter->logic[type]) {
1412 errno = EBUSY;
1413 return -1;
1414 }
1415
1416 filter->logic[type] = logic;
1417
1418 return 0;
1419 }
1420
1421 /**
1422 * nfct_filter_attach - attach a filter to a socket descriptor
1423 * \param fd socket descriptor
1424 * \param filter filter that we want to attach to the socket
1425 *
1426 * This function returns -1 on error and set errno appropriately. If the
1427 * function returns EINVAL probably you have found a bug in it. Please,
1428 * report this.
1429 */
nfct_filter_attach(int fd,struct nfct_filter * filter)1430 int nfct_filter_attach(int fd, struct nfct_filter *filter)
1431 {
1432 assert(filter != NULL);
1433
1434 return __setup_netlink_socket_filter(fd, filter);
1435 }
1436
1437 /**
1438 * nfct_filter_detach - detach an existing filter
1439 * \param fd socket descriptor
1440 *
1441 * This function returns -1 on error and set errno appropriately.
1442 */
nfct_filter_detach(int fd)1443 int nfct_filter_detach(int fd)
1444 {
1445 int val = 0;
1446
1447 return setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, &val, sizeof(val));
1448 }
1449
1450 /**
1451 * @}
1452 */
1453
1454 /**
1455 * \defgroup dumpfilter Kernel-space filtering for dumping
1456 *
1457 * @{
1458 */
1459
1460 /**
1461 * nfct_filter_dump_create - create a dump filter
1462 *
1463 * This function returns a valid pointer on success, otherwise NULL is
1464 * returned and errno is appropriately set.
1465 */
nfct_filter_dump_create(void)1466 struct nfct_filter_dump *nfct_filter_dump_create(void)
1467 {
1468 return calloc(sizeof(struct nfct_filter_dump), 1);
1469 }
1470
1471 /**
1472 * nfct_filter_dump_destroy - destroy a dump filter
1473 * \param filter filter that we want to destroy
1474 *
1475 * This function releases the memory that is used by the filter object.
1476 */
nfct_filter_dump_destroy(struct nfct_filter_dump * filter)1477 void nfct_filter_dump_destroy(struct nfct_filter_dump *filter)
1478 {
1479 assert(filter != NULL);
1480 free(filter);
1481 filter = NULL;
1482 }
1483
1484 /**
1485 * nfct_filter_dump_attr_set - set filter attribute
1486 * \param filter dump filter object that we want to modify
1487 * \param type filter attribute type
1488 * \param value pointer to the value of the filter attribute
1489 */
nfct_filter_dump_set_attr(struct nfct_filter_dump * filter_dump,const enum nfct_filter_dump_attr type,const void * value)1490 void nfct_filter_dump_set_attr(struct nfct_filter_dump *filter_dump,
1491 const enum nfct_filter_dump_attr type,
1492 const void *value)
1493 {
1494 assert(filter_dump != NULL);
1495 assert(value != NULL);
1496
1497 if (unlikely(type >= NFCT_FILTER_DUMP_MAX))
1498 return;
1499
1500 if (set_filter_dump_attr_array[type]) {
1501 set_filter_dump_attr_array[type](filter_dump, value);
1502 filter_dump->set |= (1 << type);
1503 }
1504 }
1505
1506 /**
1507 * nfct_filter_dump_attr_set_u8 - set u8 dump filter attribute
1508 * \param filter dump filter object that we want to modify
1509 * \param type filter attribute type
1510 * \param value value of the filter attribute using unsigned int (32 bits).
1511 */
nfct_filter_dump_set_attr_u8(struct nfct_filter_dump * filter_dump,const enum nfct_filter_dump_attr type,uint8_t value)1512 void nfct_filter_dump_set_attr_u8(struct nfct_filter_dump *filter_dump,
1513 const enum nfct_filter_dump_attr type,
1514 uint8_t value)
1515 {
1516 nfct_filter_dump_set_attr(filter_dump, type, &value);
1517 }
1518
1519 /**
1520 * @}
1521 */
1522
1523 /**
1524 * \defgroup label Conntrack labels
1525 *
1526 * @{
1527 */
1528
1529 /**
1530 * nfct_labels_get_path - get name of default config path
1531 *
1532 * returns a pointer to a immutable (static) string containing
1533 * the default connlabel.conf file location.
1534 */
nfct_labels_get_path(void)1535 const char *nfct_labels_get_path(void)
1536 {
1537 return __labels_get_path();
1538 }
1539
1540 /**
1541 * nfct_labelmap_get_name - get name of the label bit
1542 *
1543 * \param m label map obtained from nfct_label_open
1544 * \param bit whose name should be returned
1545 *
1546 * returns a pointer to the name associated with the label.
1547 * If no name has been configured, the empty string is returned.
1548 * If bit is out of range, NULL is returned.
1549 */
nfct_labelmap_get_name(struct nfct_labelmap * m,unsigned int bit)1550 const char *nfct_labelmap_get_name(struct nfct_labelmap *m, unsigned int bit)
1551 {
1552 return __labelmap_get_name(m, bit);
1553 }
1554
1555 /**
1556 * nfct_labelmap_get_bit - get bit associated with the name
1557 *
1558 * \param h label handle obtained from nfct_labelmap_new
1559 * \param name name of the label
1560 *
1561 * returns the bit associated with the name, or negative value on error.
1562 */
nfct_labelmap_get_bit(struct nfct_labelmap * m,const char * name)1563 int nfct_labelmap_get_bit(struct nfct_labelmap *m, const char *name)
1564 {
1565 return __labelmap_get_bit(m, name);
1566 }
1567
1568 /**
1569 * nfct_labelmap_new - create a new label map
1570 *
1571 * \param mapfile the file containing the bit <-> name mapping
1572 *
1573 * If mapfile is NULL, the default mapping file is used.
1574 * returns a new label map, or NULL on error.
1575 */
nfct_labelmap_new(const char * mapfile)1576 struct nfct_labelmap *nfct_labelmap_new(const char *mapfile)
1577 {
1578 return __labelmap_new(mapfile);
1579 }
1580
1581 /**
1582 * nfct_labelmap_destroy - destroy nfct_labelmap object
1583 *
1584 * \param map the label object to destroy.
1585 *
1586 * This function releases the memory that is used by the labelmap object.
1587 */
nfct_labelmap_destroy(struct nfct_labelmap * map)1588 void nfct_labelmap_destroy(struct nfct_labelmap *map)
1589 {
1590 __labelmap_destroy(map);
1591 }
1592
1593 /**
1594 * @}
1595 */
1596
1597 /*
1598 * \defgroup bitmask bitmask object
1599 *
1600 * @{
1601 */
1602
1603 /**
1604 * nfct_bitmask_new - allocate a new bitmask
1605 *
1606 * \param max highest valid bit that can be set/unset.
1607 *
1608 * In case of success, this function returns a valid pointer to a memory blob,
1609 * otherwise NULL is returned and errno is set appropiately.
1610 */
nfct_bitmask_new(unsigned int max)1611 struct nfct_bitmask *nfct_bitmask_new(unsigned int max)
1612 {
1613 struct nfct_bitmask *b;
1614 unsigned int bytes, words;
1615
1616 if (max > 0xffff)
1617 return NULL;
1618
1619 words = DIV_ROUND_UP(max+1, 32);
1620 bytes = words * sizeof(b->bits[0]);
1621
1622 b = malloc(sizeof(*b) + bytes);
1623 if (b) {
1624 memset(b->bits, 0, bytes);
1625 b->words = words;
1626 }
1627 return b;
1628 }
1629
1630 /*
1631 * nfct_bitmask_clone - duplicate a bitmask object
1632 *
1633 * \param b pointer to the bitmask object to duplicate
1634 *
1635 * returns an identical copy of the bitmask.
1636 */
nfct_bitmask_clone(const struct nfct_bitmask * b)1637 struct nfct_bitmask *nfct_bitmask_clone(const struct nfct_bitmask *b)
1638 {
1639 unsigned int bytes = b->words * sizeof(b->bits[0]);
1640 struct nfct_bitmask *copy;
1641
1642 bytes += sizeof(*b);
1643
1644 copy = malloc(bytes);
1645 if (copy)
1646 memcpy(copy, b, bytes);
1647 return copy;
1648 }
1649
1650 /*
1651 * nfct_bitmask_set_bit - set bit in the bitmask
1652 *
1653 * \param b pointer to the bitmask object
1654 * \param bit the bit to set
1655 */
nfct_bitmask_set_bit(struct nfct_bitmask * b,unsigned int bit)1656 void nfct_bitmask_set_bit(struct nfct_bitmask *b, unsigned int bit)
1657 {
1658 unsigned int bits = b->words * 32;
1659 if (bit < bits)
1660 set_bit(bit, b->bits);
1661 }
1662
1663 /*
1664 * nfct_bitmask_test_bit - test if a bit in the bitmask is set
1665 *
1666 * \param b pointer to the bitmask object
1667 * \param bit the bit to test
1668 *
1669 * returns 0 if the bit is not set.
1670 */
nfct_bitmask_test_bit(const struct nfct_bitmask * b,unsigned int bit)1671 int nfct_bitmask_test_bit(const struct nfct_bitmask *b, unsigned int bit)
1672 {
1673 unsigned int bits = b->words * 32;
1674 return bit < bits && test_bit(bit, b->bits);
1675 }
1676
1677 /*
1678 * nfct_bitmask_unset_bit - unset bit in the bitmask
1679 *
1680 * \param b pointer to the bitmask object
1681 * \param bit the bit to clear
1682 */
nfct_bitmask_unset_bit(struct nfct_bitmask * b,unsigned int bit)1683 void nfct_bitmask_unset_bit(struct nfct_bitmask *b, unsigned int bit)
1684 {
1685 unsigned int bits = b->words * 32;
1686 if (bit < bits)
1687 unset_bit(bit, b->bits);
1688 }
1689
1690 /*
1691 * nfct_bitmask_maxbit - return highest bit that may be set/unset
1692 *
1693 * \param b pointer to the bitmask object
1694 */
nfct_bitmask_maxbit(const struct nfct_bitmask * b)1695 unsigned int nfct_bitmask_maxbit(const struct nfct_bitmask *b)
1696 {
1697 return (b->words * 32) - 1;
1698 }
1699
1700 /*
1701 * nfct_bitmask_destroy - destroy bitmask object
1702 *
1703 * \param b pointer to the bitmask object
1704 *
1705 * This function releases the memory that is used by the bitmask object.
1706 *
1707 * If you assign a bitmask object to a nf_conntrack object using
1708 * nfct_set_attr ATTR_CONNLABEL, then the ownership of the bitmask
1709 * object passes on to the nf_conntrack object. The nfct_bitmask object
1710 * will be destroyed when the nf_conntrack object is destroyed.
1711 */
nfct_bitmask_destroy(struct nfct_bitmask * b)1712 void nfct_bitmask_destroy(struct nfct_bitmask *b)
1713 {
1714 free(b);
1715 }
1716
1717 /*
1718 * nfct_bitmask_clear - clear a bitmask object
1719 *
1720 * \param b pointer to the bitmask object to clear
1721 */
nfct_bitmask_clear(struct nfct_bitmask * b)1722 void nfct_bitmask_clear(struct nfct_bitmask *b)
1723 {
1724 unsigned int bytes = b->words * sizeof(b->bits[0]);
1725 memset(b->bits, 0, bytes);
1726 }
1727
1728 /*
1729 * nfct_bitmask_equal - compare two bitmask objects
1730 *
1731 * \param b1 pointer to a valid bitmask object
1732 * \param b2 pointer to a valid bitmask object
1733 *
1734 * If both bitmask object are equal, this function returns true, otherwise
1735 * false is returned.
1736 */
nfct_bitmask_equal(const struct nfct_bitmask * b1,const struct nfct_bitmask * b2)1737 bool nfct_bitmask_equal(const struct nfct_bitmask *b1, const struct nfct_bitmask *b2)
1738 {
1739 if (b1->words != b2->words)
1740 return false;
1741
1742 return memcmp(b1->bits, b2->bits, b1->words * sizeof(b1->bits[0])) == 0;
1743 }
1744
1745 /**
1746 * @}
1747 */
1748