From 563114a47ae03c988ca0e66eddda33d485e35f6b Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 17 Jul 2008 17:20:10 +0200 Subject: add berkeley socket filtering high-level API This patch adds an abstraction level to berkeley sockets filter (BSF) for Netlink sockets available since Linux kernel 2.6.26. This provides an easy way to attach filters without knowing about BSF at all. Signed-off-by: Pablo Neira Ayuso --- utils/Makefile.am | 6 +++- utils/conntrack_filter.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 utils/conntrack_filter.c (limited to 'utils') diff --git a/utils/Makefile.am b/utils/Makefile.am index bdf3833..b0797ae 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -5,7 +5,7 @@ check_PROGRAMS = expect_dump expect_create expect_get expect_delete \ conntrack_create conntrack_dump conntrack_update \ conntrack_delete conntrack_flush conntrack_create_nat \ conntrack_get conntrack_events \ - conntrack_master + conntrack_master conntrack_filter conntrack_create_SOURCES = conntrack_create.c conntrack_create_LDADD = ../src/libnetfilter_conntrack.la @@ -39,6 +39,10 @@ conntrack_events_SOURCES = conntrack_events.c conntrack_events_LDADD = ../src/libnetfilter_conntrack.la conntrack_events_LDFLAGS = -dynamic -ldl +conntrack_filter_SOURCES = conntrack_filter.c +conntrack_filter_LDADD = ../src/libnetfilter_conntrack.la +conntrack_filter_LDFLAGS = -dynamic -ldl + conntrack_master_SOURCES = conntrack_master.c conntrack_master_LDADD = ../src/libnetfilter_conntrack.la conntrack_master_LDFLAGS = -dynamic -ldl diff --git a/utils/conntrack_filter.c b/utils/conntrack_filter.c new file mode 100644 index 0000000..7d22950 --- /dev/null +++ b/utils/conntrack_filter.c @@ -0,0 +1,83 @@ +#include +#include +#include + +#include +#include + +static int event_cb(enum nf_conntrack_msg_type type, + struct nf_conntrack *ct, + void *data) +{ + static int n = 0; + char buf[1024]; + + nfct_snprintf(buf, 1024, ct, type, NFCT_O_PLAIN, NFCT_OF_TIME); + printf("%s\n", buf); + + if (++n == 10) + return NFCT_CB_STOP; + + return NFCT_CB_CONTINUE; +} + +int main() +{ + int ret; + u_int8_t family = AF_INET; + struct nfct_handle *h; + struct nfct_filter *filter; + struct nf_conntrack *ct; + char buf[1024]; + + h = nfct_open(CONNTRACK, NF_NETLINK_CONNTRACK_NEW | + NF_NETLINK_CONNTRACK_UPDATE); + if (!h) { + perror("nfct_open"); + return 0; + } + + filter = nfct_filter_create(); + if (!filter) { + perror("nfct_create_filter"); + return 0; + } + + nfct_filter_add_attr_u32(filter, NFCT_FILTER_L4PROTO, IPPROTO_UDP); + nfct_filter_add_attr_u32(filter, NFCT_FILTER_L4PROTO, IPPROTO_TCP); + + struct nfct_filter_proto filter_proto = { + .proto = IPPROTO_TCP, + .state = TCP_CONNTRACK_ESTABLISHED + }; + + nfct_filter_add_attr(filter, NFCT_FILTER_L4PROTO_STATE, &filter_proto); + + struct nfct_filter_ipv4 filter_ipv4 = { + .addr = htonl(inet_addr("127.0.0.1")), + .mask = 0xffffffff, + }; + + nfct_filter_add_attr(filter, NFCT_FILTER_SRC_IPV4, &filter_ipv4); + + if (nfct_filter_attach(nfct_fd(h), filter) == -1) { + perror("nfct_filter_attach"); + return 0; + } + + /* release the filter object, this does not detach the filter */ + nfct_filter_destroy(filter); + + nfct_callback_register(h, NFCT_T_ALL, event_cb, NULL); + + printf("TEST: waiting for 10 events...\n"); + + ret = nfct_catch(h); + + printf("TEST: OK (%d)(%s)\n", ret, strerror(errno)); + + if (ret == -1) + exit(EXIT_FAILURE); + + nfct_close(h); +} -- cgit v1.2.3