summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorluigi <luigi@FreeBSD.org>2003-07-14 08:39:49 +0000
committerluigi <luigi@FreeBSD.org>2003-07-14 08:39:49 +0000
commitbe37c541ae6482e2829990c12ee3bc5c7dd71e1e (patch)
tree8f82fb1764ef684461825676720a22c2166ea3e0 /sbin
parent505db8074c5fc5f09d200b0b9a3394b927c562a6 (diff)
downloadFreeBSD-src-be37c541ae6482e2829990c12ee3bc5c7dd71e1e.zip
FreeBSD-src-be37c541ae6482e2829990c12ee3bc5c7dd71e1e.tar.gz
ccept of empty lines when reading from a file (this fixes a bug
introduced in the latest commits). Also: * update the 'ipfw -h' output; * allow rules of the form "100 add allow ..." i.e. with the index first. (requested by Paul Richards). This was an undocumented ipfw1 behaviour, and it is left undocumented. and minor code cleanups.
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ipfw/ipfw2.c77
1 files changed, 52 insertions, 25 deletions
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index 1c6f94e..17d98ba 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -59,7 +59,6 @@ int
do_resolv, /* Would try to resolve all */
do_time, /* Show time stamps */
do_quiet, /* Be quiet in add and flush */
- do_force, /* Don't ask for confirmation */
do_pipe, /* this cmd refers to a pipe */
do_sort, /* field to sort results (0 = no) */
do_dynamic, /* display dynamic rules */
@@ -1845,7 +1844,7 @@ help(void)
{
fprintf(stderr,
"ipfw syntax summary (but please do read the ipfw(8) manpage):\n"
-"ipfw [-acdeftnNpqS] command:"
+"ipfw [-acdeftTnNpqS] <command> where <command is one of:\n"
"add [num] [set N] [prob x] RULE-BODY\n"
"{pipe|queue} N config PIPE-BODY\n"
"[pipe|queue] {zero|delete|show} [N{,N}]\n"
@@ -1855,10 +1854,10 @@ help(void)
"ACTION: check-state | allow | count | deny | reject | skipto N |\n"
" {divert|tee} PORT | forward ADDR | pipe N | queue N\n"
"ADDR: [ MAC dst src ether_type ] \n"
-" [ from IPLIST [ PORT ] to IPLIST [ PORTLIST ] ]\n"
-"IPLIST: IPADDR[,IPADDR] | { IPADDR or ... or IPADDR }\n"
-"IPADDR: [not] { any | me | ip | ip/bits | ip:mask | ip/bits{x,y,z} }\n"
-"OPTION_LIST: OPTION [,OPTION_LIST]\n"
+" [ from IPADDR [ PORT ] to IPADDR [ PORTLIST ] ]\n"
+"IPADDR: [not] { any | me | ip/bits{x,y,z} | IPLIST }\n"
+"IPLIST: { ip | ip/bits | ip:mask }[,IPLIST]\n"
+"OPTION_LIST: OPTION [OPTION_LIST]\n"
"OPTION: bridged | {dst-ip|src-ip} ADDR | {dst-port|src-port} LIST |\n"
" estab | frag | {gid|uid} N | icmptypes LIST | in | out | ipid LIST |\n"
" iplen LIST | ipoptions SPEC | ipprecedence | ipsec | iptos SPEC |\n"
@@ -3542,11 +3541,11 @@ zero(int ac, char *av[], int optname /* IP_FW_ZERO or IP_FW_RESETLOG */)
}
static void
-flush(void)
+flush(int force)
{
int cmd = do_pipe ? IP_DUMMYNET_FLUSH : IP_FW_FLUSH;
- if (!do_force && !do_quiet) { /* need to ask user */
+ if (!force && !do_quiet) { /* need to ask user */
int c;
printf("Are you sure? [yn] ");
@@ -3569,7 +3568,21 @@ flush(void)
}
/*
- * called with the arguments (excluding program name).
+ * Free a the (locally allocated) copy of command line arguments.
+ */
+static void
+free_args(int ac, char **av)
+{
+ int i;
+
+ for (i=0; i < ac; i++)
+ free(av[i]);
+ free(av);
+}
+
+/*
+ * Called with the arguments (excluding program name).
+ * Returns 0 if successful, 1 if empty command, errx() in case of errors.
*/
static int
ipfw_main(int oldac, char **oldav)
@@ -3577,9 +3590,12 @@ ipfw_main(int oldac, char **oldav)
int ch, ac, save_ac;
char **av, **save_av;
int do_acct = 0; /* Show packet/byte count */
+ int do_force = 0; /* Don't ask for confirmation */
#define WHITESP " \t\f\v\n\r"
- if (oldac == 1) {
+ if (oldac == 0)
+ return 1;
+ else if (oldac == 1) {
/*
* If we are called with a single string, try to split it into
* arguments for subsequent parsing.
@@ -3607,7 +3623,7 @@ ipfw_main(int oldac, char **oldav)
l = j; /* the new argument length */
arg[j++] = '\0';
if (l == 0) /* empty string! */
- show_usage();
+ return 1;
/*
* First, count number of arguments. Because of the previous
@@ -3658,9 +3674,6 @@ ipfw_main(int oldac, char **oldav)
}
}
- if (ac == 0)
- show_usage();
-
/* Set the force flag for non-interactive processes */
do_force = !isatty(STDIN_FILENO);
@@ -3692,6 +3705,7 @@ ipfw_main(int oldac, char **oldav)
break;
case 'h': /* help */
+ free_args(save_ac, save_av);
help();
break; /* NOTREACHED */
@@ -3728,7 +3742,8 @@ ipfw_main(int oldac, char **oldav)
break;
default:
- show_usage();
+ free_args(save_ac, save_av);
+ return 1;
}
ac -= optind;
@@ -3736,14 +3751,25 @@ ipfw_main(int oldac, char **oldav)
NEED1("bad arguments, for usage summary ``ipfw''");
/*
+ * An undocumented behaviour of ipfw1 was to allow rule numbers first,
+ * e.g. "100 add allow ..." instead of "add 100 allow ...".
+ * In case, swap first and second argument to get the normal form.
+ */
+ if (ac > 1 && isdigit(*av[0])) {
+ char *p = av[0];
+
+ av[0] = av[1];
+ av[1] = p;
+ }
+
+ /*
* optional: pipe or queue
*/
- if (!strncmp(*av, "pipe", strlen(*av))) {
+ if (!strncmp(*av, "pipe", strlen(*av)))
do_pipe = 1;
- ac--;
- av++;
- } else if (!strncmp(*av, "queue", strlen(*av))) {
+ else if (!strncmp(*av, "queue", strlen(*av)))
do_pipe = 2;
+ if (do_pipe) {
ac--;
av++;
}
@@ -3756,6 +3782,7 @@ ipfw_main(int oldac, char **oldav)
*/
if (do_pipe > 0 && ac > 1 && isdigit(*av[0])) {
char *p = av[0];
+
av[0] = av[1];
av[1] = p;
}
@@ -3767,7 +3794,7 @@ ipfw_main(int oldac, char **oldav)
else if (!strncmp(*av, "delete", strlen(*av)))
delete(ac, av);
else if (!strncmp(*av, "flush", strlen(*av)))
- flush();
+ flush(do_force);
else if (!strncmp(*av, "zero", strlen(*av)))
zero(ac, av, IP_FW_ZERO);
else if (!strncmp(*av, "resetlog", strlen(*av)))
@@ -3787,9 +3814,7 @@ ipfw_main(int oldac, char **oldav)
errx(EX_USAGE, "bad command `%s'", *av);
/* Free memory allocated in the argument parsing. */
- for (ch=0; ch < save_ac; ch++)
- free(save_av[ch]);
- free(save_av);
+ free_args(save_ac, save_av);
return 0;
}
@@ -3931,7 +3956,9 @@ main(int ac, char *av[])
if (ac > 1 && av[ac - 1][0] == '/' && access(av[ac - 1], R_OK) == 0)
ipfw_readfile(ac, av);
- else
- ipfw_main(ac-1, av+1);
+ else {
+ if (ipfw_main(ac-1, av+1))
+ show_usage();
+ }
return EX_OK;
}
OpenPOWER on IntegriCloud