[netfilter-cvslog] r3877 - trunk/libctnetlink

laforge at netfilter.org laforge at netfilter.org
Sat Apr 16 15:29:51 CEST 2005


Author: laforge at netfilter.org
Date: 2005-04-16 15:29:50 +0200 (Sat, 16 Apr 2005)
New Revision: 3877

Modified:
   trunk/libctnetlink/ctnltest.c
   trunk/libctnetlink/libctnetlink.c
   trunk/libctnetlink/libctnetlink.h
Log:
merge with new ctnetlink patch


Modified: trunk/libctnetlink/ctnltest.c
===================================================================
--- trunk/libctnetlink/ctnltest.c	2005-04-16 13:28:42 UTC (rev 3876)
+++ trunk/libctnetlink/ctnltest.c	2005-04-16 13:29:50 UTC (rev 3877)
@@ -10,7 +10,7 @@
 
 #include <linux/types.h>
 #include <linux/netlink.h>
-#include <linux/nfnetlink_conntrack.h>
+#include <linux/netfilter/nfnetlink.h>
 
 #include "libctnetlink.h"
 
@@ -92,7 +92,7 @@
 	nladdr.nl_family = AF_NETLINK;
 
 	req.nlh.nlmsg_len = sizeof(req);
-	req.nlh.nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8)|CTNL_MSG_GETCONNTRACK;
+	req.nlh.nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8)|CTNL_MSG_CT_GET;
 	req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_DUMP|NLM_F_REQUEST;
 	req.nlh.nlmsg_pid = 0;
 	req.nlh.nlmsg_seq = 1;
@@ -115,7 +115,7 @@
 	if (cb[CTA_ORIG]) {
 		printf("orig: %s\n", 
 				display_tuple_flat(NFA_DATA(cb[CTA_ORIG])));
-		ctnl_del_conntrack(cth, NFA_DATA(cb[CTA_ORIG]));
+		ctnl_del_conntrack(cth, NFA_DATA(cb[CTA_ORIG]), CTA_ORIG);
 	}
 	if (cb[CTA_RPLY])
 		printf("rply: %s\n", 
@@ -169,7 +169,7 @@
 		exit(2);
 	}
 
-	ctnl_wilddump_request(cth, AF_INET, CTNL_MSG_GETCONNTRACK);
+	ctnl_wilddump_request(cth, AF_INET, IPCTNL_MSG_CT_GET);
 
 	while (len = recv(cth->nfnlh.fd, &buf, sizeof(buf), 0)) {
 		printf("pkt received\n");

Modified: trunk/libctnetlink/libctnetlink.c
===================================================================
--- trunk/libctnetlink/libctnetlink.c	2005-04-16 13:28:42 UTC (rev 3876)
+++ trunk/libctnetlink/libctnetlink.c	2005-04-16 13:29:50 UTC (rev 3877)
@@ -27,14 +27,12 @@
 #include <linux/netfilter_ipv4/ip_conntrack.h>
 #include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
 #include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
-#include <linux/netfilter_ipv4/ip_conntrack_icmp.h>
 #include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
-#include <linux/nfnetlink_conntrack.h>
+#include <linux/netfilter_ipv4/ip_conntrack_netlink.h>
 
 #include "libctnetlink.h"
 
-#define ctnl_error(format, args...) \
-	fprintf(stderr, "%s: " format, __FUNCTION__, ## args)
+#define ctnl_error printf
 
 /***********************************************************************
  * low level stuff 
@@ -65,11 +63,17 @@
 	int type = NFNL_MSG_TYPE(n->nlmsg_type);
 	struct ctnl_msg_handler *hdlr = cth->handler[type];
 	int ret;
+	struct nlmsgerr *msgerr;
 
 	/* end of messages reached, let's return */
 	if (n->nlmsg_type == NLMSG_DONE)
 		return -100;
 
+	if (n->nlmsg_type == NLMSG_ERROR) {
+		msgerr = NLMSG_DATA(n);
+		return msgerr->error;
+	}
+
 	if (NFNL_SUBSYS_ID(n->nlmsg_type) != NFNL_SUBSYS_CTNETLINK) {
 		ctnl_error("received message for wrong subsys, skipping\n");
 		nfnl_dump_packet(n, n->nlmsg_len, "list_conntrack_handler");
@@ -81,28 +85,16 @@
 		return 0;
 	}
 
+	if (!hdlr->handler) {
+		ctnl_error("no handler function for type %d\n", type);
+		return 0;
+	}
+
 	ret = hdlr->handler(nladdr, n, arg);
 
 	return ret;
 }
 
-/* handler used for nfnl_listen */
-static int get_conntrack_handler(struct sockaddr_nl *nladdr,
-                                  struct nlmsghdr *n, void *arg)
-{
-	struct nfgenmsg *cm = NLMSG_DATA(n);
-	struct nfattr **cb = (struct nfattr **)arg;
-
-	/* this is what we get when there's no match */
-	if (NFNL_SUBSYS_ID(n->nlmsg_type) != NFNL_SUBSYS_CTNETLINK)
-		return -1;
-        
-	nfnl_parse_attr(cb, CTA_MAX, NFM_NFA(cm), n->nlmsg_len);
-	
-	return -100; /* to get nfnl_listen to break out of the loop */
-}
-
-
 /***********************************************************************
  * high level stuff 
  ***********************************************************************/
@@ -149,7 +141,7 @@
 int ctnl_register_handler(struct ctnl_handle *cth, 
 			  struct ctnl_msg_handler *hndlr)
 {
-	if (hndlr->type >= CTNL_MSG_COUNT)
+	if (hndlr->type >= IPCTNL_MSG_COUNT)
 		return -EINVAL;
 
 	cth->handler[hndlr->type] = hndlr;
@@ -165,7 +157,7 @@
  */
 int ctnl_unregister_handler(struct ctnl_handle *cth, int type)
 {
-	if (type >= CTNL_MSG_COUNT)
+	if (type >= IPCTNL_MSG_COUNT)
 		return -EINVAL;
 
 	cth->handler[type] = NULL;
@@ -180,7 +172,7 @@
  */
 int ctnl_list_conntrack(struct ctnl_handle *cth, int family)
 {
-	if (ctnl_wilddump_request(cth, family, CTNL_MSG_GETCONNTRACK) < 0) {
+	if (ctnl_wilddump_request(cth, family, IPCTNL_MSG_CT_GET) < 0) {
 		ctnl_error("error during ctnl_wilddump_request\n");
 		return -1;
 	}
@@ -189,42 +181,63 @@
 
 }
 
+int ctnl_list_conntrack_zero_counters(struct ctnl_handle *cth, int family)
+{
+	if (ctnl_wilddump_request(cth, family, IPCTNL_MSG_CT_GET_CTRZERO) < 0) {
+		ctnl_error("error during ctnl_wilddump_request\n");
+		return -1;
+	}
+	return nfnl_listen(&cth->nfnlh, &list_conntrack_handler, cth);
+}
+
+/* TODO: Don't user list_conntrack_handler */
+int ctnl_event_conntrack(struct ctnl_handle *cth, int family)
+{
+	return nfnl_listen(&cth->nfnlh, &list_conntrack_handler, cth);
+}
+
 /**
  * ctnl_get_conntrack - get a connection from conntrack hashtable
  * cth: libctnetlink handle
  * t: tuple of connection to get
  * cb: a struct nfattr to put the connection in
  */
-int ctnl_get_conntrack(struct ctnl_handle *cth,
-		     struct ip_conntrack_tuple *t,
-		     struct nfattr **cb)
+int ctnl_get_conntrack(struct ctnl_handle *cth, 
+		       struct ip_conntrack_tuple *tuple,
+		       enum ctattr_type_t t)
 {
 	struct {
 		struct nlmsghdr nlh;
 		struct nfgenmsg g;
 	} *req;
 
-	char buf[sizeof(*req) + NFA_LENGTH(sizeof(*t))];
+	char buf[sizeof(*req) + NFA_LENGTH(sizeof(*tuple))
+		 + NFA_LENGTH(sizeof(unsigned long))];
 	memset(&buf, 0, sizeof(buf));
 
 	req = (void *) &buf;
-	
+
+	if (tuple == NULL) {
+		ctnl_error("tuple must be specified\n");
+		return -1;
+	}
+
 	nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &buf,
-			0, AF_INET, CTNL_MSG_GETCONNTRACK,
+			0, AF_INET, IPCTNL_MSG_CT_GET,
 			NLM_F_REQUEST);
 
-	if (nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_ORIG, t,
-			sizeof(*t)) < 0) {
+	if (nfnl_addattr_l(&req->nlh, sizeof(buf), t, tuple,
+				sizeof(*tuple)) < 0) {
 		ctnl_error("error during nfnl_addattr_l\n");
 		return -1;
 	}
-	
+
 	if (nfnl_send(&cth->nfnlh, (struct nlmsghdr *)&buf) < 0 ) {
 		ctnl_error("error while nfnl_send\n");
 		return -1;
 	}
 
-	return nfnl_listen(&cth->nfnlh, &get_conntrack_handler, cb);
+	return nfnl_listen(&cth->nfnlh, &list_conntrack_handler, cth);
 }
 
 /**
@@ -232,24 +245,32 @@
  * cth: libctnetlink handle
  * t: tuple of to-be-deleted connection
  */
-int ctnl_del_conntrack(struct ctnl_handle *cth, struct ip_conntrack_tuple *t)
+int ctnl_del_conntrack(struct ctnl_handle *cth, 
+		       struct ip_conntrack_tuple *tuple,
+		       enum ctattr_type_t t)
 {
 	struct {
 		struct nlmsghdr nlh;
 		struct nfgenmsg nfmsg;
 	} *req;
 
-	char buf[sizeof(*req) + NFA_LENGTH(sizeof(*t))];
+	char buf[sizeof(*req) + NFA_LENGTH(sizeof(*tuple))
+		 + NFA_LENGTH(sizeof(unsigned long))];
 	memset(&buf, 0, sizeof(buf));
 
 	req = (void *) &buf;
 
+	if (tuple == NULL) {
+		ctnl_error("tuple must be specified\n");
+		return -1;
+	}
+	
 	nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &buf,
-		      0, AF_INET, CTNL_MSG_DELCONNTRACK,
+		      0, AF_INET, IPCTNL_MSG_CT_DELETE,
 		      NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST);
 
-	if (nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_ORIG, t, 
-			   sizeof(*t)) < 0) {
+	if (nfnl_addattr_l(&req->nlh, sizeof(buf), t, tuple, 
+			   sizeof(*tuple)) < 0) {
 		ctnl_error("error during nfnl_addattr_l\n");
 		return -1;
 	}
@@ -258,13 +279,75 @@
 }
 
 /**
+ * ctnl_new_conntrack - create a connection in the conntrack hashtable
+ * cth: libctnetlink handle
+ * t: tuple of to-be-created connection
+ */
+int ctnl_new_conntrack(struct ctnl_handle *cth,
+		       struct ip_conntrack_tuple *orig,
+		       struct ip_conntrack_tuple *reply, 
+		       unsigned long timeout, struct cta_proto *proto,
+		       unsigned int status)
+{
+	struct {
+		struct nlmsghdr nlh;
+		struct nfgenmsg nfmsg;
+	} *req;
+
+	char buf[sizeof(*req) + NFA_LENGTH(sizeof(*orig))
+		 + NFA_LENGTH(sizeof(*reply)) 
+		 + NFA_LENGTH(sizeof(unsigned long))
+		 + NFA_LENGTH(sizeof(*proto))
+		 + NFA_LENGTH(sizeof(unsigned int))];
+	memset(&buf, 0, sizeof(buf));
+
+	req = (void *) &buf;
+
+	nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &buf,
+		      0, AF_INET, IPCTNL_MSG_CT_NEW,
+		      NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_CREATE);
+
+	if (nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_ORIG, orig, 
+			   sizeof(*orig)) < 0) {
+		ctnl_error("error during nfnl_addattr_l\n");
+		return -1;
+	}
+
+	if (nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_RPLY, reply, 
+			   sizeof(*reply)) < 0) {
+		ctnl_error("error during nfnl_addattr_l\n");
+		return -1;
+	}
+
+	if (nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_TIMEOUT, &timeout, 
+			   sizeof(unsigned long)) < 0) {
+		ctnl_error("error during nfnl_addattr_l\n");
+		return -1;
+	}
+
+	if (nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_PROTOINFO, proto, 
+			   sizeof(*proto)) < 0) {
+		ctnl_error("error during nfnl_addattr_l\n");
+		return -1;
+	}
+
+	if (nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_STATUS, &status,
+			   sizeof(unsigned int)) < 0) {
+		ctnl_error("error during nfnl_addattr_l\n");
+		return -1;
+	}
+
+	return nfnl_send(&cth->nfnlh, (struct nlmsghdr *)&buf);
+}
+
+/**
  * ctnl_list_expect - retrieve a list of expectations from conntrack subsys
  * cth: libctnetlink handle
  * family: AF_INET, ...
  */
 int ctnl_list_expect(struct ctnl_handle *cth, int family)
 {
-	if (ctnl_wilddump_request(cth, family, CTNL_MSG_GETEXPECT) < 0) {
+	if (ctnl_wilddump_request(cth, family, IPCTNL_MSG_EXP_GET) < 0) {
 		ctnl_error("error during ctnl_wilddump_request\n");
 		return -1;
 	}
@@ -292,7 +375,7 @@
 	req = (void *) &buf;
 
 	nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &buf,
-		      0, AF_INET, CTNL_MSG_DELEXPECT,
+		      0, AF_INET, IPCTNL_MSG_EXP_DELETE,
 		      NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST);
 
 	if (nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_ORIG, t, 

Modified: trunk/libctnetlink/libctnetlink.h
===================================================================
--- trunk/libctnetlink/libctnetlink.h	2005-04-16 13:28:42 UTC (rev 3876)
+++ trunk/libctnetlink/libctnetlink.h	2005-04-16 13:29:50 UTC (rev 3877)
@@ -13,8 +13,8 @@
 #include <netinet/in.h>
 #include <asm/types.h>
 #include <linux/if.h>
-#include <linux/nfnetlink.h>
-#include <linux/nfnetlink_conntrack.h> 
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter_ipv4/ip_conntrack_netlink.h> 
 #include <linux/netfilter_ipv4/ip_conntrack.h>
 #include "../libnfnetlink/libnfnetlink.h"
 
@@ -27,7 +27,7 @@
 
 struct ctnl_handle {
 	struct nfnl_handle nfnlh;
-	struct ctnl_msg_handler *handler[CTNL_MSG_COUNT];
+	struct ctnl_msg_handler *handler[IPCTNL_MSG_COUNT];
 };
 
 extern int ctnl_open(struct ctnl_handle *cth, unsigned subscriptions);
@@ -37,10 +37,12 @@
 				 struct ctnl_msg_handler *hndlr);
 extern int ctnl_get_conntrack(struct ctnl_handle *cth,
 			      struct ip_conntrack_tuple *tuple,
-			      struct nfattr **cb);
+			      enum ctattr_type_t t);
 extern int ctnl_del_conntrack(struct ctnl_handle *cth,
-			      struct ip_conntrack_tuple *t);
+			      struct ip_conntrack_tuple *tuple,
+			      enum ctattr_type_t t);
 extern int ctnl_list_conntrack(struct ctnl_handle *cth, int family);
+extern int ctnl_list_conntrack_zero_counters(struct ctnl_handle *cth, int family);
 
 extern int ctnl_list_expect(struct ctnl_handle *cth, int family);
 extern int ctnl_del_expect(struct ctnl_handle *cth,




More information about the netfilter-cvslog mailing list