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
.Os FreeBSD
.Sh NAME
@ -249,6 +249,14 @@ 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
@ -262,10 +270,6 @@ Remember to test very carefully.
It is a good idea to be near the console when doing this.
.It
Don't forget the loopback interface.
.It
Don't filter
.Nm all
if you are also specifying a port.
.El
.Sh FINE POINTS
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
.Xr gethostbyname 3 ,
.Xr getservbyport 3 ,
.Xr divert 4 ,
.Xr ip 4 ,
.Xr ipfirewall 4 ,
.Xr ipaccounting 4 ,
.Xr divert 4 ,
.Xr protocols 5 ,
.Xr services 5 ,
.Xr reboot 8 ,
.Xr syslogd 8
.Sh BUGS
@ -338,7 +343,7 @@ do
.Em NOT
do anything you don't understand.
.Pp
When manipulating/adding chain entries, service names are
When manipulating/adding chain entries, service and protocol names are
not accepted.
.Sh HISTORY
Initially this utility was written for BSDI by:

View File

@ -16,7 +16,7 @@
*
* 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) {
struct servent *se;
struct protoent *pe;
const char *protocol;
switch (flg & IP_FW_F_KIND) {
@ -88,11 +89,20 @@ print_port(port, comma, flg)
break;
}
se = getservbyport(htons(port), protocol);
if (protocol) {
se = getservbyport(htons(port), protocol);
if (se) {
printf("%s%s", comma, se->s_name);
printed = 1;
if (se) {
printf("%s%s", comma, se->s_name);
printed = 1;
}
} else {
pe = getprotobynumber(port);
if (pe) {
printf("%s%s", comma, pe->p_name);
printed = 1;
}
}
}
if (!printed)
@ -165,7 +175,7 @@ show_ipfw(chain)
printf(" udp ");
break;
case IP_FW_F_ALL:
printf(" all ");
printf(" ip ");
break;
default:
break;
@ -200,13 +210,15 @@ show_ipfw(chain)
printf(inet_ntoa(chain->fw_src));
}
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_KIND) != IP_FW_F_ALL) {
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 = ",";
}
}
printf(" to ");
@ -247,6 +259,18 @@ show_ipfw(chain)
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)
@ -374,6 +398,7 @@ show_usage(str)
"\t\ttcpflags [!]{syn|fin|rst|ack|psh|urg},...\n"
"\t\tipoptions [!]{ssrr|lsrr|rr|ts},...\n"
"\t\ticmptypes {type},...\n"
"\t\tproto {ipproto},...\n"
, progname
);
@ -445,17 +470,22 @@ fill_ip(ipno, mask, acp, avp)
}
void
add_port(cnt, ptr, off, port)
add_port(cnt, ptr, off, port, proto)
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 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;
(*cnt)++;
}
int
fill_port(cnt, ptr, off, arg)
fill_port(cnt, ptr, off, arg, proto)
u_short *cnt, *ptr, off;
char *arg;
{
@ -464,6 +494,8 @@ fill_port(cnt, ptr, off, arg)
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");
@ -480,7 +512,7 @@ fill_port(cnt, ptr, off, arg)
s = strchr(arg,',');
if (s)
*s++ = '\0';
add_port(cnt, ptr, off, atoi(arg));
add_port(cnt, ptr, off, atoi(arg), proto);
arg = s;
}
return initial_range;
@ -672,7 +704,7 @@ add(ac,av)
fill_ip(&rule.fw_src, &rule.fw_smsk, &ac, &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;
av++; ac--;
}
@ -686,7 +718,7 @@ add(ac,av)
fill_ip(&rule.fw_dst, &rule.fw_dmsk, &ac, &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;
av++; ac--;
}
@ -711,7 +743,7 @@ add(ac,av)
for (q = rule.fw_via_name; *q && !isdigit(*q) && *q != '*'; q++)
continue;
if (*q == '*')
rule.fw_flg = IP_FW_F_IFUWILD;
rule.fw_flg |= IP_FW_F_IFUWILD;
else
rule.fw_via_unit = atoi(q);
*q = '\0';
@ -759,6 +791,13 @@ add(ac,av)
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");
}