Skip site navigation (1)Skip section navigation (2)
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>