Subject: Re: kernel ip_randomid() and libc randomid(3) still "broken"
To: None <tech-net@NetBSD.org>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: tech-net
Date: 11/16/2003 18:26:01
The following patch relegates the random ip_id code to a config-time
option. I chose RANDOM_IP_ID simply because the ifdef already exists
in our tree (in sys/netipsec, via FreeBSD).

Charles' comment (that the code should be removed) has been heard.

I'm not (yet) myself prepared to remove it. If someone wants to do
that, this patch makes it trivial to do so, yet leaves ip_newid() as a
`hook' that can be used later, for better randomized IP IDs.

I've heard a couple of people say that Sun has a smarter random IP_ID
allocation, maybe based on inpcb state?. I haven't tried to implement
that, as I've never heard how it handles IDs for IP output packets not
associated with an inpcb (e.g., outbound ICMP, or multicast/broadcast).

This patch also stops applyling htons() to random IP IDs.
I can't see any point in it at all.



Index: netinet/files.netinet
===================================================================
RCS file: /cvsroot/src/sys/netinet/files.netinet,v
retrieving revision 1.2
diff -u -r1.2 files.netinet
--- netinet/files.netinet	2003/09/06 03:36:30	1.2
+++ netinet/files.netinet	2003/11/17 02:08:14
@@ -2,7 +2,7 @@
 
 defflag opt_tcp_debug.h		TCP_DEBUG
 defparam opt_tcp_debug.h	TCP_NDEBUG
-defflag opt_inet.h		INET INET6 INET6_MD_CKSUM
+defflag opt_inet.h		INET INET6 INET6_MD_CKSUM RANDOM_IP_ID
 defparam opt_inet_conf.h	SUBNETSARELOCAL HOSTZEROBROADCAST
 
 defflag				MROUTING
@@ -19,7 +19,7 @@
 file	netinet/in_proto.c	inet
 file	netinet/ip_flow.c	inet & gateway
 file	netinet/ip_icmp.c	inet
-file	netinet/ip_id.c		inet
+file	netinet/ip_id.c		random_ip_id
 file	netinet/ip_input.c	inet
 file	netinet/ip_mroute.c	inet & mrouting
 file	netinet/ip_output.c	inet
Index: netinet/ip_var.h
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_var.h,v
retrieving revision 1.59
diff -u -r1.59 ip_var.h
--- netinet/ip_var.h	2003/09/06 03:36:31	1.59
+++ netinet/ip_var.h	2003/11/17 02:08:14
@@ -251,7 +251,24 @@
 void	ipflow_create __P((const struct route *, struct mbuf *));
 void	ipflow_slowtimo __P((void));
 
+extern uint16_t	ip_id;
+static __inline uint16_t ip_newid __P((void));
+
+#ifdef RANDOM_IP_ID
 u_int16_t ip_randomid __P((void));
+extern int ip_do_randomid;
 #endif
+
+static __inline uint16_t
+ip_newid(void)
+{
+#ifdef RANDOM_IP_ID
+	return ((ip_do_randomid) ? ip_randomid() : htons(ip_id++));
+#else	/* !RANDOM_IP_ID */
+	return htons(ip_id++);
+#endif	/* !RANDOM_IP_ID */
+}
+
+#endif  /* _KERNEL */
 
 #endif /* _NETINET_IP_VAR_H_ */
Index: netinet/ip_mroute.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_mroute.c,v
retrieving revision 1.80
diff -u -r1.80 ip_mroute.c
--- netinet/ip_mroute.c	2003/09/06 03:36:30	1.80
+++ netinet/ip_mroute.c	2003/11/17 02:08:15
@@ -1564,7 +1564,7 @@
 	 */
 	ip_copy = mtod(mb_copy, struct ip *);
 	*ip_copy = multicast_encap_iphdr;
-	ip_copy->ip_id = htons(ip_randomid());
+	ip_copy->ip_id = ip_newid();
 	ip_copy->ip_len = htons(len);
 	ip_copy->ip_src = vifp->v_lcl_addr;
 	ip_copy->ip_dst = vifp->v_rmt_addr;
Index: netinet/ip_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_output.c,v
retrieving revision 1.126
diff -u -r1.126 ip_output.c
--- netinet/ip_output.c	2003/10/17 20:31:12	1.126
+++ netinet/ip_output.c	2003/11/17 02:08:16
@@ -235,7 +235,7 @@
 	if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) {
 		ip->ip_v = IPVERSION;
 		ip->ip_off = htons(0);
-		ip->ip_id = htons(ip_randomid());
+		ip->ip_id = ip_newid();
 		ip->ip_hl = hlen >> 2;
 		ipstat.ips_localout++;
 	} else {
Index: netinet/raw_ip.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/raw_ip.c,v
retrieving revision 1.76
diff -u -r1.76 raw_ip.c
--- netinet/raw_ip.c	2003/09/06 03:36:31	1.76
+++ netinet/raw_ip.c	2003/11/17 02:08:16
@@ -379,7 +379,7 @@
 		HTONS(ip->ip_len);
 		HTONS(ip->ip_off);
 		if (ip->ip_id == 0)
-			ip->ip_id = htons(ip_randomid());
+			ip->ip_id = ip_newid();
 		opts = NULL;
 		/* XXX prevent ip_output from overwriting header fields */
 		flags |= IP_RAWOUTPUT;
Index: netinet6/ipsec.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ipsec.c,v
retrieving revision 1.87
diff -u -r1.87 ipsec.c
--- netinet6/ipsec.c	2003/10/03 22:08:26	1.87
+++ netinet6/ipsec.c	2003/11/17 02:08:18
@@ -2123,7 +2123,7 @@
 		ipseclog((LOG_ERR, "IPv4 ipsec: size exceeds limit: "
 		    "leave ip_len as is (invalid packet)\n"));
 	}
-	ip->ip_id = htons(ip_randomid());
+	ip->ip_id = ip_newid();
 	bcopy(&((struct sockaddr_in *)&sav->sah->saidx.src)->sin_addr,
 		&ip->ip_src, sizeof(ip->ip_src));
 	bcopy(&((struct sockaddr_in *)&sav->sah->saidx.dst)->sin_addr,
Index: netipsec/xform_ipip.c
===================================================================
RCS file: /cvsroot/src/sys/netipsec/xform_ipip.c,v
retrieving revision 1.6
diff -u -r1.6 xform_ipip.c
--- netipsec/xform_ipip.c	2003/11/14 07:15:28	1.6
+++ netipsec/xform_ipip.c	2003/11/17 02:08:18
@@ -484,7 +484,9 @@
 		ipo->ip_src = saidx->src.sin.sin_addr;
 		ipo->ip_dst = saidx->dst.sin.sin_addr;
 
-#if defined(__NetBSD__) || defined(RANDOM_IP_ID)
+#if defined(__NetBSD__) 
+		ipo->ip_id = ip_newid();
+#elif defined(RANDOM_IP_ID)
 		ipo->ip_id = ip_randomid();
 #else
 		ipo->ip_id = htons(ip_id++);