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++);