Date: Wed, 27 May 2009 05:32:52 GMT From: Cyberman Wu <cyberman.wu@gmail.com> To: freebsd-gnats-submit@FreeBSD.org Subject: bin/134975: ipfw can't work with set in rule file. Message-ID: <200905270532.n4R5Wqsb085240@www.freebsd.org> Resent-Message-ID: <200905270540.n4R5e1rg027377@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 134975 >Category: bin >Synopsis: ipfw can't work with set in rule file. >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed May 27 05:40:00 UTC 2009 >Closed-Date: >Last-Modified: >Originator: Cyberman Wu >Release: FreeBSD 7.0r-p5 >Organization: Meganovo >Environment: FreeBSD test.freebsd.com 7.0-RELEASE-p5 FreeBSD 7.0-RELEASE-p5 #0: Wed Oct 1 10:10:12 UTC 2008 root@i386-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC i386 >Description: First to say, I've tested on both FreeBSD 7.1 and 7.2 and the problem is still here. The only change is the later versions use a structure to organize global variables. Since I'm more familiar with 7.0 I'll use its code to illustrate the problem. These days I'm thinking to port ipfw to another system, and when I read the source code I found here will cause a problem in ipfw_main from ipfw2.c: /* * Optional: pipe, queue or nat. */ do_nat = 0; do_pipe = 0; if (!strncmp(*av, "nat", strlen(*av))) do_nat = 1; else if (!strncmp(*av, "pipe", strlen(*av))) do_pipe = 1; else if (_substrcmp(*av, "queue") == 0) do_pipe = 2; else if (!strncmp(*av, "set", strlen(*av))) { if (ac > 1 && isdigit(av[1][0])) { use_set = strtonum(av[1], 0, RESVD_SET, &errstr); if (errstr) errx(EX_DATAERR, "invalid set number %s\n", av[1]); ac -= 2; av += 2; use_set++; } } If we specify rule file using 'pathname' on command line rather than a command, ipfw_main will be called in loop, but once 'use_set' is set, it will never be clear again, if the next rule is some command like 'add', since 'use_set' is not zero, it will either say 'bad command' or do some other things: int try_next = 0; if (use_set == 0) { if (_substrcmp(*av, "add") == 0) add(ac, av); else if (do_nat && _substrcmp(*av, "show") == 0) show_nat(ac, av); else if (do_pipe && _substrcmp(*av, "config") == 0) config_pipe(ac, av); else if (do_nat && _substrcmp(*av, "config") == 0) config_nat(ac, av); else if (_substrcmp(*av, "set") == 0) sets_handler(ac, av); else if (_substrcmp(*av, "table") == 0) table_handler(ac, av); else if (_substrcmp(*av, "enable") == 0) sysctl_handler(ac, av, 1); else if (_substrcmp(*av, "disable") == 0) sysctl_handler(ac, av, 0); else try_next = 1; } if (use_set || try_next) { if (_substrcmp(*av, "delete") == 0) delete(ac, av); else if (_substrcmp(*av, "flush") == 0) flush(do_force); else if (_substrcmp(*av, "zero") == 0) zero(ac, av, IP_FW_ZERO); else if (_substrcmp(*av, "resetlog") == 0) zero(ac, av, IP_FW_RESETLOG); else if (_substrcmp(*av, "print") == 0 || _substrcmp(*av, "list") == 0) list(ac, av, do_acct); else if (_substrcmp(*av, "show") == 0) list(ac, av, 1 /* show counters */); else errx(EX_USAGE, "bad command `%s'", *av); } Then I test it on FreeBSD 7.0/7.1/7.2, all the same. >How-To-Repeat: First create a file 'fw_test.rule' which including the following commands: -q set 12 flush add set 12 allow tcp from any to me 12345 in add set 12 allow tcp from me 12345 to any out Then use ipfw to execute it: test# ipfw /root/fw_test.rule Line 2: bad command `add' >Fix: /* * Optional: pipe, queue or nat. */ do_nat = 0; do_pipe = 0; /* * Added by Cyberman Wu on May 16th, 2009. */ use_set = 0; if (!strncmp(*av, "nat", strlen(*av))) do_nat = 1; else if (!strncmp(*av, "pipe", strlen(*av))) do_pipe = 1; else if (_substrcmp(*av, "queue") == 0) do_pipe = 2; else if (!strncmp(*av, "set", strlen(*av))) { if (ac > 1 && isdigit(av[1][0])) { use_set = strtonum(av[1], 0, RESVD_SET, &errstr); if (errstr) errx(EX_DATAERR, "invalid set number %s\n", av[1]); ac -= 2; av += 2; use_set++; } } >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905270532.n4R5Wqsb085240>