From owner-freebsd-ipfw Tue Aug 21 16:48: 6 2001 Delivered-To: freebsd-ipfw@freebsd.org Received: from kawoserv.kawo2.rwth-aachen.de (kawoserv.kawo2.RWTH-Aachen.DE [134.130.180.1]) by hub.freebsd.org (Postfix) with ESMTP id CD58B37B419 for ; Tue, 21 Aug 2001 16:47:09 -0700 (PDT) (envelope-from alex@big.endian.de) Received: from zerogravity.kawo2.rwth-aachen.de (zerogravity.kawo2.rwth-aachen.de [134.130.181.28]) by kawoserv.kawo2.rwth-aachen.de (8.9.3/8.9.3) with ESMTP id BAA27788 for ; Wed, 22 Aug 2001 01:47:09 +0200 Received: by zerogravity.kawo2.rwth-aachen.de (Postfix, from userid 1001) id B809B14A1B; Wed, 22 Aug 2001 01:47:08 +0200 (CEST) Date: Wed, 22 Aug 2001 01:47:08 +0200 From: Alexander Langer To: freebsd-ipfw@FreeBSD.org Subject: "ipfw move oldrulenum newrulenum" revised Message-ID: <20010822014708.A11739@zerogravity.kawo2.rwth-aachen.d> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i X-PGP-Fingerprint: 44 28 CA 4C 46 5B D3 A8 A8 E3 BA F3 4E 60 7D 7F X-PGP-at: finger alex@big.endian.de X-Verwirrung: Dieser Header dient der allgemeinen Verwirrung. Sender: owner-freebsd-ipfw@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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