• Main Page
  • Modules
  • Data Structures
  • Files
  • File List

api.c

00001 /*
00002  * (C) 2006 by Pablo Neira Ayuso <pablo@netfilter.org>
00003  *
00004  * This software may be used and distributed according to the terms
00005  * of the GNU General Public License, incorporated herein by reference.
00006  */
00007 
00008 #include <stdlib.h>
00009 #include <string.h> /* for memset */
00010 #include <errno.h>
00011 #include <assert.h>
00012 
00013 #include "internal/internal.h"
00014 
00072 struct nf_conntrack *nfct_new(void)
00073 {
00074         struct nf_conntrack *ct;
00075 
00076         ct = malloc(sizeof(struct nf_conntrack));
00077         if (!ct)
00078                 return NULL;
00079 
00080         memset(ct, 0, sizeof(struct nf_conntrack));
00081 
00082         return ct;
00083 }
00084 
00089 void nfct_destroy(struct nf_conntrack *ct)
00090 {
00091         assert(ct != NULL);
00092         if (ct->secctx)
00093                 free(ct->secctx);
00094         free(ct);
00095         ct = NULL; /* bugtrap */
00096 }
00097 
00102 size_t nfct_sizeof(const struct nf_conntrack *ct)
00103 {
00104         assert(ct != NULL);
00105         return sizeof(*ct);
00106 }
00107 
00122 size_t nfct_maxsize(void)
00123 {
00124         return sizeof(struct nf_conntrack);
00125 }
00126 
00134 struct nf_conntrack *nfct_clone(const struct nf_conntrack *ct)
00135 {
00136         struct nf_conntrack *clone;
00137 
00138         assert(ct != NULL);
00139 
00140         if ((clone = nfct_new()) == NULL)
00141                 return NULL;
00142         memcpy(clone, ct, sizeof(*ct));
00143 
00144         return clone;
00145 }
00146 
00155 int nfct_setobjopt(struct nf_conntrack *ct, unsigned int option)
00156 {
00157         assert(ct != NULL);
00158 
00159         if (unlikely(option > NFCT_SOPT_MAX)) {
00160                 errno = EOPNOTSUPP;
00161                 return -1;
00162         }
00163 
00164         return __setobjopt(ct, option);
00165 }
00166 
00175 int nfct_getobjopt(const struct nf_conntrack *ct, unsigned int option)
00176 {
00177         assert(ct != NULL);
00178 
00179         if (unlikely(option > NFCT_GOPT_MAX)) {
00180                 errno = EOPNOTSUPP;
00181                 return -1;
00182         }
00183 
00184         return __getobjopt(ct, option);
00185 }
00186 
00210 int nfct_callback_register(struct nfct_handle *h,
00211                            enum nf_conntrack_msg_type type,
00212                            int (*cb)(enum nf_conntrack_msg_type type,
00213                                      struct nf_conntrack *ct, 
00214                                      void *data),
00215                            void *data)
00216 {
00217         struct __data_container *container;
00218 
00219         assert(h != NULL);
00220 
00221         container = malloc(sizeof(struct __data_container));
00222         if (!container)
00223                 return -1;
00224         memset(container, 0, sizeof(struct __data_container));
00225 
00226         h->cb = cb;
00227         container->h = h;
00228         container->type = type;
00229         container->data = data;
00230 
00231         h->nfnl_cb_ct.call = __callback;
00232         h->nfnl_cb_ct.data = container;
00233         h->nfnl_cb_ct.attr_count = CTA_MAX;
00234 
00235         nfnl_callback_register(h->nfnlssh_ct, 
00236                                IPCTNL_MSG_CT_NEW,
00237                                &h->nfnl_cb_ct);
00238 
00239         nfnl_callback_register(h->nfnlssh_ct,
00240                                IPCTNL_MSG_CT_DELETE,
00241                                &h->nfnl_cb_ct);
00242 
00243         return 0;
00244 }
00245 
00250 void nfct_callback_unregister(struct nfct_handle *h)
00251 {
00252         assert(h != NULL);
00253 
00254         nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_NEW);
00255         nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_DELETE);
00256 
00257         h->cb = NULL;
00258         free(h->nfnl_cb_ct.data);
00259 
00260         h->nfnl_cb_ct.call = NULL;
00261         h->nfnl_cb_ct.data = NULL;
00262         h->nfnl_cb_ct.attr_count = 0;
00263 }
00264 
00284 int nfct_callback_register2(struct nfct_handle *h,
00285                             enum nf_conntrack_msg_type type,
00286                             int (*cb)(const struct nlmsghdr *nlh,
00287                                       enum nf_conntrack_msg_type type,
00288                                       struct nf_conntrack *ct, 
00289                                       void *data),
00290                            void *data)
00291 {
00292         struct __data_container *container;
00293 
00294         assert(h != NULL);
00295 
00296         container = calloc(sizeof(struct __data_container), 1);
00297         if (container == NULL)
00298                 return -1;
00299 
00300         h->cb2 = cb;
00301         container->h = h;
00302         container->type = type;
00303         container->data = data;
00304 
00305         h->nfnl_cb_ct.call = __callback;
00306         h->nfnl_cb_ct.data = container;
00307         h->nfnl_cb_ct.attr_count = CTA_MAX;
00308 
00309         nfnl_callback_register(h->nfnlssh_ct, 
00310                                IPCTNL_MSG_CT_NEW,
00311                                &h->nfnl_cb_ct);
00312 
00313         nfnl_callback_register(h->nfnlssh_ct,
00314                                IPCTNL_MSG_CT_DELETE,
00315                                &h->nfnl_cb_ct);
00316 
00317         return 0;
00318 }
00319 
00324 void nfct_callback_unregister2(struct nfct_handle *h)
00325 {
00326         assert(h != NULL);
00327 
00328         nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_NEW);
00329         nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_DELETE);
00330 
00331         h->cb2 = NULL;
00332         free(h->nfnl_cb_ct.data);
00333 
00334         h->nfnl_cb_ct.call = NULL;
00335         h->nfnl_cb_ct.data = NULL;
00336         h->nfnl_cb_ct.attr_count = 0;
00337 }
00338 
00361 void nfct_set_attr(struct nf_conntrack *ct,
00362                    const enum nf_conntrack_attr type, 
00363                    const void *value)
00364 {
00365         assert(ct != NULL);
00366         assert(value != NULL);
00367 
00368         if (unlikely(type >= ATTR_MAX))
00369                 return;
00370 
00371         if (set_attr_array[type]) {
00372                 set_attr_array[type](ct, value);
00373                 set_bit(type, ct->set);
00374         }
00375 }
00376 
00383 void nfct_set_attr_u8(struct nf_conntrack *ct,
00384                       const enum nf_conntrack_attr type, 
00385                       u_int8_t value)
00386 {
00387         nfct_set_attr(ct, type, &value);
00388 }
00389 
00396 void nfct_set_attr_u16(struct nf_conntrack *ct,
00397                        const enum nf_conntrack_attr type, 
00398                        u_int16_t value)
00399 {
00400         nfct_set_attr(ct, type, &value);
00401 }
00402 
00409 void nfct_set_attr_u32(struct nf_conntrack *ct,
00410                        const enum nf_conntrack_attr type, 
00411                        u_int32_t value)
00412 {
00413         nfct_set_attr(ct, type, &value);
00414 }
00415 
00422 void nfct_set_attr_u64(struct nf_conntrack *ct,
00423                        const enum nf_conntrack_attr type, 
00424                        u_int64_t value)
00425 {
00426         nfct_set_attr(ct, type, &value);
00427 }
00428 
00437 const void *nfct_get_attr(const struct nf_conntrack *ct,
00438                           const enum nf_conntrack_attr type)
00439 {
00440         assert(ct != NULL);
00441 
00442         if (unlikely(type >= ATTR_MAX)) {
00443                 errno = EINVAL;
00444                 return NULL;
00445         }
00446 
00447         if (!test_bit(type, ct->set)) {
00448                 errno = ENODATA;
00449                 return NULL;
00450         }
00451 
00452         assert(get_attr_array[type]);
00453 
00454         return get_attr_array[type](ct);
00455 }
00456 
00466 u_int8_t nfct_get_attr_u8(const struct nf_conntrack *ct,
00467                           const enum nf_conntrack_attr type)
00468 {
00469         const u_int8_t *ret = nfct_get_attr(ct, type);
00470         return ret == NULL ? 0 : *ret;
00471 }
00472 
00482 u_int16_t nfct_get_attr_u16(const struct nf_conntrack *ct,
00483                             const enum nf_conntrack_attr type)
00484 {
00485         const u_int16_t *ret = nfct_get_attr(ct, type);
00486         return ret == NULL ? 0 : *ret;
00487 }
00488 
00498 u_int32_t nfct_get_attr_u32(const struct nf_conntrack *ct,
00499                             const enum nf_conntrack_attr type)
00500 {
00501         const u_int32_t *ret = nfct_get_attr(ct, type);
00502         return ret == NULL ? 0 : *ret;
00503 }
00504 
00514 u_int64_t nfct_get_attr_u64(const struct nf_conntrack *ct,
00515                             const enum nf_conntrack_attr type)
00516 {
00517         const u_int64_t *ret = nfct_get_attr(ct, type);
00518         return ret == NULL ? 0 : *ret;
00519 }
00520 
00529 int nfct_attr_is_set(const struct nf_conntrack *ct,
00530                      const enum nf_conntrack_attr type)
00531 {
00532         assert(ct != NULL);
00533 
00534         if (unlikely(type >= ATTR_MAX)) {
00535                 errno = EINVAL;
00536                 return -1;
00537         }
00538         return test_bit(type, ct->set);
00539 }
00540 
00550 int nfct_attr_is_set_array(const struct nf_conntrack *ct,
00551                            const enum nf_conntrack_attr *type_array,
00552                            int size)
00553 {
00554         int i;
00555 
00556         assert(ct != NULL);
00557 
00558         for (i=0; i<size; i++) {
00559                 if (unlikely(type_array[i] >= ATTR_MAX)) {
00560                         errno = EINVAL;
00561                         return -1;
00562                 }
00563                 if (!test_bit(type_array[i], ct->set))
00564                         return 0;
00565         }
00566         return 1;
00567 }
00568 
00577 int nfct_attr_unset(struct nf_conntrack *ct,
00578                     const enum nf_conntrack_attr type)
00579 {
00580         assert(ct != NULL);
00581 
00582         if (unlikely(type >= ATTR_MAX)) {
00583                 errno = EINVAL;
00584                 return -1;
00585         }
00586         unset_bit(type, ct->set);
00587 
00588         return 0;
00589 }
00590 
00600 void nfct_set_attr_grp(struct nf_conntrack *ct,
00601                        const enum nf_conntrack_attr_grp type,
00602                        const void *data)
00603 {
00604         assert(ct != NULL);
00605 
00606         if (unlikely(type >= ATTR_GRP_MAX))
00607                 return;
00608 
00609         if (set_attr_grp_array[type]) {
00610                 set_attr_grp_array[type](ct, data);
00611                 set_bitmask_u32(ct->set, attr_grp_bitmask[type], __NFCT_BITSET);
00612         }
00613 }
00614 
00624 int nfct_get_attr_grp(const struct nf_conntrack *ct,
00625                       const enum nf_conntrack_attr_grp type,
00626                       void *data)
00627 {
00628         assert(ct != NULL);
00629 
00630         if (unlikely(type >= ATTR_GRP_MAX)) {
00631                 errno = EINVAL;
00632                 return -1;
00633         }
00634         if (!test_bitmask_u32(ct->set, attr_grp_bitmask[type], __NFCT_BITSET)) {
00635                 errno = ENODATA;
00636                 return -1;
00637         }
00638         assert(get_attr_grp_array[type]);
00639         get_attr_grp_array[type](ct, data);
00640         return 0;
00641 }
00642 
00650 int nfct_attr_grp_is_set(const struct nf_conntrack *ct,
00651                          const enum nf_conntrack_attr_grp type)
00652 {
00653         assert(ct != NULL);
00654 
00655         if (unlikely(type >= ATTR_GRP_MAX)) {
00656                 errno = EINVAL;
00657                 return -1;
00658         }
00659         return test_bitmask_u32(ct->set, attr_grp_bitmask[type], __NFCT_BITSET);
00660 }
00661 
00670 int nfct_attr_grp_unset(struct nf_conntrack *ct,
00671                         const enum nf_conntrack_attr_grp type)
00672 {
00673         assert(ct != NULL);
00674 
00675         if (unlikely(type >= ATTR_GRP_MAX)) {
00676                 errno = EINVAL;
00677                 return -1;
00678         }
00679         unset_bitmask_u32(ct->set, attr_grp_bitmask[type], __NFCT_BITSET);
00680 
00681         return 0;
00682 }
00683 
00709 int nfct_build_conntrack(struct nfnl_subsys_handle *ssh,
00710                          void *req,
00711                          size_t size,
00712                          u_int16_t type,
00713                          u_int16_t flags,
00714                          const struct nf_conntrack *ct)
00715 {
00716         assert(ssh != NULL);
00717         assert(req != NULL);
00718         assert(ct != NULL);
00719 
00720         return __build_conntrack(ssh, req, size, type, flags, ct);
00721 }
00722 
00757 int nfct_build_query(struct nfnl_subsys_handle *ssh,
00758                      const enum nf_conntrack_query qt,
00759                      const void *data,
00760                      void *buffer,
00761                      unsigned int size)
00762 {
00763         struct nfnlhdr *req = buffer;
00764         const u_int32_t *family = data;
00765 
00766         assert(ssh != NULL);
00767         assert(data != NULL);
00768         assert(req != NULL);
00769 
00770         memset(req, 0, size);
00771 
00772         switch(qt) {
00773         case NFCT_Q_CREATE:
00774                 nfct_build_conntrack(ssh, req, size, IPCTNL_MSG_CT_NEW, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK|NLM_F_EXCL, data);
00775                 break;
00776         case NFCT_Q_UPDATE:
00777                 nfct_build_conntrack(ssh, req, size, IPCTNL_MSG_CT_NEW, NLM_F_REQUEST|NLM_F_ACK, data);
00778                 break;
00779         case NFCT_Q_DESTROY:
00780                 nfct_build_conntrack(ssh, req, size, IPCTNL_MSG_CT_DELETE, NLM_F_REQUEST|NLM_F_ACK, data);
00781                 break;
00782         case NFCT_Q_GET:
00783                 nfct_build_conntrack(ssh, req, size, IPCTNL_MSG_CT_GET, NLM_F_REQUEST|NLM_F_ACK, data);
00784                 break;
00785         case NFCT_Q_FLUSH:
00786                 nfnl_fill_hdr(ssh, &req->nlh, 0, *family, 0, IPCTNL_MSG_CT_DELETE, NLM_F_REQUEST|NLM_F_ACK);
00787                 break;
00788         case NFCT_Q_DUMP:
00789                 nfnl_fill_hdr(ssh, &req->nlh, 0, *family, 0, IPCTNL_MSG_CT_GET, NLM_F_REQUEST|NLM_F_DUMP);
00790                 break;
00791         case NFCT_Q_DUMP_RESET:
00792                 nfnl_fill_hdr(ssh, &req->nlh, 0, *family, 0, IPCTNL_MSG_CT_GET_CTRZERO, NLM_F_REQUEST|NLM_F_DUMP);
00793                 break;
00794         case NFCT_Q_CREATE_UPDATE:
00795                 nfct_build_conntrack(ssh, req, size, IPCTNL_MSG_CT_NEW, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK, data);
00796                 break;
00797 
00798         default:
00799                 errno = ENOTSUP;
00800                 return -1;
00801         }
00802         return 1;
00803 }
00804 
00829 int nfct_parse_conntrack(enum nf_conntrack_msg_type type,
00830                          const struct nlmsghdr *nlh,
00831                          struct nf_conntrack *ct)
00832 {
00833         unsigned int flags;
00834         int len = nlh->nlmsg_len;
00835         struct nfgenmsg *nfhdr = NLMSG_DATA(nlh);
00836         struct nfattr *cda[CTA_MAX];
00837 
00838         assert(nlh != NULL);
00839         assert(ct != NULL);
00840 
00841         len -= NLMSG_LENGTH(sizeof(struct nfgenmsg));
00842         if (len < 0) {
00843                 errno = EINVAL;
00844                 return NFCT_T_ERROR;
00845         }
00846 
00847         flags = __parse_message_type(nlh);
00848         if (!(flags & type))
00849                 return 0;
00850 
00851         nfnl_parse_attr(cda, CTA_MAX, NFA_DATA(nfhdr), len);
00852 
00853         __parse_conntrack(nlh, cda, ct);
00854 
00855         return flags;
00856 }
00857 
00876 int nfct_query(struct nfct_handle *h,
00877                const enum nf_conntrack_query qt,
00878                const void *data)
00879 {
00880         size_t size = 4096;     /* enough for now */
00881         union {
00882                 char buffer[size];
00883                 struct nfnlhdr req;
00884         } u;
00885 
00886         assert(h != NULL);
00887         assert(data != NULL);
00888 
00889         if (nfct_build_query(h->nfnlssh_ct, qt, data, &u.req, size) == -1)
00890                 return -1;
00891 
00892         return nfnl_query(h->nfnlh, &u.req.nlh);
00893 }
00894 
00908 int nfct_send(struct nfct_handle *h,
00909               const enum nf_conntrack_query qt,
00910               const void *data)
00911 {
00912         size_t size = 4096;     /* enough for now */
00913         union {
00914                 char buffer[size];
00915                 struct nfnlhdr req;
00916         } u;
00917 
00918         assert(h != NULL);
00919         assert(data != NULL);
00920 
00921         if (nfct_build_query(h->nfnlssh_ct, qt, data, &u.req, size) == -1)
00922                 return -1;
00923 
00924         return nfnl_send(h->nfnlh, &u.req.nlh);
00925 }
00926 
00927 
00936 int nfct_catch(struct nfct_handle *h)
00937 {
00938         assert(h != NULL);
00939 
00940         return nfnl_catch(h->nfnlh);
00941 }
00942 
00979 int nfct_snprintf(char *buf,
00980                   unsigned int size,
00981                   const struct nf_conntrack *ct,
00982                   unsigned int msg_type,
00983                   unsigned int out_type,
00984                   unsigned int flags) 
00985 {
00986         assert(buf != NULL);
00987         assert(size > 0);
00988         assert(ct != NULL);
00989 
00990         return __snprintf_conntrack(buf, size, ct, msg_type, out_type, flags);
00991 }
00992 
01011 int nfct_compare(const struct nf_conntrack *ct1, 
01012                  const struct nf_conntrack *ct2)
01013 {
01014         assert(ct1 != NULL);
01015         assert(ct2 != NULL);
01016 
01017         return __compare(ct1, ct2, NFCT_CMP_ALL);
01018 }
01019 
01057 int nfct_cmp(const struct nf_conntrack *ct1, 
01058              const struct nf_conntrack *ct2,
01059              unsigned int flags)
01060 {
01061         assert(ct1 != NULL);
01062         assert(ct2 != NULL);
01063 
01064         return __compare(ct1, ct2, flags);
01065 }
01066 
01089 void nfct_copy(struct nf_conntrack *ct1,
01090                const struct nf_conntrack *ct2,
01091                unsigned int flags)
01092 {
01093         int i;
01094 
01095         assert(ct1 != NULL);
01096         assert(ct2 != NULL);
01097 
01098         if (flags == NFCT_CP_ALL) {
01099                 for (i=0; i<ATTR_MAX; i++) {
01100                         if (test_bit(i, ct2->set)) {
01101                                 assert(copy_attr_array[i]);
01102                                 copy_attr_array[i](ct1, ct2);
01103                                 set_bit(i, ct1->set);
01104                         }
01105                 }
01106                 return;
01107         }
01108 
01109         static const int cp_orig_mask[] = {
01110                 ATTR_ORIG_IPV4_SRC,
01111                 ATTR_ORIG_IPV4_DST,
01112                 ATTR_ORIG_IPV6_SRC,
01113                 ATTR_ORIG_IPV6_DST,
01114                 ATTR_ORIG_PORT_SRC,
01115                 ATTR_ORIG_PORT_DST,
01116                 ATTR_ICMP_TYPE,
01117                 ATTR_ICMP_CODE,
01118                 ATTR_ICMP_ID,
01119                 ATTR_ORIG_L3PROTO,
01120                 ATTR_ORIG_L4PROTO,
01121         };
01122         #define __CP_ORIG_MAX sizeof(cp_orig_mask)/sizeof(int)
01123 
01124         if (flags & NFCT_CP_ORIG) {
01125                 for (i=0; i<__CP_ORIG_MAX; i++) {
01126                         if (test_bit(cp_orig_mask[i], ct2->set)) {
01127                                 assert(copy_attr_array[i]);
01128                                 copy_attr_array[cp_orig_mask[i]](ct1, ct2);
01129                                 set_bit(cp_orig_mask[i], ct1->set);
01130                         }
01131                 }
01132         }
01133 
01134         static const int cp_repl_mask[] = {
01135                 ATTR_REPL_IPV4_SRC,
01136                 ATTR_REPL_IPV4_DST,
01137                 ATTR_REPL_IPV6_SRC,
01138                 ATTR_REPL_IPV6_DST,
01139                 ATTR_REPL_PORT_SRC,
01140                 ATTR_REPL_PORT_DST,
01141                 ATTR_REPL_L3PROTO,
01142                 ATTR_REPL_L4PROTO,
01143         };
01144         #define __CP_REPL_MAX sizeof(cp_repl_mask)/sizeof(int)
01145 
01146         if (flags & NFCT_CP_REPL) {
01147                 for (i=0; i<__CP_REPL_MAX; i++) {
01148                         if (test_bit(cp_repl_mask[i], ct2->set)) {
01149                                 assert(copy_attr_array[i]);
01150                                 copy_attr_array[cp_repl_mask[i]](ct1, ct2);
01151                                 set_bit(cp_repl_mask[i], ct1->set);
01152                         }
01153                 }
01154         }
01155 
01156         if (flags & NFCT_CP_META) {
01157                 for (i=ATTR_TCP_STATE; i<ATTR_MAX; i++) {
01158                         if (test_bit(i, ct2->set)) {
01159                                 assert(copy_attr_array[i]),
01160                                 copy_attr_array[i](ct1, ct2);
01161                                 set_bit(i, ct1->set);
01162                         }
01163                 }
01164         }
01165 }
01166 
01175 void nfct_copy_attr(struct nf_conntrack *ct1,
01176                     const struct nf_conntrack *ct2,
01177                     const enum nf_conntrack_attr type)
01178 {
01179         if (test_bit(type, ct2->set)) {
01180                 assert(copy_attr_array[type]);
01181                 copy_attr_array[type](ct1, ct2);
01182                 set_bit(type, ct1->set);
01183         }
01184 }
01185 
01202 struct nfct_filter *nfct_filter_create(void)
01203 {
01204         return calloc(sizeof(struct nfct_filter), 1);
01205 }
01206 
01215 void nfct_filter_destroy(struct nfct_filter *filter)
01216 {
01217         assert(filter != NULL);
01218         free(filter);
01219         filter = NULL;
01220 }
01221 
01231 void nfct_filter_add_attr(struct nfct_filter *filter,
01232                           const enum nfct_filter_attr type, 
01233                           const void *value)
01234 {
01235         assert(filter != NULL);
01236         assert(value != NULL);
01237 
01238         if (unlikely(type >= NFCT_FILTER_MAX))
01239                 return;
01240 
01241         if (filter_attr_array[type]) {
01242                 filter_attr_array[type](filter, value);
01243                 set_bit(type, filter->set);
01244         }
01245 }
01246 
01255 void nfct_filter_add_attr_u32(struct nfct_filter *filter,
01256                               const enum nfct_filter_attr type,
01257                               u_int32_t value)
01258 {
01259         nfct_filter_add_attr(filter, type, &value);
01260 }
01261 
01277 int nfct_filter_set_logic(struct nfct_filter *filter,
01278                           const enum nfct_filter_attr type,
01279                           const enum nfct_filter_logic logic)
01280 {
01281         if (unlikely(type >= NFCT_FILTER_MAX)) {
01282                 errno = ENOTSUP;
01283                 return -1;
01284         }
01285 
01286         if (filter->logic[type]) {
01287                 errno = EBUSY;
01288                 return -1;
01289         }
01290 
01291         filter->logic[type] = logic;
01292 
01293         return 0;
01294 }
01295 
01305 int nfct_filter_attach(int fd, struct nfct_filter *filter)
01306 {
01307         assert(filter != NULL);
01308 
01309         return __setup_netlink_socket_filter(fd, filter);
01310 }
01311 
01318 int nfct_filter_detach(int fd)
01319 {
01320         int val = 0;
01321 
01322         return setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, &val, sizeof(val));
01323 }
01324 

Generated on Wed Jan 26 2011 23:11:37 for libnetfilter_conntrack by  doxygen 1.7.1