PATCH: ip_input.c, ip_output.c, ipfw.8

Ian FREISLICH if at hetzner.co.za
Wed Mar 10 01:12:50 PST 2004


Hi

Noted in the BUGS section of the ipfw manual page:

    Packets that match a tee rule should not be immediately accepted, 
but
    should continue going through the rule list.  This may be fixed in a
    later version.

I've needed to get a copy of packets before the firewall potentially
drops them or passes them to dummynet, but I still want the firewall
to process the packets as normal and not just accept them.

Here's a patch to fix the bug.  If all is in order, please commit
it otherwise let me know how and what I should change so that it can
be committed.  It would also be nice if it can be MFC'd.

Ian

--
Ian Freislich

-------------- next part --------------
Index: sbin/ipfw/ipfw.8
===================================================================
RCS file: /home/ncvs/src/sbin/ipfw/ipfw.8,v
retrieving revision 1.139
diff -u -d -r1.139 ipfw.8
--- sbin/ipfw/ipfw.8	23 Jan 2004 06:37:19 -0000	1.139
+++ sbin/ipfw/ipfw.8	10 Mar 2004 09:03:06 -0000
@@ -658,10 +658,7 @@
 .Xr divert 4
 socket bound to port
 .Ar port .
-The search terminates and the original packet is accepted
-(but see Section
-.Sx BUGS
-below).
+The search continues at the next rule.
 .It Cm unreach Ar code
 Discard packets that match this rule, and try to send an ICMP
 unreachable notice with code
@@ -2169,12 +2166,6 @@
 are reassembled before delivery to the socket.
 The action used on those packet is the one from the
 rule which matches the first fragment of the packet.
-.Pp
-Packets that match a
-.Cm tee
-rule should not be immediately accepted, but should continue
-going through the rule list.
-This may be fixed in a later version.
 .Pp
 Packets diverted to userland, and then reinserted by a userland process
 may lose various packet attributes.
Index: sys/netinet/ip_input.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.266
diff -u -d -r1.266 ip_input.c
--- sys/netinet/ip_input.c	1 Mar 2004 22:37:01 -0000	1.266
+++ sys/netinet/ip_input.c	10 Mar 2004 08:35:58 -0000
@@ -473,6 +473,9 @@
 		if (args.next_hop)
 			goto ours;
 
+#ifdef IPDIVERT
+again:
+#endif
 		args.m = m;
 		i = ip_fw_chk_ptr(&args);
 		m = args.m;
@@ -854,20 +857,22 @@
 		divert_packet(m, 1);
 		ipstat.ips_delivered++;
 
-		/* If 'tee', continue with original packet */
+		/* If 'tee', continue processing firewall rules
+		 * with the original packet */
 		if (clone == NULL)
 			return;
 		m = clone;
-		ip = mtod(m, struct ip *);
-		ip->ip_len += hlen;
 		/*
 		 * Jump backwards to complete processing of the
 		 * packet.  We do not need to clear args.next_hop
 		 * as that will not be used again and the cloned packet
 		 * doesn't contain a divert packet tag so we won't
 		 * re-entry this block.
+		 * We must not clear args.divert_rule since it is
+		 * used to maintain context for continued rule
+		 * processing.
 		 */
-		goto pass;
+		goto again;
 	}
 #endif
 
Index: sys/netinet/ip_output.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.211
diff -u -d -r1.211 ip_output.c
--- sys/netinet/ip_output.c	2 Mar 2004 14:37:23 -0000	1.211
+++ sys/netinet/ip_output.c	10 Mar 2004 08:35:32 -0000
@@ -731,6 +731,9 @@
 	if (fw_enable && IPFW_LOADED && !args.next_hop) {
 		struct sockaddr_in *old = dst;
 
+#ifdef IPDIVERT
+again:
+#endif
 		args.m = m;
 		args.next_hop = dst;
 		args.oif = ifp;
@@ -807,11 +810,10 @@
 			/* Deliver packet to divert input routine */
 			divert_packet(m, 0);
 
-			/* If 'tee', continue with original packet */
+			/* If 'tee', continue processing firewall
+			 * rules with the original packet */
 			if (clone != NULL) {
-				m = clone;
-				ip = mtod(m, struct ip *);
-				goto pass;
+				goto again;
 			}
 			goto done;
 		}


More information about the freebsd-current mailing list