summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorpst <pst@FreeBSD.org>1996-08-13 19:43:24 +0000
committerpst <pst@FreeBSD.org>1996-08-13 19:43:24 +0000
commitec444da95fd9d19755af5b5e1f976423bc345a7b (patch)
treefa3539b0a536bd8bd8a0ef2b70c786dbda610e0b /sbin
parent8542445a70b5accf790f1ebb2d915ac459ceadb6 (diff)
downloadFreeBSD-src-ec444da95fd9d19755af5b5e1f976423bc345a7b.zip
FreeBSD-src-ec444da95fd9d19755af5b5e1f976423bc345a7b.tar.gz
Completely rewrite handling of protocol field for firewalls, things are
now completely consistent across all IP protocols and should be quite a bit faster. Use getprotoname() extensively, performed minor cleanups of admin utility. The admin utility could use a good kick in the pants. Basicly, these were the minimal changes I could make to the code to get it up to tollerable shape. There will be some future commits to clean up the basic architecture of the firewall code, and if I'm feeling ambitious, I may pull in changes like NAT from Linux and make the firewall hooks comletely generic so that a user can either load the ipfw module or the ipfilter module (cf Darren Reed). Discussed with: fenner & alex
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ipfw/ipfw.842
-rw-r--r--sbin/ipfw/ipfw.c160
2 files changed, 72 insertions, 130 deletions
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index d2bad95..c1f63a2 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -5,7 +5,7 @@
.Nm ipfw
.Nd controlling utility for IP firewall
.Sh SYNOPSIS
-.Nm ipfw
+.Nm
.Ar file
.Nm ipfw
flush
@@ -47,10 +47,12 @@ via
If used as shown in the first synopsis line, the
.Ar file
will be read line by line and applied as arguments to the
-.Nm ipfw
+.Nm
command.
.Pp
-The ipfw code works by going through the rule-list for each packet,
+The
+.Nm
+code works by going through the rule-list for each packet,
until a match is found.
All rules have two associated counters, a packet count and
a byte count.
@@ -142,6 +144,10 @@ Only TCP packets match.
Only UDP packets match.
.It Nm icmp
Only ICMP packets match.
+.It Nm <number|name>
+Only packets for the specified protocol matches (see
+.Pa /etc/protocols
+for a complete list).
.El
.Pp
.Ar src
@@ -249,14 +255,6 @@ Matches if the ICMP type is in the list
.Ar types .
The list may be specified as any combination of ranges
or individual types separated by commas.
-.It proto Ar ipproto
-Matches if the protocol field in the IP header matches
-any of the protocol numbers specified by the list
-.Ar ipproto
-(see
-.Pa /etc/protocols
-for a complete list).
-Protocol ranges may not be used.
.El
.Sh CHECKLIST
Here are some important points to consider when designing your
@@ -324,8 +322,6 @@ This rule diverts all incoming packets from 192.168.2.0/24 to divert port 5000:
.Pp
.Dl ipfw divert 5000 all from 192.168.2.0/24 to any in
.Sh SEE ALSO
-.Xr gethostbyname 3 ,
-.Xr getservbyport 3 ,
.Xr divert 4 ,
.Xr ip 4 ,
.Xr ipfirewall 4 ,
@@ -345,16 +341,12 @@ do anything you don't understand.
.Pp
When manipulating/adding chain entries, service and protocol names are
not accepted.
+.Sh AUTHORS
+Ugen J. S. Antsilevich,
+Poul-Henning Kamp,
+Alex Nash,
+Archie Cobbs.
+API based upon code written by Daniel Boulet for BSDI.
.Sh HISTORY
-Initially this utility was written for BSDI by:
-.Pp
-.Dl Daniel Boulet <danny@BouletFermat.ab.ca>
-.Pp
-The FreeBSD version is written completely by:
-.Pp
-.Dl Ugen J.S.Antsilevich <ugen@FreeBSD.ORG>
-.Pp
-This has all been extensively rearranged by Poul-Henning Kamp and
-Alex Nash.
-.Pp
-Packet diversion added by Archie Cobbs <archie@whistle.com>.
+.Nm
+first appeared in FreeBSD 2.0.
diff --git a/sbin/ipfw/ipfw.c b/sbin/ipfw/ipfw.c
index fdc5ed0..b466bab 100644
--- a/sbin/ipfw/ipfw.c
+++ b/sbin/ipfw/ipfw.c
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 1996 Alex Nash
- * Copyright (c) 1996 Poul-Henning Kamp
+ * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp
* Copyright (c) 1994 Ugen J.S.Antsilevich
+ *
* Idea and grammar partially left from:
* Copyright (c) 1993 Daniel Boulet
*
@@ -16,7 +16,7 @@
*
* NEW command line interface for IP firewall facility
*
- * $Id: ipfw.c,v 1.30 1996/08/05 02:38:51 alex Exp $
+ * $Id: ipfw.c,v 1.31 1996/08/13 00:41:05 pst Exp $
*
*/
@@ -66,43 +66,27 @@ mask_bits(m_ad)
}
void
-print_port(port, comma, flg)
- u_short port,flg;
+print_port(prot, port, comma)
+ u_char prot;
+ u_short port;
const char *comma;
{
+ struct servent *se;
+ struct protoent *pe;
+ const char *protocol;
int printed = 0;
if (do_resolv) {
- struct servent *se;
- struct protoent *pe;
- const char *protocol;
-
- switch (flg & IP_FW_F_KIND) {
- case IP_FW_F_TCP:
- protocol = "tcp";
- break;
- case IP_FW_F_UDP:
- protocol = "udp";
- break;
- default:
- protocol = NULL;
- break;
- }
-
- if (protocol) {
- se = getservbyport(htons(port), protocol);
-
- if (se) {
- printf("%s%s", comma, se->s_name);
- printed = 1;
- }
- } else {
- pe = getprotobynumber(port);
+ pe = getprotobynumber(prot);
+ if (pe)
+ protocol = pe->p_name;
+ else
+ protocol = NULL;
- if (pe) {
- printf("%s%s", comma, pe->p_name);
- printed = 1;
- }
+ se = getservbyport(htons(port), protocol);
+ if (se) {
+ printf("%s%s", comma, se->s_name);
+ printed = 1;
}
}
if (!printed)
@@ -116,7 +100,8 @@ show_ipfw(chain)
char *comma;
u_long adrt;
struct hostent *he;
- int i,mb;
+ struct protoent *pe;
+ int i, mb;
if (do_resolv)
setservent(1/*stayopen*/);
@@ -164,24 +149,13 @@ show_ipfw(chain)
if (chain->fw_flg & IP_FW_F_PRN)
printf(" log");
- switch (chain->fw_flg & IP_FW_F_KIND) {
- case IP_FW_F_ICMP:
- printf(" icmp ");
- break;
- case IP_FW_F_TCP:
- printf(" tcp ");
- break;
- case IP_FW_F_UDP:
- printf(" udp ");
- break;
- case IP_FW_F_ALL:
- printf(" ip ");
- break;
- default:
- break;
- }
+ pe = getprotobynumber(chain->fw_prot);
+ if (pe)
+ printf(" %s", pe->p_name);
+ else
+ printf("%u", chain->fw_prot);
- printf("from ");
+ printf(" from ");
adrt=ntohl(chain->fw_smsk.s_addr);
if (adrt==ULONG_MAX && do_resolv) {
@@ -210,10 +184,10 @@ show_ipfw(chain)
printf(inet_ntoa(chain->fw_src));
}
- if ((chain->fw_flg & IP_FW_F_KIND) != IP_FW_F_ALL) {
+ if (chain->fw_prot != IPPROTO_IP) {
comma = " ";
for (i=0;i<chain->fw_nsp; i++ ) {
- print_port(chain->fw_pts[i], comma, chain->fw_flg);
+ print_port(chain->fw_prot, chain->fw_pts[i], comma);
if (i==0 && (chain->fw_flg & IP_FW_F_SRNG))
comma = "-";
else
@@ -252,25 +226,14 @@ show_ipfw(chain)
comma = " ";
for (i=0;i<chain->fw_ndp;i++) {
- print_port(chain->fw_pts[chain->fw_nsp+i], comma, chain->fw_flg);
+ print_port(chain->fw_prot, chain->fw_pts[chain->fw_nsp+i],
+ comma);
if (i==0 && (chain->fw_flg & IP_FW_F_DRNG))
comma = "-";
else
comma = ",";
}
- if ((chain->fw_flg & IP_FW_F_KIND) == IP_FW_F_ALL && chain->fw_nsp) {
- printf(" proto");
- comma = " ";
- for (i=0;i<chain->fw_nsp; i++) {
- print_port(chain->fw_pts[i], comma, chain->fw_flg);
- if (i==0 && (chain->fw_flg & IP_FW_F_SRNG))
- comma = "-";
- else
- comma = ",";
- }
- }
-
if ((chain->fw_flg & IP_FW_F_IN) && (chain->fw_flg & IP_FW_F_OUT))
;
else if (chain->fw_flg & IP_FW_F_IN)
@@ -387,7 +350,7 @@ show_usage(str)
"\t\tzero [number]\n"
"\trule:\taction proto src dst extras...\n"
"\t\taction: {allow|deny|reject|count|divert port} [log]\n"
-"\t\tproto: {ip|tcp|udp|icmp}}\n"
+"\t\tproto: {ip|tcp|udp|icmp|<number>}}\n"
"\t\tsrc: from {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
"\t\tdst: to {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
"\textras:\n"
@@ -470,22 +433,17 @@ fill_ip(ipno, mask, acp, avp)
}
void
-add_port(cnt, ptr, off, port, proto)
+add_port(cnt, ptr, off, port)
u_short *cnt, *ptr, off, port;
- int proto;
{
- if (proto && port > 255)
- errx(1, "proto must be in the range 0-255");
if (off + *cnt >= IP_FW_MAX_PORTS)
- errx(1, "too many %s (max is %d)",
- proto ? "protocols" : "ports",
- IP_FW_MAX_PORTS);
+ errx(1, "too many ports (max is %d)", IP_FW_MAX_PORTS);
ptr[off+*cnt] = port;
(*cnt)++;
}
int
-fill_port(cnt, ptr, off, arg, proto)
+fill_port(cnt, ptr, off, arg)
u_short *cnt, *ptr, off;
char *arg;
{
@@ -494,17 +452,15 @@ fill_port(cnt, ptr, off, arg, proto)
s = strchr(arg,'-');
if (s) {
- if (proto)
- errx(1,"proto ranges are not allowed");
*s++ = '\0';
if (strchr(arg, ','))
errx(1, "port range must be first in list");
- add_port(cnt, ptr, off, *arg ? atoi(arg) : 0x0000, proto);
+ add_port(cnt, ptr, off, *arg ? atoi(arg) : 0x0000);
arg = s;
s = strchr(arg,',');
if (s)
*s++ = '\0';
- add_port(cnt, ptr, off, *arg ? atoi(arg) : 0xffff, proto);
+ add_port(cnt, ptr, off, *arg ? atoi(arg) : 0xffff);
arg = s;
initial_range = 1;
}
@@ -512,7 +468,7 @@ fill_port(cnt, ptr, off, arg, proto)
s = strchr(arg,',');
if (s)
*s++ = '\0';
- add_port(cnt, ptr, off, atoi(arg), proto);
+ add_port(cnt, ptr, off, atoi(arg));
arg = s;
}
return initial_range;
@@ -644,6 +600,8 @@ add(ac,av)
{
struct ip_fw rule;
int i;
+ u_char proto;
+ struct protoent *pe;
memset(&rule, 0, sizeof rule);
@@ -683,19 +641,18 @@ add(ac,av)
}
/* protocol */
- if (ac && !strncmp(*av,"ip",strlen(*av))) {
- rule.fw_flg |= IP_FW_F_ALL; av++; ac--;
- } else if (ac && !strncmp(*av,"all",strlen(*av))) {
- rule.fw_flg |= IP_FW_F_ALL; av++; ac--;
- } else if (ac && !strncmp(*av,"tcp",strlen(*av))) {
- rule.fw_flg |= IP_FW_F_TCP; av++; ac--;
- } else if (ac && !strncmp(*av,"udp",strlen(*av))) {
- rule.fw_flg |= IP_FW_F_UDP; av++; ac--;
- } else if (ac && !strncmp(*av,"icmp",strlen(*av))) {
- rule.fw_flg |= IP_FW_F_ICMP; av++; ac--;
- } else {
+ if (ac) {
+ if ((proto = atoi(*av)) > 0) {
+ rule.fw_prot = proto; av++; ac--;
+ } else if (!strncmp(*av,"all",strlen(*av))) {
+ rule.fw_prot = IPPROTO_IP; av++; ac--;
+ } else if ((pe = getprotobyname(*av)) != NULL) {
+ rule.fw_prot = pe->p_proto; av++; ac--;
+ } else {
+ show_usage("invalid protocol\n");
+ }
+ } else
show_usage("missing protocol\n");
- }
/* from */
if (ac && !strncmp(*av,"from",strlen(*av))) { av++; ac--; }
@@ -723,9 +680,9 @@ add(ac,av)
av++; ac--;
}
- if ((rule.fw_flg & IP_FW_F_KIND) != IP_FW_F_TCP &&
- (rule.fw_flg & IP_FW_F_KIND) != IP_FW_F_UDP &&
- (rule.fw_nsp || rule.fw_ndp)) {
+ if ((rule.fw_prot != IPPROTO_TCP) &&
+ (rule.fw_prot != IPPROTO_UDP) &&
+ (rule.fw_nsp || rule.fw_ndp)) {
show_usage("only TCP and UDP protocols are valid with port specifications");
}
@@ -768,7 +725,7 @@ add(ac,av)
fill_ipopt(&rule.fw_ipopt, &rule.fw_ipnopt, av);
av++; ac--; continue;
}
- if ((rule.fw_flg & IP_FW_F_KIND) == IP_FW_F_TCP) {
+ if (rule.fw_prot == IPPROTO_TCP) {
if (!strncmp(*av,"established",strlen(*av))) {
rule.fw_tcpf |= IP_FW_TCPF_ESTAB;
av++; ac--; continue;
@@ -784,20 +741,13 @@ add(ac,av)
av++; ac--; continue;
}
}
- if ((rule.fw_flg & IP_FW_F_KIND) == IP_FW_F_ICMP) {
+ if (rule.fw_prot == IPPROTO_ICMP) {
if (ac > 1 && !strncmp(*av,"icmptypes",strlen(*av))) {
av++; ac--;
fill_icmptypes(rule.fw_icmptypes, av, &rule.fw_flg);
av++; ac--; continue;
}
}
- if ((rule.fw_flg & IP_FW_F_KIND) == IP_FW_F_ALL) {
- if (ac > 1 && !strncmp(*av,"proto",strlen(*av))) {
- av++; ac--;
- fill_port(&rule.fw_nsp, &rule.fw_pts, 0, *av, 1);
- av++; ac--; continue;
- }
- }
printf("%d %s\n",ac,*av);
show_usage("Unknown argument\n");
}
OpenPOWER on IntegriCloud