Alter ipfw's behavior with respect to fragmented packets when the packet
offset is non-zero: - Do not match fragmented packets if the rule specifies a port or TCP flags - Match fragmented packets if the rule does not specify a port and TCP flags Since ipfw cannot examine port numbers or TCP flags for such packets, it is now illegal to specify the 'frag' option with either ports or tcpflags. Both kernel and ipfw userland utility will reject rules containing a combination of these options. BEWARE: packets that were previously passed may now be rejected, and vice versa. Reviewed by: Archie Cobbs <archie@whistle.com>
This commit is contained in:
parent
27f8f85b7e
commit
ce78a1f6dd
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=33260
@ -289,6 +289,12 @@ and the length of the port list is limited to
|
|||||||
.Pa /usr/src/sys/netinet/ip_fw.h )
|
.Pa /usr/src/sys/netinet/ip_fw.h )
|
||||||
ports.
|
ports.
|
||||||
.Pp
|
.Pp
|
||||||
|
Fragmented packets which have a non-zero offset (i.e. not the first
|
||||||
|
fragment) will never match a rule which has one or more port
|
||||||
|
specifications. See the
|
||||||
|
.Ar frag
|
||||||
|
option for details on matching fragmented packets.
|
||||||
|
.Pp
|
||||||
Rules can apply to packets when they are incoming, or outgoing, or both.
|
Rules can apply to packets when they are incoming, or outgoing, or both.
|
||||||
The
|
The
|
||||||
.Ar in
|
.Ar in
|
||||||
@ -360,6 +366,10 @@ Additional
|
|||||||
.It frag
|
.It frag
|
||||||
Matches if the packet is a fragment and this is not the first fragment
|
Matches if the packet is a fragment and this is not the first fragment
|
||||||
of the datagram.
|
of the datagram.
|
||||||
|
.Ar frag
|
||||||
|
may not be used in conjunction with either
|
||||||
|
.Ar tcpflags
|
||||||
|
or TCP/UDP port specifications.
|
||||||
.It in
|
.It in
|
||||||
Matches if this packet was on the way in.
|
Matches if this packet was on the way in.
|
||||||
.It out
|
.It out
|
||||||
@ -399,6 +409,12 @@ and
|
|||||||
.Ar urg .
|
.Ar urg .
|
||||||
The absence of a particular flag may be denoted
|
The absence of a particular flag may be denoted
|
||||||
with a ``!''.
|
with a ``!''.
|
||||||
|
A rule which contains a
|
||||||
|
.Ar tcpflags
|
||||||
|
specification can never match a fragmented packet which has
|
||||||
|
a non-zero offset. See the
|
||||||
|
.Ar frag
|
||||||
|
option for details on matching fragmented packets.
|
||||||
.It icmptypes Ar types
|
.It icmptypes Ar types
|
||||||
Matches if the ICMP type is in the list
|
Matches if the ICMP type is in the list
|
||||||
.Ar types .
|
.Ar types .
|
||||||
|
@ -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.52 1998/01/08 00:27:31 alex Exp $
|
* $Id: ipfw.c,v 1.53 1998/01/08 03:03:50 alex Exp $
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -502,7 +502,7 @@ show_usage(const char *fmt, ...)
|
|||||||
" src: from [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
|
" src: from [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
|
||||||
" dst: to [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
|
" dst: to [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
|
||||||
" extras:\n"
|
" extras:\n"
|
||||||
" fragment\n"
|
" fragment (may not be used with ports or tcpflags)\n"
|
||||||
" in\n"
|
" in\n"
|
||||||
" out\n"
|
" out\n"
|
||||||
" {xmit|recv|via} {iface|ip|any}\n"
|
" {xmit|recv|via} {iface|ip|any}\n"
|
||||||
@ -1108,6 +1108,15 @@ add(ac,av)
|
|||||||
} else if ((rule.fw_flg & IP_FW_F_OIFACE) && (rule.fw_flg & IP_FW_F_IN))
|
} else if ((rule.fw_flg & IP_FW_F_OIFACE) && (rule.fw_flg & IP_FW_F_IN))
|
||||||
show_usage("can't check xmit interface of incoming packets");
|
show_usage("can't check xmit interface of incoming packets");
|
||||||
|
|
||||||
|
/* frag may not be used in conjunction with ports or TCP flags */
|
||||||
|
if (rule.fw_flg & IP_FW_F_FRAG) {
|
||||||
|
if (rule.fw_tcpf || rule.fw_tcpnf)
|
||||||
|
show_usage(EX_USAGE, "can't mix 'frag' and tcpflags");
|
||||||
|
|
||||||
|
if (rule.fw_nports)
|
||||||
|
show_usage(EX_USAGE, "can't mix 'frag' and port specifications");
|
||||||
|
}
|
||||||
|
|
||||||
if (!do_quiet)
|
if (!do_quiet)
|
||||||
show_ipfw(&rule, 10, 10);
|
show_ipfw(&rule, 10, 10);
|
||||||
i = setsockopt(s, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule);
|
i = setsockopt(s, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule);
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
*
|
*
|
||||||
* This software is provided ``AS IS'' without any warranties of any kind.
|
* This software is provided ``AS IS'' without any warranties of any kind.
|
||||||
*
|
*
|
||||||
* $Id: ip_fw.c,v 1.76 1998/02/06 12:13:51 eivind Exp $
|
* $Id: ip_fw.c,v 1.77 1998/02/09 06:10:10 eivind Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -459,8 +459,18 @@ ip_fw_chk(struct ip **pip, int hlen,
|
|||||||
|
|
||||||
if (offset == 1) /* cf. RFC 1858 */
|
if (offset == 1) /* cf. RFC 1858 */
|
||||||
goto bogusfrag;
|
goto bogusfrag;
|
||||||
if (offset != 0) /* Flags, ports aren't valid */
|
if (offset != 0) {
|
||||||
|
/*
|
||||||
|
* TCP flags and ports aren't available in this
|
||||||
|
* packet -- if this rule specified either one,
|
||||||
|
* we consider the rule a non-match.
|
||||||
|
*/
|
||||||
|
if (f->fw_nports != 0 ||
|
||||||
|
f->fw_tcpf != f->fw_tcpnf)
|
||||||
|
continue;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
PULLUP_TO(hlen + 14);
|
PULLUP_TO(hlen + 14);
|
||||||
tcp = (struct tcphdr *) ((u_long *)ip + ip->ip_hl);
|
tcp = (struct tcphdr *) ((u_long *)ip + ip->ip_hl);
|
||||||
if (f->fw_tcpf != f->fw_tcpnf && !tcpflg_match(tcp, f))
|
if (f->fw_tcpf != f->fw_tcpnf && !tcpflg_match(tcp, f))
|
||||||
@ -474,8 +484,17 @@ ip_fw_chk(struct ip **pip, int hlen,
|
|||||||
{
|
{
|
||||||
struct udphdr *udp;
|
struct udphdr *udp;
|
||||||
|
|
||||||
if (offset != 0) /* Ports aren't valid */
|
if (offset != 0) {
|
||||||
|
/*
|
||||||
|
* Port specification is unavailable -- if this
|
||||||
|
* rule specifies a port, we consider the rule
|
||||||
|
* a non-match.
|
||||||
|
*/
|
||||||
|
if (f->fw_nports != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
PULLUP_TO(hlen + 4);
|
PULLUP_TO(hlen + 4);
|
||||||
udp = (struct udphdr *) ((u_long *)ip + ip->ip_hl);
|
udp = (struct udphdr *) ((u_long *)ip + ip->ip_hl);
|
||||||
src_port = ntohs(udp->uh_sport);
|
src_port = ntohs(udp->uh_sport);
|
||||||
@ -868,6 +887,19 @@ check_ipfw_struct(struct ip_fw *frwl)
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((frwl->fw_flg & IP_FW_F_FRAG) &&
|
||||||
|
(frwl->fw_prot == IPPROTO_UDP || frwl->fw_prot == IPPROTO_TCP)) {
|
||||||
|
if (frwl->fw_nports) {
|
||||||
|
dprintf(("%s cannot mix 'frag' and ports\n", err_prefix));
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
if (frwl->fw_prot == IPPROTO_TCP &&
|
||||||
|
frwl->fw_tcpf != frwl->fw_tcpnf) {
|
||||||
|
dprintf(("%s cannot mix 'frag' and TCP flags\n", err_prefix));
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Check command specific stuff */
|
/* Check command specific stuff */
|
||||||
switch (frwl->fw_flg & IP_FW_F_COMMAND)
|
switch (frwl->fw_flg & IP_FW_F_COMMAND)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user