[netfilter-cvslog] r3497 - in trunk: nfsim/core nfsim/kernelenv nfsim/tools nfsim-testsuite/03NAT

rusty at netfilter.org rusty at netfilter.org
Thu Dec 23 03:19:49 CET 2004


Author: rusty at netfilter.org
Date: 2004-12-23 03:19:48 +0100 (Thu, 23 Dec 2004)
New Revision: 3497

Added:
   trunk/nfsim/tools/tcpsession.c
Modified:
   trunk/nfsim-testsuite/03NAT/61ftpdata-epsv.sim
   trunk/nfsim-testsuite/03NAT/61ftpdata-pasv.sim
   trunk/nfsim-testsuite/03NAT/62ftpdata-eprt.sim
   trunk/nfsim-testsuite/03NAT/62ftpdata-port.sim
   trunk/nfsim-testsuite/03NAT/64-ftp-seq-adjust.sim
   trunk/nfsim-testsuite/03NAT/65-ftp-ack-adjust.sim
   trunk/nfsim/core/expect.c
   trunk/nfsim/core/tui.c
   trunk/nfsim/core/tui.h
   trunk/nfsim/kernelenv/kernelenv.c
   trunk/nfsim/tools/gen_ip.c
   trunk/nfsim/tools/gen_ip.h
   trunk/nfsim/tools/hook.c
Log:
Add "tcpsession" command: requires some modifications to allow others to run commands (esp. nested expectation handling).
Use tcpsession in FTP tests, which clasically ignored failures during TCP handshake (causing --failtest times to explode).


Modified: trunk/nfsim/core/expect.c
===================================================================
--- trunk/nfsim/core/expect.c	2004-12-23 02:16:32 UTC (rev 3496)
+++ trunk/nfsim/core/expect.c	2004-12-23 02:19:48 UTC (rev 3497)
@@ -37,7 +37,12 @@
 };
 
 static struct expect *expect;
-static char *current_command;
+struct cmdstack
+{
+	struct cmdstack *prev;
+	char *command;
+};
+static struct cmdstack *current_command;
 
 /* We don't need to try to match every pattern length: we only need
  * lengths where the next char matches. */
@@ -129,7 +134,7 @@
 	 * expect something to happen twice. */
 	for (e = expect; e; e = e->next) {
 		if (!e->matched
-		    && streq(current_command, e->command)
+		    && streq(current_command->command, e->command)
 		    && matches(e->pattern, line)) {
 			e->matched = 1;
 			ret = true;
@@ -140,17 +145,22 @@
 
 static void expect_pre_command(const char *command)
 {
-	current_command = talloc_strdup(NULL, command);
+	struct cmdstack *new = talloc(NULL, struct cmdstack);
+	new->prev = current_command;
+	new->command = talloc_strdup(new, command);
+	current_command = new;
 }
 
-static void expect_post_command(const char *command)
+static bool expect_post_command(const char *command)
 {
 	struct expect **e, **next, *old;
+	bool ret = true;
+	struct cmdstack *oldcmd;
 
 	for (e = &expect; *e; e = next) {
 		next = &(*e)->next;
 
-		if (!streq(current_command, (*e)->command))
+		if (!streq(current_command->command, (*e)->command))
 			continue;
 
 		if (!(*e)->invert && !(*e)->matched) {
@@ -159,12 +169,14 @@
 					    (*e)->pattern);
 			nfsim_log(LOG_UI, "Pattern '%s' did not match",
 				  (*e)->pattern);
+			ret = false;
 		} else if ((*e)->invert && (*e)->matched) {
 			if (tui_abort_on_fail)
 				script_fail("Pattern '%s' matched",
 					    (*e)->pattern);
 			nfsim_log(LOG_UI, "Pattern '%s' matched",
 				  (*e)->pattern);
+			ret = false;
 		}
 
 		/* Unlink from list and free. */
@@ -174,7 +186,11 @@
 
 		talloc_free(old);
 	}
-	talloc_free(current_command);
+
+	oldcmd = current_command;
+	current_command = current_command->prev;
+	talloc_free(oldcmd);
+	return ret;
 }
 
 static bool expect_cmd(int argc, char **argv)

Modified: trunk/nfsim/core/tui.c
===================================================================
--- trunk/nfsim/core/tui.c	2004-12-23 02:16:32 UTC (rev 3496)
+++ trunk/nfsim/core/tui.c	2004-12-23 02:19:48 UTC (rev 3497)
@@ -47,7 +47,7 @@
 struct pre_post_hook {
 	struct	list_head list;
 	void	(*pre)(const char *);
-	void	(*post)(const char *);
+	bool	(*post)(const char *);
 };
 
 static LIST_HEAD(commands);
@@ -93,12 +93,15 @@
 			i->pre(cmd);
 }
 
-static void do_post_commands(const char *cmd)
+static bool do_post_commands(const char *cmd)
 {
 	struct pre_post_hook *i;
+	bool ret = true;
+
 	list_for_each_entry(i, &pre_post_hooks, list)
-		if (i->post)
-			i->post(cmd);
+		if (i->post && !i->post(cmd))
+			ret = false;
+	return ret;
 }
 
 static bool tui_help(int argc, char **argv)
@@ -190,11 +193,36 @@
 	exit(EXIT_SCRIPTFAIL);
 }
 
+bool tui_do_command(int argc, char *argv[], bool abort)
+{
+	struct command *cmd;
+	bool ret = true;
+	
+	if ((cmd = find_command(argv[0]))) {
+		do_pre_commands(cmd->name);
+		if (!cmd->handler(argc, argv)) {
+			/* Abort on UNEXPECTED failure. */
+			if (!nfsim_log(LOG_UI, "%s: command failed", argv[0])
+			    && abort)
+				script_fail("%s failed", argv[0]);
+			ret = false;
+		}
+		if (!do_post_commands(cmd->name))
+			ret = false;
+		return ret;
+	}
+
+	/* Someone might expect this command not to be found? */
+	if (!nfsim_log(LOG_UI, "%s: command not found", argv[0])
+	    && abort)
+		script_fail("%s not found", argv[0]);
+	return false;
+}
+
 static void process_line(char *line)
 {
 	int argc, prevspace;
 	char *argv[TUI_MAX_ARGS+1], quotemode;
-	struct command *cmd;
 
 	prevspace = 1;
 	quotemode = 0;
@@ -215,27 +243,10 @@
 		line++;
 	}
 
-	if ((!argc) || (*argv[0] == '#'))
-		goto skip;
-
-	argv[argc] = NULL;
-
-	if ((cmd = find_command(argv[0]))) {
-		do_pre_commands(cmd->name);
-		if (!cmd->handler(argc, argv)) {
-			/* Abort on UNEXPECTED failure. */
-			if (!nfsim_log(LOG_UI, "%s: command failed", argv[0])
-			    && tui_abort_on_fail)
-				script_fail("%s failed", argv[0]);
-		}
-		do_post_commands(cmd->name);
-	} else {
-		/* Someone might expect this command not to be found? */
-		if (!nfsim_log(LOG_UI, "%s: command not found", argv[0])
-		    && tui_abort_on_fail)
-			script_fail("%s not found", argv[0]);
+	if (argc > 0 && *argv[0] != '#') {
+		argv[argc] = NULL;
+		tui_do_command(argc, argv, tui_abort_on_fail);
 	}
-skip:
 	tui_linenum++;
 	return;
 }
@@ -289,7 +300,7 @@
 }
 
 int tui_register_pre_post_hook(void (*pre)(const char *),
-			       void (*post)(const char *))
+			       bool (*post)(const char *))
 {
 	struct pre_post_hook *h;
 

Modified: trunk/nfsim/core/tui.h
===================================================================
--- trunk/nfsim/core/tui.h	2004-12-23 02:16:32 UTC (rev 3496)
+++ trunk/nfsim/core/tui.h	2004-12-23 02:19:48 UTC (rev 3497)
@@ -32,10 +32,12 @@
 			 void (*helpfn)(int argc, char **argv));
 
 int tui_register_pre_post_hook(void (*pre)(const char *),
-			       void (*post)(const char *));
+			       bool (*post)(const char *));
 
 void tui_run(bool interactive, int fd);
 
+bool tui_do_command(int argc, char *argv[], bool abort);
+
 /* Is this a valid command?  Sanity check for expect. */
 bool tui_is_command(const char *name);
 

Modified: trunk/nfsim/kernelenv/kernelenv.c
===================================================================
--- trunk/nfsim/kernelenv/kernelenv.c	2004-12-23 02:16:32 UTC (rev 3496)
+++ trunk/nfsim/kernelenv/kernelenv.c	2004-12-23 02:19:48 UTC (rev 3497)
@@ -606,7 +606,7 @@
 	return 1;
 }
 
-static void do_running_timers(const char *cmd)
+static bool do_running_timers(const char *cmd)
 {
 	struct timer_list *t, *next;
 	list_for_each_entry_safe(t, next, &__running_timers, entry) {
@@ -614,6 +614,7 @@
 		list_del(&t->entry);
 		talloc_free(t->use);
 	}
+	return true;
 }
 
 void schedule(void)

Modified: trunk/nfsim/tools/gen_ip.c
===================================================================
--- trunk/nfsim/tools/gen_ip.c	2004-12-23 02:16:32 UTC (rev 3496)
+++ trunk/nfsim/tools/gen_ip.c	2004-12-23 02:19:48 UTC (rev 3497)
@@ -170,6 +170,22 @@
 	return dst;
 }
 
+int gen_ip_data_length(unsigned int datanum, char *data[])
+{
+	char buf[1024], *p;
+	unsigned int i, len = 0;
+
+	for (i = 0; i < datanum; i++) {
+		p = copy_printable(buf, data[i]);
+		if (!p)
+			return -1;
+		len += p - buf;
+		if (i > 0)
+			len++;
+	}
+	return len;
+}
+
 static int parse_header(struct packet *packet,
 			const char *srcip, const char *dstip,
 			const char *lenstr, const char *protocol,

Modified: trunk/nfsim/tools/gen_ip.h
===================================================================
--- trunk/nfsim/tools/gen_ip.h	2004-12-23 02:16:32 UTC (rev 3496)
+++ trunk/nfsim/tools/gen_ip.h	2004-12-23 02:19:48 UTC (rev 3497)
@@ -30,4 +30,6 @@
 /* Convert string of form w.x.y.z to an address.  NULL on fail. */
 struct in_addr *dotted_to_addr(const char *dotted);
 
+/* How many bytes will this take up?  Used by tcpsession */
+int gen_ip_data_length(unsigned int datanum, char *data[]);
 #endif /* _NFSIM_GEN_IP_H */

Modified: trunk/nfsim/tools/hook.c
===================================================================
--- trunk/nfsim/tools/hook.c	2004-12-23 02:16:32 UTC (rev 3496)
+++ trunk/nfsim/tools/hook.c	2004-12-23 02:19:48 UTC (rev 3497)
@@ -76,19 +76,20 @@
 	    : "UNKNOWN");
 }
 
-static void hook_post_cleanup(const char *command)
+static bool hook_post_cleanup(const char *command)
 {
 	struct hook_list *l, *next;
 
 	/* A little hacky, but it works: only clean up after gen_ip. */
 	if (!streq(command, "gen_ip"))
-		return;
+		return true;
 
 	list_for_each_entry_safe(l, next, &hooks, list) {
 		nf_unregister_hook(&l->ops);
 		list_del(&l->list);
 		free(l);
 	}
+	return true;
 }	
 
 static bool hook_cmd(int argc, char **argv)

Added: trunk/nfsim/tools/tcpsession.c
===================================================================
--- trunk/nfsim/tools/tcpsession.c	2004-12-23 02:16:32 UTC (rev 3496)
+++ trunk/nfsim/tools/tcpsession.c	2004-12-23 02:19:48 UTC (rev 3497)
@@ -0,0 +1,321 @@
+/*
+
+Copyright (c) 2004 Rusty Russell
+
+This file is part of nfsim.
+
+nfsim 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.
+
+nfsim is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with nfsim; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <core.h>
+#include <tui.h>
+#include <log.h>
+#include <utils.h>
+#include "gen_ip.h"
+
+static void tcpsession_help(int argc, char **argv)
+{
+#include "tcpsession-help:tcpsession"
+/*** XML Help:
+    <section id="c:tcpsession">
+     <title><command>tcpsession</command></title>
+     <para>Generate TCP session</para>
+     <cmdsynopsis>
+      <command>tcpsession</command>
+      <arg choice="req">OPEN</arg>
+      <arg choice="req">src</arg>
+      <arg choice="req">dest</arg>
+      <arg choice="req">srcpt</arg>
+      <arg choice="req">dstpt</arg>
+     </cmdsynopsis>
+     <cmdsynopsis>
+      <command>tcpsession</command>
+      <arg choice="req">OPEN</arg>
+      <arg choice="req">src</arg>
+      <arg choice="req">dest</arg>
+      <arg choice="req">srcpt</arg>
+      <arg choice="req">dstpt</arg>
+      <arg choice="req">reply-src</arg>
+      <arg choice="req">reply-dest</arg>
+      <arg choice="req">reply-srcpt</arg>
+      <arg choice="req">reply-dstpt</arg>
+     </cmdsynopsis>
+     <cmdsynopsis>
+      <command>tcpsession</command>
+      <arg choice="req">DATA</arg>
+      <arg choice="req">direction</arg>
+      <arg choice="req"><replaceable>args</replaceable></arg>
+     </cmdsynopsis>
+     <cmdsynopsis>
+      <command>tcpsession</command>
+      <arg choice="req">LENCHANGE</arg>
+      <arg choice="req"><replaceable>number</replaceable></arg>
+     </cmdsynopsis>
+     <cmdsynopsis>
+      <command>tcpsession</command>
+      <arg choice="req">CLOSE</arg>
+      <arg choice="req">direction</arg>
+     </cmdsynopsis>
+
+     <para><command>tcpsession</command> is shorthand for creating a
+     TCP session using multiple gen_ip commands.  The four-argument
+     <arg>OPEN</arg> form creates a simple connection (no NAT
+     expected), the eight-argument form creates a connection which
+     might be NATted.  You can only have one open connection at a
+     time: this is used for all operations.  Sequence numbers will be
+     1001 for the sender, and 2001 for the recipient.  Initial packet
+     comes in eth0, replies come in eth1. </para>
+
+     <para>The <arg>DATA</arg> form sends data on the current
+     connection, in a single packet (and sends an ACK in reply).
+     <arg>direction</arg> is either 'original' or 'reply'.</para>
+
+     <para>The <arg>LENCHANGE</arg> command sets expected change in
+     length of the next packet.  It is used to tell
+     <command>tcpsession</command> that the next packet is going to
+     expected to be shortened or lengthened.</para>
+
+     <para>The <arg>CLOSE</arg> form sends the required FIN and ACK
+     packets to close the connection: <arg>direction</arg> specifies
+     who initiates the close.</para>
+    </section>
+*/
+}
+
+struct tcp_endpoint
+{
+	char *interface;
+	char *src, *dst, *spt, *dpt;
+	u32 seq, ack;
+};
+
+struct tcpsession
+{
+	struct tcp_endpoint original, reply;
+	int lenchange;
+};
+static struct tcpsession *curr = NULL;
+
+static bool tcp_send(struct tcp_endpoint *in, struct tcp_endpoint *out,
+		     int datalen, const char *flags, const char *win,
+		     int datanum, char *data[])
+{
+	char *ctx = talloc(NULL, char);
+	char *argv[20];
+	int argc;
+
+	argc = 0;
+	argv[argc++] = talloc_strdup(ctx, "expect");
+	argv[argc++] = talloc_strdup(ctx, "gen_ip");
+	argv[argc++] = talloc_asprintf(ctx, "send:%s", out->interface);
+	argv[argc++] = talloc_asprintf(ctx, "{IPv4 %s %s %i 6 %s %s %s"
+				       " SEQ=%u ACK=%u*}",
+				       out->dst, out->src,
+				       datalen + curr->lenchange, 
+				       out->dpt, out->spt, flags,
+				       out->ack, out->seq);
+	argv[argc] = NULL;
+
+	/* Don't have it abort, do that at top level. */
+	if (!tui_do_command(argc, argv, false))
+		goto fail;
+
+	argc = 0;
+	argv[argc++] = talloc_strdup(ctx, "gen_ip");
+	argv[argc++] = talloc_asprintf(ctx, "IF=%s", in->interface);
+	argv[argc++] = talloc_strdup(ctx, in->src);
+	argv[argc++] = talloc_strdup(ctx, in->dst);
+	argv[argc++] = talloc_asprintf(ctx, "%i", datalen);
+	argv[argc++] = talloc_strdup(ctx, "6");
+	argv[argc++] = talloc_strdup(ctx, in->spt);
+	argv[argc++] = talloc_strdup(ctx, in->dpt);
+	argv[argc++] = talloc_strdup(ctx, flags);
+	argv[argc++] = talloc_asprintf(ctx, "SEQ=%u", in->seq);
+	argv[argc++] = talloc_asprintf(ctx, "ACK=%u", in->ack);
+	if (win)
+		argv[argc++] = talloc_strdup(ctx, win);
+	if (datanum) {
+		unsigned int i;
+		argv[argc++] = talloc_strdup(ctx, "DATA");
+		for (i = 0; i < datanum; i++)
+			argv[argc++] = talloc_strdup(ctx, data[i]);
+	}
+	argv[argc] = NULL;
+
+	if (!tui_do_command(argc, argv, false))
+		goto fail;
+
+	talloc_free(ctx);
+	return true;
+fail:
+	talloc_free(ctx);
+	return false;
+}
+
+static bool open_session(const char *src, const char *dst, 
+			 const char *spt, const char *dpt, 
+			 const char *reply_src, const char *reply_dst, 
+			 const char *reply_spt, const char *reply_dpt)
+{
+	curr = talloc(NULL, struct tcpsession);
+
+	curr->original.src = talloc_strdup(curr, src);
+	curr->original.dst = talloc_strdup(curr, dst);
+	curr->original.spt = talloc_strdup(curr, spt);
+	curr->original.dpt = talloc_strdup(curr, dpt);
+	curr->original.interface = talloc_strdup(curr, "eth0");
+	curr->original.seq = 1000;
+	curr->original.ack = 2000;
+
+	curr->reply.src = talloc_strdup(curr, reply_src);
+	curr->reply.dst = talloc_strdup(curr, reply_dst);
+	curr->reply.spt = talloc_strdup(curr, reply_spt);
+	curr->reply.dpt = talloc_strdup(curr, reply_dpt);
+	curr->reply.interface = talloc_strdup(curr, "eth1");
+	curr->reply.seq = 2000;
+	curr->reply.ack = 1000;
+
+	curr->lenchange = 0;
+
+	if (!tcp_send(&curr->original, &curr->reply, 0, "SYN", "WIN=512",
+		      0, NULL))
+		goto fail;
+	curr->original.seq++;
+	curr->reply.ack++;
+	if (!tcp_send(&curr->reply, &curr->original, 0, "SYN/ACK", "WIN=512",
+		      0, NULL))
+		goto fail;
+	curr->reply.seq++;
+	curr->original.ack++;
+	if (!tcp_send(&curr->original, &curr->reply, 0, "ACK", "WIN=512",
+		      0, NULL))
+		goto fail;
+	return true;
+fail:
+	talloc_free(curr);
+	curr = NULL;
+	return false;
+}
+
+static bool send_data(struct tcp_endpoint *in, struct tcp_endpoint *out,
+		      int datanum, char *data[])		      
+{
+	int len = gen_ip_data_length(datanum, data);
+
+	if (!tcp_send(in, out, len, "ACK", NULL,
+		      datanum, data))
+		return false;
+	in->seq += len;
+	out->ack += len + curr->lenchange;
+	curr->lenchange = 0;
+
+#if 0
+	/* Send ACK. */
+	return tcp_send(out, in, 0, "ACK", NULL, 0, NULL);
+#else
+	return true;
+#endif
+}
+
+static bool close_session(struct tcp_endpoint *in, struct tcp_endpoint *out)
+{
+	if (!tcp_send(in, out, 0, "FIN/ACK", NULL, 0, NULL))
+		return false;
+	in->seq++;
+	out->ack++;
+	if (!tcp_send(out, in, 0, "FIN/ACK", NULL, 0, NULL))
+		return false;
+	talloc_free(curr);
+	curr = NULL;
+	return true;
+}
+
+static bool tcpsession(int argc, char *argv[])
+{
+	if (argc < 2) {
+		tcpsession_help(argc, argv);
+		return false;
+	}
+	if (streq(argv[1], "OPEN")) {
+		if (curr) {
+			nfsim_log(LOG_ALWAYS, "Session already open!");
+			return false;
+		}
+		if (argc == 6)
+			return open_session(argv[2],argv[3],argv[4],argv[5],
+					    argv[3],argv[2],argv[5],argv[4]);
+		if (argc == 10)
+			return open_session(argv[2],argv[3],argv[4],argv[5],
+					    argv[6],argv[7],argv[8],argv[9]);
+		tcpsession_help(argc, argv);
+		return false;
+	}
+	if (streq(argv[1], "DATA")) {
+		if (!curr) {
+			nfsim_log(LOG_ALWAYS, "Session not open!");
+			return false;
+		}
+		if (argc < 3) {
+			tcpsession_help(argc, argv);
+			return false;
+		}
+		if (streq(argv[2], "original"))
+			return send_data(&curr->original, &curr->reply,
+					 argc-3, argv+3);
+		if (streq(argv[2], "reply"))
+			return send_data(&curr->reply, &curr->original,
+					 argc-3, argv+3);
+		tcpsession_help(argc, argv);
+		return false;
+	}
+	if (streq(argv[1], "LENCHANGE")) {
+		int change;
+		if (argc != 3) {
+			tcpsession_help(argc, argv);
+			return false;
+		}
+		change = atoi(argv[2]);
+		if (!change) {
+			tcpsession_help(argc, argv);
+			return false;
+		}
+		curr->lenchange = change;
+		return true;
+	}
+	if (streq(argv[1], "CLOSE")) {
+		if (!curr) {
+			nfsim_log(LOG_ALWAYS, "Session not open!");
+			return false;
+		}
+		if (argc != 3) {
+			tcpsession_help(argc, argv);
+			return false;
+		}
+		if (streq(argv[2], "original"))
+			return close_session(&curr->original, &curr->reply);
+		if (streq(argv[2], "reply"))
+			return close_session(&curr->reply, &curr->original);
+	}
+	tcpsession_help(argc, argv);
+	return false;
+}
+
+static void init(void)
+{
+	tui_register_command("tcpsession", tcpsession, tcpsession_help);
+}
+
+init_call(init);
+

Modified: trunk/nfsim-testsuite/03NAT/61ftpdata-epsv.sim
===================================================================
--- trunk/nfsim-testsuite/03NAT/61ftpdata-epsv.sim	2004-12-23 02:16:32 UTC (rev 3496)
+++ trunk/nfsim-testsuite/03NAT/61ftpdata-epsv.sim	2004-12-23 02:19:48 UTC (rev 3497)
@@ -1,18 +1,18 @@
 # Destination NAT test.
 iptables -t nat -A PREROUTING -d 192.168.1.2 -p tcp --dport 21 -j DNAT --to-dest 192.168.1.13
 
-# Generate initial packets: handshake, then FTP PASV response.
-gen_ip IF=eth0 192.168.0.2 192.168.1.2 0 6 1024 21 SYN SEQ=1000 WIN=512
-gen_ip IF=eth1 192.168.1.13 192.168.0.2 0 6 21 1024 SYN/ACK SEQ=2000 ACK=1001 WIN=512
-gen_ip IF=eth0 192.168.0.2 192.168.1.2 0 6 1024 21 ACK SEQ=1001 ACK=2001 WIN=512
+tcpsession OPEN 192.168.0.2 192.168.1.2 1024 21 192.168.1.13 192.168.0.2 21 1024
 # Need \n on the end of previous packet for this to work.
-gen_ip IF=eth1 192.168.1.13 192.168.0.2 10 6 21 1024 ACK SEQ=2001 ACK=1001 DATA Hi Marc!\r\n
+tcpsession DATA reply Hi Marc!\r\n
 
 # NAT code changes delimiters to |.
 expect gen_ip send:eth0 {IPv4 192.168.1.2 192.168.0.2 31 6 21 1024 ACK SEQ=2011 ACK=1001 DATA 229 Some text here (|||2028|)\r\n}
-gen_ip IF=eth1 192.168.1.13 192.168.0.2 31 6 21 1024 ACK SEQ=2011 ACK=1001 DATA 229 Some text here (???2028?)\r\n
+tcpsession DATA reply 229 Some text here (???2028?)\r\n
 
+# send an actual SYN.
 expect gen_ip send:eth1 {IPv4 192.168.0.2 192.168.1.13 0 6 1025 2028 SYN}
 gen_ip IF=eth0 192.168.0.2 192.168.1.2 0 6 1025 2028 SYN
 
+tcpsession CLOSE reply
+
 iptables -t nat -D PREROUTING -d 192.168.1.2 -p tcp --dport 21 -j DNAT --to-dest 192.168.1.13

Modified: trunk/nfsim-testsuite/03NAT/61ftpdata-pasv.sim
===================================================================
--- trunk/nfsim-testsuite/03NAT/61ftpdata-pasv.sim	2004-12-23 02:16:32 UTC (rev 3496)
+++ trunk/nfsim-testsuite/03NAT/61ftpdata-pasv.sim	2004-12-23 02:19:48 UTC (rev 3497)
@@ -2,39 +2,31 @@
 iptables -t nat -A PREROUTING -d 192.168.1.2 -p tcp --dport 21 -j DNAT --to-dest 192.168.1.13
 
 # Generate initial packets: handshake, then FTP PASV response.
-gen_ip IF=eth0 192.168.0.2 192.168.1.2 0 6 1024 21 SYN SEQ=1000 WIN=512
-gen_ip IF=eth1 192.168.1.13 192.168.0.2 0 6 21 1024 SYN/ACK SEQ=2000 ACK=1001 WIN=512
-gen_ip IF=eth0 192.168.0.2 192.168.1.2 0 6 1024 21 ACK SEQ=1001 ACK=2001 WIN=512
+tcpsession OPEN 192.168.0.2 192.168.1.2 1024 21 192.168.1.13 192.168.0.2 21 1024
 # Need \n on the end of previous packet for this to work.
-gen_ip IF=eth1 192.168.1.13 192.168.0.2 10 6 21 1024 ACK SEQ=2001 ACK=1001 DATA Hi Marc!\r\n
+tcpsession DATA reply Hi Marc!\r\n
 
 # 48 bytes of data, shrinks to 47.
-expect gen_ip send:eth0 {IPv4 192.168.1.2 192.168.0.2 47 6 21 1024 ACK SEQ=2011 ACK=1001 DATA 227 Entering Passive Mode (192,168,1,2,7,236)\r\n}
-gen_ip IF=eth1 192.168.1.13 192.168.0.2 48 6 21 1024 ACK SEQ=2011 ACK=1001 DATA 227 Entering Passive Mode (192,168,1,13,7,236)\r\n
+tcpsession LENCHANGE -1
+tcpsession DATA reply 227 Entering Passive Mode (192,168,1,13,7,236)\r\n
 
 # Send through future packets to check SYN/ACK correction (should come
 # out one less, if seq > above).
 
-# Retransmit: unaffected.
+# Retransmit: unaffected (we do this manually: tcpsession is too dumb).
 expect gen_ip send:eth0 {IPv4 192.168.1.2 192.168.0.2 47 6 21 1024 ACK SEQ=2011 ACK=1001 DATA 227 Entering Passive Mode (192,168,1,2,7,236)\r\n}
 gen_ip IF=eth1 192.168.1.13 192.168.0.2 48 6 21 1024 ACK SEQ=2011 ACK=1001 DATA 227 Entering Passive Mode (192,168,1,13,7,236)\r\n
 
 # ACK from client: should have one added, if after.
-expect gen_ip send:eth1 {IPv4 192.168.0.2 192.168.1.13 0 6 1024 21 ACK SEQ=1001 ACK=2011}
-gen_ip IF=eth0 192.168.0.2 192.168.1.2 0 6 1024 21 ACK SEQ=1001 ACK=2011
+tcpsession DATA original x
 
-expect gen_ip send:eth1 {IPv4 192.168.0.2 192.168.1.13 0 6 1024 21 ACK SEQ=1001 ACK=2059}
-gen_ip IF=eth0 192.168.0.2 192.168.1.2 0 6 1024 21 ACK SEQ=1001 ACK=2058
-
 # SEQ from server: should have one subtracted, if after.
-expect gen_ip send:eth0 {IPv4 192.168.1.2 192.168.0.2 0 6 21 1024 ACK SEQ=2011 ACK=1001}
-gen_ip IF=eth1 192.168.1.13 192.168.0.2 0 6 21 1024 ACK SEQ=2011 ACK=1001
+tcpsession DATA reply x
 
-expect gen_ip send:eth0 {IPv4 192.168.1.2 192.168.0.2 0 6 21 1024 ACK SEQ=2058 ACK=1001}
-gen_ip IF=eth1 192.168.1.13 192.168.0.2 0 6 21 1024 ACK SEQ=2059 ACK=1001
-
 # Send through the actual SYN for data connection.
 expect gen_ip send:eth1 {IPv4 192.168.0.2 192.168.1.13 0 6 1025 2028 SYN}
 gen_ip IF=eth0 192.168.0.2 192.168.1.2 0 6 1025 2028 SYN
 
+tcpsession CLOSE original
+
 iptables -t nat -D PREROUTING -d 192.168.1.2 -p tcp --dport 21 -j DNAT --to-dest 192.168.1.13

Modified: trunk/nfsim-testsuite/03NAT/62ftpdata-eprt.sim
===================================================================
--- trunk/nfsim-testsuite/03NAT/62ftpdata-eprt.sim	2004-12-23 02:16:32 UTC (rev 3496)
+++ trunk/nfsim-testsuite/03NAT/62ftpdata-eprt.sim	2004-12-23 02:19:48 UTC (rev 3497)
@@ -1,19 +1,19 @@
 # Script to test ftp module's data mangling
 
-# FIXME: test double mangling.
-
 # Source NAT test.
 iptables -t nat -A POSTROUTING -o eth1 -p tcp --dport 21 -j SNAT --to-source 192.168.0.100
 
 # Generate initial packets: handshake, then FTP PASV response.
-gen_ip IF=eth0 192.168.0.2 192.168.1.2 0 6 1024 21 SYN SEQ=1000 WIN=512
-gen_ip IF=eth1 192.168.1.2 192.168.0.100 0 6 21 1024 SYN/ACK SEQ=2000 ACK=1001 WIN=512
-gen_ip IF=eth0 192.168.0.2 192.168.1.2 0 6 1024 21 ACK SEQ=1001 ACK=2001 WIN=512
-gen_ip IF=eth0 192.168.0.2 192.168.1.2 10 6 1024 21 ACK SEQ=1001 ACK=2001 DATA Hi Marc!\r\n
+tcpsession OPEN 192.168.0.2 192.168.1.2 1024 21 192.168.1.2 192.168.0.100 21 1024
 
-expect gen_ip send:eth1 {IPv4 192.168.0.100 192.168.1.2 29 6 1024 21 ACK SEQ=1011 ACK=2001 DATA EPRT |1|192.168.0.100|2028|\r\n}
-gen_ip IF=eth0 192.168.0.2 192.168.1.2 27 6 1024 21 ACK SEQ=1011 ACK=2001 DATA EPRT /1/192.168.0.2/2028/\r\n
+# Need preceeding \n
+tcpsession DATA original Hi Marc!\r\n
 
+# Now should extend packet data and change IP address.
+tcpsession LENCHANGE 2
+expect gen_ip *DATA EPRT |1|192.168.0.100|2028|\r\n}
+tcpsession DATA original EPRT /1/192.168.0.2/2028/\r\n
+
 # Retransmit: we've had a \n from last one, but it should still mangle
 # this correctly.
 expect gen_ip send:eth1 {IPv4 192.168.0.100 192.168.1.2 29 6 1024 21 ACK SEQ=1011 ACK=2001 DATA EPRT |1|192.168.0.100|2028|\r\n}
@@ -21,32 +21,30 @@
 
 # Send through future packets to check SYN/ACK correction (should come
 # out two less, if seq > above).
+tcpsession DATA original x
+tcpsession DATA reply x
 
+# Check seq on older packets not changed.
 expect gen_ip send:eth0 {IPv4 192.168.1.2 192.168.0.2 0 6 21 1024 ACK SEQ=2001 ACK=1001}
 gen_ip IF=eth1 192.168.1.2 192.168.0.100 0 6 21 1024 ACK SEQ=2001 ACK=1001
-expect gen_ip send:eth0 {IPv4 192.168.1.2 192.168.0.2 0 6 21 1024 ACK SEQ=2001 ACK=1030}
-gen_ip IF=eth1 192.168.1.2 192.168.0.100 0 6 21 1024 ACK SEQ=2001 ACK=1032
-
 expect gen_ip send:eth1 {IPv4 192.168.0.100 192.168.1.2 0 6 1024 21 ACK SEQ=1001 ACK=2001}
 gen_ip IF=eth0 192.168.0.2 192.168.1.2 0 6 1024 21 ACK SEQ=1001 ACK=2001
-expect gen_ip send:eth1 {IPv4 192.168.0.100 192.168.1.2 0 6 1024 21 ACK SEQ=1031 ACK=2001}
-gen_ip IF=eth0 192.168.0.2 192.168.1.2 0 6 1024 21 ACK SEQ=1029 ACK=2001
 
 # Now, test that a second connection gets mapped to a different port,
-# if mapped to same IP address.
-# Generate initial packets: handshake, then FTP EPRT command.
-gen_ip IF=eth0 192.168.0.3 192.168.1.2 0 6 1025 21 SYN SEQ=1000 WIN=512
-gen_ip IF=eth1 192.168.1.2 192.168.0.100 0 6 21 1025 SYN/ACK SEQ=2000 ACK=1001 WIN=512
-gen_ip IF=eth0 192.168.0.3 192.168.1.2 0 6 1025 21 ACK SEQ=1001 ACK=2001
+# if mapped to same IP address.  Close won't happen since timer not running.
+tcpsession CLOSE original
 
-# Need preceeding \n.
-gen_ip IF=eth0 192.168.0.3 192.168.1.2 10 6 1025 21 ACK SEQ=1001 ACK=2001 DATA Hi Marc!\r\n
+tcpsession OPEN 192.168.0.3 192.168.1.2 1025 21 192.168.1.2 192.168.0.100 21 1025
+tcpsession DATA original Hi Marc!\r\n
 
-expect gen_ip send:eth1 {IPv4 192.168.0.100 192.168.1.2 29 6 1025 21 ACK SEQ=1011 ACK=2001 DATA EPRT |1|192.168.0.100|2029|\r\n}
-gen_ip IF=eth0 192.168.0.3 192.168.1.2 27 6 1025 21 ACK SEQ=1011 ACK=2001 DATA EPRT x1x192.168.0.3x2028x\r\n
+expect gen_ip *DATA EPRT |1|192.168.0.100|2029|\r\n}
+tcpsession LENCHANGE 2
+tcpsession DATA original EPRT /1/192.168.0.3/2028/\r\n
 
 # Send through the actual SYN for data connection.
 expect gen_ip send:eth0 {IPv4 192.168.1.2 192.168.0.2 0 6 1025 2028 SYN}
 gen_ip IF=eth1 192.168.1.2 192.168.0.100 0 6 1025 2028 SYN
 
+tcpsession CLOSE original
+
 iptables -t nat -D POSTROUTING -o eth1 -p tcp --dport 21 -j SNAT --to-source 192.168.0.100

Modified: trunk/nfsim-testsuite/03NAT/62ftpdata-port.sim
===================================================================
--- trunk/nfsim-testsuite/03NAT/62ftpdata-port.sim	2004-12-23 02:16:32 UTC (rev 3496)
+++ trunk/nfsim-testsuite/03NAT/62ftpdata-port.sim	2004-12-23 02:19:48 UTC (rev 3497)
@@ -1,19 +1,19 @@
 # Script to test ftp module's data mangling
 
-# FIXME: test double mangling.
-
 # Source NAT test.
 iptables -t nat -A POSTROUTING -o eth1 -p tcp --dport 21 -j SNAT --to-source 192.168.0.100
 
 # Generate initial packets: handshake, then FTP PASV response.
-gen_ip IF=eth0 192.168.0.2 192.168.1.2 0 6 1024 21 SYN SEQ=1000 WIN=512
-gen_ip IF=eth1 192.168.1.2 192.168.0.100 0 6 21 1024 SYN/ACK SEQ=2000 ACK=1001 WIN=512
-gen_ip IF=eth0 192.168.0.2 192.168.1.2 0 6 1024 21 ACK SEQ=1001 ACK=2001 WIN=512
-gen_ip IF=eth0 192.168.0.2 192.168.1.2 10 6 1024 21 ACK SEQ=1001 ACK=2001 DATA Hi Marc!\r\n
+tcpsession OPEN 192.168.0.2 192.168.1.2 1024 21 192.168.1.2 192.168.0.100 21 1024
 
-expect gen_ip send:eth1 {IPv4 192.168.0.100 192.168.1.2 26 6 1024 21 ACK SEQ=1011 ACK=2001 DATA PORT 192,168,0,100,7,236\r\n}
-gen_ip IF=eth0 192.168.0.2 192.168.1.2 24 6 1024 21 ACK SEQ=1011 ACK=2001 DATA PORT 192,168,0,2,7,236\r\n
+# Need preceeding \n
+tcpsession DATA original Hi Marc!\r\n
 
+# Now should extend packet data and change IP address.
+tcpsession LENCHANGE 2
+expect gen_ip *DATA PORT 192,168,0,100,7,236\r\n}
+tcpsession DATA original PORT 192,168,0,2,7,236\r\n
+
 # Retransmit: we've had a \n from last one, but it should still mangle
 # this correctly.
 expect gen_ip send:eth1 {IPv4 192.168.0.100 192.168.1.2 26 6 1024 21 ACK SEQ=1011 ACK=2001 DATA PORT 192,168,0,100,7,236\r\n}
@@ -21,32 +21,30 @@
 
 # Send through future packets to check SYN/ACK correction (should come
 # out two less, if seq > above).
+tcpsession DATA original x
+tcpsession DATA reply x
 
+# Check seq on older packets not changed.
 expect gen_ip send:eth0 {IPv4 192.168.1.2 192.168.0.2 0 6 21 1024 ACK SEQ=2001 ACK=1001}
 gen_ip IF=eth1 192.168.1.2 192.168.0.100 0 6 21 1024 ACK SEQ=2001 ACK=1001
-expect gen_ip send:eth0 {IPv4 192.168.1.2 192.168.0.2 0 6 21 1024 ACK SEQ=2001 ACK=1030}
-gen_ip IF=eth1 192.168.1.2 192.168.0.100 0 6 21 1024 ACK SEQ=2001 ACK=1032
-
 expect gen_ip send:eth1 {IPv4 192.168.0.100 192.168.1.2 0 6 1024 21 ACK SEQ=1001 ACK=2001}
 gen_ip IF=eth0 192.168.0.2 192.168.1.2 0 6 1024 21 ACK SEQ=1001 ACK=2001
-expect gen_ip send:eth1 {IPv4 192.168.0.100 192.168.1.2 0 6 1024 21 ACK SEQ=1031 ACK=2001}
-gen_ip IF=eth0 192.168.0.2 192.168.1.2 0 6 1024 21 ACK SEQ=1029 ACK=2001
 
 # Now, test that a second connection gets mapped to a different port,
-# if mapped to same IP address.
-# Generate initial packets: handshake, then FTP EPRT command.
-gen_ip IF=eth0 192.168.0.3 192.168.1.2 0 6 1025 21 SYN SEQ=1000 WIN=512
-gen_ip IF=eth1 192.168.1.2 192.168.0.100 0 6 21 1025 SYN/ACK SEQ=2000 ACK=1001 WIN=512
-gen_ip IF=eth0 192.168.0.3 192.168.1.2 0 6 1025 21 ACK SEQ=1001 ACK=2001
+# if mapped to same IP address.  Close won't happen since timer not running.
+tcpsession CLOSE original
 
-# Need preceeding \n.
-gen_ip IF=eth0 192.168.0.3 192.168.1.2 10 6 1025 21 ACK SEQ=1001 ACK=2001 DATA Hi Marc!\r\n
+tcpsession OPEN 192.168.0.3 192.168.1.2 1025 21 192.168.1.2 192.168.0.100 21 1025
+tcpsession DATA original Hi Marc!\r\n
 
-expect gen_ip send:eth1 {IPv4 192.168.0.100 192.168.1.2 26 6 1025 21 ACK SEQ=1011 ACK=2001 DATA PORT 192,168,0,100,7,237\r\n}
-gen_ip IF=eth0 192.168.0.3 192.168.1.2 24 6 1025 21 ACK SEQ=1011 ACK=2001 DATA PORT 192,168,0,3,7,237\r\n
+expect gen_ip *DATA PORT 192,168,0,100,7,237\r\n}
+tcpsession LENCHANGE 2
+tcpsession DATA original PORT 192,168,0,3,7,236\r\n
 
 # Send through the actual SYN for data connection.
 expect gen_ip send:eth0 {IPv4 192.168.1.2 192.168.0.2 0 6 1025 2028 SYN}
 gen_ip IF=eth1 192.168.1.2 192.168.0.100 0 6 1025 2028 SYN
 
+tcpsession CLOSE original
+
 iptables -t nat -D POSTROUTING -o eth1 -p tcp --dport 21 -j SNAT --to-source 192.168.0.100

Modified: trunk/nfsim-testsuite/03NAT/64-ftp-seq-adjust.sim
===================================================================
--- trunk/nfsim-testsuite/03NAT/64-ftp-seq-adjust.sim	2004-12-23 02:16:32 UTC (rev 3496)
+++ trunk/nfsim-testsuite/03NAT/64-ftp-seq-adjust.sim	2004-12-23 02:19:48 UTC (rev 3497)
@@ -7,14 +7,14 @@
 iptables -t nat -A POSTROUTING -s 192.168.0.200 -p tcp --dport 21 -j SNAT --to-source 192.168.0.1
 
 # Generate initial packets: handshake, then FTP PORT command.
-gen_ip IF=eth0 192.168.0.200 192.168.1.2 0 6 1024 21 SYN SEQ=1000 WIN=512
-gen_ip IF=eth1 192.168.1.2 192.168.0.1 0 6 21 1024 SYN/ACK SEQ=2000 ACK=1001 WIN=512
-gen_ip IF=eth0 192.168.0.200 192.168.1.2 0 6 1024 21 ACK SEQ=1001 ACK=2001 WIN=512
+tcpsession OPEN 192.168.0.200 192.168.1.2 1024 21 192.168.1.2 192.168.0.1 21 1024
 
 # Need preceeding \n.
-gen_ip IF=eth0 192.168.0.200 192.168.1.2 10 6 1024 21 ACK SEQ=1001 ACK=2001 DATA Hi Marc!\r\n
+tcpsession DATA original Hi Marc!\r\n
 
-gen_ip IF=eth0 192.168.0.200 192.168.1.2 26 6 1024 21 ACK SEQ=1011 ACK=2001 DATA PORT 192,168,0,200,7,236\r\n
+tcpsession LENCHANGE -2
+expect gen_ip send:eth1*DATA PORT 192,168,0,1,7,236\r\n}
+tcpsession DATA original PORT 192,168,0,200,7,236\r\n
 
 expect gen_ip send:eth1 {IPv4 192.168.0.1 192.168.1.2 6 6 1024 21 ACK SEQ=1035 ACK=2001 DATA Test!\n}
 gen_ip IF=eth0 192.168.0.200 192.168.1.2 6 6 1024 21 ACK SEQ=1037 ACK=2001 DATA Test!\n
@@ -23,6 +23,7 @@
 expect gen_ip send:eth1 {IPv4 192.168.0.1 192.168.1.2 10 6 1024 21 ACK SEQ=1001 ACK=2001 DATA Hi Marc!\r\n}
 gen_ip IF=eth0 192.168.0.200 192.168.1.2 10 6 1024 21 ACK SEQ=1001 ACK=2001 DATA Hi Marc!\r\n
 
+tcpsession CLOSE original
 iptables -t nat -D POSTROUTING -s 192.168.0.200 -p tcp --dport 21 -j SNAT --to-source 192.168.0.1
 
 ### Second run: make string LONGER.
@@ -30,15 +31,14 @@
 iptables -t nat -A POSTROUTING -s 192.168.0.5 -p tcp --dport 21 -j SNAT --to-source 192.168.0.205
 
 # Generate initial packets: handshake, then FTP PORT command.
-gen_ip IF=eth0 192.168.0.5 192.168.1.2 0 6 1024 21 SYN SEQ=1000 WIN=512
-gen_ip IF=eth1 192.168.1.2 192.168.0.205 0 6 21 1024 SYN/ACK SEQ=2000 ACK=1001 WIN=512
-gen_ip IF=eth0 192.168.0.5 192.168.1.2 0 6 1024 21 ACK SEQ=1001 ACK=2001 WIN=512
+tcpsession OPEN 192.168.0.5 192.168.1.2 1024 21 192.168.1.2 192.168.0.205 21 1024
 
 # Need \n before PORT command.
-gen_ip IF=eth0 192.168.0.5 192.168.1.2 10 6 1024 21 ACK SEQ=1001 ACK=2001 DATA Hi Marc!\r\n
+tcpsession DATA original Hi Marc!\r\n
 
-expect gen_ip send:eth1 {IPv4 192.168.0.205 192.168.1.2 26 6 1024 21 ACK SEQ=1011 ACK=2001 DATA PORT 192,168,0,205,7,236\r\n}
-gen_ip IF=eth0 192.168.0.5 192.168.1.2 24 6 1024 21 ACK SEQ=1011 ACK=2001 DATA PORT 192,168,0,5,7,236\r\n
+tcpsession LENCHANGE 2
+expect gen_ip send:eth1*DATA PORT 192,168,0,205,7,236\r\n}
+tcpsession DATA original PORT 192,168,0,5,7,236\r\n
 
 # Now send next packet, and see that it gets through.
 expect gen_ip send:eth1 {IPv4 192.168.0.205 192.168.1.2 6 6 1024 21 ACK SEQ=1037 ACK=2001 DATA Test!\n}

Modified: trunk/nfsim-testsuite/03NAT/65-ftp-ack-adjust.sim
===================================================================
--- trunk/nfsim-testsuite/03NAT/65-ftp-ack-adjust.sim	2004-12-23 02:16:32 UTC (rev 3496)
+++ trunk/nfsim-testsuite/03NAT/65-ftp-ack-adjust.sim	2004-12-23 02:19:48 UTC (rev 3497)
@@ -6,12 +6,9 @@
 iptables -A FORWARD -m state ! --state NEW,ESTABLISHED,RELATED -j DROP
 
 # Generate initial packets: handshake, then FTP PORT command.
-gen_ip IF=eth0 192.168.0.10 192.168.1.2 0 6 1024 21 SYN SEQ=1000 WIN=512
-gen_ip IF=eth1 192.168.1.2 192.168.0.1 0 6 21 1024 SYN/ACK SEQ=2000 ACK=1001 WIN=512
-gen_ip IF=eth0 192.168.0.10 192.168.1.2 0 6 1024 21 ACK SEQ=1001 ACK=2001 WIN=512
-
+tcpsession OPEN 192.168.0.10 192.168.1.2 1024 21 192.168.1.2 192.168.0.1 21 1024
 # Need \n before PORT command.
-gen_ip IF=eth0 192.168.0.10 192.168.1.2 10 6 1024 21 ACK SEQ=1001 ACK=2001 DATA Hi Marc!\r\n
+tcpsession DATA original Hi Marc!\r\n
 
 # Generate a whole heap of them: failure only occurs when offset >
 # packetsize of reply.  Ack to expand window, Then Reset each data




More information about the netfilter-cvslog mailing list