From owner-freebsd-ipfw Tue Aug 21 17: 3: 0 2001 Delivered-To: freebsd-ipfw@freebsd.org Received: from iguana.aciri.org (iguana.aciri.org [192.150.187.36]) by hub.freebsd.org (Postfix) with ESMTP id 5E4B137B409 for ; Tue, 21 Aug 2001 17:02:13 -0700 (PDT) (envelope-from rizzo@iguana.aciri.org) Received: (from rizzo@localhost) by iguana.aciri.org (8.11.3/8.11.1) id f7M00Cn37370; Tue, 21 Aug 2001 17:00:12 -0700 (PDT) (envelope-from rizzo) From: Luigi Rizzo Message-Id: <200108220000.f7M00Cn37370@iguana.aciri.org> Subject: Re: "ipfw move oldrulenum newrulenum" revised In-Reply-To: <20010822014708.A11739@zerogravity.kawo2.rwth-aachen.d> from Alexander Langer at "Aug 22, 2001 1:47: 8 am" To: alex@big.endian.de (Alexander Langer) Date: Tue, 21 Aug 2001 17:00:12 -0700 (PDT) Cc: freebsd-ipfw@FreeBSD.ORG X-Mailer: ELM [version 2.4ME+ PL43 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit 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 not only stats, also any dynamic rule associated with it. dummynet support is irrelevant as it makes no sense to just renumber pipes. But i believe that a "move" command is essentially useless, and the ipfw command already does a zillion things so i would really try and avoid adding more and more functions to it. cheers luigi > > 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 > To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-ipfw" in the body of the message