Skip site navigation (1)Skip section navigation (2)
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>