summaryrefslogtreecommitdiffstats
path: root/src/conntrack
diff options
context:
space:
mode:
Diffstat (limited to 'src/conntrack')
-rw-r--r--src/conntrack/Makefile.am2
-rw-r--r--src/conntrack/api.c36
-rw-r--r--src/conntrack/bsf.c30
-rw-r--r--src/conntrack/callback.c55
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;
-}