[netfilter-cvslog] r6820 - in trunk/conntrack-tools: . examples/cli extensions include src

pablo at netfilter.org pablo at netfilter.org
Sun May 6 19:36:13 CEST 2007


Author: pablo at netfilter.org
Date: 2007-05-06 19:36:13 +0200 (Sun, 06 May 2007)
New Revision: 6820

Removed:
   trunk/conntrack-tools/extensions/libct_proto_sctp.c
Modified:
   trunk/conntrack-tools/conntrack.8
   trunk/conntrack-tools/examples/cli/test.sh
   trunk/conntrack-tools/extensions/Makefile.am
   trunk/conntrack-tools/extensions/libct_proto_icmp.c
   trunk/conntrack-tools/extensions/libct_proto_tcp.c
   trunk/conntrack-tools/extensions/libct_proto_udp.c
   trunk/conntrack-tools/include/conntrack.h
   trunk/conntrack-tools/src/conntrack.c
Log:
- add warning note to ctnl_test.c: old API is deprecated
- split expect_api_test.c into small example files expect_*.c
- introduce alias tags for original tuple attributes
- introduce nfexp_sizeof and nfexp_maxsize
- build expectation attributes iif they are set
- fix l3num setting in expect/build.c



Modified: trunk/conntrack-tools/conntrack.8
===================================================================
--- trunk/conntrack-tools/conntrack.8	2007-05-02 13:22:07 UTC (rev 6819)
+++ trunk/conntrack-tools/conntrack.8	2007-05-06 17:36:13 UTC (rev 6820)
@@ -1,6 +1,7 @@
-.TH CONNTRACK 8 "Jun 23, 2005" "" ""
+.TH CONNTRACK 8 "May 6, 2007" "" ""
 
 .\" Man page written by Harald Welte <laforge at netfilter.org (Jun 2005)
+.\" Maintained by Pablo Neira Ayuso <pablo at netfilter.org (May 2007)
 
 .SH NAME
 conntrack \- administration tool for netfilter connection tracking
@@ -74,6 +75,10 @@
 Atomically zero counters after reading them.  This option is only valid in
 combination with the "-L, --dump" command options.
 .TP
+.BI "-x, --xml "
+Display output in XML format.  This option is only valid in combination with 
+the "-L, --dump", "-E, --event" and "-G, --get" command options.
+.TP
 .BI "-e, --event-mask " "[ALL|NEW|UPDATES|DESTROY][,...]"
 Set the bitmask of events that are to be generated by the in-kernel ctnetlink
 event code.  Using this parameter, you can reduce the event messages generated
@@ -139,4 +144,4 @@
 .PP
 Pablo Neira wrote the conntrack tool, Harald Welte added support for conntrack based accounting counters.
 .PP
-Man page written by Harald Welte <laforge at netfilter.org>.
+Man page written by Harald Welte <laforge at netfilter.org> and Pablo Neira Ayuso <pablo at netfilter.org>.

Modified: trunk/conntrack-tools/examples/cli/test.sh
===================================================================
--- trunk/conntrack-tools/examples/cli/test.sh	2007-05-02 13:22:07 UTC (rev 6819)
+++ trunk/conntrack-tools/examples/cli/test.sh	2007-05-06 17:36:13 UTC (rev 6820)
@@ -32,7 +32,7 @@
 		echo "creating a new conntrack (NAT)"
 		$CONNTRACK -I --orig-src $SRC --orig-dst $DST \
 		-p tcp --orig-port-src $SPORT  --orig-port-dst $DPORT \
-		--state LISTEN -u SEEN_REPLY,SRC_NAT -t 50 -a 8.8.8.8
+		--state LISTEN -u SEEN_REPLY -t 50 --dst-nat 8.8.8.8
 		;;
 	get)
 		echo "getting a conntrack"
@@ -78,18 +78,17 @@
 		--tuple-src 4.4.4.4 --tuple-dst 5.5.5.5 \
 		--mask-src 255.255.255.0 --mask-dst 255.255.255.255 \
 		-p tcp --orig-port-src $SPORT --orig-port-dst $DPORT \
-		-t 200 --tuple-port-src 10 --tuple-port-dst 300 \
+		-t 200 --tuple-port-src 10240 --tuple-port-dst 10241\
 		--mask-port-src 10 --mask-port-dst 300
 		;;
 	get-expect)
 		$CONNTRACK -G expect --orig-src 4.4.4.4 --orig-dst 5.5.5.5 \
-		--p tcp --orig-port-src 0 --orig-port-dst 0 \
-		--mask-port-src 10 --mask-port-dst 11
+		--p tcp --orig-port-src 10240 --orig-port-dst 10241
 		;;
 	delete-expect)
 		$CONNTRACK -D expect --orig-src 4.4.4.4 \
-		--orig-dst 5.5.5.5 -p tcp --orig-port-src 0 \
-		--orig-port-dst 0 --mask-port-src 10 --mask-port-dst 11
+		--orig-dst 5.5.5.5 -p tcp --orig-port-src 10240 \
+		--orig-port-dst 10241
 		;;
 	*)
 		echo "Usage: $0 [dump"

Modified: trunk/conntrack-tools/extensions/Makefile.am
===================================================================
--- trunk/conntrack-tools/extensions/Makefile.am	2007-05-02 13:22:07 UTC (rev 6819)
+++ trunk/conntrack-tools/extensions/Makefile.am	2007-05-06 17:36:13 UTC (rev 6820)
@@ -4,7 +4,7 @@
 LIBS=
 
 pkglib_LTLIBRARIES = ct_proto_tcp.la ct_proto_udp.la		\
-		     ct_proto_icmp.la ct_proto_sctp.la
+		     ct_proto_icmp.la
 
 ct_proto_tcp_la_SOURCES = libct_proto_tcp.c
 ct_proto_tcp_la_LDFLAGS = -module -avoid-version
@@ -12,5 +12,3 @@
 ct_proto_udp_la_LDFLAGS = -module -avoid-version
 ct_proto_icmp_la_SOURCES = libct_proto_icmp.c
 ct_proto_icmp_la_LDFLAGS = -module -avoid-version
-ct_proto_sctp_la_SOURCES = libct_proto_sctp.c
-ct_proto_sctp_la_LDFLAGS = -module -avoid-version

Modified: trunk/conntrack-tools/extensions/libct_proto_icmp.c
===================================================================
--- trunk/conntrack-tools/extensions/libct_proto_icmp.c	2007-05-02 13:22:07 UTC (rev 6819)
+++ trunk/conntrack-tools/extensions/libct_proto_icmp.c	2007-05-06 17:36:13 UTC (rev 6820)
@@ -1,6 +1,6 @@
 /*
- * (C) 2005 by Pablo Neira Ayuso <pablo at eurodev.net>
- *	       Harald Welte <laforge at netfilter.org>
+ * (C) 2005-2007 by Pablo Neira Ayuso <pablo at netfilter.org>
+ *     2005 by Harald Welte <laforge 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
@@ -43,35 +43,42 @@
 	    [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1};
 
 static int parse(char c, char *argv[], 
-		 struct nfct_tuple *orig,
-		 struct nfct_tuple *reply,
-		 struct nfct_tuple *exptuple,
-		 struct nfct_tuple *mask,
-		 union nfct_protoinfo *proto,
+		 struct nf_conntrack *ct,
+		 struct nf_conntrack *exptuple,
+		 struct nf_conntrack *mask,
 		 unsigned int *flags)
 {
 	switch(c) {
 		case '1':
-			if (optarg) {
-				orig->l4dst.icmp.type = atoi(optarg);
-				reply->l4dst.icmp.type =
-					invmap[orig->l4dst.icmp.type] - 1;
-				*flags |= ICMP_TYPE;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u8(ct, 
+					 ATTR_ICMP_TYPE,
+					 atoi(optarg));
+			/* FIXME: 
+			reply->l4dst.icmp.type =
+				invmap[orig->l4dst.icmp.type] - 1;
+			*/
+			*flags |= ICMP_TYPE;
 			break;
 		case '2':
-			if (optarg) {
-				orig->l4dst.icmp.code = atoi(optarg);
-				reply->l4dst.icmp.code = 0;
-				*flags |= ICMP_CODE;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u8(ct, 
+					 ATTR_ICMP_CODE,
+					 atoi(optarg));
+			*flags |= ICMP_CODE;
 			break;
 		case '3':
-			if (optarg) {
-				orig->l4src.icmp.id = htons(atoi(optarg));
-				reply->l4dst.icmp.id = 0;
-				*flags |= ICMP_ID;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(ct,
+					  ATTR_ICMP_ID,
+					  htons(atoi(optarg)));
+			*flags |= ICMP_ID;
 			break;
 	}
 	return 1;
@@ -79,8 +86,7 @@
 
 static int final_check(unsigned int flags,
 		       unsigned int command,
-		       struct nfct_tuple *orig,
-		       struct nfct_tuple *reply)
+		       struct nf_conntrack *ct)
 {
 	if (!(flags & ICMP_TYPE))
 		return 0;

Deleted: trunk/conntrack-tools/extensions/libct_proto_sctp.c
===================================================================
--- trunk/conntrack-tools/extensions/libct_proto_sctp.c	2007-05-02 13:22:07 UTC (rev 6819)
+++ trunk/conntrack-tools/extensions/libct_proto_sctp.c	2007-05-06 17:36:13 UTC (rev 6820)
@@ -1,164 +0,0 @@
-/*
- * (C) 2005 by Harald Welte <laforge at netfilter.org>
- *     2006 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 "conntrack.h"
-#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
-#include <libnetfilter_conntrack/libnetfilter_conntrack_sctp.h>
-
-static struct option opts[] = {
-	{"orig-port-src", 1, 0, '1'},
-	{"orig-port-dst", 1, 0, '2'},
-	{"reply-port-src", 1, 0, '3'},
-	{"reply-port-dst", 1, 0, '4'},
-	{"state", 1, 0, '5'},
-	{"tuple-port-src", 1, 0, '6'},
-	{"tuple-port-dst", 1, 0, '7'},
-	{0, 0, 0, 0}
-};
-
-static const char *states[] = {
-	"NONE",
-	"CLOSED",
-	"COOKIE_WAIT",
-	"COOKIE_ECHOED",
-	"ESTABLISHED",
-	"SHUTDOWN_SENT",
-	"SHUTDOWN_RECV",
-	"SHUTDOWN_ACK_SENT",
-};
-
-static void help()
-{
-	fprintf(stdout, "--orig-port-src        original source port\n");
-	fprintf(stdout, "--orig-port-dst        original destination port\n");
-	fprintf(stdout, "--reply-port-src       reply source port\n");
-	fprintf(stdout, "--reply-port-dst       reply destination port\n");
-	fprintf(stdout, "--state                SCTP state, fe. ESTABLISHED\n");
-	fprintf(stdout, "--tuple-port-src	expectation tuple src port\n");
-	fprintf(stdout, "--tuple-port-src	expectation tuple dst port\n");
-}
-
-static int parse_options(char c, char *argv[], 
-			 struct nfct_tuple *orig,
-			 struct nfct_tuple *reply,
-			 struct nfct_tuple *exptuple,
-			 struct nfct_tuple *mask,
-			 union nfct_protoinfo *proto,
-			 unsigned int *flags)
-{
-	switch(c) {
-		case '1':
-			if (optarg) {
-				orig->l4src.sctp.port = htons(atoi(optarg));
-				*flags |= SCTP_ORIG_SPORT;
-			}
-			break;
-		case '2':
-			if (optarg) {
-				orig->l4dst.sctp.port = htons(atoi(optarg));
-				*flags |= SCTP_ORIG_DPORT;
-			}
-			break;
-		case '3':
-			if (optarg) {
-				reply->l4src.sctp.port = htons(atoi(optarg));
-				*flags |= SCTP_REPL_SPORT;
-			}
-			break;
-		case '4':
-			if (optarg) {
-				reply->l4dst.sctp.port = htons(atoi(optarg));
-				*flags |= SCTP_REPL_DPORT;
-			}
-			break;
-		case '5':
-			if (optarg) {
-				int i;
-				for (i=0; i<10; i++) {
-					if (strcmp(optarg, states[i]) == 0) {
-						/* FIXME: Add state to
-						 * nfct_protoinfo
-						proto->sctp.state = i; */
-						break;
-					}
-				}
-				if (i == 10) {
-					printf("doh?\n");
-					return 0;
-				}
-				*flags |= SCTP_STATE;
-			}
-			break;
-		case '6':
-			if (optarg) {
-				exptuple->l4src.sctp.port = htons(atoi(optarg));
-				*flags |= SCTP_EXPTUPLE_SPORT;
-			}
-			break;
-		case '7':
-			if (optarg) {
-				exptuple->l4dst.sctp.port = htons(atoi(optarg));
-				*flags |= SCTP_EXPTUPLE_DPORT;
-			}
-
-	}
-	return 1;
-}
-
-static int final_check(unsigned int flags,
-		       unsigned int command,
-		       struct nfct_tuple *orig,
-		       struct nfct_tuple *reply)
-{
-	int ret = 0;
-	
-	if ((flags & (SCTP_ORIG_SPORT|SCTP_ORIG_DPORT)) 
-	    && !(flags & (SCTP_REPL_SPORT|SCTP_REPL_DPORT))) {
-		reply->l4src.sctp.port = orig->l4dst.sctp.port;
-		reply->l4dst.sctp.port = orig->l4src.sctp.port;
-		ret = 1;
-	} else if (!(flags & (SCTP_ORIG_SPORT|SCTP_ORIG_DPORT))
-	            && (flags & (SCTP_REPL_SPORT|SCTP_REPL_DPORT))) {
-		orig->l4src.sctp.port = reply->l4dst.sctp.port;
-		orig->l4dst.sctp.port = reply->l4src.sctp.port;
-		ret = 1;
-	}
-	if ((flags & (SCTP_ORIG_SPORT|SCTP_ORIG_DPORT)) 
-	    && ((flags & (SCTP_REPL_SPORT|SCTP_REPL_DPORT))))
-		ret = 1;
-
-	/* --state is missing and we are trying to create a conntrack */
-	if (ret && (command & CT_CREATE) && (!(flags & SCTP_STATE)))
-		ret = 0;
-
-	return ret;
-}
-
-static struct ctproto_handler sctp = {
-	.name 			= "sctp",
-	.protonum		= IPPROTO_SCTP,
-	.parse_opts		= parse_options,
-	.final_check		= final_check,
-	.help			= help,
-	.opts			= opts,
-	.version		= VERSION,
-};
-
-static void __attribute__ ((constructor)) init(void);
-
-static void init(void)
-{
-	register_proto(&sctp);
-}

Modified: trunk/conntrack-tools/extensions/libct_proto_tcp.c
===================================================================
--- trunk/conntrack-tools/extensions/libct_proto_tcp.c	2007-05-02 13:22:07 UTC (rev 6819)
+++ trunk/conntrack-tools/extensions/libct_proto_tcp.c	2007-05-06 17:36:13 UTC (rev 6820)
@@ -1,5 +1,5 @@
 /*
- * (C) 2005 by Pablo Neira Ayuso <pablo at eurodev.net>
+ * (C) 2005-2007 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
@@ -56,78 +56,112 @@
 	fprintf(stdout, "--state                TCP state, fe. ESTABLISHED\n");
 }
 
-static int parse_options(char c, char *argv[], 
-			 struct nfct_tuple *orig,
-			 struct nfct_tuple *reply,
-			 struct nfct_tuple *exptuple,
-			 struct nfct_tuple *mask,
-			 union nfct_protoinfo *proto,
+static int parse_options(char c, char *argv[],
+			 struct nf_conntrack *ct,
+			 struct nf_conntrack *exptuple,
+			 struct nf_conntrack *mask,
 			 unsigned int *flags)
 {
+	int i;
+
 	switch(c) {
 		case '1':
-			if (optarg) {
-				orig->l4src.tcp.port = htons(atoi(optarg));
-				*flags |= TCP_ORIG_SPORT;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(ct, 
+					  ATTR_ORIG_PORT_SRC, 
+					  htons(atoi(optarg)));
+
+			*flags |= TCP_ORIG_SPORT;
 			break;
 		case '2':
-			if (optarg) {
-				orig->l4dst.tcp.port = htons(atoi(optarg));
-				*flags |= TCP_ORIG_DPORT;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(ct, 
+					  ATTR_ORIG_PORT_DST, 
+					  htons(atoi(optarg)));
+
+			*flags |= TCP_ORIG_DPORT;
 			break;
 		case '3':
-			if (optarg) {
-				reply->l4src.tcp.port = htons(atoi(optarg));
-				*flags |= TCP_REPL_SPORT;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(ct, 
+					  ATTR_REPL_PORT_SRC, 
+					  htons(atoi(optarg)));
+
+			*flags |= TCP_REPL_SPORT;
 			break;
 		case '4':
-			if (optarg) {
-				reply->l4dst.tcp.port = htons(atoi(optarg));
-				*flags |= TCP_REPL_DPORT;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(ct, 
+					  ATTR_REPL_PORT_DST, 
+					  htons(atoi(optarg)));
+
+			*flags |= TCP_REPL_DPORT;
 			break;
 		case '5':
-			if (optarg) {
-				mask->l4src.tcp.port = htons(atoi(optarg));
-				*flags |= TCP_MASK_SPORT;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(mask, 
+					  ATTR_ORIG_PORT_SRC, 
+					  htons(atoi(optarg)));
+
+			*flags |= TCP_MASK_SPORT;
 			break;
 		case '6':
-			if (optarg) {
-				mask->l4dst.tcp.port = htons(atoi(optarg));
-				*flags |= TCP_MASK_DPORT;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(mask, 
+					  ATTR_ORIG_PORT_DST, 
+					  htons(atoi(optarg)));
+
+			*flags |= TCP_MASK_DPORT;
 			break;
 		case '7':
-			if (optarg) {
-				int i;
-				for (i=0; i<10; i++) {
-					if (strcmp(optarg, states[i]) == 0) {
-						proto->tcp.state = i;
-						break;
-					}
+			if (!optarg)
+				break;
+
+			for (i=0; i<10; i++) {
+				if (strcmp(optarg, states[i]) == 0) {
+					nfct_set_attr_u8(ct,
+							 ATTR_TCP_STATE,
+							 i);
+					break;
 				}
-				if (i == 10) {
-					printf("doh?\n");
-					return 0;
-				}
-				*flags |= TCP_STATE;
 			}
+			if (i == 10) {
+				printf("doh?\n");
+				return 0;
+			}
+			*flags |= TCP_STATE;
 			break;
 		case '8':
-			if (optarg) {
-				exptuple->l4src.tcp.port = htons(atoi(optarg));
-				*flags |= TCP_EXPTUPLE_SPORT;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(exptuple, 
+					  ATTR_ORIG_PORT_SRC, 
+					  htons(atoi(optarg)));
+
+			*flags |= TCP_EXPTUPLE_SPORT;
 			break;
 		case '9':
-			if (optarg) {
-				exptuple->l4dst.tcp.port = htons(atoi(optarg));
-				*flags |= TCP_EXPTUPLE_DPORT;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(exptuple, 
+					  ATTR_ORIG_PORT_DST, 
+					  htons(atoi(optarg)));
+
+			*flags |= TCP_EXPTUPLE_DPORT;
 			break;
 	}
 	return 1;
@@ -135,20 +169,27 @@
 
 static int final_check(unsigned int flags,
 		       unsigned int command,
-		       struct nfct_tuple *orig,
-		       struct nfct_tuple *reply)
+		       struct nf_conntrack *ct)
 {
 	int ret = 0;
-	
+
 	if ((flags & (TCP_ORIG_SPORT|TCP_ORIG_DPORT)) 
 	    && !(flags & (TCP_REPL_SPORT|TCP_REPL_DPORT))) {
-		reply->l4src.tcp.port = orig->l4dst.tcp.port;
-		reply->l4dst.tcp.port = orig->l4src.tcp.port;
+	    	nfct_set_attr_u16(ct,
+				  ATTR_REPL_PORT_SRC, 
+				  nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST));
+		nfct_set_attr_u16(ct,
+				  ATTR_REPL_PORT_DST,
+				  nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC));
 		ret = 1;
 	} else if (!(flags & (TCP_ORIG_SPORT|TCP_ORIG_DPORT))
 	            && (flags & (TCP_REPL_SPORT|TCP_REPL_DPORT))) {
-		orig->l4src.tcp.port = reply->l4dst.tcp.port;
-		orig->l4dst.tcp.port = reply->l4src.tcp.port;
+	    	nfct_set_attr_u16(ct,
+				  ATTR_ORIG_PORT_SRC, 
+				  nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST));
+		nfct_set_attr_u16(ct,
+				  ATTR_ORIG_PORT_DST,
+				  nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC));
 		ret = 1;
 	}
 	if ((flags & (TCP_ORIG_SPORT|TCP_ORIG_DPORT)) 

Modified: trunk/conntrack-tools/extensions/libct_proto_udp.c
===================================================================
--- trunk/conntrack-tools/extensions/libct_proto_udp.c	2007-05-02 13:22:07 UTC (rev 6819)
+++ trunk/conntrack-tools/extensions/libct_proto_udp.c	2007-05-06 17:36:13 UTC (rev 6820)
@@ -1,5 +1,5 @@
 /*
- * (C) 2005 by Pablo Neira Ayuso <pablo at eurodev.net>
+ * (C) 2005-2007 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
@@ -10,11 +10,13 @@
 #include <stdio.h>
 #include <getopt.h>
 #include <stdlib.h>
+#include <string.h>
 #include <netinet/in.h> /* For htons */
-#include "conntrack.h"
 #include <libnetfilter_conntrack/libnetfilter_conntrack.h>
 #include <libnetfilter_conntrack/libnetfilter_conntrack_udp.h>
 
+#include "conntrack.h"
+
 static struct option opts[] = {
 	{"orig-port-src", 1, 0, '1'},
 	{"orig-port-dst", 1, 0, '2'},
@@ -39,38 +41,54 @@
 	fprintf(stdout, "--tuple-port-src	expectation tuple dst port\n");
 }
 
-static int parse_options(char c, char *argv[], 
-			 struct nfct_tuple *orig,
-			 struct nfct_tuple *reply,
+static int parse_options(char c, char *argv[],
+			 struct nf_conntrack *ct,
 			 struct nfct_tuple *exptuple,
 			 struct nfct_tuple *mask,
-			 union nfct_protoinfo *proto,
 			 unsigned int *flags)
 {
+	int i;
+
 	switch(c) {
 		case '1':
-			if (optarg) {
-				orig->l4src.udp.port = htons(atoi(optarg));
-				*flags |= UDP_ORIG_SPORT;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(ct, 
+					  ATTR_ORIG_PORT_SRC, 
+					  htons(atoi(optarg)));
+
+			*flags |= UDP_ORIG_SPORT;
 			break;
 		case '2':
-			if (optarg) {
-				orig->l4dst.udp.port = htons(atoi(optarg));
-				*flags |= UDP_ORIG_DPORT;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(ct, 
+					  ATTR_ORIG_PORT_DST, 
+					  htons(atoi(optarg)));
+
+			*flags |= UDP_ORIG_DPORT;
 			break;
 		case '3':
-			if (optarg) {
-				reply->l4src.udp.port = htons(atoi(optarg));
-				*flags |= UDP_REPL_SPORT;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(ct, 
+					  ATTR_REPL_PORT_SRC, 
+					  htons(atoi(optarg)));
+
+			*flags |= UDP_REPL_SPORT;
 			break;
 		case '4':
-			if (optarg) {
-				reply->l4dst.udp.port = htons(atoi(optarg));
-				*flags |= UDP_REPL_DPORT;
-			}
+			if (!optarg)
+				break;
+
+			nfct_set_attr_u16(ct, 
+					  ATTR_REPL_PORT_DST, 
+					  htons(atoi(optarg)));
+
+			*flags |= UDP_REPL_DPORT;
 			break;
 		case '5':
 			if (optarg) {
@@ -95,32 +113,41 @@
 				exptuple->l4dst.udp.port = htons(atoi(optarg));
 				*flags |= UDP_EXPTUPLE_DPORT;
 			}
-
+			break;
 	}
 	return 1;
 }
 
 static int final_check(unsigned int flags,
 		       unsigned int command,
-		       struct nfct_tuple *orig,
-		       struct nfct_tuple *reply)
+		       struct nf_conntrack *ct)
 {
+	int ret = 0;
+	
 	if ((flags & (UDP_ORIG_SPORT|UDP_ORIG_DPORT)) 
 	    && !(flags & (UDP_REPL_SPORT|UDP_REPL_DPORT))) {
-		reply->l4src.udp.port = orig->l4dst.udp.port;
-		reply->l4dst.udp.port = orig->l4src.udp.port;
-		return 1;
+	    	nfct_set_attr_u16(ct,
+				  ATTR_REPL_PORT_SRC, 
+				  nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST));
+		nfct_set_attr_u16(ct,
+				  ATTR_REPL_PORT_DST,
+				  nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC));
+		ret = 1;
 	} else if (!(flags & (UDP_ORIG_SPORT|UDP_ORIG_DPORT))
 	            && (flags & (UDP_REPL_SPORT|UDP_REPL_DPORT))) {
-		orig->l4src.udp.port = reply->l4dst.udp.port;
-		orig->l4dst.udp.port = reply->l4src.udp.port;
-		return 1;
+	    	nfct_set_attr_u16(ct,
+				  ATTR_ORIG_PORT_SRC, 
+				  nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST));
+		nfct_set_attr_u16(ct,
+				  ATTR_ORIG_PORT_DST,
+				  nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC));
+		ret = 1;
 	}
 	if ((flags & (UDP_ORIG_SPORT|UDP_ORIG_DPORT)) 
 	    && ((flags & (UDP_REPL_SPORT|UDP_REPL_DPORT))))
-		return 1;
+		ret = 1;
 
-	return 0;
+	return ret;
 }
 
 static struct ctproto_handler udp = {

Modified: trunk/conntrack-tools/include/conntrack.h
===================================================================
--- trunk/conntrack-tools/include/conntrack.h	2007-05-02 13:22:07 UTC (rev 6819)
+++ trunk/conntrack-tools/include/conntrack.h	2007-05-06 17:36:13 UTC (rev 6820)
@@ -1,10 +1,6 @@
 #ifndef _CONNTRACK_H
 #define _CONNTRACK_H
 
-#ifdef HAVE_CONFIG_H
-#include "../config.h"
-#endif
-
 #include "linux_list.h"
 #include <getopt.h>
 #include <libnetfilter_conntrack/libnetfilter_conntrack.h>
@@ -122,9 +118,18 @@
 	CT_OPT_FAMILY_BIT	= 16,
 	CT_OPT_FAMILY		= (1 << CT_OPT_FAMILY_BIT),
 
-	CT_OPT_MAX_BIT		= CT_OPT_FAMILY_BIT
+	CT_OPT_SRC_NAT_BIT	= 17,
+	CT_OPT_SRC_NAT		= (1 << CT_OPT_SRC_NAT_BIT),
+
+	CT_OPT_DST_NAT_BIT	= 18,
+	CT_OPT_DST_NAT		= (1 << CT_OPT_DST_NAT_BIT),
+
+	CT_OPT_XML_BIT		= 19,
+	CT_OPT_XML		= (1 << CT_OPT_XML_BIT),
+
+	CT_OPT_MAX		= CT_OPT_XML_BIT
 };
-#define NUMBER_OF_OPT   CT_OPT_MAX_BIT+1
+#define NUMBER_OF_OPT	CT_OPT_MAX+1
 
 struct ctproto_handler {
 	struct list_head 	head;
@@ -136,17 +141,14 @@
 	enum ctattr_protoinfo	protoinfo_attr;
 	
 	int (*parse_opts)(char c, char *argv[], 
-		     struct nfct_tuple *orig,
-		     struct nfct_tuple *reply,
-		     struct nfct_tuple *exptuple,
-		     struct nfct_tuple *mask,
-		     union nfct_protoinfo *proto,
+		     struct nf_conntrack *ct,
+		     struct nf_conntrack *exptuple,
+		     struct nf_conntrack *mask,
 		     unsigned int *flags);
 
 	int (*final_check)(unsigned int flags,
 			   unsigned int command,
-			   struct nfct_tuple *orig,
-			   struct nfct_tuple *reply);
+			   struct nf_conntrack *ct);
 
 	void (*help)();
 

Modified: trunk/conntrack-tools/src/conntrack.c
===================================================================
--- trunk/conntrack-tools/src/conntrack.c	2007-05-02 13:22:07 UTC (rev 6819)
+++ trunk/conntrack-tools/src/conntrack.c	2007-05-06 17:36:13 UTC (rev 6820)
@@ -1,5 +1,5 @@
 /*
- * (C) 2005 by Pablo Neira Ayuso <pablo at netfilter.org>
+ * (C) 2005-2007 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
@@ -29,6 +29,8 @@
  * 	Add support for expect creation
  * 2005-09-24 Harald Welte <laforge at netfilter.org>:
  * 	Remove remaints of "-A"
+ * 2007-04-22 Pablo Neira Ayuso <pablo at netfilter.org>:
+ * 	Ported to the new libnetfilter_conntrack API
  *
  */
 #include <stdio.h>
@@ -63,7 +65,7 @@
 = { 2,  0,  0,  0,  0,  2,  2,  2,  2,  2,  0,  0,  0,  2,  2 };
 
 static const char optflags[NUMBER_OF_OPT]
-= {'s','d','r','q','p','t','u','z','e','[',']','{','}','a','m','i','f'};
+= {'s','d','r','q','p','t','u','z','e','[',']','{','}','a','m','i','f','n','g','x'};
 
 static struct option original_opts[] = {
 	{"dump", 2, 0, 'L'},
@@ -88,10 +90,13 @@
 	{"tuple-dst", 1, 0, ']'},
 	{"mask-src", 1, 0, '{'},
 	{"mask-dst", 1, 0, '}'},
-	{"nat-range", 1, 0, 'a'},
+	{"nat-range", 1, 0, 'a'},	/* deprecated */
 	{"mark", 1, 0, 'm'},
-	{"id", 2, 0, 'i'},
+	{"id", 2, 0, 'i'},		/* deprecated */
 	{"family", 1, 0, 'f'},
+	{"src-nat", 1, 0, 'n'},
+	{"dst-nat", 1, 0, 'g'},
+	{"xml", 0, 0, 'x'},
 	{0, 0, 0, 0}
 };
 
@@ -113,28 +118,33 @@
 static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
 /* Well, it's better than "Re: Linux vs FreeBSD" */
 {
-          /*   s d r q p t u z e x y k l a m i f*/
-/*CT_LIST*/   {2,2,2,2,2,0,0,2,0,0,0,0,0,0,2,2,2},
-/*CT_CREATE*/ {2,2,2,2,1,1,1,0,0,0,0,0,0,2,2,0,0},
-/*CT_UPDATE*/ {2,2,2,2,1,2,2,0,0,0,0,0,0,0,2,2,0},
-/*CT_DELETE*/ {2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,2,0},
-/*CT_GET*/    {2,2,2,2,1,0,0,0,0,0,0,0,0,0,0,2,0},
-/*CT_FLUSH*/  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-/*CT_EVENT*/  {2,2,2,2,2,0,0,0,2,0,0,0,0,0,2,0,0},
-/*VERSION*/   {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-/*HELP*/      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-/*EXP_LIST*/  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2},
-/*EXP_CREATE*/{1,1,2,2,1,1,2,0,0,1,1,1,1,0,0,0,0},
-/*EXP_DELETE*/{1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0},
-/*EXP_GET*/   {1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0},
-/*EXP_FLUSH*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-/*EXP_EVENT*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+          /*   s d r q p t u z e x y k l a m i f n g x */
+/*CT_LIST*/   {2,2,2,2,2,0,0,2,0,0,0,0,0,0,2,2,2,0,0,2},
+/*CT_CREATE*/ {2,2,2,2,1,1,1,0,0,0,0,0,0,2,2,0,0,2,2,0},
+/*CT_UPDATE*/ {2,2,2,2,1,2,2,0,0,0,0,0,0,0,2,2,0,0,0,0},
+/*CT_DELETE*/ {2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0},
+/*CT_GET*/    {2,2,2,2,1,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2},
+/*CT_FLUSH*/  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+/*CT_EVENT*/  {2,2,2,2,2,0,0,0,2,0,0,0,0,0,2,0,0,0,0,2},
+/*VERSION*/   {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+/*HELP*/      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+/*EXP_LIST*/  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0},
+/*EXP_CREATE*/{1,1,2,2,1,1,2,0,0,1,1,1,1,0,0,0,0,0,0,0},
+/*EXP_DELETE*/{1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+/*EXP_GET*/   {1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+/*EXP_FLUSH*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+/*EXP_EVENT*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
 };
 
 static char *lib_dir = CONNTRACK_LIB_DIR;
 
 static LIST_HEAD(proto_list);
 
+static unsigned int options;
+static unsigned int command;
+
+#define CT_COMPARISON (CT_OPT_PROTO | CT_OPT_ORIG | CT_OPT_REPL | CT_OPT_MARK)
+
 void register_proto(struct ctproto_handler *h)
 {
 	if (strcmp(h->version, VERSION) != 0) {
@@ -328,7 +338,7 @@
 			return table[i].message;
 	}
 
-	return strerror(err);
+	return strerror(-err);
 }
 
 #define PARSE_STATUS 0
@@ -340,9 +350,8 @@
 	size_t  size;
 	unsigned int value[6];
 } parse_array[PARSE_MAX] = {
-	{ {"ASSURED", "SEEN_REPLY", "UNSET", "SRC_NAT", "DST_NAT","FIXED_TIMEOUT"}, 6,
-	  { IPS_ASSURED, IPS_SEEN_REPLY, 0, 
-	    IPS_SRC_NAT_DONE, IPS_DST_NAT_DONE, IPS_FIXED_TIMEOUT} },
+	{ {"ASSURED", "SEEN_REPLY", "UNSET", "FIXED_TIMEOUT"}, 4,
+	  { IPS_ASSURED, IPS_SEEN_REPLY, 0, IPS_FIXED_TIMEOUT} },
 	{ {"ALL", "NEW", "UPDATES", "DESTROY"}, 4,
 	  {~0U, NF_NETLINK_CONNTRACK_NEW, NF_NETLINK_CONNTRACK_UPDATE, 
 	   NF_NETLINK_CONNTRACK_DESTROY} },
@@ -354,7 +363,17 @@
 {
 	int i, ret = 0;
 	struct parse_parameter *p = &parse_array[parse_type];
-	
+
+	if (strncasecmp(str, "SRC_NAT", strlen) == 0) {
+		printf("skipping SRC_NAT, use --src-nat instead\n");
+		return 1;
+	}
+
+	if (strncasecmp(str, "DST_NAT", strlen) == 0) {
+		printf("skipping DST_NAT, use --dst-nat instead\n");
+		return 1;
+	}
+
 	for (i = 0; i < p->size; i++)
 		if (strncasecmp(str, p->parameter[i], strlen) == 0) {
 			*value |= p->value[i];
@@ -430,7 +449,7 @@
 	unsigned int family;
 };
 
-int __parse_inetaddr(const char *cp, struct addr_parse *parse)
+int parse_inetaddr(const char *cp, struct addr_parse *parse)
 {
 	if (inet_aton(cp, &parse->addr))
 		return AF_INET;
@@ -442,12 +461,17 @@
 	exit_error(PARAMETER_PROBLEM, "Invalid IP address `%s'.", cp);
 }
 
-int parse_inetaddr(const char *cp, union nfct_address *address)
+union ct_address {
+	u_int32_t v4;
+	u_int32_t v6[4];
+};
+
+int parse_addr(const char *cp, union ct_address *address)
 {
 	struct addr_parse parse;
 	int ret;
-	
-	if ((ret = __parse_inetaddr(cp, &parse)) == AF_INET)
+
+	if ((ret = parse_inetaddr(cp, &parse)) == AF_INET)
 		address->v4 = parse.addr.s_addr;
 	else if (ret == AF_INET6)
 		memcpy(address->v6, &parse.addr6, sizeof(parse.addr6));
@@ -457,73 +481,43 @@
 
 /* Shamelessly stolen from libipt_DNAT ;). Ranges expected in network order. */
 static void
-nat_parse(char *arg, int portok, struct nfct_nat *range)
+nat_parse(char *arg, int portok, struct nf_conntrack *obj, int type)
 {
 	char *colon, *dash, *error;
-	struct addr_parse parse;
+	union ct_address parse;
 
-	memset(range, 0, sizeof(range));
 	colon = strchr(arg, ':');
 
 	if (colon) {
-		int port;
+		u_int16_t port;
 
 		if (!portok)
 			exit_error(PARAMETER_PROBLEM,
 				   "Need TCP or UDP with port specification");
 
 		port = atoi(colon+1);
-		if (port == 0 || port > 65535)
+		if (port == 0)
 			exit_error(PARAMETER_PROBLEM,
 				   "Port `%s' not valid\n", colon+1);
 
 		error = strchr(colon+1, ':');
 		if (error)
 			exit_error(PARAMETER_PROBLEM,
-				   "Invalid port:port syntax - use dash\n");
+				   "Invalid port:port syntax\n");
 
-		dash = strchr(colon, '-');
-		if (!dash) {
-			range->l4min.tcp.port
-				= range->l4max.tcp.port
-				= htons(port);
-		} else {
-			int maxport;
-
-			maxport = atoi(dash + 1);
-			if (maxport == 0 || maxport > 65535)
-				exit_error(PARAMETER_PROBLEM,
-					   "Port `%s' not valid\n", dash+1);
-			if (maxport < port)
-				/* People are stupid.  */
-				exit_error(PARAMETER_PROBLEM,
-					   "Port range `%s' funky\n", colon+1);
-			range->l4min.tcp.port = htons(port);
-			range->l4max.tcp.port = htons(maxport);
-		}
-		/* Starts with a colon? No IP info... */
-		if (colon == arg)
-			return;
-		*colon = '\0';
+		if (type == CT_OPT_SRC_NAT)
+			nfct_set_attr_u16(obj, ATTR_SNAT_PORT, port);
+		else if (type == CT_OPT_DST_NAT)
+			nfct_set_attr_u16(obj, ATTR_DNAT_PORT, port);
 	}
 
-	dash = strchr(arg, '-');
-	if (colon && dash && dash > colon)
-		dash = NULL;
-
-	if (dash)
-		*dash = '\0';
-
-	if (__parse_inetaddr(arg, &parse) != AF_INET)
+	if (parse_addr(arg, &parse) != AF_INET)
 		return;
 
-	range->min_ip = parse.addr.s_addr;
-	if (dash) {
-		if (__parse_inetaddr(dash+1, &parse) != AF_INET)
-			return;
-		range->max_ip = parse.addr.s_addr;
-	} else
-		range->max_ip = parse.addr.s_addr;
+	if (type == CT_OPT_SRC_NAT)
+		nfct_set_attr_u32(obj, ATTR_SNAT_IPV4, parse.v4);
+	else if (type == CT_OPT_DST_NAT)
+		nfct_set_attr_u32(obj, ATTR_DNAT_IPV4, parse.v4);
 }
 
 static void event_sighandler(int s)
@@ -548,10 +542,12 @@
 
 static const char usage_conntrack_parameters[] =
 	"Conntrack parameters and options:\n"
-	"  -a, --nat-range min_ip[-max_ip]\tNAT ip range\n"
+	"  -n, --src-nat ip\tsource NAT ip\n"
+	"  -g, --dst-nat ip\tdestination NAT ip\n"
 	"  -m, --mark mark\t\t\tSet mark\n"
 	"  -e, --event-mask eventmask\t\tEvent mask, eg. NEW,DESTROY\n"
 	"  -z, --zero \t\t\t\tZero counters while listing\n"
+	"  -x, --xml \t\t\t\tDisplay output in XML format\n";
 	;
 
 static const char usage_expectation_parameters[] =
@@ -571,7 +567,6 @@
 	"  -f, --family proto\t\tLayer 3 Protocol, eg. 'ipv6'\n"
 	"  -t, --timeout timeout\t\tSet timeout\n"
 	"  -u, --status status\t\tSet status, eg. ASSURED\n"
-	"  -i, --id [id]\t\t\tShow or set conntrack ID\n"
 	;
   
 
@@ -586,33 +581,78 @@
 	fprintf(stdout, "\n%s", usage_parameters);
 }
 
-#define CT_COMPARISON (CT_OPT_PROTO | CT_OPT_ORIG | CT_OPT_REPL | CT_OPT_MARK)
+unsigned int output_flags = NFCT_O_DEFAULT;
 
-static struct nfct_tuple orig, reply, mask;
-static struct nfct_tuple exptuple;
+static int event_cb(enum nf_conntrack_msg_type type,
+		    struct nf_conntrack *ct,
+		    void *data)
+{
+	char buf[1024];
+	struct nf_conntrack *obj = data;
+
+	if (options & CT_COMPARISON && !nfct_compare(obj, ct))
+		return NFCT_CB_CONTINUE;
+
+	nfct_snprintf(buf, 1024, ct, type, output_flags, 0);
+	printf("%s\n", buf);
+
+	return NFCT_CB_CONTINUE;
+}
+
+static int dump_cb(enum nf_conntrack_msg_type type,
+		   struct nf_conntrack *ct,
+		   void *data)
+{
+	char buf[1024];
+	struct nf_conntrack *obj = data;
+
+	if (options & CT_COMPARISON && !nfct_compare(obj, ct))
+		return NFCT_CB_CONTINUE;
+
+	nfct_snprintf(buf, 1024, ct, NFCT_T_UNKNOWN, output_flags, 0);
+	printf("%s\n", buf);
+
+	return NFCT_CB_CONTINUE;
+}
+
+static int dump_exp_cb(enum nf_conntrack_msg_type type,
+		      struct nf_expect *exp,
+		      void *data)
+{
+	char buf[1024];
+
+	nfexp_snprintf(buf, 1024, exp, NFCT_T_UNKNOWN, NFCT_O_DEFAULT, 0);
+	printf("%s\n", buf);
+
+	return NFCT_CB_CONTINUE;
+}
+
 static struct ctproto_handler *h;
-static union nfct_protoinfo proto;
-static struct nfct_nat range;
-static struct nfct_conntrack *ct;
-static struct nfct_expect *exp;
-static unsigned long timeout;
-static unsigned int status;
-static unsigned int mark;
-static unsigned int id = NFCT_ANY_ID;
-static struct nfct_conntrack_compare cmp;
 
 int main(int argc, char *argv[])
 {
 	int c;
-	unsigned int command = 0, options = 0;
-	unsigned int type = 0, event_mask = 0;
-	unsigned int l3flags = 0, l4flags = 0, metaflags = 0;
+	unsigned int type = 0, event_mask = 0, l4flags = 0, status = 0;
 	int res = 0;
 	int family = AF_UNSPEC;
-	struct nfct_conntrack_compare *pcmp;
+	char __obj[nfct_maxsize()];
+	char __exptuple[nfct_maxsize()];
+	char __mask[nfct_maxsize()];
+	struct nf_conntrack *obj = (struct nf_conntrack *) __obj;
+	struct nf_conntrack *exptuple = (struct nf_conntrack *) __exptuple;
+	struct nf_conntrack *mask = (struct nf_conntrack *) __mask;
+	char __exp[nfexp_maxsize()];
+	struct nf_expect *exp = (struct nf_expect *) __exp;
+	int l3protonum;
+	union ct_address ad;
 
+	memset(__obj, 0, sizeof(__obj));
+	memset(__exptuple, 0, sizeof(__exptuple));
+	memset(__mask, 0, sizeof(__mask));
+	memset(__exp, 0, sizeof(__exp));
+
 	while ((c = getopt_long(argc, argv, 
-		"L::I::U::D::G::E::F::hVs:d:r:q:p:t:u:e:a:z[:]:{:}:m:i::f:", 
+		"L::I::U::D::G::E::F::hVs:d:r:q:p:t:u:e:a:z[:]:{:}:m:i::f:x", 
 		opts, NULL)) != -1) {
 	switch(c) {
 		case 'L':
@@ -673,68 +713,99 @@
 			break;
 		case 's':
 			options |= CT_OPT_ORIG_SRC;
-			if (optarg) {
-				orig.l3protonum =
-					parse_inetaddr(optarg, &orig.src);
-				set_family(&family, orig.l3protonum);
-				if (orig.l3protonum == AF_INET)
-					l3flags |= IPV4_ORIG_SRC;
-				else if (orig.l3protonum == AF_INET6)
-					l3flags |= IPV6_ORIG_SRC;
+			if (!optarg)
+				break;
+
+			l3protonum = parse_addr(optarg, &ad);
+			set_family(&family, l3protonum);
+			if (l3protonum == AF_INET) {
+				nfct_set_attr_u32(obj, 
+						  ATTR_ORIG_IPV4_SRC, 
+						  ad.v4);
+			} else if (l3protonum == AF_INET6) {
+				nfct_set_attr(obj,
+					      ATTR_ORIG_IPV6_SRC, 
+					      &ad.v6);
 			}
+			nfct_set_attr_u8(obj, ATTR_ORIG_L3PROTO, l3protonum);
 			break;
 		case 'd':
 			options |= CT_OPT_ORIG_DST;
-			if (optarg) {
-				orig.l3protonum = 
-					parse_inetaddr(optarg, &orig.dst);
-				set_family(&family, orig.l3protonum);
-				if (orig.l3protonum == AF_INET)
-					l3flags |= IPV4_ORIG_DST;
-				else if (orig.l3protonum == AF_INET6)
-					l3flags |= IPV6_ORIG_DST;
+			if (!optarg)
+				break;
+
+			l3protonum = parse_addr(optarg, &ad);
+			set_family(&family, l3protonum);
+			if (l3protonum == AF_INET) {
+				nfct_set_attr_u32(obj, 
+						  ATTR_ORIG_IPV4_DST,
+						  ad.v4);
+			} else if (l3protonum == AF_INET6) {
+				nfct_set_attr(obj,
+					      ATTR_ORIG_IPV6_DST,
+					      &ad.v6);
 			}
+			nfct_set_attr_u8(obj, ATTR_ORIG_L3PROTO, l3protonum);
 			break;
 		case 'r':
 			options |= CT_OPT_REPL_SRC;
-			if (optarg) {
-				reply.l3protonum = 
-					parse_inetaddr(optarg, &reply.src);
-				set_family(&family, reply.l3protonum);
-				if (orig.l3protonum == AF_INET)
-					l3flags |= IPV4_REPL_SRC;
-				else if (orig.l3protonum == AF_INET6)
-					l3flags |= IPV6_REPL_SRC;
+			if (!optarg)
+				break;
+
+			l3protonum = parse_addr(optarg, &ad);
+			set_family(&family, l3protonum);
+			if (l3protonum == AF_INET) {
+				nfct_set_attr_u32(obj,
+						  ATTR_REPL_IPV4_SRC, 
+						  ad.v4);
+			} else if (l3protonum == AF_INET6) {
+				nfct_set_attr(obj,
+					      ATTR_REPL_IPV6_SRC,
+					      &ad.v6);
 			}
+			nfct_set_attr_u8(obj, ATTR_REPL_L3PROTO, l3protonum);
 			break;
 		case 'q':
 			options |= CT_OPT_REPL_DST;
-			if (optarg) {
-				reply.l3protonum = 
-					parse_inetaddr(optarg, &reply.dst);
-				set_family(&family, reply.l3protonum);
-				if (orig.l3protonum == AF_INET)
-					l3flags |= IPV4_REPL_DST;
-				else if (orig.l3protonum == AF_INET6)
-					l3flags |= IPV6_REPL_DST;
+			if (!optarg)
+				break;
+
+			l3protonum = parse_addr(optarg, &ad);
+			set_family(&family, l3protonum);
+			if (l3protonum == AF_INET) {
+				nfct_set_attr_u32(obj,
+						  ATTR_REPL_IPV4_DST,
+						  ad.v4);
+			} else if (l3protonum == AF_INET6) {
+				nfct_set_attr(obj,
+					      ATTR_REPL_IPV6_DST,
+					      &ad.v6);
 			}
+			nfct_set_attr_u8(obj, ATTR_REPL_L3PROTO, l3protonum);
 			break;
 		case 'p':
 			options |= CT_OPT_PROTO;
 			h = findproto(optarg);
 			if (!h)
 				exit_error(PARAMETER_PROBLEM, "proto needed\n");
-			orig.protonum = h->protonum;
-			reply.protonum = h->protonum;
-			exptuple.protonum = h->protonum;
-			mask.protonum = h->protonum;
-			opts = merge_options(opts, h->opts, 
-					     &h->option_offset);
+
+			nfct_set_attr_u8(obj, ATTR_ORIG_L4PROTO, h->protonum);
+			nfct_set_attr_u8(obj, ATTR_REPL_L4PROTO, h->protonum);
+			nfct_set_attr_u8(exptuple, 
+					 ATTR_ORIG_L4PROTO, 
+					 h->protonum);
+			nfct_set_attr_u8(mask, 
+					 ATTR_ORIG_L4PROTO, 
+					 h->protonum);
+			opts = merge_options(opts, h->opts, &h->option_offset);
 			break;
 		case 't':
 			options |= CT_OPT_TIMEOUT;
-			if (optarg)
-				timeout = atol(optarg);
+			if (!optarg)
+				continue;
+
+			nfct_set_attr_u32(obj, ATTR_TIMEOUT, atol(optarg));
+			nfexp_set_attr_u32(exp, ATTR_EXP_TIMEOUT, atol(optarg));
 			break;
 		case 'u': {
 			if (!optarg)
@@ -742,6 +813,7 @@
 
 			options |= CT_OPT_STATUS;
 			parse_parameter(optarg, &status, PARSE_STATUS);
+			nfct_set_attr_u32(obj, ATTR_STATUS, status);
 			break;
 		}
 		case 'e':
@@ -753,59 +825,102 @@
 			break;
 		case '{':
 			options |= CT_OPT_MASK_SRC;
-			if (optarg) {
-				mask.l3protonum = 
-					parse_inetaddr(optarg, &mask.src);
-				set_family(&family, mask.l3protonum);
+			if (!optarg)
+				break;
+
+			l3protonum = parse_addr(optarg, &ad);
+			set_family(&family, l3protonum);
+			if (l3protonum == AF_INET) {
+				nfct_set_attr_u32(mask, 
+						  ATTR_ORIG_IPV4_SRC,
+						  ad.v4);
+			} else if (l3protonum == AF_INET6) {
+				nfct_set_attr(mask,
+					      ATTR_ORIG_IPV6_SRC,
+					      &ad.v6);
 			}
+			nfct_set_attr_u8(mask, ATTR_ORIG_L3PROTO, l3protonum);
 			break;
 		case '}':
 			options |= CT_OPT_MASK_DST;
-			if (optarg) {
-				mask.l3protonum = 
-					parse_inetaddr(optarg, &mask.dst);
-				set_family(&family, mask.l3protonum);
+			if (!optarg)
+				break;
+
+			l3protonum = parse_addr(optarg, &ad);
+			set_family(&family, l3protonum);
+			if (l3protonum == AF_INET) {
+				nfct_set_attr_u32(mask, 
+						  ATTR_ORIG_IPV4_DST,
+						  ad.v4);
+			} else if (l3protonum == AF_INET6) {
+				nfct_set_attr(mask,
+					      ATTR_ORIG_IPV6_DST,
+					      &ad.v6);
 			}
+			nfct_set_attr_u8(mask, ATTR_ORIG_L3PROTO, l3protonum);
 			break;
 		case '[':
 			options |= CT_OPT_EXP_SRC;
-			if (optarg) {
-				exptuple.l3protonum = 
-					parse_inetaddr(optarg, &exptuple.src);
-				set_family(&family, exptuple.l3protonum);
+			if (!optarg)
+				break;
+
+			l3protonum = parse_addr(optarg, &ad);
+			set_family(&family, l3protonum);
+			if (l3protonum == AF_INET) {
+				nfct_set_attr_u32(exptuple, 
+						  ATTR_ORIG_IPV4_SRC,
+						  ad.v4);
+			} else if (l3protonum == AF_INET6) {
+				nfct_set_attr(exptuple,
+					      ATTR_ORIG_IPV6_SRC,
+					      &ad.v6);
 			}
+			nfct_set_attr_u8(exptuple, 
+					 ATTR_ORIG_L3PROTO, 
+					 l3protonum);
 			break;
 		case ']':
 			options |= CT_OPT_EXP_DST;
-			if (optarg) {
-				exptuple.l3protonum = 
-					parse_inetaddr(optarg, &exptuple.dst);
-				set_family(&family, exptuple.l3protonum);
+			if (!optarg)
+				break;
+
+			l3protonum = parse_addr(optarg, &ad);
+			set_family(&family, l3protonum);
+			if (l3protonum == AF_INET) {
+				nfct_set_attr_u32(exptuple, 
+						  ATTR_ORIG_IPV4_DST,
+						  ad.v4);
+			} else if (l3protonum == AF_INET6) {
+				nfct_set_attr(exptuple,
+					      ATTR_ORIG_IPV6_DST,
+					      &ad.v6);
 			}
+			nfct_set_attr_u8(exptuple, 
+					 ATTR_ORIG_L3PROTO, 
+					 l3protonum);
 			break;
 		case 'a':
-			options |= CT_OPT_NATRANGE;
+			printf("warning: ignoring --nat-range, "
+			       "use --src-nat or --dst-nat instead.\n");
+			break;
+		case 'n':
+			options |= CT_OPT_SRC_NAT;
 			set_family(&family, AF_INET);
-			nat_parse(optarg, 1, &range);
+			nat_parse(optarg, 1, obj, CT_OPT_SRC_NAT);
 			break;
+		case 'g':
+			options |= CT_OPT_DST_NAT;
+			set_family(&family, AF_INET);
+			nat_parse(optarg, 1, obj, CT_OPT_DST_NAT);
 		case 'm':
 			options |= CT_OPT_MARK;
-			mark = atol(optarg);
-			metaflags |= NFCT_MARK;
+			if (!optarg)
+				continue;
+			nfct_set_attr_u32(obj, ATTR_MARK, atol(optarg));
 			break;
-		case 'i': {
-			char *s = NULL;
-			options |= CT_OPT_ID;
-			if (optarg)
-				break;
-			else if (optind < argc && argv[optind][0] != '-'
-					&& argv[optind][0] != '!')
-				s = argv[optind++];
-
-			if (s)
-				id = atol(s);
+		case 'i':
+			printf("warning: ignoring --id. deprecated option.\n");
 			break;
-		}
 		case 'f':
 			options |= CT_OPT_FAMILY;
 			if (strncmp(optarg, "ipv4", strlen("ipv4")) == 0)
@@ -816,11 +931,14 @@
 				exit_error(PARAMETER_PROBLEM, "Unknown "
 					   "protocol family\n");
 			break;
+		case 'x':
+			options |= CT_OPT_XML;
+			output_flags = NFCT_O_XML;
+			break;
 		default:
 			if (h && h->parse_opts 
-			    &&!h->parse_opts(c - h->option_offset, argv, &orig, 
-				             &reply, &exptuple, &mask, &proto, 
-					     &l4flags))
+			    &&!h->parse_opts(c - h->option_offset, argv, obj,
+			    		     exptuple, mask, &l4flags))
 				exit_error(PARAMETER_PROBLEM, "parse error\n");
 
 			/* Unknown argument... */
@@ -842,7 +960,7 @@
 
 	if (!(command & CT_HELP)
 	    && h && h->final_check 
-	    && !h->final_check(l4flags, command, &orig, &reply)) {
+	    && !h->final_check(l4flags, command, obj)) {
 		usage(argv[0]);
 		extension_help(h);
 		exit_error(PARAMETER_PROBLEM, "Missing protocol arguments!\n");
@@ -855,39 +973,18 @@
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
 
-		if (options & CT_COMPARISON) {
+		if (options & CT_COMPARISON && 
+		    options & CT_OPT_ZERO)
+			exit_error(PARAMETER_PROBLEM, "Can't use -z with "
+						      "filtering parameters");
 
-			if (options & CT_OPT_ZERO)
-				exit_error(PARAMETER_PROBLEM, "Can't use -z "
-					   "with filtering parameters");
+		nfct_callback_register(cth, NFCT_T_ALL, dump_cb, obj);
 
-			ct = nfct_conntrack_alloc(&orig, &reply, timeout,
-						  &proto, status, mark, id,
-						  NULL);
-			if (!ct)
-				exit_error(OTHER_PROBLEM, "Not enough memory");
-			
-			cmp.ct = ct;
-			cmp.flags = metaflags;
-			cmp.l3flags = l3flags;
-			cmp.l4flags = l4flags;
-			pcmp = &cmp;
-		}
-
-		if (options & CT_OPT_ID)
-			nfct_register_callback(cth, 
-					nfct_default_conntrack_display_id,
-					(void *) pcmp);
-		else
-			nfct_register_callback(cth,
-					nfct_default_conntrack_display,
-					(void *) pcmp);
-			
 		if (options & CT_OPT_ZERO)
-			res = 
-			nfct_dump_conntrack_table_reset_counters(cth, family);
+			res = nfct_query(cth, NFCT_Q_DUMP_RESET, &family);
 		else
-			res = nfct_dump_conntrack_table(cth, family);
+			res = nfct_query(cth, NFCT_Q_DUMP, &family);
+
 		nfct_close(cth);
 		break;
 
@@ -895,96 +992,144 @@
 		cth = nfct_open(EXPECT, 0);
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
-		if (options & CT_OPT_ID)
-			nfct_register_callback(cth, 
-					nfct_default_expect_display_id,
-					NULL);
-		else
-			nfct_register_callback(cth,
-					nfct_default_expect_display,
-					NULL);
-		res = nfct_dump_expect_list(cth, family);
+
+		nfexp_callback_register(cth, NFCT_T_ALL, dump_exp_cb, NULL);
+		res = nfexp_query(cth, NFCT_Q_DUMP, &family);
 		nfct_close(cth);
 		break;
 			
 	case CT_CREATE:
 		if ((options & CT_OPT_ORIG) 
 		    && !(options & CT_OPT_REPL)) {
-			reply.l3protonum = orig.l3protonum;
-			memcpy(&reply.src, &orig.dst, sizeof(reply.src));
-			memcpy(&reply.dst, &orig.src, sizeof(reply.dst));
+		    	nfct_set_attr_u8(obj, 
+					 ATTR_REPL_L3PROTO, 
+					 nfct_get_attr_u8(obj,
+					 		  ATTR_ORIG_L3PROTO));
+			if (family == AF_INET) {
+				nfct_set_attr_u32(obj,
+						  ATTR_REPL_IPV4_SRC,
+						  nfct_get_attr_u32(obj,
+						  	ATTR_ORIG_IPV4_DST));
+				nfct_set_attr_u32(obj,
+						  ATTR_REPL_IPV4_DST,
+						  nfct_get_attr_u32(obj,
+						  	ATTR_ORIG_IPV4_SRC));
+			} else if (family == AF_INET6) {
+				nfct_set_attr(obj,
+					      ATTR_REPL_IPV6_SRC,
+					      nfct_get_attr(obj,
+					      		ATTR_ORIG_IPV6_DST));
+				nfct_set_attr(obj,
+					      ATTR_REPL_IPV6_DST,
+					      nfct_get_attr(obj,
+					      		ATTR_ORIG_IPV6_SRC));
+			}
 		} else if (!(options & CT_OPT_ORIG)
 			   && (options & CT_OPT_REPL)) {
-			orig.l3protonum = reply.l3protonum;
-			memcpy(&orig.src, &reply.dst, sizeof(orig.src));
-			memcpy(&orig.dst, &reply.src, sizeof(orig.dst));
+		    	nfct_set_attr_u8(obj, 
+					 ATTR_ORIG_L3PROTO, 
+					 nfct_get_attr_u8(obj,
+					 		  ATTR_REPL_L3PROTO));
+			if (family == AF_INET) {
+				nfct_set_attr_u32(obj,
+						  ATTR_ORIG_IPV4_SRC,
+						  nfct_get_attr_u32(obj,
+						  	ATTR_REPL_IPV4_DST));
+				nfct_set_attr_u32(obj,
+						  ATTR_ORIG_IPV4_DST,
+						  nfct_get_attr_u32(obj,
+						  	ATTR_REPL_IPV4_SRC));
+			} else if (family == AF_INET6) {
+				nfct_set_attr(obj,
+					      ATTR_ORIG_IPV6_SRC,
+					      nfct_get_attr(obj,
+					      		ATTR_REPL_IPV6_DST));
+				nfct_set_attr(obj,
+					      ATTR_ORIG_IPV6_DST,
+					      nfct_get_attr(obj,
+					      		ATTR_REPL_IPV6_SRC));
+			}
 		}
-		if (options & CT_OPT_NATRANGE)
-			ct = nfct_conntrack_alloc(&orig, &reply, timeout, 
-						  &proto, status, mark, id,
-						  &range);
-		else
-			ct = nfct_conntrack_alloc(&orig, &reply, timeout, 
-						  &proto, status, mark, id,
-						  NULL);
-		if (!ct)
-			exit_error(OTHER_PROBLEM, "Not Enough memory");
-		
+
 		cth = nfct_open(CONNTRACK, 0);
-		if (!cth) {
-			nfct_conntrack_free(ct);
+		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
-		}
-		res = nfct_create_conntrack(cth, ct);
+
+		res = nfct_query(cth, NFCT_Q_CREATE, obj);
 		nfct_close(cth);
-		nfct_conntrack_free(ct);
 		break;
 
 	case EXP_CREATE:
-		if (options & CT_OPT_ORIG)
-			exp = nfct_expect_alloc(&orig, &exptuple,
-						&mask, timeout, id);
-		else if (options & CT_OPT_REPL)
-			exp = nfct_expect_alloc(&reply, &exptuple,
-						&mask, timeout, id);
-		if (!exp)
-			exit_error(OTHER_PROBLEM, "Not enough memory");
+		nfexp_set_attr(exp, ATTR_EXP_MASTER, obj);
+		nfexp_set_attr(exp, ATTR_EXP_EXPECTED, exptuple);
+		nfexp_set_attr(exp, ATTR_EXP_MASK, mask);
 
 		cth = nfct_open(EXPECT, 0);
-		if (!cth) {
-			nfct_expect_free(exp);
+		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
-		}
-		res = nfct_create_expectation(cth, exp);
-		nfct_expect_free(exp);
+
+		res = nfexp_query(cth, NFCT_Q_CREATE, exp);
 		nfct_close(cth);
 		break;
 
 	case CT_UPDATE:
 		if ((options & CT_OPT_ORIG) 
 		    && !(options & CT_OPT_REPL)) {
-			reply.l3protonum = orig.l3protonum;
-			memcpy(&reply.src, &orig.dst, sizeof(reply.src));
-			memcpy(&reply.dst, &orig.src, sizeof(reply.dst));
+		    	nfct_set_attr_u8(obj, 
+					 ATTR_REPL_L3PROTO, 
+					 nfct_get_attr_u8(obj,
+					 		  ATTR_ORIG_L3PROTO));
+			if (family == AF_INET) {
+				nfct_set_attr_u32(obj,
+						  ATTR_REPL_IPV4_SRC,
+						  nfct_get_attr_u32(obj,
+						  	ATTR_ORIG_IPV4_DST));
+				nfct_set_attr_u32(obj,
+						  ATTR_REPL_IPV4_DST,
+						  nfct_get_attr_u32(obj,
+						  	ATTR_ORIG_IPV4_SRC));
+			} else if (family == AF_INET6) {
+				nfct_set_attr(obj,
+					      ATTR_REPL_IPV6_SRC,
+					      nfct_get_attr(obj,
+					      		ATTR_ORIG_IPV6_DST));
+				nfct_set_attr(obj,
+					      ATTR_REPL_IPV6_DST,
+					      nfct_get_attr(obj,
+					      		ATTR_ORIG_IPV6_SRC));
+			}
 		} else if (!(options & CT_OPT_ORIG)
 			   && (options & CT_OPT_REPL)) {
-			orig.l3protonum = reply.l3protonum;
-			memcpy(&orig.src, &reply.dst, sizeof(orig.src));
-			memcpy(&orig.dst, &reply.src, sizeof(orig.dst));
+		    	nfct_set_attr_u8(obj, 
+					 ATTR_ORIG_L3PROTO, 
+					 nfct_get_attr_u8(obj,
+					 		  ATTR_REPL_L3PROTO));
+			if (family == AF_INET) {
+				nfct_set_attr_u32(obj,
+						  ATTR_ORIG_IPV4_SRC,
+						  nfct_get_attr_u32(obj,
+						  	ATTR_REPL_IPV4_DST));
+				nfct_set_attr_u32(obj,
+						  ATTR_ORIG_IPV4_DST,
+						  nfct_get_attr_u32(obj,
+						  	ATTR_REPL_IPV4_SRC));
+			} else if (family == AF_INET6) {
+				nfct_set_attr(obj,
+					      ATTR_ORIG_IPV6_SRC,
+					      nfct_get_attr(obj,
+					      		ATTR_REPL_IPV6_DST));
+				nfct_set_attr(obj,
+					      ATTR_ORIG_IPV6_DST,
+					      nfct_get_attr(obj,
+					      		ATTR_REPL_IPV6_SRC));
+			}
 		}
-		ct = nfct_conntrack_alloc(&orig, &reply, timeout,
-					  &proto, status, mark, id,
-					  NULL);
-		if (!ct)
-			exit_error(OTHER_PROBLEM, "Not enough memory");
-		
+
 		cth = nfct_open(CONNTRACK, 0);
-		if (!cth) {
-			nfct_conntrack_free(ct);
+		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
-		}
-		res = nfct_update_conntrack(cth, ct);
-		nfct_conntrack_free(ct);
+
+		res = nfct_query(cth, NFCT_Q_UPDATE, obj);
 		nfct_close(cth);
 		break;
 		
@@ -995,25 +1140,19 @@
 		cth = nfct_open(CONNTRACK, 0);
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
-		if (options & CT_OPT_ORIG)
-			res = nfct_delete_conntrack(cth, &orig, 
-						    NFCT_DIR_ORIGINAL,
-						    id);
-		else if (options & CT_OPT_REPL)
-			res = nfct_delete_conntrack(cth, &reply, 
-						    NFCT_DIR_REPLY,
-						    id);
+
+		res = nfct_query(cth, NFCT_Q_DESTROY, obj);
 		nfct_close(cth);
 		break;
 
 	case EXP_DELETE:
+		nfexp_set_attr(exp, ATTR_EXP_EXPECTED, obj);
+
 		cth = nfct_open(EXPECT, 0);
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
-		if (options & CT_OPT_ORIG)
-			res = nfct_delete_expectation(cth, &orig, id);
-		else if (options & CT_OPT_REPL)
-			res = nfct_delete_expectation(cth, &reply, id);
+
+		res = nfexp_query(cth, NFCT_Q_DESTROY, exp);
 		nfct_close(cth);
 		break;
 
@@ -1021,27 +1160,21 @@
 		cth = nfct_open(CONNTRACK, 0);
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
-		nfct_register_callback(cth, nfct_default_conntrack_display,
-					NULL);
-		if (options & CT_OPT_ORIG)
-			res = nfct_get_conntrack(cth, &orig,
-						 NFCT_DIR_ORIGINAL, id);
-		else if (options & CT_OPT_REPL)
-			res = nfct_get_conntrack(cth, &reply,
-						 NFCT_DIR_REPLY, id);
+
+		nfct_callback_register(cth, NFCT_T_ALL, dump_cb, obj);
+		res = nfct_query(cth, NFCT_Q_GET, obj);
 		nfct_close(cth);
 		break;
 
 	case EXP_GET:
+		nfexp_set_attr(exp, ATTR_EXP_MASTER, obj);
+
 		cth = nfct_open(EXPECT, 0);
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
-		nfct_register_callback(cth, nfct_default_expect_display,
-					NULL);
-		if (options & CT_OPT_ORIG)
-			res = nfct_get_expectation(cth, &orig, id);
-		else if (options & CT_OPT_REPL)
-			res = nfct_get_expectation(cth, &reply, id);
+
+		nfexp_callback_register(cth, NFCT_T_ALL, dump_exp_cb, NULL);
+		res = nfexp_query(cth, NFCT_Q_GET, exp);
 		nfct_close(cth);
 		break;
 
@@ -1049,7 +1182,7 @@
 		cth = nfct_open(CONNTRACK, 0);
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
-		res = nfct_flush_conntrack_table(cth, AF_INET);
+		res = nfct_query(cth, NFCT_Q_FLUSH, &family);
 		nfct_close(cth);
 		break;
 
@@ -1057,7 +1190,7 @@
 		cth = nfct_open(EXPECT, 0);
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
-		res = nfct_flush_expectation_table(cth, AF_INET);
+		res = nfexp_query(cth, NFCT_Q_FLUSH, &family);
 		nfct_close(cth);
 		break;
 		
@@ -1070,25 +1203,8 @@
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
 		signal(SIGINT, event_sighandler);
-
-		if (options & CT_COMPARISON) {
-			ct = nfct_conntrack_alloc(&orig, &reply, timeout,
-						  &proto, status, mark, id, 
-						  NULL);
-			if (!ct)
-				exit_error(OTHER_PROBLEM, "Not enough memory");
-
-			cmp.ct = ct;
-			cmp.flags = metaflags;
-			cmp.l3flags = l3flags;
-			cmp.l4flags = l4flags;
-			pcmp = &cmp;
-		}
-
-		nfct_register_callback(cth,
-				       nfct_default_conntrack_event_display, 
-				       (void *) pcmp);
-		res = nfct_event_conntrack(cth);
+		nfct_callback_register(cth, NFCT_T_ALL, event_cb, obj);
+		res = nfct_catch(cth);
 		nfct_close(cth);
 		break;
 
@@ -1097,9 +1213,8 @@
 		if (!cth)
 			exit_error(OTHER_PROBLEM, "Can't open handler");
 		signal(SIGINT, event_sighandler);
-		nfct_register_callback(cth, nfct_default_expect_display,
-					NULL);
-		res = nfct_event_expectation(cth);
+		nfexp_callback_register(cth, NFCT_T_ALL, dump_exp_cb, NULL);
+		res = nfexp_catch(cth);
 		nfct_close(cth);
 		break;
 			
@@ -1123,7 +1238,7 @@
 	}
 
 	if (res < 0) {
-		fprintf(stderr, "Operation failed: %s\n", err2str(res, command));
+		fprintf(stderr, "Operation failed: %s\n", err2str(-errno, command));
 		exit(OTHER_PROBLEM);
 	}
 




More information about the netfilter-cvslog mailing list