Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Aug 2001 01:47:08 +0200
From:      Alexander Langer <alex@big.endian.de>
To:        freebsd-ipfw@FreeBSD.org
Subject:   "ipfw move oldrulenum newrulenum" revised
Message-ID:  <20010822014708.A11739@zerogravity.kawo2.rwth-aachen.d>

Next in thread | Raw E-Mail | Index | Archive | Help
Hi!

18 months ago I already wrote "ipfw move", but I didn't like that version.

I now revised it.
It adds "ipfw move oldrule newrule" stuff, done completely in userland
(this also means, transfer stats are discarded, though I don't know
why the kernel's add-function does this:  the values are even
given back to the setsockopt call.).
I also haven't yet added dummynet support, and the manpage update
is still outstanding.

Comments?

Alex

cvs diff: Diffing .
Index: ipfw.c
===================================================================
RCS file: /storage/ncvs/src/sbin/ipfw/ipfw.c,v
retrieving revision 1.108
diff -u -r1.108 ipfw.c
--- ipfw.c	6 Aug 2001 13:03:38 -0000	1.108
+++ ipfw.c	21 Aug 2001 23:42:25 -0000
@@ -62,7 +62,7 @@
 		do_resolv,		/* Would try to resolve all */
 		do_acct,		/* Show packet/byte count  */
 		do_time,		/* Show time stamps	   */
-		do_quiet,		/* Be quiet in add and flush  */
+		do_quiet,		/* Be quiet in add, flush and move */
 		do_force,		/* Don't ask for confirmation */
 		do_pipe,		/* this cmd refers to a pipe */
 		do_sort,		/* field to sort results (0 = no) */
@@ -878,6 +878,7 @@
 "    [pipe] delete number ...\n"
 "    [pipe] list [number ...]\n"
 "    [pipe] show [number ...]\n"
+"    [pipe] move number number\n"
 "    zero [number ...]\n"
 "    resetlog [number ...]\n"
 "    pipe number config [pipeconfig]\n"
@@ -1324,6 +1325,93 @@
 }
 
 static void
+move(int ac, char *av[])
+{
+	struct ip_fw *rules, *r;
+	struct dn_pipe *pipes;
+	void *data = NULL;
+	int n, nbytes, nstat;
+	int exitval = EX_OK;
+	char *endptr;
+	int seen = 0;
+
+	/* move stuff */
+	long old_rulenum, new_rulenum;
+	char **old_av;
+
+	old_av = av;
+	av++; ac--;
+
+	if (ac != 2)
+		errx(EX_USAGE,
+		    "wrong number for arguments for move: %d (expected 2)",
+		    ac);
+
+	/* convert command line rule numbers */
+	old_rulenum = strtol(*av, &endptr, 10);
+	if (old_rulenum == LONG_MIN || old_rulenum == LONG_MAX ||
+	    *endptr != NULL)
+		errx(EX_DATAERR, "invalid rule number: %s", *av);
+	av++; ac--;
+
+	new_rulenum = strtol(*av, &endptr, 10);
+	if (new_rulenum == LONG_MIN || old_rulenum == LONG_MAX ||
+	    *endptr != NULL)
+		errx(EX_DATAERR, "invalid number: %s", *av);
+	av++; ac--;
+
+	/* get rules or pipes from kernel, resizing array as necessary */
+	{
+		const int unit = do_pipe ? sizeof(*pipes) : sizeof(*rules);
+		const int ocmd = do_pipe ? IP_DUMMYNET_GET : IP_FW_GET;
+		int nalloc = unit;
+		nbytes = nalloc;
+
+		while (nbytes >= nalloc) {
+			nalloc = nalloc * 2 + 200;
+			nbytes = nalloc;
+			if ((data = realloc(data, nbytes)) == NULL)
+				err(EX_OSERR, "realloc");
+			if (getsockopt(s, IPPROTO_IP, ocmd, data, &nbytes) < 0)
+				err(EX_OSERR, "getsockopt(IP_%s_GET)",
+				    do_pipe ? "DUMMYNET" : "FW");
+		}
+	}
+
+	rules = (struct ip_fw *)data;
+	for (nstat = 0; rules[nstat].fw_number < 65535; ++nstat)
+		/* nothing */ ;
+	nstat++; /* counting starts from 0 ... */
+
+	/* now, find all rules with the old number, add them
+           with the new number and delete the old rule */
+	for (n = seen = 0, r = rules; n < nstat; n++, r++)
+		if (r->fw_number == old_rulenum) {
+			seen = 1;
+
+			r->fw_number = new_rulenum;
+
+			nbytes = sizeof(struct ip_fw);
+			if (getsockopt(s, IPPROTO_IP, IP_FW_ADD,
+			    r, &nbytes) == -1)
+				err(EX_UNAVAILABLE,
+				    "getsockopt(%s)", "IP_FW_ADD");
+			if (!do_quiet)
+				show_ipfw(r);
+		}
+	if (!seen)
+		errx(EX_UNAVAILABLE, "rule %ld does not exist",
+		    old_rulenum);
+
+	/* Now, delete old rule */
+	delete(2, old_av);
+
+	free(data);
+	
+	exit(exitval);
+}
+
+static void
 verify_interface(union ip_fw_if *ifu)
 {
 	struct ifreq ifr;
@@ -2392,6 +2480,8 @@
 				printf("Flushed all %s.\n",
 				    do_pipe ? "pipes" : "rules");
 		}
+	} else if (!strncmp(*av, "move", strlen(*av))) {
+		move(ac, av);
 	} else if (!strncmp(*av, "zero", strlen(*av))) {
 		zero(ac, av);
 	} else if (!strncmp(*av, "resetlog", strlen(*av))) {


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ipfw" in the body of the message




Want to link to this message? Use this URL: <http://docs.FreeBSD.org/cgi/mid.cgi?20010822014708.A11739>