From owner-freebsd-bugs@FreeBSD.ORG Wed May 27 05:40:01 2009 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7E8761065672 for ; Wed, 27 May 2009 05:40:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 56F4E8FC1E for ; Wed, 27 May 2009 05:40:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id n4R5e1B8027378 for ; Wed, 27 May 2009 05:40:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.3/8.14.3/Submit) id n4R5e1rg027377; Wed, 27 May 2009 05:40:01 GMT (envelope-from gnats) Resent-Date: Wed, 27 May 2009 05:40:01 GMT Resent-Message-Id: <200905270540.n4R5e1rg027377@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Cyberman Wu Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 59F751065672 for ; Wed, 27 May 2009 05:32:52 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 488EE8FC12 for ; Wed, 27 May 2009 05:32:52 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.3/8.14.3) with ESMTP id n4R5WqQW085241 for ; Wed, 27 May 2009 05:32:52 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.3/8.14.3/Submit) id n4R5Wqsb085240; Wed, 27 May 2009 05:32:52 GMT (envelope-from nobody) Message-Id: <200905270532.n4R5Wqsb085240@www.freebsd.org> Date: Wed, 27 May 2009 05:32:52 GMT From: Cyberman Wu To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: bin/134975: ipfw can't work with set in rule file. X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 May 2009 05:40:01 -0000 >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: