diff options
Diffstat (limited to 'src/conntrack')
-rw-r--r-- | src/conntrack/Makefile.am | 2 | ||||
-rw-r--r-- | src/conntrack/api.c | 36 | ||||
-rw-r--r-- | src/conntrack/bsf.c | 30 | ||||
-rw-r--r-- | src/conntrack/callback.c | 55 |
4 files changed, 49 insertions, 74 deletions
diff --git a/src/conntrack/Makefile.am b/src/conntrack/Makefile.am index 68c2d72..34afefb 100644 --- a/src/conntrack/Makefile.am +++ b/src/conntrack/Makefile.am @@ -4,7 +4,7 @@ AM_CFLAGS = -Wall ${LIBNFNETLINK_CFLAGS} noinst_LTLIBRARIES = libnfconntrack.la -libnfconntrack_la_SOURCES = api.c callback.c \ +libnfconntrack_la_SOURCES = api.c \ getter.c setter.c \ parse.c build.c \ snprintf.c \ diff --git a/src/conntrack/api.c b/src/conntrack/api.c index d7f16fe..825afba 100644 --- a/src/conntrack/api.c +++ b/src/conntrack/api.c @@ -226,17 +226,17 @@ int nfct_callback_register(struct nfct_handle *h, container->type = type; container->data = data; - h->nfnl_cb.call = __callback; - h->nfnl_cb.data = container; - h->nfnl_cb.attr_count = CTA_MAX; + h->nfnl_cb_ct.call = __callback; + h->nfnl_cb_ct.data = container; + h->nfnl_cb_ct.attr_count = CTA_MAX; nfnl_callback_register(h->nfnlssh_ct, IPCTNL_MSG_CT_NEW, - &h->nfnl_cb); + &h->nfnl_cb_ct); nfnl_callback_register(h->nfnlssh_ct, IPCTNL_MSG_CT_DELETE, - &h->nfnl_cb); + &h->nfnl_cb_ct); return 0; } @@ -253,11 +253,11 @@ void nfct_callback_unregister(struct nfct_handle *h) nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_DELETE); h->cb = NULL; - free(h->nfnl_cb.data); + free(h->nfnl_cb_ct.data); - h->nfnl_cb.call = NULL; - h->nfnl_cb.data = NULL; - h->nfnl_cb.attr_count = 0; + h->nfnl_cb_ct.call = NULL; + h->nfnl_cb_ct.data = NULL; + h->nfnl_cb_ct.attr_count = 0; } /** @@ -300,17 +300,17 @@ int nfct_callback_register2(struct nfct_handle *h, container->type = type; container->data = data; - h->nfnl_cb.call = __callback; - h->nfnl_cb.data = container; - h->nfnl_cb.attr_count = CTA_MAX; + h->nfnl_cb_ct.call = __callback; + h->nfnl_cb_ct.data = container; + h->nfnl_cb_ct.attr_count = CTA_MAX; nfnl_callback_register(h->nfnlssh_ct, IPCTNL_MSG_CT_NEW, - &h->nfnl_cb); + &h->nfnl_cb_ct); nfnl_callback_register(h->nfnlssh_ct, IPCTNL_MSG_CT_DELETE, - &h->nfnl_cb); + &h->nfnl_cb_ct); return 0; } @@ -327,11 +327,11 @@ void nfct_callback_unregister2(struct nfct_handle *h) nfnl_callback_unregister(h->nfnlssh_ct, IPCTNL_MSG_CT_DELETE); h->cb2 = NULL; - free(h->nfnl_cb.data); + free(h->nfnl_cb_ct.data); - h->nfnl_cb.call = NULL; - h->nfnl_cb.data = NULL; - h->nfnl_cb.attr_count = 0; + h->nfnl_cb_ct.call = NULL; + h->nfnl_cb_ct.data = NULL; + h->nfnl_cb_ct.attr_count = 0; } /** diff --git a/src/conntrack/bsf.c b/src/conntrack/bsf.c index 69a7f14..ae7fa4a 100644 --- a/src/conntrack/bsf.c +++ b/src/conntrack/bsf.c @@ -8,6 +8,7 @@ #include "internal/internal.h" #include "internal/stack.h" #include <linux/filter.h> +#include <stddef.h> /* offsetof */ #ifndef SKF_AD_NLATTR #define SKF_AD_NLATTR 12 @@ -214,6 +215,33 @@ nfct_bsf_jump_to(struct sock_filter *this, int line, int pos) return NEW_POS(__code); }; +/* this helps to skip messages coming from the ctnetlink expectation subsys. */ +static int +bsf_cmp_subsys(struct sock_filter *this, int pos, u_int8_t subsys) +{ + struct sock_filter __code[] = { + [0] = { + /* X = offset to nlh->nlmsg_type */ + .code = BPF_LDX|BPF_IMM, + .k = offsetof(struct nlmsghdr, nlmsg_type), + }, + [1] = { + /* A = skb->data[X+k:B] (subsys_id) */ + .code = BPF_LD|BPF_B|BPF_IND, + .k = sizeof(u_int8_t), + }, + [2] = { + /* A == subsys ? jump +1 : accept */ + .code = BPF_JMP|BPF_JEQ|BPF_K, + .k = subsys, + .jt = 1, + .jf = 0, + }, + }; + memcpy(&this[pos], &__code, sizeof(__code)); + return NEW_POS(__code); +} + static int add_state_filter_cta(struct sock_filter *this, unsigned int cta_protoinfo_proto, @@ -584,6 +612,8 @@ int __setup_netlink_socket_filter(int fd, struct nfct_filter *f) memset(bsf, 0, sizeof(bsf)); + j += bsf_cmp_subsys(&bsf[j], j, NFNL_SUBSYS_CTNETLINK); + j += nfct_bsf_ret_verdict(bsf, NFCT_FILTER_ACCEPT, j); j += bsf_add_proto_filter(f, &bsf[j]); j += bsf_add_saddr_ipv4_filter(f, &bsf[j]); j += bsf_add_daddr_ipv4_filter(f, &bsf[j]); diff --git a/src/conntrack/callback.c b/src/conntrack/callback.c deleted file mode 100644 index c83a564..0000000 --- a/src/conntrack/callback.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * (C) 2006 by Pablo Neira Ayuso <pablo@netfilter.org> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - */ - -#include "internal/internal.h" - -int __callback(struct nlmsghdr *nlh, struct nfattr *nfa[], void *data) -{ - int ret = NFNL_CB_STOP; - unsigned int type; - struct nf_conntrack *ct; - int len = nlh->nlmsg_len; - struct __data_container *container = data; - - len -= NLMSG_LENGTH(sizeof(struct nfgenmsg)); - if (len < 0) - return NFNL_CB_CONTINUE; - - type = __parse_message_type(nlh); - if (!(type & container->type)) - return NFNL_CB_CONTINUE; - - ct = nfct_new(); - if (!ct) - return NFNL_CB_CONTINUE; - - __parse_conntrack(nlh, nfa, ct); - - if (container->h->cb) - ret = container->h->cb(type, ct, container->data); - else if (container->h->cb2) - ret = container->h->cb2(nlh, type, ct, container->data); - - switch(ret) { - case NFCT_CB_FAILURE: - free(ct); - ret = NFNL_CB_FAILURE; - break; - case NFCT_CB_STOP: - free(ct); - ret = NFNL_CB_STOP; - break; - case NFCT_CB_CONTINUE: - free(ct); - ret = NFNL_CB_CONTINUE; - break; - case NFCT_CB_STOLEN: - ret = NFNL_CB_CONTINUE; - break; - } - return ret; -} |