From 25b2d74cebc9680dde4028f2f50aec396b29559e Mon Sep 17 00:00:00 2001 From: "/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=pablo/emailAddress=pablo@netfilter.org" Date: Sat, 3 Dec 2005 22:50:27 +0000 Subject: o Fixed bugs in UDP and SCTP protocol handlers (parse_proto) o Added the comparison infrastructure for layer-4 protocols o Added libnetfilter_conntrack_[tcp|udp|icmp|sctp].h that contains the protocol flags used by the comparison infrastructure o Added nfct_conntrack_compare to compare two conntracks based on flags o Killed nfct_event_netlink_handler o nfct_event_[conntrack|expect] requires ROOT privileges (reason: netlink multicast) o Bumped version to 0.29 --- configure.in | 2 +- extensions/libnetfilter_conntrack_icmp.c | 24 +++++++++ extensions/libnetfilter_conntrack_sctp.c | 32 +++++++++++- extensions/libnetfilter_conntrack_tcp.c | 31 +++++++++++ extensions/libnetfilter_conntrack_udp.c | 32 +++++++++++- include/libnetfilter_conntrack/Makefile.am | 2 +- .../libnetfilter_conntrack.h | 23 ++++++-- .../libnetfilter_conntrack_extensions.h | 2 + .../libnetfilter_conntrack_icmp.h | 22 ++++++++ .../libnetfilter_conntrack_sctp.h | 34 ++++++++++++ .../libnetfilter_conntrack_tcp.h | 34 ++++++++++++ .../libnetfilter_conntrack_udp.h | 34 ++++++++++++ src/libnetfilter_conntrack.c | 61 ++++++++++++++++++---- utils/ctnl_test.c | 5 ++ 14 files changed, 318 insertions(+), 20 deletions(-) create mode 100644 include/libnetfilter_conntrack/libnetfilter_conntrack_icmp.h create mode 100644 include/libnetfilter_conntrack/libnetfilter_conntrack_sctp.h create mode 100644 include/libnetfilter_conntrack/libnetfilter_conntrack_tcp.h create mode 100644 include/libnetfilter_conntrack/libnetfilter_conntrack_udp.h diff --git a/configure.in b/configure.in index be2d882..b269bec 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ AC_INIT AC_CANONICAL_SYSTEM -AM_INIT_AUTOMAKE(libnetfilter_conntrack, 0.0.28) +AM_INIT_AUTOMAKE(libnetfilter_conntrack, 0.0.29) AC_PROG_CC AM_PROG_LIBTOOL diff --git a/extensions/libnetfilter_conntrack_icmp.c b/extensions/libnetfilter_conntrack_icmp.c index a6cfe77..a69f43d 100644 --- a/extensions/libnetfilter_conntrack_icmp.c +++ b/extensions/libnetfilter_conntrack_icmp.c @@ -15,6 +15,7 @@ #include #include #include +#include static void parse_proto(struct nfattr *cda[], struct nfct_tuple *tuple) { @@ -51,12 +52,35 @@ static int print_proto(char *buf, struct nfct_tuple *t) ntohs(t->l4src.icmp.id))); } +static int compare(struct nfct_conntrack *ct1, + struct nfct_conntrack *ct2, + unsigned int flags) +{ + int ret = 1; + + if (flags & ICMP_TYPE) + if (ct1->tuple[NFCT_DIR_ORIGINAL].l4dst.icmp.type != + ct2->tuple[NFCT_DIR_ORIGINAL].l4dst.icmp.type) + ret = 0; + if (flags & ICMP_CODE) + if (ct1->tuple[NFCT_DIR_ORIGINAL].l4dst.icmp.code != + ct2->tuple[NFCT_DIR_ORIGINAL].l4dst.icmp.code) + ret = 0; + if (flags & ICMP_ID) + if (ct1->tuple[NFCT_DIR_REPLY].l4src.icmp.id != + ct2->tuple[NFCT_DIR_REPLY].l4src.icmp.id) + ret = 0; + + return ret; +} + static struct nfct_proto icmp = { .name = "icmp", .protonum = IPPROTO_ICMP, .parse_proto = parse_proto, .build_tuple_proto = build_tuple_proto, .print_proto = print_proto, + .compare = compare, .version = VERSION }; diff --git a/extensions/libnetfilter_conntrack_sctp.c b/extensions/libnetfilter_conntrack_sctp.c index 81a2467..aa06f6d 100644 --- a/extensions/libnetfilter_conntrack_sctp.c +++ b/extensions/libnetfilter_conntrack_sctp.c @@ -15,6 +15,7 @@ #include #include #include +#include static void parse_proto(struct nfattr *cda[], struct nfct_tuple *tuple) { @@ -38,9 +39,9 @@ static void build_tuple_proto(struct nfnlhdr *req, int size, struct nfct_tuple *t) { nfnl_addattr_l(&req->nlh, size, CTA_PROTO_SRC_PORT, - &t->l4src.tcp.port, sizeof(u_int16_t)); + &t->l4src.sctp.port, sizeof(u_int16_t)); nfnl_addattr_l(&req->nlh, size, CTA_PROTO_DST_PORT, - &t->l4dst.tcp.port, sizeof(u_int16_t)); + &t->l4dst.sctp.port, sizeof(u_int16_t)); } static int print_protoinfo(char *buf, union nfct_protoinfo *protoinfo) @@ -55,6 +56,32 @@ static int print_proto(char *buf, struct nfct_tuple *tuple) htons(tuple->l4dst.sctp.port))); } +static int compare(struct nfct_conntrack *ct1, + struct nfct_conntrack *ct2, + unsigned int flags) +{ + int ret = 1; + + if (flags & SCTP_ORIG_SPORT) + if (ct1->tuple[NFCT_DIR_ORIGINAL].l4src.sctp.port != + ct2->tuple[NFCT_DIR_ORIGINAL].l4src.sctp.port) + ret = 0; + if (flags & SCTP_ORIG_DPORT) + if (ct1->tuple[NFCT_DIR_ORIGINAL].l4dst.sctp.port != + ct2->tuple[NFCT_DIR_ORIGINAL].l4dst.sctp.port) + ret = 0; + if (flags & SCTP_REPL_SPORT) + if (ct1->tuple[NFCT_DIR_REPLY].l4src.sctp.port != + ct2->tuple[NFCT_DIR_REPLY].l4src.sctp.port) + ret = 0; + if (flags & SCTP_REPL_DPORT) + if (ct1->tuple[NFCT_DIR_REPLY].l4dst.sctp.port != + ct2->tuple[NFCT_DIR_REPLY].l4dst.sctp.port) + ret = 0; + + return ret; +} + static struct nfct_proto sctp = { .name = "sctp", .protonum = IPPROTO_SCTP, @@ -63,6 +90,7 @@ static struct nfct_proto sctp = { .build_tuple_proto = build_tuple_proto, .print_proto = print_proto, .print_protoinfo = print_protoinfo, + .compare = compare, .version = VERSION }; diff --git a/extensions/libnetfilter_conntrack_tcp.c b/extensions/libnetfilter_conntrack_tcp.c index 95503ec..dc50315 100644 --- a/extensions/libnetfilter_conntrack_tcp.c +++ b/extensions/libnetfilter_conntrack_tcp.c @@ -15,6 +15,7 @@ #include #include #include +#include static const char *states[] = { "NONE", @@ -93,6 +94,35 @@ static int print_proto(char *buf, struct nfct_tuple *tuple) htons(tuple->l4dst.tcp.port))); } +static int compare(struct nfct_conntrack *ct1, + struct nfct_conntrack *ct2, + unsigned int flags) +{ + int ret = 1; + + if (flags & TCP_ORIG_SPORT) + if (ct1->tuple[NFCT_DIR_ORIGINAL].l4src.tcp.port != + ct2->tuple[NFCT_DIR_ORIGINAL].l4src.tcp.port) + ret = 0; + if (flags & TCP_ORIG_DPORT) + if (ct1->tuple[NFCT_DIR_ORIGINAL].l4dst.tcp.port != + ct2->tuple[NFCT_DIR_ORIGINAL].l4dst.tcp.port) + ret = 0; + if (flags & TCP_REPL_SPORT) + if (ct1->tuple[NFCT_DIR_REPLY].l4src.tcp.port != + ct2->tuple[NFCT_DIR_REPLY].l4src.tcp.port) + ret = 0; + if (flags & TCP_REPL_DPORT) + if (ct1->tuple[NFCT_DIR_REPLY].l4dst.tcp.port != + ct2->tuple[NFCT_DIR_REPLY].l4dst.tcp.port) + ret = 0; + if (flags & TCP_STATE) + if (ct1->protoinfo.tcp.state != ct2->protoinfo.tcp.state) + ret = 0; + + return ret; +} + static struct nfct_proto tcp = { .name = "tcp", .protonum = IPPROTO_TCP, @@ -102,6 +132,7 @@ static struct nfct_proto tcp = { .build_protoinfo = build_protoinfo, .print_protoinfo = print_protoinfo, .print_proto = print_proto, + .compare = compare, .version = VERSION }; diff --git a/extensions/libnetfilter_conntrack_udp.c b/extensions/libnetfilter_conntrack_udp.c index 21c599a..bd33280 100644 --- a/extensions/libnetfilter_conntrack_udp.c +++ b/extensions/libnetfilter_conntrack_udp.c @@ -15,6 +15,7 @@ #include #include #include +#include static void parse_proto(struct nfattr *cda[], struct nfct_tuple *tuple) { @@ -36,9 +37,35 @@ static void build_tuple_proto(struct nfnlhdr *req, int size, struct nfct_tuple *t) { nfnl_addattr_l(&req->nlh, size, CTA_PROTO_SRC_PORT, - &t->l4src.tcp.port, sizeof(u_int16_t)); + &t->l4src.udp.port, sizeof(u_int16_t)); nfnl_addattr_l(&req->nlh, size, CTA_PROTO_DST_PORT, - &t->l4dst.tcp.port, sizeof(u_int16_t)); + &t->l4dst.udp.port, sizeof(u_int16_t)); +} + +static int compare(struct nfct_conntrack *ct1, + struct nfct_conntrack *ct2, + unsigned int flags) +{ + int ret = 1; + + if (flags & UDP_ORIG_SPORT) + if (ct1->tuple[NFCT_DIR_ORIGINAL].l4src.udp.port != + ct2->tuple[NFCT_DIR_ORIGINAL].l4src.udp.port) + ret = 0; + if (flags & UDP_ORIG_DPORT) + if (ct1->tuple[NFCT_DIR_ORIGINAL].l4dst.udp.port != + ct2->tuple[NFCT_DIR_ORIGINAL].l4dst.udp.port) + ret = 0; + if (flags & UDP_REPL_SPORT) + if (ct1->tuple[NFCT_DIR_REPLY].l4src.udp.port != + ct2->tuple[NFCT_DIR_REPLY].l4src.udp.port) + ret = 0; + if (flags & UDP_REPL_DPORT) + if (ct1->tuple[NFCT_DIR_REPLY].l4dst.udp.port != + ct2->tuple[NFCT_DIR_REPLY].l4dst.udp.port) + ret = 0; + + return ret; } static struct nfct_proto udp = { @@ -47,6 +74,7 @@ static struct nfct_proto udp = { .build_tuple_proto = build_tuple_proto, .parse_proto = parse_proto, .print_proto = print_proto, + .compare = compare, .version = VERSION, }; diff --git a/include/libnetfilter_conntrack/Makefile.am b/include/libnetfilter_conntrack/Makefile.am index da43eec..d6e11c5 100644 --- a/include/libnetfilter_conntrack/Makefile.am +++ b/include/libnetfilter_conntrack/Makefile.am @@ -1,4 +1,4 @@ -pkginclude_HEADERS = libnetfilter_conntrack.h linux_nfnetlink_conntrack.h +pkginclude_HEADERS = libnetfilter_conntrack.h linux_nfnetlink_conntrack.h libnetfilter_conntrack_tcp.h libnetfilter_conntrack_udp.h libnetfilter_conntrack_icmp.h libnetfilter_conntrack_sctp.h noinst_HEADERS = libnetfilter_conntrack_extensions.h diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h index 9fbb969..a93e246 100644 --- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h +++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h @@ -108,6 +108,11 @@ struct nfct_expect { u_int32_t id; }; +struct nfct_conntrack_compare { + struct nfct_conntrack *ct; + unsigned int flag; + unsigned int protoflag; +}; enum { NFCT_STATUS_BIT = 0, @@ -234,10 +239,12 @@ extern void nfct_unregister_callback(struct nfct_handle *cth); /* * callback displayers */ -extern int nfct_default_conntrack_display(void *arg, unsigned int, int, void *); -extern int nfct_default_conntrack_display_id(void *arg, unsigned int, int, void *); -extern int nfct_default_expect_display(void *arg, unsigned int, int, void *); -extern int nfct_default_expect_display_id(void *arg, unsigned int, int, void *); +extern int nfct_default_conntrack_display(void *, unsigned int, int, void *); +extern int nfct_default_conntrack_display_id(void *, unsigned int, int, void *); +extern int nfct_default_expect_display(void *, unsigned int, int, void *); +extern int nfct_default_expect_display_id(void *, unsigned int, int, void *); +extern int nfct_default_conntrack_event_display(void *, unsigned int, int, + void *); /* * [Create|update|get|destroy] conntracks @@ -282,6 +289,14 @@ extern int nfct_sprintf_mark(char *buf, struct nfct_conntrack *ct); extern int nfct_sprintf_use(char *buf, struct nfct_conntrack *ct); extern int nfct_sprintf_id(char *buf, u_int32_t id); +/* + * Conntrack comparison + */ +extern int nfct_conntrack_compare(struct nfct_conntrack *ct1, + struct nfct_conntrack *ct2, + unsigned int cmp_flag, + unsigned int cmp_protoflag); + /* * Expectations */ diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack_extensions.h b/include/libnetfilter_conntrack/libnetfilter_conntrack_extensions.h index 25430d7..db7828d 100644 --- a/include/libnetfilter_conntrack/libnetfilter_conntrack_extensions.h +++ b/include/libnetfilter_conntrack/libnetfilter_conntrack_extensions.h @@ -29,6 +29,8 @@ struct nfct_proto { void (*build_protoinfo)(struct nfnlhdr *, int, struct nfct_conntrack *); int (*print_protoinfo)(char *, union nfct_protoinfo *); int (*print_proto)(char *, struct nfct_tuple *); + int (*compare)(struct nfct_conntrack *, struct nfct_conntrack *, + unsigned int); }; extern void nfct_register_proto(struct nfct_proto *h); diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack_icmp.h b/include/libnetfilter_conntrack/libnetfilter_conntrack_icmp.h new file mode 100644 index 0000000..837621b --- /dev/null +++ b/include/libnetfilter_conntrack/libnetfilter_conntrack_icmp.h @@ -0,0 +1,22 @@ +/* + * (C) 2005 by Pablo Neira Ayuso + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ + +#ifndef _LIBNETFILTER_CONNTRACK_ICMP_H_ +#define _LIBNETFILTER_CONNTRACK_ICMP_H_ + +enum icmp_flags { + ICMP_TYPE_BIT = 0, + ICMP_TYPE = (1 << ICMP_TYPE_BIT), + + ICMP_CODE_BIT = 1, + ICMP_CODE = (1 << ICMP_CODE_BIT), + + ICMP_ID_BIT = 2, + ICMP_ID = (1 << ICMP_ID_BIT) +}; + +#endif diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack_sctp.h b/include/libnetfilter_conntrack/libnetfilter_conntrack_sctp.h new file mode 100644 index 0000000..366bc9c --- /dev/null +++ b/include/libnetfilter_conntrack/libnetfilter_conntrack_sctp.h @@ -0,0 +1,34 @@ +/* + * (C) 2005 by Pablo Neira Ayuso + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ + +#ifndef _LIBNETFILTER_CONNTRACK_SCTP_H_ +#define _LIBNETFILTER_CONNTRACK_SCTP_H_ + +enum sctp_flags { + SCTP_ORIG_SPORT_BIT = 0, + SCTP_ORIG_SPORT = (1 << SCTP_ORIG_SPORT_BIT), + + SCTP_ORIG_DPORT_BIT = 1, + SCTP_ORIG_DPORT = (1 << SCTP_ORIG_DPORT_BIT), + + SCTP_REPL_SPORT_BIT = 2, + SCTP_REPL_SPORT = (1 << SCTP_REPL_SPORT_BIT), + + SCTP_REPL_DPORT_BIT = 3, + SCTP_REPL_DPORT = (1 << SCTP_REPL_DPORT_BIT), + + SCTP_MASK_SPORT_BIT = 4, + SCTP_MASK_SPORT = (1 << SCTP_MASK_SPORT_BIT), + + SCTP_MASK_DPORT_BIT = 5, + SCTP_MASK_DPORT = (1 << SCTP_MASK_DPORT_BIT), + + SCTP_STATE_BIT = 6, + SCTP_STATE = (1 << SCTP_STATE_BIT) +}; + +#endif diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack_tcp.h b/include/libnetfilter_conntrack/libnetfilter_conntrack_tcp.h new file mode 100644 index 0000000..7231417 --- /dev/null +++ b/include/libnetfilter_conntrack/libnetfilter_conntrack_tcp.h @@ -0,0 +1,34 @@ +/* + * (C) 2005 by Pablo Neira Ayuso + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ + +#ifndef _LIBNETFILTER_CONNTRACK_TCP_H_ +#define _LIBNETFILTER_CONNTRACK_TCP_H_ + +enum tcp_flags { + TCP_ORIG_SPORT_BIT = 0, + TCP_ORIG_SPORT = (1 << TCP_ORIG_SPORT_BIT), + + TCP_ORIG_DPORT_BIT = 1, + TCP_ORIG_DPORT = (1 << TCP_ORIG_DPORT_BIT), + + TCP_REPL_SPORT_BIT = 2, + TCP_REPL_SPORT = (1 << TCP_REPL_SPORT_BIT), + + TCP_REPL_DPORT_BIT = 3, + TCP_REPL_DPORT = (1 << TCP_REPL_DPORT_BIT), + + TCP_MASK_SPORT_BIT = 4, + TCP_MASK_SPORT = (1 << TCP_MASK_SPORT_BIT), + + TCP_MASK_DPORT_BIT = 5, + TCP_MASK_DPORT = (1 << TCP_MASK_DPORT_BIT), + + TCP_STATE_BIT = 6, + TCP_STATE = (1 << TCP_STATE_BIT) +}; + +#endif diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack_udp.h b/include/libnetfilter_conntrack/libnetfilter_conntrack_udp.h new file mode 100644 index 0000000..895095e --- /dev/null +++ b/include/libnetfilter_conntrack/libnetfilter_conntrack_udp.h @@ -0,0 +1,34 @@ +/* + * (C) 2005 by Pablo Neira Ayuso + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ + +#ifndef _LIBNETFILTER_CONNTRACK_UDP_H_ +#define _LIBNETFILTER_CONNTRACK_UDP_H_ + +enum udp_flags { + UDP_ORIG_SPORT_BIT = 0, + UDP_ORIG_SPORT = (1 << UDP_ORIG_SPORT_BIT), + + UDP_ORIG_DPORT_BIT = 1, + UDP_ORIG_DPORT = (1 << UDP_ORIG_DPORT_BIT), + + UDP_REPL_SPORT_BIT = 2, + UDP_REPL_SPORT = (1 << UDP_REPL_SPORT_BIT), + + UDP_REPL_DPORT_BIT = 3, + UDP_REPL_DPORT = (1 << UDP_REPL_DPORT_BIT), + + UDP_MASK_SPORT_BIT = 4, + UDP_MASK_SPORT = (1 << UDP_MASK_SPORT_BIT), + + UDP_MASK_DPORT_BIT = 5, + UDP_MASK_DPORT = (1 << UDP_MASK_DPORT_BIT), + + UDP_STATE_BIT = 6, + UDP_STATE = (1 << UDP_STATE_BIT) +}; + +#endif diff --git a/src/libnetfilter_conntrack.c b/src/libnetfilter_conntrack.c index e207a7f..54dd82c 100644 --- a/src/libnetfilter_conntrack.c +++ b/src/libnetfilter_conntrack.c @@ -8,6 +8,7 @@ * (at your option) any later version. */ #include +#include #include #include #include @@ -604,6 +605,10 @@ int nfct_default_conntrack_display(void *arg, unsigned int flags, int type, { char buf[512]; int size; + struct nfct_conntrack_compare *cmp = data; + + if (cmp && !nfct_conntrack_compare(cmp->ct, arg, 0, cmp->protoflag)) + return 0; memset(buf, 0, sizeof(buf)); size = nfct_sprintf_conntrack(buf, arg, flags); @@ -618,6 +623,10 @@ int nfct_default_conntrack_display_id(void *arg, unsigned int flags, int type, { char buf[512]; int size; + struct nfct_conntrack_compare *cmp = data; + + if (cmp && !nfct_conntrack_compare(cmp->ct, arg, 0, cmp->protoflag)) + return 0; memset(buf, 0, sizeof(buf)); size = nfct_sprintf_conntrack_id(buf, arg, flags); @@ -627,6 +636,13 @@ int nfct_default_conntrack_display_id(void *arg, unsigned int flags, int type, return 0; } +int nfct_default_conntrack_event_display(void *arg, unsigned int flags, + int type, void *data) +{ + fprintf(stdout, "%9s ", msgtype[type]); + return nfct_default_conntrack_display_id(arg, flags, type, data); +} + int nfct_sprintf_expect_proto(char *buf, struct nfct_expect *exp) { return(sprintf(buf, "%u proto=%d ", exp->timeout, @@ -684,15 +700,6 @@ int nfct_default_expect_display_id(void *arg, unsigned int flags, int type, return 0; } -static int nfct_event_netlink_handler(struct nfct_handle *cth, - struct nlmsghdr *nlh, - void *arg) -{ - int type = NFNL_MSG_TYPE(nlh->nlmsg_type); - fprintf(stdout, "%9s ", msgtype[typemsg2enum(type, nlh->nlmsg_flags)]); - return nfct_conntrack_netlink_handler(cth, nlh, arg); -} - static int nfct_expect_netlink_handler(struct nfct_handle *cth, struct nlmsghdr *nlh, void *arg) { @@ -763,6 +770,28 @@ void nfct_conntrack_free(struct nfct_conntrack *ct) free(ct); } +int nfct_conntrack_compare(struct nfct_conntrack *ct1, + struct nfct_conntrack *ct2, + unsigned int cmp_flag, + unsigned int cmp_protoflag) +{ + struct nfct_proto *proto; + + if (ct1->tuple[NFCT_DIR_ORIGINAL].protonum != + ct2->tuple[NFCT_DIR_ORIGINAL].protonum) + return 0; + + /* + * TODO: implement tuple, status, mark... comparison. + */ + + proto = findproto(proto2str[ct1->tuple[NFCT_DIR_ORIGINAL].protonum]); + if (!proto) + return 0; + + return proto->compare(ct1, ct2, cmp_protoflag); +} + int nfct_create_conntrack(struct nfct_handle *cth, struct nfct_conntrack *ct) { struct nfnlhdr *req; @@ -938,7 +967,13 @@ int nfct_dump_conntrack_table_reset_counters(struct nfct_handle *cth) int nfct_event_conntrack(struct nfct_handle *cth) { - cth->handler = nfct_event_netlink_handler; + /* + * You need to be root to listen to conntrack events + */ + if (getuid() != 0) + return -EPERM; + + cth->handler = nfct_conntrack_netlink_handler; return nfnl_listen(&cth->nfnlh, &callback_handler, cth); } @@ -1092,6 +1127,12 @@ int nfct_delete_expectation(struct nfct_handle *cth,struct nfct_tuple *tuple, int nfct_event_expectation(struct nfct_handle *cth) { + /* + * You need to be root to listen to conntrack events + */ + if (getuid() != 0) + return -EPERM; + cth->handler = nfct_expect_netlink_handler; return nfnl_listen(&cth->nfnlh, &callback_handler, cth); } diff --git a/utils/ctnl_test.c b/utils/ctnl_test.c index f1361d3..e5075ef 100644 --- a/utils/ctnl_test.c +++ b/utils/ctnl_test.c @@ -90,6 +90,11 @@ int main(int argc, char **argv) if (ret < 0 && ret != -EEXIST) errors++; + if (ret == -EINVAL) + fprintf(stdout, "NFNETLINK answers: -EINVAL, make sure " + "ip_conntrack_netlink is loaded and " + "you have NET_CAPABILITIES"); + nfct_register_callback(cth, nfct_default_conntrack_display, NULL); ret = nfct_dump_conntrack_table_reset_counters(cth); fprintf(stdout, "TEST 2: dump conntrack table and reset (%d)\n", ret); -- cgit v1.2.3