Date: Tue, 10 Feb 1998 21:12:21 -0600 (CST) From: Alex Nash <nash@mcs.net> To: avalon@coombs.anu.edu.au Cc: archie@whistle.com, freebsd-hackers@FreeBSD.ORG Subject: Re: ipfw logs ports for fragments Message-ID: <199802110312.VAA08417@nash.pr.mcs.net> In-Reply-To: <199802102235.QAA26217@Mailbox.mcs.net>
next in thread | previous in thread | raw e-mail | index | archive | help
On 11 Feb, Darren Reed wrote: >> Now the question is.. which exception to make? >> >> #1 Don't even TRY to match rules containing port ranges and/or flags >> to non-zero offset fragments. > > Correct. > >> #2 Match port range/flag rules to non-zero offset fragments by testing >> the rule AS IF it did not contain the port range and/or flag >> restrictions. > > Wrong. I think Darren and I are in agreement on this. The patches below modify ipfw to: - Not match fragmented packets (where offset != 0) if the rule specifies a port and/or TCP flags - Match fragmented packets (where offset != 0) if the rule does not specify a port and/or TCP flags Naturally, the standard source, dest, protocol, interface, etc. fields must also match in the above cases. Alex Index: ip_fw.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_fw.c,v retrieving revision 1.77 diff -c -r1.77 ip_fw.c *** ip_fw.c 1998/02/09 06:10:10 1.77 --- ip_fw.c 1998/02/11 02:58:35 *************** *** 459,466 **** if (offset == 1) /* cf. RFC 1858 */ goto bogusfrag; ! if (offset != 0) /* Flags, ports aren't valid */ 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)) --- 459,476 ---- if (offset == 1) /* cf. RFC 1858 */ goto bogusfrag; ! 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,481 **** { struct udphdr *udp; ! if (offset != 0) /* Ports aren't valid */ break; PULLUP_TO(hlen + 4); udp = (struct udphdr *) ((u_long *)ip + ip->ip_hl); src_port = ntohs(udp->uh_sport); --- 484,500 ---- { struct udphdr *udp; ! 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); *************** *** 866,871 **** --- 885,903 ---- (frwl->fw_dst.s_addr & (~frwl->fw_dmsk.s_addr))) { dprintf(("%s rule never matches\n", err_prefix)); 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' with TCP flags\n", err_prefix)); + return(NULL); + } } /* Check command specific stuff */ Index: ipfw.8 =================================================================== RCS file: /home/ncvs/src/sbin/ipfw/ipfw.8,v retrieving revision 1.37 diff -c -r1.37 ipfw.8 *** ipfw.8 1998/01/07 02:23:03 1.37 --- ipfw.8 1998/02/11 02:57:41 *************** *** 289,294 **** --- 289,300 ---- .Pa /usr/src/sys/netinet/ip_fw.h ) ports. .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. The .Ar in *************** *** 360,365 **** --- 366,375 ---- .It frag Matches if the packet is a fragment and this is not the first fragment of the datagram. + .Ar frag + may not be used in conjunction with either + .Ar tcpflags + or TCP/UDP port specifications. .It in Matches if this packet was on the way in. .It out *************** *** 399,404 **** --- 409,420 ---- .Ar urg . The absence of a particular flag may be denoted 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 Matches if the ICMP type is in the list .Ar types . Index: ipfw.c =================================================================== RCS file: /home/ncvs/src/sbin/ipfw/ipfw.c,v retrieving revision 1.53 diff -c -r1.53 ipfw.c *** ipfw.c 1998/01/08 03:03:50 1.53 --- ipfw.c 1998/02/11 02:57:54 *************** *** 1108,1113 **** --- 1108,1122 ---- } 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"); + /* 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) + errx(EX_USAGE, "can't mix 'frag' and tcpflags"); + + if (rule.fw_nports) + errx(EX_USAGE, "can't mix 'frag' and port specifications"); + } + if (!do_quiet) show_ipfw(&rule, 10, 10); i = setsockopt(s, IPPROTO_IP, IP_FW_ADD, &rule, sizeof rule); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199802110312.VAA08417>