summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.in2
-rw-r--r--extensions/libnetfilter_conntrack_icmp.c24
-rw-r--r--extensions/libnetfilter_conntrack_sctp.c32
-rw-r--r--extensions/libnetfilter_conntrack_tcp.c31
-rw-r--r--extensions/libnetfilter_conntrack_udp.c32
-rw-r--r--include/libnetfilter_conntrack/Makefile.am2
-rw-r--r--include/libnetfilter_conntrack/libnetfilter_conntrack.h23
-rw-r--r--include/libnetfilter_conntrack/libnetfilter_conntrack_extensions.h2
-rw-r--r--include/libnetfilter_conntrack/libnetfilter_conntrack_icmp.h22
-rw-r--r--include/libnetfilter_conntrack/libnetfilter_conntrack_sctp.h34
-rw-r--r--include/libnetfilter_conntrack/libnetfilter_conntrack_tcp.h34
-rw-r--r--include/libnetfilter_conntrack/libnetfilter_conntrack_udp.h34
-rw-r--r--src/libnetfilter_conntrack.c61
-rw-r--r--utils/ctnl_test.c5
14 files changed, 318 insertions, 20 deletions
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 <libnetfilter_conntrack/linux_nfnetlink_conntrack.h>
#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
#include <libnetfilter_conntrack/libnetfilter_conntrack_extensions.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack_icmp.h>
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 <libnetfilter_conntrack/linux_nfnetlink_conntrack.h>
#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
#include <libnetfilter_conntrack/libnetfilter_conntrack_extensions.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack_sctp.h>
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 <libnetfilter_conntrack/linux_nfnetlink_conntrack.h>
#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
#include <libnetfilter_conntrack/libnetfilter_conntrack_extensions.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack_tcp.h>
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 <libnetfilter_conntrack/linux_nfnetlink_conntrack.h>
#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
#include <libnetfilter_conntrack/libnetfilter_conntrack_extensions.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack_udp.h>
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 <pablo@eurodev.net>
+ *
+ * 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 <pablo@eurodev.net>
+ *
+ * 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 <pablo@eurodev.net>
+ *
+ * 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 <pablo@eurodev.net>
+ *
+ * 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 <stdio.h>
+#include <unistd.h>
#include <getopt.h>
#include <dlfcn.h>
#include <stdlib.h>
@@ -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);