[netfilter-cvslog] r4378 - in trunk/libnetfilter_conntrack: include/libnetfilter_conntrack src

pablo at netfilter.org pablo at netfilter.org
Fri Oct 21 20:21:05 CEST 2005


Author: pablo at netfilter.org
Date: 2005-10-21 20:21:03 +0200 (Fri, 21 Oct 2005)
New Revision: 4378

Modified:
   trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h
   trunk/libnetfilter_conntrack/src/libnetfilter_conntrack.c
Log:
o Bumped version to 0.1.3
o Add support for ID's
o Fixed stupid bug in NFCT_* flags, I'm stupid
o Simplify handler logic
o Define event message NFCT_MSG_*
o Add support for conntrack marking (kernelspace part still missing)



Modified: trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h
===================================================================
--- trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h	2005-10-21 02:47:07 UTC (rev 4377)
+++ trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h	2005-10-21 18:21:03 UTC (rev 4378)
@@ -17,13 +17,19 @@
 #include <linux/netfilter_ipv4/ip_conntrack.h>
 #include "linux_list.h"
 
-#define LIBNETFILTER_CONNTRACK_VERSION "0.1.2"
+#define LIBNETFILTER_CONNTRACK_VERSION "0.1.3"
 
 enum {
 	CONNTRACK = NFNL_SUBSYS_CTNETLINK,
 	EXPECT = NFNL_SUBSYS_CTNETLINK_EXP
 };
 
+/*
+ * In case that the user doesn't want to do some kind
+ * of action against a conntrack based on its ID 
+ */
+#define NFCT_ANY_ID 0
+
 union nfct_l4 {
 	/* Add other protocols here. */
 	u_int16_t all;
@@ -115,49 +121,54 @@
 
 enum {
 	NFCT_STATUS_BIT = 0,
-	NFCT_STATUS = (NFCT_STATUS_BIT << 1),
+	NFCT_STATUS = (1 << NFCT_STATUS_BIT),
 	
 	NFCT_PROTOINFO_BIT = 1,
-	NFCT_PROTOINFO = (NFCT_PROTOINFO_BIT << 1),
+	NFCT_PROTOINFO = (1 << NFCT_PROTOINFO_BIT),
 
 	NFCT_TIMEOUT_BIT = 2,
-	NFCT_TIMEOUT = (NFCT_TIMEOUT_BIT << 1),
+	NFCT_TIMEOUT = (1 << NFCT_TIMEOUT_BIT),
 
 	NFCT_MARK_BIT = 3,
-	NFCT_MARK = (NFCT_MARK_BIT << 1),
+	NFCT_MARK = (1 << NFCT_MARK_BIT),
 
 	NFCT_COUNTERS_BIT = 4,
-	NFCT_COUNTERS = (NFCT_COUNTERS_BIT << 1),
+	NFCT_COUNTERS = (1 << NFCT_COUNTERS_BIT),
 
 	NFCT_USE_BIT = 5,
-	NFCT_USE = (NFCT_USE_BIT << 1),
+	NFCT_USE = (1 << NFCT_USE_BIT),
 
 	NFCT_ID_BIT = 6,
-	NFCT_ID = (NFCT_ID_BIT << 1)
+	NFCT_ID = (1 << NFCT_ID_BIT)
 };
 
-typedef void (*nfct_callback)(void *arg, unsigned int flags);
-
-struct nfct_msg_handler {
-	int type;
-	int (*handler)(struct sockaddr_nl *, struct nlmsghdr *, void *arg);
+enum {
+	NFCT_MSG_UNKNOWN,
+	NFCT_MSG_NEW,
+	NFCT_MSG_UPDATE,
+	NFCT_MSG_DESTROY
 };
 
+typedef void (*nfct_callback)(void *arg, unsigned int flags, int);
+typedef int (*nfct_handler)(struct sockaddr_nl *, struct nlmsghdr *, void *arg);
+
 struct nfct_handle {
 	struct nfnl_handle nfnlh;
-	nfct_callback callback;
-	struct nfct_msg_handler *handler[IPCTNL_MSG_MAX];
+	nfct_callback callback;		/* user callback */
+	nfct_handler handler;		/* netlink handler */
 };
 
 extern struct nfct_conntrack *
 nfct_conntrack_alloc(struct nfct_tuple *orig, struct nfct_tuple *reply,
 		     unsigned long timeout, union nfct_protoinfo *proto,
-		     unsigned int status, struct nfct_nat *range);
+		     unsigned int status, unsigned long mark,
+		     unsigned int id, struct nfct_nat *range);
 extern void nfct_conntrack_free(struct nfct_conntrack *ct);
 
 extern struct nfct_expect *
 nfct_expect_alloc(struct nfct_tuple *master, struct nfct_tuple *tuple,
-		  struct nfct_tuple *mask, unsigned long timeout);
+		  struct nfct_tuple *mask, unsigned long timeout, 
+		  unsigned int id);
 extern void nfct_expect_free(struct nfct_expect *exp);
 
 extern void nfct_register_proto(struct nfct_proto *h);
@@ -170,17 +181,19 @@
 /*
  * callback displayers
  */
-extern void nfct_default_conntrack_display(void *arg, unsigned int flags); 
-extern void nfct_default_expect_display(void *arg, unsigned int flags);
+extern void nfct_default_conntrack_display(void *arg, unsigned int, int); 
+extern void nfct_default_expect_display(void *arg, unsigned int, int);
 
 extern int nfct_create_conntrack(struct nfct_handle *cth, 
 				 struct nfct_conntrack *ct);
 extern int nfct_update_conntrack(struct nfct_handle *cth,
 				 struct nfct_conntrack *ct);
 extern int nfct_delete_conntrack(struct nfct_handle *cth, 
-				 struct nfct_tuple *tuple, int dir);
+				 struct nfct_tuple *tuple, int dir, 
+				 unsigned int id);
 extern int nfct_get_conntrack(struct nfct_handle *cth, 
-			      struct nfct_tuple *tuple, int dir); 
+			      struct nfct_tuple *tuple, int dir,
+			      unsigned int id); 
 extern int nfct_dump_conntrack_table(struct nfct_handle *cth);
 extern int nfct_dump_conntrack_table_reset_counters(struct nfct_handle *cth);
 extern int nfct_event_conntrack(struct nfct_handle *cth); 
@@ -190,9 +203,12 @@
  */
 extern int nfct_dump_expect_list(struct nfct_handle *cth);
 extern int nfct_flush_conntrack_table(struct nfct_handle *cth);
-extern int nfct_get_expectation(struct nfct_handle *cth,struct nfct_tuple *tuple);
+extern int nfct_get_expectation(struct nfct_handle *cth, 
+				struct nfct_tuple *tuple,
+				unsigned int id);
 extern int nfct_create_expectation(struct nfct_handle *cth, struct nfct_expect *);
-extern int nfct_delete_expectation(struct nfct_handle *cth,struct nfct_tuple *tuple);
+extern int nfct_delete_expectation(struct nfct_handle *cth,
+				   struct nfct_tuple *tuple, unsigned int id);
 extern int nfct_event_expectation(struct nfct_handle *cth);
 extern int nfct_flush_expectation_table(struct nfct_handle *cth);
 

Modified: trunk/libnetfilter_conntrack/src/libnetfilter_conntrack.c
===================================================================
--- trunk/libnetfilter_conntrack/src/libnetfilter_conntrack.c	2005-10-21 02:47:07 UTC (rev 4377)
+++ trunk/libnetfilter_conntrack/src/libnetfilter_conntrack.c	2005-10-21 18:21:03 UTC (rev 4378)
@@ -40,8 +40,6 @@
 			    struct nlmsghdr *n, void *arg)
 {
 	struct nfct_handle *cth = (struct nfct_handle *) arg;
-	int type = NFNL_MSG_TYPE(n->nlmsg_type);
-	struct nfct_msg_handler *hdlr = cth->handler[type];
 	int ret;
 
 	if (NFNL_SUBSYS_ID(n->nlmsg_type) != NFNL_SUBSYS_CTNETLINK &&
@@ -50,14 +48,11 @@
 		return 0;
 	}
 
-	if (!hdlr)
+	if (!cth->handler)
 		return 0;
 
-	if (!hdlr->handler)
-		return 0;
+	ret = cth->handler(nladdr, n, arg);
 
-	ret = hdlr->handler(nladdr, n, arg);
-
 	return ret;
 }
 
@@ -109,15 +104,9 @@
 	cth->callback = callback;
 }
 
-static int nfct_register_handler(struct nfct_handle *cth, 
-				 struct nfct_msg_handler *hndlr)
+static void nfct_set_handler(struct nfct_handle *cth, nfct_handler hndlr)
 {
-	if (hndlr->type >= IPCTNL_MSG_MAX)
-		return -EINVAL;
-
-	cth->handler[hndlr->type] = hndlr;
-	
-	return 0;
+	cth->handler = hndlr;
 }
 
 static void nfct_build_tuple_ip(struct nfnlhdr *req, int size, 
@@ -264,6 +253,10 @@
 	nfnl_addattr_l(&req->nlh, size, CTA_TIMEOUT, &ct->timeout, 
 		       sizeof(unsigned long));
 
+	if (ct->id != NFCT_ANY_ID)
+		nfnl_addattr_l(&req->nlh, size, CTA_ID, &ct->id, 
+			       sizeof(unsigned int));
+
 	nfct_build_protoinfo(req, size, ct);
 	if (ct->nat.min_ip != 0)
 		nfct_build_nat(req, size, ct);
@@ -317,7 +310,7 @@
 	if (status & IPS_ASSURED)
 		size = sprintf(buf, "[ASSURED] ");
 	if (!(status & IPS_SEEN_REPLY))
-		size = sprintf(buf, "[UNREPLIED] ");
+		size += sprintf(buf+size, "[UNREPLIED] ");
 
 	return size;
 }
@@ -399,6 +392,23 @@
 				NFA_DATA(tb[CTA_COUNTERS32_BYTES-1]));
 }
 
+static char *msgtype[] = {"[UNKNOWN]", "[NEW]", "[UPDATE]", "[DESTROY]"};
+
+static int typemsg2enum(u_int8_t type, u_int8_t flags)
+{
+	int ret = NFCT_MSG_UNKNOWN;
+
+	if (type == IPCTNL_MSG_CT_NEW) {
+		if (flags & NLM_F_CREATE)
+			ret = NFCT_MSG_NEW;
+		else
+			ret = NFCT_MSG_UPDATE;
+	} else if (type == IPCTNL_MSG_CT_DELETE)
+		ret = NFCT_MSG_DESTROY;
+
+	return ret;
+}
+
 static int nfct_conntrack_netlink_handler(struct sockaddr_nl *sock, 
 					  struct nlmsghdr *nlh, void *arg)
 {
@@ -409,6 +419,7 @@
 	struct nfct_conntrack ct;
 	unsigned int flags = 0;
 	struct nfct_handle *cth = arg;
+	int type = NFNL_MSG_TYPE(nlh->nlmsg_type);
 
 	memset(&ct, 0, sizeof(struct nfct_conntrack));
 
@@ -462,12 +473,13 @@
 		attr = NFA_NEXT(attr, attrlen);
 	}
 	if (cth->callback)
-		cth->callback((void *) &ct, flags);
+		cth->callback((void *) &ct, flags,
+			      typemsg2enum(type, nlh->nlmsg_flags));
 
 	return 0;
 }
 
-void nfct_default_conntrack_display(void *arg, unsigned int flags)
+void nfct_default_conntrack_display(void *arg, unsigned int flags, int type)
 {
 	struct nfct_conntrack *ct = arg;
 	struct nfct_proto *h = NULL;
@@ -525,7 +537,7 @@
 	fprintf(stdout, buf);
 }
 
-void nfct_default_expect_display(void *arg, unsigned int flags)
+void nfct_default_expect_display(void *arg, unsigned int flags, int type)
 {
 	struct nfct_expect *exp = arg;
 	char buf[256];
@@ -543,27 +555,12 @@
 	fprintf(stdout, buf);
 }
 
-static char *typemsg2str(type, flags)
+static int nfct_event_netlink_handler(struct sockaddr_nl *sock, 
+				      struct nlmsghdr *nlh,
+				      void *arg)
 {
-	char *ret = "[UNKNOWN]";
-
-	if (type == IPCTNL_MSG_CT_NEW) {
-		if (flags & NLM_F_CREATE)
-			ret = "[NEW]";
-		else
-			ret = "[UPDATE]";
-	} else if (type == IPCTNL_MSG_CT_DELETE)
-		ret = "[DESTROY]";
-
-	return ret;
-}
-
-static int nfct_event_handler(struct sockaddr_nl *sock, 
-			      struct nlmsghdr *nlh,
-			      void *arg)
-{
 	int type = NFNL_MSG_TYPE(nlh->nlmsg_type);
-	fprintf(stdout, "%9s ", typemsg2str(type, nlh->nlmsg_flags));
+	fprintf(stdout, "%9s ", msgtype[typemsg2enum(type, nlh->nlmsg_flags)]);
 	return nfct_conntrack_netlink_handler(sock, nlh, arg);
 }
 
@@ -576,6 +573,7 @@
 	struct nfattr *attr = NFM_NFA(NLMSG_DATA(nlh));
 	int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len);
 	struct nfct_expect exp;
+	int type = NFNL_MSG_TYPE(nlh->nlmsg_type);
 
 	memset(&exp, 0, sizeof(struct nfct_expect));
 
@@ -604,7 +602,8 @@
 		attr = NFA_NEXT(attr, attrlen);
 	}
 	if (cth->callback)
-		cth->callback((void *)&exp, 0);
+		cth->callback((void *)&exp, 0, 
+			      typemsg2enum(type, nlh->nlmsg_flags));
 
 	return 0;
 }
@@ -612,7 +611,8 @@
 struct nfct_conntrack *
 nfct_conntrack_alloc(struct nfct_tuple *orig, struct nfct_tuple *reply,
 		     unsigned long timeout, union nfct_protoinfo *proto,
-		     unsigned int status, struct nfct_nat *range)
+		     unsigned int status, unsigned long mark, 
+		     unsigned int id, struct nfct_nat *range)
 {
 	struct nfct_conntrack *ct;
 
@@ -626,6 +626,9 @@
 	ct->timeout = htonl(timeout);
 	ct->status = htonl(status);
 	ct->protoinfo = *proto;
+	ct->mark = htonl(mark);
+	if (id != NFCT_ANY_ID)
+		ct->id = htonl(id);
 	if (range)
 		ct->nat = *range;
 
@@ -682,8 +685,8 @@
 	return ret;
 }
 
-int nfct_delete_conntrack(struct nfct_handle *cth, 
-			  struct nfct_tuple *tuple, int dir)
+int nfct_delete_conntrack(struct nfct_handle *cth, struct nfct_tuple *tuple, 
+			  int dir, unsigned int id)
 {
 	int ret;
 	struct nfnlhdr *req;
@@ -699,6 +702,10 @@
 
 	nfct_build_tuple(req, sizeof(buf), tuple, type);
 
+	if (id != NFCT_ANY_ID)
+		nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_ID, &id, 
+			       sizeof(unsigned int));
+
 	if (nfnl_send(&cth->nfnlh, &req->nlh) < 0)
 		return -1;
 
@@ -708,19 +715,15 @@
 }
 
 /* get_conntrack_handler */
-int nfct_get_conntrack(struct nfct_handle *cth, 
-		       struct nfct_tuple *tuple, int dir)
+int nfct_get_conntrack(struct nfct_handle *cth, struct nfct_tuple *tuple, 
+		       int dir, unsigned int id)
 {
 	int ret;
 	struct nfnlhdr *req;
-	struct nfct_msg_handler h = {
-		.type = 0,
-		.handler = nfct_conntrack_netlink_handler
-	};
 	char buf[NFCT_BUFSIZE];
 	int type = dir ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG;
 
-	nfct_register_handler(cth, &h);
+	nfct_set_handler(cth, nfct_conntrack_netlink_handler);
 	
 	memset(&buf, 0, sizeof(buf));
 	req = (void *) &buf;
@@ -729,8 +732,12 @@
 		      AF_INET, 0, IPCTNL_MSG_CT_GET,
 		      NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_ACK);
 	
-	nfct_build_tuple(req, sizeof(buf), tuple, type); 
+	nfct_build_tuple(req, sizeof(buf), tuple, type);
 
+        if (id != NFCT_ANY_ID)
+		nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_ID, &id,
+			       sizeof(unsigned int));
+
 	if (nfnl_send(&cth->nfnlh, &req->nlh) < 0)
 		return -1;
 
@@ -742,13 +749,9 @@
 static int __nfct_dump_conntrack_table(struct nfct_handle *cth, int zero)
 {
 	int ret, msg;
-	struct nfct_msg_handler h = {
-		.type = IPCTNL_MSG_CT_NEW, /* Hm... really? */
-		.handler = nfct_conntrack_netlink_handler
-	};
 	struct nfnlhdr req;
 	
-	nfct_register_handler(cth, &h);
+	nfct_set_handler(cth, nfct_conntrack_netlink_handler);
 
 	if (zero)
 		msg = IPCTNL_MSG_CT_GET_CTRZERO;
@@ -778,19 +781,9 @@
 
 int nfct_event_conntrack(struct nfct_handle *cth)
 {
-	struct nfct_msg_handler hnew = {
-		.type = IPCTNL_MSG_CT_NEW,
-		.handler = nfct_event_handler
-	};
-	struct nfct_msg_handler hdestroy = {
-		.type = IPCTNL_MSG_CT_DELETE,
-		.handler = nfct_event_handler
-	};
 	int ret;
 
-	nfct_register_handler(cth, &hnew);
-	nfct_register_handler(cth, &hdestroy);
-
+	nfct_set_handler(cth, nfct_event_netlink_handler);
 	ret = nfnl_listen(&cth->nfnlh, &callback_handler, cth);
 
 	return 0;
@@ -813,15 +806,10 @@
 
 int nfct_dump_expect_list(struct nfct_handle *cth)
 {
-	struct nfct_msg_handler h = {
-		.type = IPCTNL_MSG_EXP_NEW,
-		.handler = nfct_expect_netlink_handler
-	};
 	int ret;
 	struct nfnlhdr req;
 
-	nfct_register_handler(cth, &h);
-
+	nfct_set_handler(cth, nfct_expect_netlink_handler);
 	nfnl_fill_hdr(&cth->nfnlh, &req.nlh, 0, AF_INET, 0,
 		      IPCTNL_MSG_EXP_GET, NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST);
 
@@ -854,12 +842,9 @@
 	return ret;
 }
 
-int nfct_get_expectation(struct nfct_handle *cth, struct nfct_tuple *tuple)
+int nfct_get_expectation(struct nfct_handle *cth, struct nfct_tuple *tuple,
+			 unsigned int id)
 {
-	struct nfct_msg_handler h = {
-		.type = IPCTNL_MSG_EXP_NEW,
-		.handler = nfct_expect_netlink_handler
-	};
 	int ret;
 	struct nfnlhdr *req;
 	char buf[NFCT_BUFSIZE];
@@ -870,9 +855,13 @@
 	nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, AF_INET, 0, IPCTNL_MSG_EXP_GET,
 		      NLM_F_REQUEST|NLM_F_ACK);
 
-	nfct_register_handler(cth, &h);
+	nfct_set_handler(cth, nfct_expect_netlink_handler);
 	nfct_build_tuple(req, sizeof(buf), tuple, CTA_EXPECT_MASTER);
-	
+
+	if (id != NFCT_ANY_ID)
+		nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_ID, &id,
+			       sizeof(unsigned int));
+
 	if (nfnl_send(&cth->nfnlh, &req->nlh) < 0)
 		return -1;
 
@@ -883,7 +872,8 @@
 
 struct nfct_expect *
 nfct_expect_alloc(struct nfct_tuple *master, struct nfct_tuple *tuple,
-		  struct nfct_tuple *mask, unsigned long timeout)
+		  struct nfct_tuple *mask, unsigned long timeout, 
+		  unsigned int id)
 {
 	struct nfct_expect *exp;
 
@@ -896,6 +886,8 @@
 	exp->tuple = *tuple;
 	exp->mask = *mask;
 	exp->timeout = htonl(timeout);
+	if (id != NFCT_ANY_ID)
+		exp->id = htonl(id);
 
 	return exp;
 }
@@ -921,9 +913,8 @@
 	nfct_build_tuple(req, sizeof(buf), &exp->tuple, CTA_EXPECT_TUPLE);
 	nfct_build_tuple(req, sizeof(buf), &exp->mask, CTA_EXPECT_MASK);
 	
-	if (nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_TIMEOUT, 
-			   &exp->timeout, sizeof(unsigned long)) < 0)
-		return -1;	
+	nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_TIMEOUT, 
+		       &exp->timeout, sizeof(unsigned long));
 
 	if (nfnl_send(&cth->nfnlh, &req->nlh) < 0 )
 		return -1;
@@ -933,7 +924,8 @@
 	return ret;
 }
 
-int nfct_delete_expectation(struct nfct_handle *cth,struct nfct_tuple *tuple)
+int nfct_delete_expectation(struct nfct_handle *cth,struct nfct_tuple *tuple,
+			    unsigned int id)
 {
 	int ret;
 	struct nfnlhdr *req;
@@ -948,6 +940,10 @@
 
 	nfct_build_tuple(req, sizeof(buf), tuple, CTA_EXPECT_MASTER);
 
+	if (id != NFCT_ANY_ID)
+		nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_ID, &id,
+			       sizeof(unsigned int));
+	
 	if (nfnl_send(&cth->nfnlh, &req->nlh) < 0)
 		return -1;
 
@@ -958,18 +954,9 @@
 
 int nfct_event_expectation(struct nfct_handle *cth)
 {
-	struct nfct_msg_handler hnew = {
-		.type = IPCTNL_MSG_EXP_NEW,
-		.handler = nfct_expect_netlink_handler
-	};
-	struct nfct_msg_handler hdestroy = {
-		.type = IPCTNL_MSG_EXP_DELETE,
-		.handler = nfct_expect_netlink_handler
-	};
 	int ret;
 	
-	nfct_register_handler(cth, &hnew);
-	nfct_register_handler(cth, &hdestroy);
+	nfct_set_handler(cth, nfct_expect_netlink_handler);
 	ret = nfnl_listen(&cth->nfnlh, &callback_handler, cth);
 
 	return ret;




More information about the netfilter-cvslog mailing list