Reducing ip_id information leakage

Garrett Wollman wollman at lcs.mit.edu
Tue Apr 29 15:47:54 PDT 2003


Here's a patch inspired by a recent Steve Bellovin paper.  It also
saves a bswap operation in the common case for non-TCP (non-PMTUD)
traffic.  Untested as yet, but I have great faith....

-GAWollman


Index: ip_output.c
===================================================================
RCS file: /home/cvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.187
diff -u -r1.187 ip_output.c
--- ip_output.c	12 Apr 2003 06:11:46 -0000	1.187
+++ ip_output.c	29 Apr 2003 22:42:55 -0000
@@ -223,17 +223,29 @@
 	pkt_dst = args.next_hop ? args.next_hop->sin_addr : ip->ip_dst;
 
 	/*
-	 * Fill in IP header.
+	 * Fill in IP header.  If we are not allowing fragmentation,
+	 * then the ip_id field is meaningless, so send it as zero
+	 * to reduce information leakage.  Otherwise, if we are not
+	 * randomizing ip_id, then don't bother to convert it to network
+	 * byte order -- it's just a nonce.  Note that a 16-bit counter
+	 * will wrap around in less than 10 seconds at 100 Mbit/s on a
+	 * medium with MTU 1500.  See Steven M. Bellovin, "A Technique
+	 * for Counting NATted Hosts", Proc. IMW'02, available at
+	 * <http://www.research.att.com/~smb/papers/fnat.pdf>.
 	 */
 	if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) {
 		ip->ip_v = IPVERSION;
 		ip->ip_hl = hlen >> 2;
 		ip->ip_off &= IP_DF;
+		if (ip->ip_off)
+			ip->ip_id = 0;
+		else {
 #ifdef RANDOM_IP_ID
-		ip->ip_id = ip_randomid();
+			ip->ip_id = ip_randomid();
 #else
-		ip->ip_id = htons(ip_id++);
+			ip->ip_id = ip_id++;
 #endif
+		}
 		ipstat.ips_localout++;
 	} else {
 		hlen = ip->ip_hl << 2;


More information about the freebsd-net mailing list