aboutsummaryrefslogtreecommitdiff
path: root/sbin/ipfw
diff options
context:
space:
mode:
authorAlexander Langer <alex@FreeBSD.org>1998-01-07 02:23:04 +0000
committerAlexander Langer <alex@FreeBSD.org>1998-01-07 02:23:04 +0000
commit19b7e28d5858bbd4566ff634839f65a37f2fce01 (patch)
tree5d019a123dc2aa989af4ef7687955d70206d7302 /sbin/ipfw
parent62c1db1d1bd41adfc987eaf3516579c9b075b480 (diff)
downloadsrc-19b7e28d5858bbd4566ff634839f65a37f2fce01.tar.gz
src-19b7e28d5858bbd4566ff634839f65a37f2fce01.zip
Support listing/showing specific rules supplied on the command line.
Use error codes from <sysexits.h>.
Notes
Notes: svn path=/head/; revision=32303
Diffstat (limited to 'sbin/ipfw')
-rw-r--r--sbin/ipfw/ipfw.82
-rw-r--r--sbin/ipfw/ipfw.c101
2 files changed, 74 insertions, 29 deletions
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index c4535c586e52..b3eec6c9a088 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -26,11 +26,13 @@ delete
.Nm ipfw
.Op Fl aftN
list
+.Op Ar number ...
.Nm ipfw
.Oo
.Fl ftN
.Oc
show
+.Op Ar number ...
.Nm ipfw
.Oo
.Fl q
diff --git a/sbin/ipfw/ipfw.c b/sbin/ipfw/ipfw.c
index 1af1c73a41d7..faa6b8d6904d 100644
--- a/sbin/ipfw/ipfw.c
+++ b/sbin/ipfw/ipfw.c
@@ -16,7 +16,7 @@
*
* NEW command line interface for IP firewall facility
*
- * $Id: ipfw.c,v 1.49 1997/12/26 03:24:26 alex Exp $
+ * $Id: ipfw.c,v 1.50 1998/01/06 00:11:57 alex Exp $
*
*/
@@ -36,6 +36,7 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
+#include <sysexits.h>
#include <net/if.h>
#include <netinet/in.h>
@@ -81,6 +82,8 @@ static struct icmpcode icmpcodes[] = {
{ 0, NULL }
};
+static void show_usage(const char *fmt, ...);
+
static int
mask_bits(struct in_addr m_ad)
{
@@ -222,7 +225,7 @@ show_ipfw(struct ip_fw *chain)
}
break;
default:
- errx(1, "impossible");
+ errx(EX_OSERR, "impossible");
}
if (chain->fw_flg & IP_FW_F_PRN)
@@ -404,14 +407,54 @@ list(ac, av)
struct ip_fw *r;
struct ip_fw rules[1024];
int l,i;
+ unsigned long rulenum;
+ int bytes;
+ /* extract rules from kernel */
memset(rules,0,sizeof rules);
- l = sizeof rules;
- i = getsockopt(s, IPPROTO_IP, IP_FW_GET, rules, &l);
+ bytes = sizeof rules;
+ i = getsockopt(s, IPPROTO_IP, IP_FW_GET, rules, &bytes);
if (i < 0)
err(2,"getsockopt(IP_FW_GET)");
- for (r=rules; l >= sizeof rules[0]; r++, l-=sizeof rules[0])
- show_ipfw(r);
+ if (!ac) {
+ /* display all rules */
+ for (r = rules, l = bytes; l >= sizeof rules[0];
+ r++, l-=sizeof rules[0])
+ show_ipfw(r);
+ }
+ else {
+ /* display specific rules requested on command line */
+ int exitval = EX_OK;
+
+ while (ac--) {
+ char *endptr;
+ int seen;
+
+ /* convert command line rule # */
+ rulenum = strtoul(*av++, &endptr, 10);
+ if (*endptr) {
+ exitval = EX_USAGE;
+ warn("invalid rule number: %s", av - 1);
+ continue;
+ }
+ seen = 0;
+ for (r = rules, l = bytes;
+ l >= sizeof rules[0] && r->fw_number <= rulenum;
+ r++, l-=sizeof rules[0])
+ if (rulenum == r->fw_number) {
+ show_ipfw(r);
+ seen = 1;
+ }
+ if (!seen) {
+ /* give precedence to other error(s) */
+ if (exitval == EX_OK)
+ exitval = EX_UNAVAILABLE;
+ warnx("rule %lu does not exist", rulenum);
+ }
+ }
+ if (exitval != EX_OK)
+ exit(exitval);
+ }
}
static void
@@ -430,8 +473,8 @@ show_usage(const char *fmt, ...)
" flush\n"
" add [number] rule\n"
" delete number ...\n"
-" list [number]\n"
-" show [number]\n"
+" list [number ...]\n"
+" show [number ...]\n"
" zero [number ...]\n"
" rule: action proto src dst extras...\n"
" action:\n"
@@ -450,7 +493,7 @@ show_usage(const char *fmt, ...)
" ipoptions [!]{ssrr|lsrr|rr|ts},...\n"
" icmptypes {type[,type]}...\n");
- exit(1);
+ exit(EX_USAGE);
}
static int
@@ -543,7 +586,7 @@ add_port(cnt, ptr, off, port)
u_short *cnt, *ptr, off, port;
{
if (off + *cnt >= IP_FW_MAX_PORTS)
- errx(1, "too many ports (max is %d)", IP_FW_MAX_PORTS);
+ errx(EX_USAGE, "too many ports (max is %d)", IP_FW_MAX_PORTS);
ptr[off+*cnt] = port;
(*cnt)++;
}
@@ -564,14 +607,14 @@ lookup_port(const char *arg, int test, int nodash)
val = htons(s->s_port);
} else {
if (!test) {
- errx(1, "unknown port ``%s''", arg);
+ errx(EX_DATAERR, "unknown port ``%s''", arg);
}
val = -1;
}
} else {
if (val < 0 || val > 0xffff) {
if (!test) {
- errx(1, "port ``%s'' out of range", arg);
+ errx(EX_DATAERR, "port ``%s'' out of range", arg);
}
val = -1;
}
@@ -591,7 +634,7 @@ fill_port(cnt, ptr, off, arg)
if (*s == '-') {
*s++ = '\0';
if (strchr(arg, ','))
- errx(1, "port range must be first in list");
+ errx(EX_USAGE, "port range must be first in list");
add_port(cnt, ptr, off, *arg ? lookup_port(arg, 0, 0) : 0x0000);
arg = s;
s = strchr(arg,',');
@@ -713,8 +756,8 @@ delete(ac,av)
{
struct ip_fw rule;
int i;
- int failed = 0;
-
+ int exitval = EX_OK;
+
memset(&rule, 0, sizeof rule);
av++; ac--;
@@ -724,12 +767,12 @@ delete(ac,av)
rule.fw_number = atoi(*av); av++; ac--;
i = setsockopt(s, IPPROTO_IP, IP_FW_DEL, &rule, sizeof rule);
if (i) {
- failed = 1;
+ exitval = EX_UNAVAILABLE;
warn("rule %u: setsockopt(%s)", rule.fw_number, "IP_FW_DEL");
}
}
- if (failed)
- exit(1);
+ if (exitval != EX_OK)
+ exit(exitval);
}
static void
@@ -1051,7 +1094,7 @@ badviacombo:
show_ipfw(&rule);
i = setsockopt(s, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule);
if (i)
- err(1, "setsockopt(%s)", "IP_FW_ADD");
+ err(EX_UNAVAILABLE, "setsockopt(%s)", "IP_FW_ADD");
}
static void
@@ -1064,12 +1107,12 @@ zero (ac, av)
if (!ac) {
/* clear all entries */
if (setsockopt(s,IPPROTO_IP,IP_FW_ZERO,NULL,0)<0)
- err(1, "setsockopt(%s)", "IP_FW_ZERO");
+ err(EX_UNAVAILABLE, "setsockopt(%s)", "IP_FW_ZERO");
if (!do_quiet)
printf("Accounting cleared.\n");
} else {
struct ip_fw rule;
- int failed = 0;
+ int failed = EX_OK;
memset(&rule, 0, sizeof rule);
while (ac) {
@@ -1080,7 +1123,7 @@ zero (ac, av)
IP_FW_ZERO, &rule, sizeof rule)) {
warn("rule %u: setsockopt(%s)", rule.fw_number,
"IP_FW_ZERO");
- failed = 1;
+ failed = EX_UNAVAILABLE;
}
else
printf("Entry %d cleared\n",
@@ -1088,8 +1131,8 @@ zero (ac, av)
} else
show_usage("invalid rule number ``%s''", *av);
}
- if (failed)
- exit(1);
+ if (failed != EX_OK)
+ exit(failed);
}
}
@@ -1162,7 +1205,7 @@ ipfw_main(ac,av)
}
if ( do_flush ) {
if (setsockopt(s,IPPROTO_IP,IP_FW_FLUSH,NULL,0) < 0)
- err(1, "setsockopt(%s)", "IP_FW_FLUSH");
+ err(EX_UNAVAILABLE, "setsockopt(%s)", "IP_FW_FLUSH");
if (!do_quiet)
printf("Flushed all rules.\n");
}
@@ -1196,14 +1239,14 @@ main(ac, av)
s = socket( AF_INET, SOCK_RAW, IPPROTO_RAW );
if ( s < 0 )
- err(1, "socket");
+ err(EX_UNAVAILABLE, "socket");
setbuf(stdout,0);
if (av[1] && !access(av[1], R_OK)) {
lineno = 0;
if ((f = fopen(av[1], "r")) == NULL)
- err(1, "fopen: %s", av[1]);
+ err(EX_UNAVAILABLE, "fopen: %s", av[1]);
while (fgets(buf, BUFSIZ, f)) {
lineno++;
@@ -1218,7 +1261,7 @@ main(ac, av)
if (i == 1)
continue;
if (i == MAX_ARGS)
- errx(1, "%s: too many arguments", linename);
+ errx(EX_USAGE, "%s: too many arguments", linename);
args[i] = NULL;
ipfw_main(i, args);
@@ -1226,5 +1269,5 @@ main(ac, av)
fclose(f);
} else
ipfw_main(ac,av);
- return 0;
+ return EX_OK;
}