[netfilter-cvslog] r6339 - in trunk/libnetfilter_conntrack: . extensions include/libnetfilter_conntrack l3extensions src

pablo at netfilter.org pablo at netfilter.org
Mon Dec 26 03:29:05 CET 2005


Author: pablo at netfilter.org
Date: 2005-12-26 03:29:02 +0100 (Mon, 26 Dec 2005)
New Revision: 6339

Added:
   trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack_ipv4.h
   trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack_ipv6.h
   trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack_l3extensions.h
   trunk/libnetfilter_conntrack/l3extensions/
   trunk/libnetfilter_conntrack/l3extensions/Makefile.am
   trunk/libnetfilter_conntrack/l3extensions/libnetfilter_conntrack_ipv4.c
   trunk/libnetfilter_conntrack/l3extensions/libnetfilter_conntrack_ipv6.c
Modified:
   trunk/libnetfilter_conntrack/Makefile.am
   trunk/libnetfilter_conntrack/configure.in
   trunk/libnetfilter_conntrack/extensions/libnetfilter_conntrack_icmp.c
   trunk/libnetfilter_conntrack/extensions/libnetfilter_conntrack_sctp.c
   trunk/libnetfilter_conntrack/extensions/libnetfilter_conntrack_tcp.c
   trunk/libnetfilter_conntrack/extensions/libnetfilter_conntrack_udp.c
   trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/Makefile.am
   trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h
   trunk/libnetfilter_conntrack/src/libnetfilter_conntrack.c
Log:
o add IPv6 support
o clean up layer-4 compare functions
o finish the comparison infrastructure: support for tuple/mark matching
o fix bug in the default event display when used in conjunction with the
comparison infrastructure.
o Bumped version to 0.0.30

Thanks to Yasuyuki Kozakai for:
[LIBNETFILTER_CONNTRACK] fix dumping IPv6 connections
that in included in this commit.



Modified: trunk/libnetfilter_conntrack/Makefile.am
===================================================================
--- trunk/libnetfilter_conntrack/Makefile.am	2005-12-25 21:03:43 UTC (rev 6338)
+++ trunk/libnetfilter_conntrack/Makefile.am	2005-12-26 02:29:02 UTC (rev 6339)
@@ -2,7 +2,7 @@
 
 AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
 
-SUBDIRS	= include src extensions utils
+SUBDIRS	= include src l3extensions extensions utils
 LINKOPTS = -lnfnetlink
 
 man_MANS = #nfnetlink_conntrack.3 nfnetlink_conntrack.7

Modified: trunk/libnetfilter_conntrack/configure.in
===================================================================
--- trunk/libnetfilter_conntrack/configure.in	2005-12-25 21:03:43 UTC (rev 6338)
+++ trunk/libnetfilter_conntrack/configure.in	2005-12-26 02:29:02 UTC (rev 6339)
@@ -4,7 +4,7 @@
 
 AC_CANONICAL_SYSTEM
 
-AM_INIT_AUTOMAKE(libnetfilter_conntrack, 0.0.29)
+AM_INIT_AUTOMAKE(libnetfilter_conntrack, 0.0.30)
 
 AC_PROG_CC
 AM_PROG_LIBTOOL
@@ -21,6 +21,41 @@
 AC_CHECK_LIB([nfnetlink], [nfnl_listen])
 AC_CHECK_HEADER([libnfnetlink/linux_nfnetlink.h], [AC_MSG_RESULT([found])], [AC_MSG_ERROR([libnfnetlink 0.0.12 or later needed])])
 
+AC_CHECK_HEADERS(arpa/inet.h)
+dnl Check for inet_ntop
+AC_CHECK_FUNCS(inet_ntop)
+dnl Again, some systems have it, but not IPv6
+if test "$ac_cv_func_inet_ntop" = "yes" ; then
+AC_MSG_CHECKING(if inet_ntop supports IPv6)
+AC_TRY_RUN(
+   [
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#include <errno.h>
+int main()
+  {
+     struct in6_addr addr6;
+     char buf[128];
+     if (inet_ntop(AF_INET6, &addr6, buf, 128) == 0 && errno == EAFNOSUPPORT)
+        exit(1);
+     else
+        exit(0);
+  }
+  ], [ AC_MSG_RESULT(yes)
+       AC_DEFINE_UNQUOTED(HAVE_INET_NTOP_IPV6, 1, [Define to 1 if inet_ntop supports IPv6.])
+     ], AC_MSG_RESULT(no),AC_MSG_RESULT(no))
+fi
+
 if test ! -z "$libdir"; then
 	MODULE_DIR="\\\"$libdir/libnetfilter_conntrack/\\\""
 	CFLAGS="$CFLAGS -DLIBNETFILTER_CONNTRACK_DIR=$MODULE_DIR"
@@ -28,5 +63,5 @@
 
 
 dnl Output the makefile
-AC_OUTPUT(Makefile src/Makefile include/Makefile utils/Makefile include/libnetfilter_conntrack/Makefile extensions/Makefile)
+AC_OUTPUT(Makefile src/Makefile include/Makefile utils/Makefile include/libnetfilter_conntrack/Makefile l3extensions/Makefile extensions/Makefile)
 

Modified: trunk/libnetfilter_conntrack/extensions/libnetfilter_conntrack_icmp.c
===================================================================
--- trunk/libnetfilter_conntrack/extensions/libnetfilter_conntrack_icmp.c	2005-12-25 21:03:43 UTC (rev 6338)
+++ trunk/libnetfilter_conntrack/extensions/libnetfilter_conntrack_icmp.c	2005-12-26 02:29:02 UTC (rev 6339)
@@ -56,22 +56,20 @@
 		   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;
+			return 0;
 	if (flags & ICMP_CODE)
 		if (ct1->tuple[NFCT_DIR_ORIGINAL].l4dst.icmp.code !=
 		    ct2->tuple[NFCT_DIR_ORIGINAL].l4dst.icmp.code)
-			ret = 0;
+			return 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 0;
 
-	return ret;
+	return 1;
 }
 
 static struct nfct_proto icmp = {

Modified: trunk/libnetfilter_conntrack/extensions/libnetfilter_conntrack_sctp.c
===================================================================
--- trunk/libnetfilter_conntrack/extensions/libnetfilter_conntrack_sctp.c	2005-12-25 21:03:43 UTC (rev 6338)
+++ trunk/libnetfilter_conntrack/extensions/libnetfilter_conntrack_sctp.c	2005-12-26 02:29:02 UTC (rev 6339)
@@ -60,26 +60,24 @@
 		   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;
+			return 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;
+			return 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;
+			return 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 0;
 
-	return ret;
+	return 1;
 }
 
 static struct nfct_proto sctp = {

Modified: trunk/libnetfilter_conntrack/extensions/libnetfilter_conntrack_tcp.c
===================================================================
--- trunk/libnetfilter_conntrack/extensions/libnetfilter_conntrack_tcp.c	2005-12-25 21:03:43 UTC (rev 6338)
+++ trunk/libnetfilter_conntrack/extensions/libnetfilter_conntrack_tcp.c	2005-12-26 02:29:02 UTC (rev 6339)
@@ -98,29 +98,27 @@
 		   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;
+			return 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;
+			return 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;
+			return 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;
+			return 0;
 	if (flags & TCP_STATE)
 		if (ct1->protoinfo.tcp.state != ct2->protoinfo.tcp.state)
-			ret = 0;
+			return 0;
 
-	return ret;
+	return 1;
 }
 
 static struct nfct_proto tcp = {

Modified: trunk/libnetfilter_conntrack/extensions/libnetfilter_conntrack_udp.c
===================================================================
--- trunk/libnetfilter_conntrack/extensions/libnetfilter_conntrack_udp.c	2005-12-25 21:03:43 UTC (rev 6338)
+++ trunk/libnetfilter_conntrack/extensions/libnetfilter_conntrack_udp.c	2005-12-26 02:29:02 UTC (rev 6339)
@@ -46,26 +46,24 @@
 		   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;
+			return 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;
+			return 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;
+			return 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 0;
 
-	return ret;
+	return 1;
 }
 
 static struct nfct_proto udp = {

Modified: trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/Makefile.am
===================================================================
--- trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/Makefile.am	2005-12-25 21:03:43 UTC (rev 6338)
+++ trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/Makefile.am	2005-12-26 02:29:02 UTC (rev 6339)
@@ -1,4 +1,4 @@
 
-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
+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 libnetfilter_conntrack_ipv4.h libnetfilter_conntrack_ipv6.h
 
 noinst_HEADERS = libnetfilter_conntrack_extensions.h

Modified: trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h
===================================================================
--- trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h	2005-12-25 21:03:43 UTC (rev 6338)
+++ trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h	2005-12-26 02:29:02 UTC (rev 6339)
@@ -109,8 +109,9 @@
 
 struct nfct_conntrack_compare {
 	struct nfct_conntrack *ct;
-	unsigned int flag;
-	unsigned int protoflag;
+	unsigned int flags;
+	unsigned int l3flags;
+	unsigned int l4flags;
 };
 
 enum {
@@ -294,8 +295,7 @@
  */
 extern int nfct_conntrack_compare(struct nfct_conntrack *ct1, 
 				  struct nfct_conntrack *ct2,
-				  unsigned int cmp_flag,
-				  unsigned int cmp_protoflag);
+				  struct nfct_conntrack_compare *cmp);
 
 /* 
  * Expectations

Added: trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack_ipv4.h
===================================================================
--- trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack_ipv4.h	2005-12-25 21:03:43 UTC (rev 6338)
+++ trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack_ipv4.h	2005-12-26 02:29:02 UTC (rev 6339)
@@ -0,0 +1,29 @@
+/*
+ * (C) 2005 by Pablo Neira Ayuso <pablo at 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_IPV4_H_
+#define _LIBNETFILTER_CONNTRACK_IPV4_H_
+
+enum ipv4_flags {
+	IPV4_ORIG_SRC_BIT = 0,
+	IPV4_ORIG_SRC = (1 << IPV4_ORIG_SRC_BIT),
+
+	IPV4_ORIG_DST_BIT = 1,
+	IPV4_ORIG_DST = (1 << IPV4_ORIG_DST_BIT),
+
+	IPV4_ORIG = (IPV4_ORIG_SRC | IPV4_ORIG_DST),
+
+	IPV4_REPL_SRC_BIT = 2,
+	IPV4_REPL_SRC = (1 << IPV4_REPL_SRC_BIT),
+
+	IPV4_REPL_DST_BIT = 3,
+	IPV4_REPL_DST = (1 << IPV4_REPL_DST_BIT),
+
+	IPV4_REPL = (IPV4_REPL_SRC | IPV4_REPL_DST)
+};
+
+#endif

Added: trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack_ipv6.h
===================================================================
--- trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack_ipv6.h	2005-12-25 21:03:43 UTC (rev 6338)
+++ trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack_ipv6.h	2005-12-26 02:29:02 UTC (rev 6339)
@@ -0,0 +1,29 @@
+/*
+ * (C) 2005 by Pablo Neira Ayuso <pablo at 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_IPV6_H_
+#define _LIBNETFILTER_CONNTRACK_IPV6_H_
+
+enum ipv6_flags {
+	IPV6_ORIG_SRC_BIT = 0,
+	IPV6_ORIG_SRC = (1 << IPV6_ORIG_SRC_BIT),
+
+	IPV6_ORIG_DST_BIT = 1,
+	IPV6_ORIG_DST = (1 << IPV6_ORIG_DST_BIT),
+
+	IPV6_ORIG = (IPV6_ORIG_SRC | IPV6_ORIG_DST),
+
+	IPV6_REPL_SRC_BIT = 2,
+	IPV6_REPL_SRC = (1 << IPV6_REPL_SRC_BIT),
+
+	IPV6_REPL_DST_BIT = 3,
+	IPV6_REPL_DST = (1 << IPV6_REPL_DST_BIT),
+
+	IPV6_REPL = (IPV6_REPL_SRC | IPV6_REPL_DST)
+};
+
+#endif

Added: trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack_l3extensions.h
===================================================================
--- trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack_l3extensions.h	2005-12-25 21:03:43 UTC (rev 6338)
+++ trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack_l3extensions.h	2005-12-26 02:29:02 UTC (rev 6339)
@@ -0,0 +1,29 @@
+/*
+ * (C) 2005 by Pablo Neira Ayuso <pablo at 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_L3EXTENSIONS_H_
+#define _LIBNETFILTER_CONNTRACK_L3EXTENSIONS_H_
+
+#include "linux_list.h"
+
+struct nfct_l3proto {
+	struct list_head head;
+	
+	char 		*name;
+	u_int16_t 	protonum;
+	char		*version;
+	
+	void (*parse_proto)(struct nfattr **, struct nfct_tuple *);
+	void (*build_tuple_proto)(struct nfnlhdr *, int, struct nfct_tuple *);
+	int (*print_proto)(char *, struct nfct_tuple *);
+	int (*compare)(struct nfct_conntrack *, struct nfct_conntrack *,
+		       unsigned int);
+};
+
+extern void nfct_register_l3proto(struct nfct_l3proto *h);
+
+#endif

Added: trunk/libnetfilter_conntrack/l3extensions/Makefile.am
===================================================================
--- trunk/libnetfilter_conntrack/l3extensions/Makefile.am	2005-12-25 21:03:43 UTC (rev 6338)
+++ trunk/libnetfilter_conntrack/l3extensions/Makefile.am	2005-12-26 02:29:02 UTC (rev 6339)
@@ -0,0 +1,16 @@
+include $(top_srcdir)/Make_global.am
+
+AUTOMAKE_OPTIONS = no-dependencies foreign
+
+AM_CFLAGS=-fPIC -Wall
+LIBS=
+
+pkglib_LTLIBRARIES = nfct_l3proto_ipv4.la nfct_l3proto_ipv6.la
+
+nfct_l3proto_ipv4_la_SOURCES = libnetfilter_conntrack_ipv4.c 
+nfct_l3proto_ipv4_la_LDFLAGS = -module -avoid-version -release $(VERSION)
+nfct_l3proto_ipv4_la_LIBADD = ../src/libnetfilter_conntrack.la
+
+nfct_l3proto_ipv6_la_SOURCES = libnetfilter_conntrack_ipv6.c
+nfct_l3proto_ipv6_la_LDFLAGS = -module -avoid-version -release $(VERSION)
+nfct_l3proto_ipv6_la_LIBADD = ../src/libnetfilter_conntrack.la

Added: trunk/libnetfilter_conntrack/l3extensions/libnetfilter_conntrack_ipv4.c
===================================================================
--- trunk/libnetfilter_conntrack/l3extensions/libnetfilter_conntrack_ipv4.c	2005-12-25 21:03:43 UTC (rev 6338)
+++ trunk/libnetfilter_conntrack/l3extensions/libnetfilter_conntrack_ipv4.c	2005-12-26 02:29:02 UTC (rev 6339)
@@ -0,0 +1,94 @@
+/*
+ * (C) 2005 by Pablo Neira Ayuso <pablo at netfilter.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <stdio.h>
+#include <arpa/inet.h>
+#include <netinet/in.h> /* For htons */
+#include <libnetfilter_conntrack/linux_nfnetlink_conntrack.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack_l3extensions.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack_ipv4.h>
+
+static void parse_proto(struct nfattr *cda[], struct nfct_tuple *tuple)
+{
+	if (cda[CTA_IP_V4_SRC-1])
+		tuple->src.v4 = *(u_int32_t *)NFA_DATA(cda[CTA_IP_V4_SRC-1]);
+
+	if (cda[CTA_IP_V4_DST-1])
+		tuple->dst.v4 = *(u_int32_t *)NFA_DATA(cda[CTA_IP_V4_DST-1]);
+}
+
+static void build_tuple_proto(struct nfnlhdr *req, int size,
+                              struct nfct_tuple *t)
+{
+	nfnl_addattr_l(&req->nlh, size, CTA_IP_V4_SRC, &t->src.v4,
+		       sizeof(u_int32_t));
+	nfnl_addattr_l(&req->nlh, size, CTA_IP_V4_DST, &t->dst.v4,
+		       sizeof(u_int32_t));
+}
+
+static int print_proto(char *buf, struct nfct_tuple *tuple)
+{
+	struct in_addr src = { .s_addr = tuple->src.v4 };
+	struct in_addr dst = { .s_addr = tuple->dst.v4 };
+	int size;
+
+	size = sprintf(buf, "src=%s ", inet_ntoa(src));
+	size += sprintf(buf+size, "dst=%s ", inet_ntoa(dst));
+
+	return size;
+}
+
+static int compare(struct nfct_conntrack *ct1,
+		   struct nfct_conntrack *ct2,
+		   unsigned int flags)
+{
+	if (flags & IPV4_ORIG)
+		if (ct1->tuple[NFCT_DIR_ORIGINAL].l3protonum !=
+		    ct2->tuple[NFCT_DIR_ORIGINAL].l3protonum)
+			return 0;
+	if (flags & IPV4_REPL)
+		if (ct1->tuple[NFCT_DIR_REPLY].l3protonum !=
+		    ct2->tuple[NFCT_DIR_REPLY].l3protonum)
+			return 0;
+	if (flags & IPV4_ORIG_SRC)
+		if (ct1->tuple[NFCT_DIR_ORIGINAL].src.v4 !=
+		    ct2->tuple[NFCT_DIR_ORIGINAL].src.v4)
+			return 0;
+	if (flags & IPV4_ORIG_DST)
+		if (ct1->tuple[NFCT_DIR_ORIGINAL].dst.v4 !=
+		    ct2->tuple[NFCT_DIR_ORIGINAL].dst.v4)
+			return 0;
+	if (flags & IPV4_REPL_SRC)
+		if (ct1->tuple[NFCT_DIR_REPLY].src.v4 !=
+		    ct2->tuple[NFCT_DIR_REPLY].src.v4)
+			return 0;
+	if (flags & IPV4_REPL_DST)
+		if (ct1->tuple[NFCT_DIR_REPLY].dst.v4 !=
+		    ct2->tuple[NFCT_DIR_REPLY].dst.v4)
+			return 0;
+
+	return 1;
+}
+
+static struct nfct_l3proto ipv4 = {
+	.name			= "ipv4",
+	.protonum		= AF_INET,
+	.parse_proto		= parse_proto,
+	.build_tuple_proto	= build_tuple_proto,
+	.print_proto		= print_proto,
+	.compare		= compare,
+	.version		= VERSION
+};
+
+static void __attribute__ ((constructor)) init(void);
+
+static void init(void)
+{
+        nfct_register_l3proto(&ipv4);
+}

Added: trunk/libnetfilter_conntrack/l3extensions/libnetfilter_conntrack_ipv6.c
===================================================================
--- trunk/libnetfilter_conntrack/l3extensions/libnetfilter_conntrack_ipv6.c	2005-12-25 21:03:43 UTC (rev 6338)
+++ trunk/libnetfilter_conntrack/l3extensions/libnetfilter_conntrack_ipv6.c	2005-12-26 02:29:02 UTC (rev 6339)
@@ -0,0 +1,115 @@
+/*
+ * (C) 2005 by Pablo Neira Ayuso <pablo at netfilter.org>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <stdio.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h> /* For htons */
+#include <arpa/inet.h>
+#include <libnetfilter_conntrack/linux_nfnetlink_conntrack.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack_l3extensions.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack_ipv6.h>
+
+#ifndef HAVE_INET_NTOP_IPV6
+#warning "inet_ntop does not support IPv6"
+#endif
+
+static void parse_proto(struct nfattr *cda[], struct nfct_tuple *tuple)
+{
+	if (cda[CTA_IP_V6_SRC-1])
+		memcpy(tuple->src.v6, NFA_DATA(cda[CTA_IP_V6_SRC-1]), 
+		       sizeof(u_int32_t)*4);
+
+	if (cda[CTA_IP_V6_DST-1])
+		memcpy(tuple->dst.v6, NFA_DATA(cda[CTA_IP_V6_DST-1]),
+		       sizeof(u_int32_t)*4);
+}
+
+static void build_tuple_proto(struct nfnlhdr *req, int size,
+                              struct nfct_tuple *t)
+{
+	nfnl_addattr_l(&req->nlh, size, CTA_IP_V6_SRC, &t->src.v6,
+		       sizeof(u_int32_t)*4);
+	nfnl_addattr_l(&req->nlh, size, CTA_IP_V6_DST, &t->dst.v6,
+		       sizeof(u_int32_t)*4);
+}
+
+static int print_proto(char *buf, struct nfct_tuple *tuple)
+{
+	struct in6_addr src;
+	struct in6_addr dst;
+	char tmp[INET6_ADDRSTRLEN];
+	int size;
+
+	memcpy(&src.in6_u, tuple->src.v6, sizeof(struct in6_addr));
+	memcpy(&dst.in6_u, tuple->dst.v6, sizeof(struct in6_addr));
+
+	if (!inet_ntop(AF_INET6, &src, tmp, sizeof(tmp)))
+		return 0;
+	size = sprintf(buf, "src=%s ", tmp);
+	if (!inet_ntop(AF_INET6, &dst, tmp, sizeof(tmp)))
+		return 0;
+	size += sprintf(buf + size, "dst=%s ", tmp);
+
+	return size;
+}
+
+static int compare(struct nfct_conntrack *ct1,
+		   struct nfct_conntrack *ct2,
+		   unsigned int flags)
+{
+	if (flags & IPV6_ORIG)
+		if (ct1->tuple[NFCT_DIR_ORIGINAL].l3protonum !=
+		    ct2->tuple[NFCT_DIR_ORIGINAL].l3protonum)
+			return 0;
+	if (flags & IPV6_REPL)
+		if (ct1->tuple[NFCT_DIR_REPLY].l3protonum !=
+		    ct2->tuple[NFCT_DIR_REPLY].l3protonum)
+			return 0;
+	if (flags & IPV6_ORIG_SRC)
+		if (memcmp(ct1->tuple[NFCT_DIR_ORIGINAL].src.v6,
+			   ct2->tuple[NFCT_DIR_ORIGINAL].src.v6,
+			   sizeof(u_int32_t)*4) == 0)
+			return 0;
+	if (flags & IPV6_ORIG_DST)
+		if (memcmp(ct1->tuple[NFCT_DIR_ORIGINAL].dst.v6,
+			   ct2->tuple[NFCT_DIR_ORIGINAL].dst.v6,
+			   sizeof(u_int32_t)*4) == 0)
+			return 0;
+	if (flags & IPV6_REPL_SRC)
+		if (memcmp(ct1->tuple[NFCT_DIR_REPLY].src.v6,
+			   ct2->tuple[NFCT_DIR_REPLY].src.v6,
+			   sizeof(u_int32_t)*4) == 0)
+			return 0;
+	if (flags & IPV6_REPL_DST)
+		if (memcmp(ct1->tuple[NFCT_DIR_REPLY].dst.v6,
+			   ct2->tuple[NFCT_DIR_REPLY].dst.v6,
+			   sizeof(u_int32_t)*4) == 0)
+			return 0;
+
+	return 1;
+}
+
+static struct nfct_l3proto ipv6 = {
+	.name			= "ipv6",
+	.protonum		= AF_INET6,
+	.parse_proto		= parse_proto,
+	.build_tuple_proto	= build_tuple_proto,
+	.print_proto		= print_proto,
+	.compare		= compare,
+	.version		= VERSION
+};
+
+static void __attribute__ ((constructor)) init(void);
+
+static void init(void)
+{
+        nfct_register_l3proto(&ipv6);
+}

Modified: trunk/libnetfilter_conntrack/src/libnetfilter_conntrack.c
===================================================================
--- trunk/libnetfilter_conntrack/src/libnetfilter_conntrack.c	2005-12-25 21:03:43 UTC (rev 6338)
+++ trunk/libnetfilter_conntrack/src/libnetfilter_conntrack.c	2005-12-26 02:29:02 UTC (rev 6339)
@@ -19,6 +19,7 @@
 #include "linux_list.h"
 #include <libnfnetlink/libnfnetlink.h>
 #include <libnetfilter_conntrack/libnetfilter_conntrack.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack_l3extensions.h>
 #include <libnetfilter_conntrack/libnetfilter_conntrack_extensions.h>
 
 #define NFCT_BUFSIZE 4096
@@ -36,13 +37,19 @@
 
 static char *lib_dir = LIBNETFILTER_CONNTRACK_DIR;
 static LIST_HEAD(proto_list);
+static LIST_HEAD(l3proto_list);
 static char *proto2str[IPPROTO_MAX] = {
 	[IPPROTO_TCP] = "tcp",
         [IPPROTO_UDP] = "udp",
         [IPPROTO_ICMP] = "icmp",
         [IPPROTO_SCTP] = "sctp"
 };
+static char *l3proto2str[AF_MAX] = {
+	[AF_INET] = "ipv4",
+	[AF_INET6] = "ipv6"
+};
 static struct nfct_proto *findproto(char *name);
+static struct nfct_l3proto *findl3proto(char *name);
 
 /* handler used for nfnl_listen */
 static int callback_handler(struct sockaddr_nl *nladdr,
@@ -133,15 +140,14 @@
 				struct nfct_tuple *t)
 {
 	struct nfattr *nest;
+	struct nfct_l3proto *h;
 
 	nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_IP);
 
-	nfnl_addattr_l(&req->nlh, size, CTA_IP_V4_SRC, &t->src.v4, 
-		       sizeof(u_int32_t));
+	h = findl3proto(l3proto2str[t->l3protonum]);
+	if (h && h->build_tuple_proto)
+		h->build_tuple_proto(req, size, t);
 
-	nfnl_addattr_l(&req->nlh, size, CTA_IP_V4_DST, &t->dst.v4,
-		       sizeof(u_int32_t));
-
 	nfnl_nest_end(&req->nlh, nest);
 }
 
@@ -282,6 +288,39 @@
 	return handler;
 }
 
+static struct nfct_l3proto *findl3proto(char *name)
+{
+	struct list_head *i;
+	struct nfct_l3proto *cur = NULL, *handler = NULL;
+
+	if (!name) 
+		return handler;
+
+	lib_dir = getenv("LIBNETFILTER_CONNTRACK_DIR");
+	if (!lib_dir)
+		lib_dir = LIBNETFILTER_CONNTRACK_DIR;
+
+	list_for_each(i, &l3proto_list) {
+		cur = (struct nfct_l3proto *) i;
+		if (strcmp(cur->name, name) == 0) {
+			handler = cur;
+			break;
+		}
+	}
+
+	if (!handler) {
+		char path[sizeof("nfct_l3proto_.so") + strlen(VERSION)
+			 + strlen(name) + strlen(lib_dir)];
+                sprintf(path, "%s/nfct_l3proto_%s-%s.so",lib_dir,name,VERSION);
+		if (dlopen(path, RTLD_NOW))
+			handler = findl3proto(name);
+		else
+			fprintf(stderr, "%s\n", dlerror());
+	}
+
+	return handler;
+}
+
 int nfct_sprintf_status_assured(char *buf, struct nfct_conntrack *ct)
 {
 	int size = 0;
@@ -305,13 +344,12 @@
 static void parse_ip(struct nfattr *attr, struct nfct_tuple *tuple)
 {
 	struct nfattr *tb[CTA_IP_MAX];
+	struct nfct_l3proto *h;
 
         nfnl_parse_nested(tb, CTA_IP_MAX, attr);
-	if (tb[CTA_IP_V4_SRC-1])
-		tuple->src.v4 = *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_SRC-1]);
-
-	if (tb[CTA_IP_V4_DST-1])
-		tuple->dst.v4 = *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_DST-1]);
+	h = findl3proto(l3proto2str[tuple->l3protonum]);
+	if (h && h->parse_proto)
+		h->parse_proto(tb, tuple);
 }
 
 static void parse_proto(struct nfattr *attr, struct nfct_tuple *tuple)
@@ -412,6 +450,9 @@
 
 	memset(&ct, 0, sizeof(struct nfct_conntrack));
 
+	ct.tuple[NFCT_DIR_ORIGINAL].l3protonum = nfhdr->nfgen_family;
+	ct.tuple[NFCT_DIR_REPLY].l3protonum = nfhdr->nfgen_family;
+
 	nfnl_parse_attr(cda, CTA_MAX, NFA_DATA(nfhdr), len);
 
 	if (cda[CTA_TUPLE_ORIG-1])
@@ -500,11 +541,11 @@
 int nfct_sprintf_address(char *buf, struct nfct_tuple *t)
 {
 	int size = 0;
-	struct in_addr src = { .s_addr = t->src.v4 };
-	struct in_addr dst = { .s_addr = t->dst.v4 };
+	struct nfct_l3proto *h;
 
-	size += sprintf(buf, "src=%s ", inet_ntoa(src));
-	size += sprintf(buf+size, "dst=%s ", inet_ntoa(dst));
+	h = findl3proto(l3proto2str[t->l3protonum]);
+	if (h && h->print_proto)
+		size += h->print_proto(buf, t);
 
 	return size;
 }
@@ -607,7 +648,7 @@
 	int size;
 	struct nfct_conntrack_compare *cmp = data;
 
-	if (cmp && !nfct_conntrack_compare(cmp->ct, arg, 0, cmp->protoflag))
+	if (cmp && !nfct_conntrack_compare(cmp->ct, arg, cmp))
 		return 0;
 
 	memset(buf, 0, sizeof(buf));
@@ -625,7 +666,7 @@
 	int size;
         struct nfct_conntrack_compare *cmp = data;
 
-	if (cmp && !nfct_conntrack_compare(cmp->ct, arg, 0, cmp->protoflag))
+	if (cmp && !nfct_conntrack_compare(cmp->ct, arg, cmp))
 		return 0;
 
 	memset(buf, 0, sizeof(buf));
@@ -639,8 +680,20 @@
 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);
+	char buf[512];
+	int size;
+	struct nfct_conntrack_compare *cmp = data;
+
+	if (cmp && !nfct_conntrack_compare(cmp->ct, arg, cmp))
+		return 0;
+
+	memset(buf, 0, sizeof(buf));
+	size = sprintf(buf, "%9s ", msgtype[type]);
+	size += nfct_sprintf_conntrack_id(buf + size, arg, flags);
+	sprintf(buf+size, "\n");
+	fprintf(stdout, buf);
+
+	return 0;
 }
 
 int nfct_sprintf_expect_proto(char *buf, struct nfct_expect *exp)
@@ -715,6 +768,8 @@
 	
 	memset(&exp, 0, sizeof(struct nfct_expect));
 
+	exp.tuple.l3protonum = nfhdr->nfgen_family;
+
 	nfnl_parse_attr(cda, CTA_EXPECT_MAX, NFA_DATA(nfhdr), len);
 
 	if (cda[CTA_EXPECT_TUPLE-1])
@@ -770,26 +825,55 @@
 	free(ct);
 }
 
+#define L3PROTONUM(ct) ct->tuple[NFCT_DIR_ORIGINAL].l3protonum
+#define L4PROTONUM(ct) ct->tuple[NFCT_DIR_ORIGINAL].protonum
+
 int nfct_conntrack_compare(struct nfct_conntrack *ct1,
 			   struct nfct_conntrack *ct2,
-			   unsigned int cmp_flag,
-			   unsigned int cmp_protoflag)
+			   struct nfct_conntrack_compare *cmp)
 {
+	struct nfct_l3proto *l3proto;
 	struct nfct_proto *proto;
+	unsigned int l3flags = cmp->l3flags;
+	unsigned int l4flags = cmp->l4flags;
+	unsigned int flags = cmp->flags;
 
-	if (ct1->tuple[NFCT_DIR_ORIGINAL].protonum !=
-	    ct2->tuple[NFCT_DIR_ORIGINAL].protonum)
+	if ((flags & NFCT_MARK) && (ct1->mark != ct2->mark))
 		return 0;
 
-	/*
-	 * TODO: implement tuple, status, mark... comparison.
-	 */
+	if (l3flags) {
+		if (ct1->tuple[NFCT_DIR_ORIGINAL].l3protonum != AF_UNSPEC && 
+		    ct2->tuple[NFCT_DIR_ORIGINAL].l3protonum != AF_UNSPEC &&
+		    ct1->tuple[NFCT_DIR_ORIGINAL].l3protonum !=
+		    ct2->tuple[NFCT_DIR_ORIGINAL].l3protonum)
+				return 0;
+		if (ct1->tuple[NFCT_DIR_REPLY].l3protonum != AF_UNSPEC && 
+		    ct2->tuple[NFCT_DIR_REPLY].l3protonum != AF_UNSPEC &&
+		    ct1->tuple[NFCT_DIR_REPLY].l3protonum !=
+		    ct2->tuple[NFCT_DIR_REPLY].l3protonum)
+				return 0;
+		l3proto = findl3proto(l3proto2str[L3PROTONUM(ct1)]);
+		if (l3proto && !l3proto->compare(ct1, ct2, l3flags))
+			return 0;
+	}
 
-	proto = findproto(proto2str[ct1->tuple[NFCT_DIR_ORIGINAL].protonum]);
-	if (!proto)
-		return 0;
+	if (l4flags) {
+		if (ct1->tuple[NFCT_DIR_ORIGINAL].protonum != 0 && 
+		    ct2->tuple[NFCT_DIR_ORIGINAL].protonum != 0 &&
+		    ct1->tuple[NFCT_DIR_ORIGINAL].protonum !=
+		    ct2->tuple[NFCT_DIR_ORIGINAL].protonum)
+				return 0;
+		if (ct1->tuple[NFCT_DIR_REPLY].protonum != 0 && 
+		    ct2->tuple[NFCT_DIR_REPLY].protonum != 0 &&
+		    ct1->tuple[NFCT_DIR_REPLY].protonum !=
+		    ct2->tuple[NFCT_DIR_REPLY].protonum)
+				return 0;
+		proto = findproto(proto2str[L4PROTONUM(ct1)]);
+		if (proto && !proto->compare(ct1, ct2, l4flags))
+			return 0;
+	}
 
-	return proto->compare(ct1, ct2, cmp_protoflag);
+	return 1;
 }
 
 int nfct_create_conntrack(struct nfct_handle *cth, struct nfct_conntrack *ct)
@@ -799,12 +883,13 @@
 	u_int32_t status = htonl(ct->status | IPS_CONFIRMED);
 	u_int32_t timeout = htonl(ct->timeout);
 	u_int32_t mark = htonl(ct->mark);
+	u_int8_t l3num = ct->tuple[NFCT_DIR_ORIGINAL].l3protonum;
 
 	req = (void *) buf;
 
 	memset(buf, 0, sizeof(buf));
 	
-	nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, AF_INET, 0, IPCTNL_MSG_CT_NEW,
+	nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, l3num, 0, IPCTNL_MSG_CT_NEW,
 		      NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK|NLM_F_EXCL);
 
 	nfct_build_tuple(req, sizeof(buf), &ct->tuple[NFCT_DIR_ORIGINAL], 
@@ -838,11 +923,12 @@
 	u_int32_t timeout = htonl(ct->timeout);
 	u_int32_t id = htonl(ct->id);
 	u_int32_t mark = htonl(ct->mark);
+	u_int8_t l3num = ct->tuple[NFCT_DIR_ORIGINAL].l3protonum;
 
 	req = (void *) &buf;
 	memset(&buf, 0, sizeof(buf));
 
-	nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, AF_INET, 0, IPCTNL_MSG_CT_NEW,
+	nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, l3num, 0, IPCTNL_MSG_CT_NEW,
 		      NLM_F_REQUEST|NLM_F_ACK);	
 
 	nfct_build_tuple(req, sizeof(buf), &ct->tuple[NFCT_DIR_ORIGINAL], 
@@ -881,12 +967,13 @@
 	struct nfnlhdr *req;
 	char buf[NFCT_BUFSIZE];
 	int type = dir ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG;
+	 u_int8_t l3num = tuple->l3protonum;
 
 	req = (void *) &buf;
 	memset(&buf, 0, sizeof(buf));
 
 	nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, 
-		      AF_INET, 0, IPCTNL_MSG_CT_DELETE, 
+		      l3num, 0, IPCTNL_MSG_CT_DELETE, 
 		      NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_ACK);
 
 	nfct_build_tuple(req, sizeof(buf), tuple, type);
@@ -907,6 +994,7 @@
 	struct nfnlhdr *req;
 	char buf[NFCT_BUFSIZE];
 	int type = dir ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG;
+	u_int8_t l3num = tuple->l3protonum;
 
 	cth->handler = nfct_conntrack_netlink_handler;
 	
@@ -914,7 +1002,7 @@
 	req = (void *) &buf;
 
 	nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0,
-		      AF_INET, 0, IPCTNL_MSG_CT_GET,
+		      l3num, 0, IPCTNL_MSG_CT_GET,
 		      NLM_F_REQUEST|NLM_F_ACK);
 	
 	nfct_build_tuple(req, sizeof(buf), tuple, type);
@@ -989,6 +1077,16 @@
 	list_add(&h->head, &proto_list);
 }
 
+void nfct_register_l3proto(struct nfct_l3proto *h)
+{
+	if (strcmp(h->version, VERSION) != 0) {
+		fprintf(stderr, "plugin `%s': version %s (I'm %s)\n",
+			h->name, h->version, VERSION);
+		exit(1);
+	}
+	list_add(&h->head, &l3proto_list);
+}
+
 int nfct_dump_expect_list(struct nfct_handle *cth, int family)
 {
 	int err;
@@ -1026,11 +1124,12 @@
 	int err;
 	struct nfnlhdr *req;
 	char buf[NFCT_BUFSIZE];
+	u_int8_t l3num = tuple->l3protonum;
 
 	memset(&buf, 0, sizeof(buf));
 	req = (void *) &buf;
 
-	nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, AF_INET, 0, IPCTNL_MSG_EXP_GET,
+	nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, l3num, 0, IPCTNL_MSG_EXP_GET,
 		      NLM_F_REQUEST|NLM_F_ACK);
 
 	cth->handler = nfct_expect_netlink_handler;
@@ -1080,10 +1179,11 @@
 	struct nfnlhdr *req;
 	char buf[NFCT_BUFSIZE];
 	req = (void *) &buf;
+	u_int8_t l3num = exp->tuple.l3protonum;
 
 	memset(&buf, 0, sizeof(buf));
 
-	nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, AF_INET, 0, IPCTNL_MSG_EXP_NEW,
+	nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, l3num, 0, IPCTNL_MSG_EXP_NEW,
 		      NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK);
 
 	nfct_build_tuple(req, sizeof(buf), &exp->master, CTA_EXPECT_MASTER);
@@ -1106,11 +1206,12 @@
 	int err;
 	struct nfnlhdr *req;
 	char buf[NFCT_BUFSIZE];
+	u_int8_t l3num = tuple->l3protonum;
 
 	memset(&buf, 0, sizeof(buf));
 	req = (void *) &buf;
 	
-	nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, AF_INET, 
+	nfnl_fill_hdr(&cth->nfnlh, &req->nlh, 0, l3num, 
 		      0, IPCTNL_MSG_EXP_DELETE,
 		      NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_ACK);
 




More information about the netfilter-cvslog mailing list