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>
