Filter by IP protocol.

Submitted by: fenner (with modifications by me)

Bring in the interface unit wildcard flag fix from rev 1.15.4.8.
This commit is contained in:
Alexander Langer 1996-08-05 02:38:51 +00:00
parent 71c011477f
commit 593f7481aa
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=17441
2 changed files with 72 additions and 28 deletions

View File

@ -1,4 +1,4 @@
.Dd February 24, 1996 .Dd July 20, 1996
.Dt IPFW 8 SMM .Dt IPFW 8 SMM
.Os FreeBSD .Os FreeBSD
.Sh NAME .Sh NAME
@ -249,6 +249,14 @@ Matches if the ICMP type is in the list
.Ar types . .Ar types .
The list may be specified as any combination of ranges The list may be specified as any combination of ranges
or individual types separated by commas. 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 .El
.Sh CHECKLIST .Sh CHECKLIST
Here are some important points to consider when designing your Here are some important points to consider when designing your
@ -262,10 +270,6 @@ Remember to test very carefully.
It is a good idea to be near the console when doing this. It is a good idea to be near the console when doing this.
.It .It
Don't forget the loopback interface. Don't forget the loopback interface.
.It
Don't filter
.Nm all
if you are also specifying a port.
.El .El
.Sh FINE POINTS .Sh FINE POINTS
There is one kind of packet that the firewall will always discard, There is one kind of packet that the firewall will always discard,
@ -322,10 +326,11 @@ This rule diverts all incoming packets from 192.168.2.0/24 to divert port 5000:
.Sh SEE ALSO .Sh SEE ALSO
.Xr gethostbyname 3 , .Xr gethostbyname 3 ,
.Xr getservbyport 3 , .Xr getservbyport 3 ,
.Xr divert 4 ,
.Xr ip 4 , .Xr ip 4 ,
.Xr ipfirewall 4 , .Xr ipfirewall 4 ,
.Xr ipaccounting 4 , .Xr protocols 5 ,
.Xr divert 4 , .Xr services 5 ,
.Xr reboot 8 , .Xr reboot 8 ,
.Xr syslogd 8 .Xr syslogd 8
.Sh BUGS .Sh BUGS
@ -338,7 +343,7 @@ do
.Em NOT .Em NOT
do anything you don't understand. do anything you don't understand.
.Pp .Pp
When manipulating/adding chain entries, service names are When manipulating/adding chain entries, service and protocol names are
not accepted. not accepted.
.Sh HISTORY .Sh HISTORY
Initially this utility was written for BSDI by: Initially this utility was written for BSDI by:

View File

@ -16,7 +16,7 @@
* *
* NEW command line interface for IP firewall facility * NEW command line interface for IP firewall facility
* *
* $Id: ipfw.c,v 1.28 1996/06/29 01:28:19 alex Exp $ * $Id: ipfw.c,v 1.29 1996/07/10 19:44:07 julian Exp $
* *
*/ */
@ -74,6 +74,7 @@ print_port(port, comma, flg)
if (do_resolv) { if (do_resolv) {
struct servent *se; struct servent *se;
struct protoent *pe;
const char *protocol; const char *protocol;
switch (flg & IP_FW_F_KIND) { switch (flg & IP_FW_F_KIND) {
@ -88,11 +89,20 @@ print_port(port, comma, flg)
break; break;
} }
se = getservbyport(htons(port), protocol); if (protocol) {
se = getservbyport(htons(port), protocol);
if (se) { if (se) {
printf("%s%s", comma, se->s_name); printf("%s%s", comma, se->s_name);
printed = 1; printed = 1;
}
} else {
pe = getprotobynumber(port);
if (pe) {
printf("%s%s", comma, pe->p_name);
printed = 1;
}
} }
} }
if (!printed) if (!printed)
@ -165,7 +175,7 @@ show_ipfw(chain)
printf(" udp "); printf(" udp ");
break; break;
case IP_FW_F_ALL: case IP_FW_F_ALL:
printf(" all "); printf(" ip ");
break; break;
default: default:
break; break;
@ -200,13 +210,15 @@ show_ipfw(chain)
printf(inet_ntoa(chain->fw_src)); printf(inet_ntoa(chain->fw_src));
} }
comma = " "; if ((chain->fw_flg & IP_FW_F_KIND) != IP_FW_F_ALL) {
for (i=0;i<chain->fw_nsp; i++ ) { comma = " ";
print_port(chain->fw_pts[i], comma, chain->fw_flg); for (i=0;i<chain->fw_nsp; i++ ) {
if (i==0 && (chain->fw_flg & IP_FW_F_SRNG)) print_port(chain->fw_pts[i], comma, chain->fw_flg);
comma = "-"; if (i==0 && (chain->fw_flg & IP_FW_F_SRNG))
else comma = "-";
comma = ","; else
comma = ",";
}
} }
printf(" to "); printf(" to ");
@ -247,6 +259,18 @@ show_ipfw(chain)
comma = ","; 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)) if ((chain->fw_flg & IP_FW_F_IN) && (chain->fw_flg & IP_FW_F_OUT))
; ;
else if (chain->fw_flg & IP_FW_F_IN) else if (chain->fw_flg & IP_FW_F_IN)
@ -374,6 +398,7 @@ show_usage(str)
"\t\ttcpflags [!]{syn|fin|rst|ack|psh|urg},...\n" "\t\ttcpflags [!]{syn|fin|rst|ack|psh|urg},...\n"
"\t\tipoptions [!]{ssrr|lsrr|rr|ts},...\n" "\t\tipoptions [!]{ssrr|lsrr|rr|ts},...\n"
"\t\ticmptypes {type},...\n" "\t\ticmptypes {type},...\n"
"\t\tproto {ipproto},...\n"
, progname , progname
); );
@ -445,17 +470,22 @@ fill_ip(ipno, mask, acp, avp)
} }
void void
add_port(cnt, ptr, off, port) add_port(cnt, ptr, off, port, proto)
u_short *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) if (off + *cnt >= IP_FW_MAX_PORTS)
errx(1, "too many ports (max is %d)", IP_FW_MAX_PORTS); errx(1, "too many %s (max is %d)",
proto ? "protocols" : "ports",
IP_FW_MAX_PORTS);
ptr[off+*cnt] = port; ptr[off+*cnt] = port;
(*cnt)++; (*cnt)++;
} }
int int
fill_port(cnt, ptr, off, arg) fill_port(cnt, ptr, off, arg, proto)
u_short *cnt, *ptr, off; u_short *cnt, *ptr, off;
char *arg; char *arg;
{ {
@ -464,6 +494,8 @@ fill_port(cnt, ptr, off, arg)
s = strchr(arg,'-'); s = strchr(arg,'-');
if (s) { if (s) {
if (proto)
errx(1,"proto ranges are not allowed");
*s++ = '\0'; *s++ = '\0';
if (strchr(arg, ',')) if (strchr(arg, ','))
errx(1, "port range must be first in list"); errx(1, "port range must be first in list");
@ -480,7 +512,7 @@ fill_port(cnt, ptr, off, arg)
s = strchr(arg,','); s = strchr(arg,',');
if (s) if (s)
*s++ = '\0'; *s++ = '\0';
add_port(cnt, ptr, off, atoi(arg)); add_port(cnt, ptr, off, atoi(arg), proto);
arg = s; arg = s;
} }
return initial_range; return initial_range;
@ -672,7 +704,7 @@ add(ac,av)
fill_ip(&rule.fw_src, &rule.fw_smsk, &ac, &av); fill_ip(&rule.fw_src, &rule.fw_smsk, &ac, &av);
if (ac && isdigit(**av)) { if (ac && isdigit(**av)) {
if (fill_port(&rule.fw_nsp, &rule.fw_pts, 0, *av)) if (fill_port(&rule.fw_nsp, &rule.fw_pts, 0, *av, 0))
rule.fw_flg |= IP_FW_F_SRNG; rule.fw_flg |= IP_FW_F_SRNG;
av++; ac--; av++; ac--;
} }
@ -686,7 +718,7 @@ add(ac,av)
fill_ip(&rule.fw_dst, &rule.fw_dmsk, &ac, &av); fill_ip(&rule.fw_dst, &rule.fw_dmsk, &ac, &av);
if (ac && isdigit(**av)) { if (ac && isdigit(**av)) {
if (fill_port(&rule.fw_ndp, &rule.fw_pts, rule.fw_nsp, *av)) if (fill_port(&rule.fw_ndp, &rule.fw_pts, rule.fw_nsp, *av, 0))
rule.fw_flg |= IP_FW_F_DRNG; rule.fw_flg |= IP_FW_F_DRNG;
av++; ac--; av++; ac--;
} }
@ -711,7 +743,7 @@ add(ac,av)
for (q = rule.fw_via_name; *q && !isdigit(*q) && *q != '*'; q++) for (q = rule.fw_via_name; *q && !isdigit(*q) && *q != '*'; q++)
continue; continue;
if (*q == '*') if (*q == '*')
rule.fw_flg = IP_FW_F_IFUWILD; rule.fw_flg |= IP_FW_F_IFUWILD;
else else
rule.fw_via_unit = atoi(q); rule.fw_via_unit = atoi(q);
*q = '\0'; *q = '\0';
@ -759,6 +791,13 @@ add(ac,av)
av++; ac--; continue; 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); printf("%d %s\n",ac,*av);
show_usage("Unknown argument\n"); show_usage("Unknown argument\n");
} }