[netfilter-cvslog] r7460 - in trunk/libnetfilter_conntrack: . include include/libnetfilter_conntrack src/conntrack

pablo at netfilter.org pablo at netfilter.org
Sun Apr 13 02:38:09 CEST 2008


Author: pablo at netfilter.org
Date: 2008-04-13 02:38:09 +0200 (Sun, 13 Apr 2008)
New Revision: 7460

Added:
   trunk/libnetfilter_conntrack/src/conntrack/copy.c
Modified:
   trunk/libnetfilter_conntrack/configure.in
   trunk/libnetfilter_conntrack/include/internal.h
   trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h
   trunk/libnetfilter_conntrack/src/conntrack/Makefile.am
   trunk/libnetfilter_conntrack/src/conntrack/api.c
   trunk/libnetfilter_conntrack/src/conntrack/build.c
   trunk/libnetfilter_conntrack/src/conntrack/compare.c
   trunk/libnetfilter_conntrack/src/conntrack/parse.c
Log:
- add nfct_cmp (replacement for nfct_compare a bit more flexible)
- add nfct_copy
- conditional build of original and reply tuples 
- fix secmark parsing


Modified: trunk/libnetfilter_conntrack/configure.in
===================================================================
--- trunk/libnetfilter_conntrack/configure.in	2008-04-12 11:55:53 UTC (rev 7459)
+++ trunk/libnetfilter_conntrack/configure.in	2008-04-13 00:38:09 UTC (rev 7460)
@@ -4,7 +4,7 @@
 
 AC_CANONICAL_SYSTEM
 
-AM_INIT_AUTOMAKE(libnetfilter_conntrack, 0.0.90)
+AM_INIT_AUTOMAKE(libnetfilter_conntrack, 0.0.91)
 
 AC_PROG_CC
 AM_PROG_LIBTOOL

Modified: trunk/libnetfilter_conntrack/include/internal.h
===================================================================
--- trunk/libnetfilter_conntrack/include/internal.h	2008-04-12 11:55:53 UTC (rev 7459)
+++ trunk/libnetfilter_conntrack/include/internal.h	2008-04-13 00:38:09 UTC (rev 7460)
@@ -199,7 +199,7 @@
 
 int __setobjopt(struct nf_conntrack *ct, unsigned int option);
 int __getobjopt(const struct nf_conntrack *ct, unsigned int option);
-int __compare(const struct nf_conntrack *ct1, const struct nf_conntrack *ct2);
+int __compare(const struct nf_conntrack *ct1, const struct nf_conntrack *ct2, unsigned int flags);
 
 typedef void (*set_exp_attr)(struct nf_expect *exp, const void *value);
 typedef const void *(*get_exp_attr)(const struct nf_expect *exp);

Modified: trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h
===================================================================
--- trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h	2008-04-12 11:55:53 UTC (rev 7459)
+++ trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h	2008-04-13 00:38:09 UTC (rev 7460)
@@ -260,9 +260,21 @@
 			 const unsigned int out_type,
 			 const unsigned int out_flags);
 
+/* comparison */
 extern int nfct_compare(const struct nf_conntrack *ct1,
 			const struct nf_conntrack *ct2);
 
+enum {
+	NFCT_CMP_ALL = 0,
+	NFCT_CMP_ORIG = (1 << 0),
+	NFCT_CMP_REPL = (1 << 1),
+};
+
+extern int nfct_cmp(const struct nf_conntrack *ct1,
+		    const struct nf_conntrack *ct2,
+		    unsigned int flags);
+
+
 /* query */
 enum nf_conntrack_query {
 	NFCT_Q_CREATE,
@@ -285,6 +297,16 @@
 
 extern int nfct_catch(struct nfct_handle *h);
 
+/* copy */
+enum {
+	NFCT_CP_ORIG = (1 << 0),
+	NFCT_CP_REPL = (1 << 1)
+};
+
+extern void nfct_copy(struct nf_conntrack *dest,
+		      const struct nf_conntrack *source,
+		      unsigned int flags);
+
 /* low level API: netlink functions */
 
 extern int nfct_build_conntrack(struct nfnl_subsys_handle *ssh,

Modified: trunk/libnetfilter_conntrack/src/conntrack/Makefile.am
===================================================================
--- trunk/libnetfilter_conntrack/src/conntrack/Makefile.am	2008-04-12 11:55:53 UTC (rev 7459)
+++ trunk/libnetfilter_conntrack/src/conntrack/Makefile.am	2008-04-13 00:38:09 UTC (rev 7460)
@@ -11,4 +11,5 @@
 			    snprintf.c \
 			    snprintf_default.c snprintf_xml.c \
 			    objopt.c \
-			    compare.c
+			    compare.c \
+			    copy.c

Modified: trunk/libnetfilter_conntrack/src/conntrack/api.c
===================================================================
--- trunk/libnetfilter_conntrack/src/conntrack/api.c	2008-04-12 11:55:53 UTC (rev 7459)
+++ trunk/libnetfilter_conntrack/src/conntrack/api.c	2008-04-13 00:38:09 UTC (rev 7460)
@@ -671,6 +671,8 @@
  *
  * If both conntrack object are equal, this function returns 1, otherwise
  * 0 is returned.
+ *
+ * NOTICE: The use nfct_cmp is preferred.
  */
 int nfct_compare(const struct nf_conntrack *ct1, 
 		 const struct nf_conntrack *ct2)
@@ -678,5 +680,68 @@
 	assert(ct1 != NULL);
 	assert(ct2 != NULL);
 
-	return __compare(ct1, ct2);
+	return __compare(ct1, ct2, NFCT_CMP_ALL);
 }
+
+/**
+ * nfct_cmp - compare two conntrack objects
+ * @ct1: pointer to a valid conntrack object
+ * @ct2: pointer to a valid conntrack object
+ * @flags: flags
+ *
+ * This function only compare attribute set in both objects, ie. if a certain
+ * attribute is not set in ct1 but it is in ct2, then the value of such 
+ * attribute is not used in the comparison.
+ *
+ * The available flags are:
+ *
+ * 	- NFCT_CMP_ALL: full comparison of both objects
+ * 	- NFCT_CMP_ORIG: it only compares the source and destination address;
+ * 	source and destination ports; and the layer 3 and 4 protocol numbers
+ * 	of the original direction.
+ * 	- NFCT_CMP_REPL: like NFCT_CMP_REPL but it compares the flow
+ * 	information that goes in the reply direction.
+ *
+ * If both conntrack object are equal, this function returns 1, otherwise
+ * 0 is returned.
+ */
+int nfct_cmp(const struct nf_conntrack *ct1, 
+	     const struct nf_conntrack *ct2,
+	     unsigned int flags)
+{
+	assert(ct1 != NULL);
+	assert(ct2 != NULL);
+
+	return __compare(ct1, ct2, flags);
+}
+
+/**
+ * nfct_copy - copy part of one source object to another
+ * @ct1: destination object
+ * @ct2: source object
+ * @flags: flags
+ *
+ * This function copies one part of the source object to the target.
+ * It behaves like clone but:
+ *
+ * 1) You have to pass an already allocated space for the target object
+ * 2) You can copy only a part of the source object to the target
+ *
+ * The current supported flags are NFCT_CP_ORIG and NFCT_CP_REPL that
+ * can be used to copy the information that identifies a flow in the
+ * original and the reply direction. This information is usually composed
+ * of: source and destination IP address; source and destination ports;
+ * layer 3 and 4 protocol number.
+ */
+void nfct_copy(struct nf_conntrack *ct1,
+	       const struct nf_conntrack *ct2,
+	       unsigned int flags)
+{
+	assert(ct1 != NULL);
+	assert(ct2 != NULL);
+
+	if (flags & NFCT_CP_ORIG)
+		__copy_tuple(ct1, ct2, __DIR_ORIG);
+	if (flags & NFCT_CP_REPL)
+		__copy_tuple(ct1, ct2, __DIR_REPL);
+}

Modified: trunk/libnetfilter_conntrack/src/conntrack/build.c
===================================================================
--- trunk/libnetfilter_conntrack/src/conntrack/build.c	2008-04-12 11:55:53 UTC (rev 7459)
+++ trunk/libnetfilter_conntrack/src/conntrack/build.c	2008-04-13 00:38:09 UTC (rev 7460)
@@ -307,9 +307,36 @@
 
 	nfnl_fill_hdr(ssh, &req->nlh, 0, l3num, 0, type, flags);
 
-	__build_tuple(req, size, &ct->tuple[__DIR_ORIG], CTA_TUPLE_ORIG);
-	__build_tuple(req, size, &ct->tuple[__DIR_REPL], CTA_TUPLE_REPLY);
+	if (test_bit(ATTR_ORIG_IPV4_SRC, ct->set) ||
+	    test_bit(ATTR_ORIG_IPV4_DST, ct->set) ||
+	    test_bit(ATTR_ORIG_IPV6_SRC, ct->set) ||
+	    test_bit(ATTR_ORIG_IPV6_DST, ct->set) ||
+	    test_bit(ATTR_ORIG_PORT_SRC, ct->set) ||
+	    test_bit(ATTR_ORIG_PORT_DST, ct->set) ||
+	    test_bit(ATTR_ORIG_L3PROTO, ct->set)  ||
+	    test_bit(ATTR_ORIG_L4PROTO, ct->set)  ||
+	    test_bit(ATTR_ICMP_TYPE, ct->set) 	  ||
+	    test_bit(ATTR_ICMP_CODE, ct->set)	  ||
+	    test_bit(ATTR_ICMP_ID, ct->set))
+		__build_tuple(req, size,
+			      &ct->tuple[__DIR_ORIG], 
+			      CTA_TUPLE_ORIG);
 
+	if (test_bit(ATTR_REPL_IPV4_SRC, ct->set) ||
+	    test_bit(ATTR_REPL_IPV4_DST, ct->set) ||
+	    test_bit(ATTR_REPL_IPV6_SRC, ct->set) ||
+	    test_bit(ATTR_REPL_IPV6_DST, ct->set) ||
+	    test_bit(ATTR_REPL_PORT_SRC, ct->set) ||
+	    test_bit(ATTR_REPL_PORT_DST, ct->set) ||
+	    test_bit(ATTR_REPL_L3PROTO, ct->set)  ||
+	    test_bit(ATTR_REPL_L4PROTO, ct->set)  ||
+	    test_bit(ATTR_ICMP_TYPE, ct->set) 	  ||
+	    test_bit(ATTR_ICMP_CODE, ct->set)	  ||
+	    test_bit(ATTR_ICMP_ID, ct->set))
+		__build_tuple(req, size, 
+			      &ct->tuple[__DIR_REPL],
+			      CTA_TUPLE_REPLY);
+
 	if (test_bit(ATTR_MASTER_IPV4_SRC, ct->set) ||
 	    test_bit(ATTR_MASTER_IPV4_DST, ct->set) ||
 	    test_bit(ATTR_MASTER_IPV6_SRC, ct->set) ||

Modified: trunk/libnetfilter_conntrack/src/conntrack/compare.c
===================================================================
--- trunk/libnetfilter_conntrack/src/conntrack/compare.c	2008-04-12 11:55:53 UTC (rev 7459)
+++ trunk/libnetfilter_conntrack/src/conntrack/compare.c	2008-04-13 00:38:09 UTC (rev 7460)
@@ -7,28 +7,34 @@
 
 #include "internal.h"
 
-int __compare(const struct nf_conntrack *ct1,
-	      const struct nf_conntrack *ct2)
+static int cmp_orig(const struct nf_conntrack *ct1,
+		    const struct nf_conntrack *ct2)
 {
-	if (test_bit(ATTR_MARK, ct1->set) && 
-	    test_bit(ATTR_MARK, ct2->set) &&
-	    ct1->mark != ct2->mark)
-	    	return 0;
+	if (test_bit(ATTR_ORIG_IPV4_SRC, ct1->set) &&
+	    test_bit(ATTR_ORIG_IPV4_SRC, ct2->set) &&
+	    ct1->tuple[__DIR_ORIG].src.v4 !=
+	    ct2->tuple[__DIR_ORIG].src.v4)
+		return 0;
 
-	if (test_bit(ATTR_TIMEOUT, ct1->set) &&
-	    test_bit(ATTR_TIMEOUT, ct2->set) &&
-	    ct1->timeout != ct2->timeout)
-	    	return 0;
+	if (test_bit(ATTR_ORIG_IPV4_DST, ct1->set) &&
+	    test_bit(ATTR_ORIG_IPV4_DST, ct2->set) &&
+	    ct1->tuple[__DIR_ORIG].dst.v4 !=
+	    ct2->tuple[__DIR_ORIG].dst.v4)
+		return 0;
 
-	if (test_bit(ATTR_STATUS, ct1->set) &&
-	    test_bit(ATTR_STATUS, ct2->set) &&
-	    ct1->status == ct2->status)
-	    	return 0;
+	if (test_bit(ATTR_ORIG_IPV6_SRC, ct1->set) &&
+	    test_bit(ATTR_ORIG_IPV6_SRC, ct2->set) &&
+	    memcmp(&ct1->tuple[__DIR_ORIG].src.v6,
+	    	   &ct2->tuple[__DIR_ORIG].src.v6,
+		   sizeof(u_int32_t)*4) == 0)
+		return 0;
 
-	if (test_bit(ATTR_TCP_STATE, ct1->set) &&
-	    test_bit(ATTR_TCP_STATE, ct2->set) &&
-	    ct1->protoinfo.tcp.state != ct2->protoinfo.tcp.state)
-	    	return 0;
+	if (test_bit(ATTR_ORIG_IPV6_DST, ct1->set) &&
+	    test_bit(ATTR_ORIG_IPV6_DST, ct2->set) &&
+	    memcmp(&ct1->tuple[__DIR_ORIG].dst.v6,
+	    	   &ct2->tuple[__DIR_ORIG].dst.v6,
+		   sizeof(u_int32_t)*4) == 0)
+		return 0;
 
 	if (test_bit(ATTR_ORIG_L3PROTO, ct1->set) &&
 	    test_bit(ATTR_ORIG_L3PROTO, ct2->set) &&
@@ -36,40 +42,20 @@
 	    ct2->tuple[__DIR_ORIG].l3protonum != AF_UNSPEC &&
 	    ct1->tuple[__DIR_ORIG].l3protonum !=
 	    ct2->tuple[__DIR_ORIG].l3protonum)
-	    	return 0;
+ 	   	return 0;
 
-	if (test_bit(ATTR_REPL_L3PROTO, ct1->set) &&
-	    test_bit(ATTR_REPL_L3PROTO, ct2->set) &&
-	    ct1->tuple[__DIR_REPL].l3protonum != AF_UNSPEC && 
-	    ct2->tuple[__DIR_REPL].l3protonum != AF_UNSPEC &&
-	    ct1->tuple[__DIR_REPL].l3protonum !=
-	    ct2->tuple[__DIR_REPL].l3protonum)
-		return 0;
-
 	if (test_bit(ATTR_ORIG_L4PROTO, ct1->set) &&
 	    test_bit(ATTR_ORIG_L4PROTO, ct2->set) &&
 	    ct1->tuple[__DIR_ORIG].protonum !=
 	    ct2->tuple[__DIR_ORIG].protonum)
 		return 0;
 
-	if (test_bit(ATTR_REPL_L4PROTO, ct1->set) &&
-	    test_bit(ATTR_REPL_L4PROTO, ct2->set) &&
-	    ct1->tuple[__DIR_REPL].protonum !=
-	    ct2->tuple[__DIR_REPL].protonum)
-		return 0;
+	return 1;
+}
 
-	if (test_bit(ATTR_ORIG_IPV4_SRC, ct1->set) &&
-	    test_bit(ATTR_ORIG_IPV4_SRC, ct2->set) &&
-	    ct1->tuple[__DIR_ORIG].src.v4 !=
-	    ct2->tuple[__DIR_ORIG].src.v4)
-		return 0;
-
-	if (test_bit(ATTR_ORIG_IPV4_DST, ct1->set) &&
-	    test_bit(ATTR_ORIG_IPV4_DST, ct2->set) &&
-	    ct1->tuple[__DIR_ORIG].dst.v4 !=
-	    ct2->tuple[__DIR_ORIG].dst.v4)
-		return 0;
-
+static int cmp_repl(const struct nf_conntrack *ct1,
+		    const struct nf_conntrack *ct2)
+{
 	if (test_bit(ATTR_REPL_IPV4_SRC, ct1->set) &&
 	    test_bit(ATTR_REPL_IPV4_SRC, ct2->set) &&
 	    ct1->tuple[__DIR_REPL].src.v4 !=
@@ -82,20 +68,6 @@
 	    ct2->tuple[__DIR_REPL].dst.v4)
 		return 0;
 
-	if (test_bit(ATTR_ORIG_IPV6_SRC, ct1->set) &&
-	    test_bit(ATTR_ORIG_IPV6_SRC, ct2->set) &&
-	    memcmp(&ct1->tuple[__DIR_ORIG].src.v6,
-	    	   &ct2->tuple[__DIR_ORIG].src.v6,
-		   sizeof(u_int32_t)*4) == 0)
-		return 0;
-
-	if (test_bit(ATTR_ORIG_IPV6_DST, ct1->set) &&
-	    test_bit(ATTR_ORIG_IPV6_DST, ct2->set) &&
-	    memcmp(&ct1->tuple[__DIR_ORIG].dst.v6,
-	    	   &ct2->tuple[__DIR_ORIG].dst.v6,
-		   sizeof(u_int32_t)*4) == 0)
-		return 0;
-
 	if (test_bit(ATTR_REPL_IPV6_SRC, ct1->set) &&
 	    test_bit(ATTR_REPL_IPV6_SRC, ct2->set) &&
 	    memcmp(&ct1->tuple[__DIR_REPL].src.v6,
@@ -110,5 +82,63 @@
 		   sizeof(u_int32_t)*4) == 0)
 		return 0;
 
+	if (test_bit(ATTR_REPL_L3PROTO, ct1->set) &&
+	    test_bit(ATTR_REPL_L3PROTO, ct2->set) &&
+	    ct1->tuple[__DIR_REPL].l3protonum != AF_UNSPEC && 
+	    ct2->tuple[__DIR_REPL].l3protonum != AF_UNSPEC &&
+	    ct1->tuple[__DIR_REPL].l3protonum !=
+	    ct2->tuple[__DIR_REPL].l3protonum)
+		return 0;
+
+	if (test_bit(ATTR_REPL_L4PROTO, ct1->set) &&
+	    test_bit(ATTR_REPL_L4PROTO, ct2->set) &&
+	    ct1->tuple[__DIR_REPL].protonum !=
+	    ct2->tuple[__DIR_REPL].protonum)
+		return 0;
+
 	return 1;
 }
+
+static int cmp_meta(const struct nf_conntrack *ct1,
+		    const struct nf_conntrack *ct2)
+{
+	if (test_bit(ATTR_MARK, ct1->set) && 
+	    test_bit(ATTR_MARK, ct2->set) &&
+	    ct1->mark != ct2->mark)
+	    	return 0;
+
+	if (test_bit(ATTR_TIMEOUT, ct1->set) &&
+	    test_bit(ATTR_TIMEOUT, ct2->set) &&
+	    ct1->timeout != ct2->timeout)
+	    	return 0;
+
+	if (test_bit(ATTR_STATUS, ct1->set) &&
+	    test_bit(ATTR_STATUS, ct2->set) &&
+	    ct1->status == ct2->status)
+	    	return 0;
+
+	if (test_bit(ATTR_TCP_STATE, ct1->set) &&
+	    test_bit(ATTR_TCP_STATE, ct2->set) &&
+	    ct1->protoinfo.tcp.state != ct2->protoinfo.tcp.state)
+	    	return 0;
+
+	return 1;
+}
+
+int __compare(const struct nf_conntrack *ct1,
+	      const struct nf_conntrack *ct2,
+	      unsigned int flags)
+{
+	if (flags == NFCT_CMP_ALL)
+		return cmp_orig(ct1, ct2) &&
+		       cmp_repl(ct1, ct2) &&
+		       cmp_meta(ct1, ct2);
+
+	if (flags & NFCT_CMP_ORIG && !cmp_orig(ct1, ct2))
+		return 0;
+
+	if (flags & NFCT_CMP_REPL && !cmp_repl(ct1, ct2))
+		return 0;
+
+	return 1;
+}

Added: trunk/libnetfilter_conntrack/src/conntrack/copy.c
===================================================================
--- trunk/libnetfilter_conntrack/src/conntrack/copy.c	                        (rev 0)
+++ trunk/libnetfilter_conntrack/src/conntrack/copy.c	2008-04-13 00:38:09 UTC (rev 7460)
@@ -0,0 +1,57 @@
+/*
+ * (C) 2008 by Pablo Neira Ayuso <pablo at netfilter.org>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ */
+
+#include "internal.h"
+
+#define TS_ORIG								\
+({									\
+	((1 << ATTR_ORIG_IPV4_SRC) | (1 << ATTR_ORIG_IPV4_DST) |	\
+	 (1 << ATTR_ORIG_IPV6_SRC) | (1 << ATTR_ORIG_IPV6_DST) |	\
+	 (1 << ATTR_ORIG_PORT_SRC) | (1 << ATTR_ORIG_PORT_DST) | 	\
+	 (1 << ATTR_ORIG_L3PROTO)  | (1 << ATTR_ORIG_L4PROTO)  | 	\
+	 (1 << ATTR_ICMP_TYPE)	   | (1 << ATTR_ICMP_CODE)     | 	\
+	 (1 << ATTR_ICMP_ID));						\
+})
+
+#define TS_REPL								\
+({									\
+	((1 << ATTR_REPL_IPV4_SRC) | (1 << ATTR_REPL_IPV4_DST) | 	\
+	 (1 << ATTR_REPL_IPV6_SRC) | (1 << ATTR_REPL_IPV6_DST) | 	\
+	 (1 << ATTR_REPL_PORT_SRC) | (1 << ATTR_REPL_PORT_DST) | 	\
+	 (1 << ATTR_REPL_L3PROTO)  | (1 << ATTR_REPL_L4PROTO)  |	\
+	 (1 << ATTR_ICMP_TYPE)	   | (1 << ATTR_ICMP_CODE)     | 	\
+	 (1 << ATTR_ICMP_ID));						\
+})
+
+#define TUPLE_SET(dir) (dir == __DIR_ORIG ? TS_ORIG : TS_REPL)
+
+void __copy_tuple(struct nf_conntrack *ct2,
+		  const struct nf_conntrack *ct1,
+		  int dir)
+{
+	memcpy(&ct2->tuple[dir].src,
+	       &ct1->tuple[dir].src,
+	       sizeof(union __nfct_address));
+
+	memcpy(&ct2->tuple[dir].dst,
+	       &ct1->tuple[dir].dst,
+	       sizeof(union __nfct_address));
+
+	ct2->tuple[dir].l3protonum = ct1->tuple[dir].l3protonum;
+	ct2->tuple[dir].protonum = ct1->tuple[dir].protonum;
+
+	memcpy(&ct2->tuple[dir].l4src,
+	       &ct1->tuple[dir].l4src,
+	       sizeof(union __nfct_l4));
+
+	memcpy(&ct2->tuple[dir].l4dst,
+	       &ct1->tuple[dir].l4dst,
+	       sizeof(union __nfct_l4));
+
+	/* XXX: this is safe but better convert bitset to uint64_t */
+	ct2->set[0] |= ct1->set[0] & TUPLE_SET(__DIR_ORIG);
+}

Modified: trunk/libnetfilter_conntrack/src/conntrack/parse.c
===================================================================
--- trunk/libnetfilter_conntrack/src/conntrack/parse.c	2008-04-12 11:55:53 UTC (rev 7459)
+++ trunk/libnetfilter_conntrack/src/conntrack/parse.c	2008-04-13 00:38:09 UTC (rev 7460)
@@ -394,7 +394,7 @@
 	}
 
 	if (cda[CTA_SECMARK-1]) {
-		ct->secmark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
+		ct->secmark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_SECMARK-1]));
 		set_bit(ATTR_SECMARK, ct->set);
 	}
 




More information about the netfilter-cvslog mailing list