Date: Tue, 21 Aug 2001 17:00:12 -0700 (PDT) From: Luigi Rizzo <rizzo@aciri.org> To: alex@big.endian.de (Alexander Langer) Cc: freebsd-ipfw@FreeBSD.ORG Subject: Re: "ipfw move oldrulenum newrulenum" revised Message-ID: <200108220000.f7M00Cn37370@iguana.aciri.org> In-Reply-To: <20010822014708.A11739@zerogravity.kawo2.rwth-aachen.d> from Alexander Langer at "Aug 22, 2001 1:47: 8 am"
next in thread | previous 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 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200108220000.f7M00Cn37370>