diff options
author | alex <alex@FreeBSD.org> | 1998-02-12 00:57:06 +0000 |
---|---|---|
committer | alex <alex@FreeBSD.org> | 1998-02-12 00:57:06 +0000 |
commit | 0fbf800481760f576d51aee10eefe415ac56ad5b (patch) | |
tree | 797efc4ee0cffbe27100802e4ec9e06304f3a6ea /sys/netinet/ip_fw.c | |
parent | 95821ff4bae98b78e9504de70097bd6da35b7322 (diff) | |
download | FreeBSD-src-0fbf800481760f576d51aee10eefe415ac56ad5b.zip FreeBSD-src-0fbf800481760f576d51aee10eefe415ac56ad5b.tar.gz |
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>
Diffstat (limited to 'sys/netinet/ip_fw.c')
-rw-r--r-- | sys/netinet/ip_fw.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c index 21011c2..854879a 100644 --- a/sys/netinet/ip_fw.c +++ b/sys/netinet/ip_fw.c @@ -12,7 +12,7 @@ * * 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 */ 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; + } PULLUP_TO(hlen + 14); tcp = (struct tcphdr *) ((u_long *)ip + ip->ip_hl); 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; - 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; + } PULLUP_TO(hlen + 4); udp = (struct udphdr *) ((u_long *)ip + ip->ip_hl); src_port = ntohs(udp->uh_sport); @@ -868,6 +887,19 @@ check_ipfw_struct(struct ip_fw *frwl) 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 */ switch (frwl->fw_flg & IP_FW_F_COMMAND) { |