1 /* 2 * (C) 2005-2011 by Pablo Neira Ayuso <pablo (at) 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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