svn commit: r250251 - in head: sbin/ping6 sys/netinet sys/netinet6

Hiroki Sato hrs at FreeBSD.org
Sat May 4 19:16:28 UTC 2013


Author: hrs
Date: Sat May  4 19:16:26 2013
New Revision: 250251
URL: http://svnweb.freebsd.org/changeset/base/250251

Log:
  Use FF02:0:0:0:0:2:FF00::/104 prefix for IPv6 Node Information Group
  Address.  Although KAME implementation used FF02:0:0:0:0:2::/96 based on
  older versions of draft-ietf-ipngwg-icmp-name-lookup, it has been changed
  in RFC 4620.
  
  The kernel always joins the /104-prefixed address, and additionally does
  /96-prefixed one only when net.inet6.icmp6.nodeinfo_oldmcprefix=1.
  The default value of the sysctl is 1.
  
  ping6(8) -N flag now uses /104-prefixed one.  When this flag is specified
  twice, it uses /96-prefixed one instead.
  
  Reviewed by:		ume
  Based on work by:	Thomas Scheffler
  PR:			conf/174957
  MFC after:		2 weeks

Modified:
  head/sbin/ping6/ping6.8
  head/sbin/ping6/ping6.c
  head/sys/netinet/icmp6.h
  head/sys/netinet6/in6.c
  head/sys/netinet6/in6_ifattach.c
  head/sys/netinet6/in6_ifattach.h
  head/sys/netinet6/in6_proto.c

Modified: head/sbin/ping6/ping6.8
==============================================================================
--- head/sbin/ping6/ping6.8	Sat May  4 19:07:22 2013	(r250250)
+++ head/sbin/ping6/ping6.8	Sat May  4 19:16:26 2013	(r250251)
@@ -29,7 +29,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 20, 2010
+.Dd May 5, 2013
 .Dt PING6 8
 .Os
 .Sh NAME
@@ -215,8 +215,8 @@ unicast and multicast packets.
 Numeric output only.
 No attempt will be made to lookup symbolic names from addresses in the reply.
 .It Fl N
-Probe node information multicast group
-.Pq Li ff02::2:xxxx:xxxx .
+Probe node information multicast group address
+.Pq Li ff02::2:ffxx:xxxx .
 .Ar host
 must be string hostname of the target
 (must not be a numeric IPv6 address).
@@ -227,6 +227,15 @@ Since node information multicast group i
 outgoing interface needs to be specified by
 .Fl I
 option.
+.Pp
+When specified twice, the address
+.Pq Li ff02::2:xxxx:xxxx
+is used instead.
+The former is in RFC 4620, the latter is in an old Internet Draft
+draft-ietf-ipngwg-icmp-name-lookup.
+Note that KAME-derived implementations including
+.Fx 
+use the latter.
 .It Fl o
 Exit successfully after receiving one reply packet.
 .It Fl p Ar pattern

Modified: head/sbin/ping6/ping6.c
==============================================================================
--- head/sbin/ping6/ping6.c	Sat May  4 19:07:22 2013	(r250250)
+++ head/sbin/ping6/ping6.c	Sat May  4 19:16:26 2013	(r250251)
@@ -287,7 +287,7 @@ void	 pr_retip(struct ip6_hdr *, u_char 
 void	 summary(void);
 void	 tvsub(struct timeval *, struct timeval *);
 int	 setpolicy(int, char *);
-char	*nigroup(char *);
+char	*nigroup(char *, int);
 void	 usage(void);
 
 int
@@ -306,6 +306,7 @@ main(int argc, char *argv[])
 	struct addrinfo hints;
 	int cc, i;
 	int ch, hold, packlen, preload, optval, ret_ga;
+	int nig_oldmcprefix = -1;
 	u_char *datap;
 	char *e, *target, *ifname = NULL, *gateway = NULL;
 	int ip6optlen = 0;
@@ -490,6 +491,7 @@ main(int argc, char *argv[])
 			break;
 		case 'N':
 			options |= F_NIGROUP;
+			nig_oldmcprefix++;
 			break;
 		case 'o':
 			options |= F_ONCE;
@@ -605,7 +607,7 @@ main(int argc, char *argv[])
 	}
 
 	if (options & F_NIGROUP) {
-		target = nigroup(argv[argc - 1]);
+		target = nigroup(argv[argc - 1], nig_oldmcprefix);
 		if (target == NULL) {
 			usage();
 			/*NOTREACHED*/
@@ -2723,7 +2725,7 @@ setpolicy(int so __unused, char *policy)
 #endif
 
 char *
-nigroup(char *name)
+nigroup(char *name, int nig_oldmcprefix)
 {
 	char *p;
 	char *q;
@@ -2733,6 +2735,7 @@ nigroup(char *name)
 	size_t l;
 	char hbuf[NI_MAXHOST];
 	struct in6_addr in6;
+	int valid;
 
 	p = strchr(name, '.');
 	if (!p)
@@ -2748,7 +2751,7 @@ nigroup(char *name)
 			*q = tolower(*(unsigned char *)q);
 	}
 
-	/* generate 8 bytes of pseudo-random value. */
+	/* generate 16 bytes of pseudo-random value. */
 	memset(&ctxt, 0, sizeof(ctxt));
 	MD5Init(&ctxt);
 	c = l & 0xff;
@@ -2756,9 +2759,23 @@ nigroup(char *name)
 	MD5Update(&ctxt, (unsigned char *)name, l);
 	MD5Final(digest, &ctxt);
 
-	if (inet_pton(AF_INET6, "ff02::2:0000:0000", &in6) != 1)
+	if (nig_oldmcprefix) {
+		/* draft-ietf-ipngwg-icmp-name-lookup */
+		valid = inet_pton(AF_INET6, "ff02::2:0000:0000", &in6);
+	} else {
+		/* RFC 4620 */
+		valid = inet_pton(AF_INET6, "ff02::2:ff00:0000", &in6);
+	}
+	if (valid != 1)
 		return NULL;	/*XXX*/
-	bcopy(digest, &in6.s6_addr[12], 4);
+	
+	if (nig_oldmcprefix) {
+		/* draft-ietf-ipngwg-icmp-name-lookup */
+		bcopy(digest, &in6.s6_addr[12], 4);
+	} else {
+		/* RFC 4620 */
+		bcopy(digest, &in6.s6_addr[13], 3);
+	}
 
 	if (inet_ntop(AF_INET6, &in6, hbuf, sizeof(hbuf)) == NULL)
 		return NULL;

Modified: head/sys/netinet/icmp6.h
==============================================================================
--- head/sys/netinet/icmp6.h	Sat May  4 19:07:22 2013	(r250250)
+++ head/sys/netinet/icmp6.h	Sat May  4 19:16:26 2013	(r250251)
@@ -659,7 +659,8 @@ void	kmod_icmp6stat_inc(int statnum);
 #define ICMPV6CTL_MLD_SOMAXSRC	22
 #define ICMPV6CTL_MLD_VERSION	23
 #define ICMPV6CTL_ND6_MAXQLEN	24
-#define ICMPV6CTL_MAXID		25
+#define ICMPV6CTL_NODEINFO_OLDMCPREFIX	25
+#define ICMPV6CTL_MAXID		26
 
 #define RTF_PROBEMTU	RTF_PROTO1
 

Modified: head/sys/netinet6/in6.c
==============================================================================
--- head/sys/netinet6/in6.c	Sat May  4 19:07:22 2013	(r250250)
+++ head/sys/netinet6/in6.c	Sat May  4 19:16:26 2013	(r250251)
@@ -106,6 +106,9 @@ __FBSDID("$FreeBSD$");
 #include <netinet6/scope6_var.h>
 #include <netinet6/in6_pcb.h>
 
+VNET_DECLARE(int, icmp6_nodeinfo_oldmcprefix);
+#define V_icmp6_nodeinfo_oldmcprefix	VNET(icmp6_nodeinfo_oldmcprefix)
+
 /*
  * Definitions of some costant IP6 addresses.
  */
@@ -947,6 +950,17 @@ in6_update_ifa_join_mc(struct ifnet *ifp
 		else
 			LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
 	}
+	if (V_icmp6_nodeinfo_oldmcprefix && 
+	     in6_nigroup_oldmcprefix(ifp, NULL, -1, &mltaddr.sin6_addr) == 0) {
+		imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, delay);
+		if (imm == NULL)
+			nd6log((LOG_WARNING, "%s: addmulti failed for %s on %s "
+			    "(errno=%d)\n", __func__, ip6_sprintf(ip6buf,
+			    &mltaddr.sin6_addr), if_name(ifp), error));
+			/* XXX not very fatal, go on... */
+		else
+			LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
+	}
 
 	/*
 	 * Join interface-local all-nodes address.

Modified: head/sys/netinet6/in6_ifattach.c
==============================================================================
--- head/sys/netinet6/in6_ifattach.c	Sat May  4 19:07:22 2013	(r250250)
+++ head/sys/netinet6/in6_ifattach.c	Sat May  4 19:16:26 2013	(r250251)
@@ -616,13 +616,16 @@ in6_ifattach_loopback(struct ifnet *ifp)
 
 /*
  * compute NI group address, based on the current hostname setting.
- * see draft-ietf-ipngwg-icmp-name-lookup-* (04 and later).
+ * see RFC 4620.
  *
  * when ifp == NULL, the caller is responsible for filling scopeid.
+ *
+ * If oldmcprefix == 1, FF02:0:0:0:0:2::/96 is used for NI group address
+ * while it is FF02:0:0:0:0:2:FF00::/104 in RFC 4620. 
  */
-int
-in6_nigroup(struct ifnet *ifp, const char *name, int namelen,
-    struct in6_addr *in6)
+static int
+in6_nigroup0(struct ifnet *ifp, const char *name, int namelen,
+    struct in6_addr *in6, int oldmcprefix)
 {
 	struct prison *pr;
 	const char *p;
@@ -667,7 +670,7 @@ in6_nigroup(struct ifnet *ifp, const cha
 			*q = *q - 'A' + 'a';
 	}
 
-	/* generate 8 bytes of pseudo-random value. */
+	/* generate 16 bytes of pseudo-random value. */
 	bzero(&ctxt, sizeof(ctxt));
 	MD5Init(&ctxt);
 	MD5Update(&ctxt, &l, sizeof(l));
@@ -677,13 +680,36 @@ in6_nigroup(struct ifnet *ifp, const cha
 	bzero(in6, sizeof(*in6));
 	in6->s6_addr16[0] = IPV6_ADDR_INT16_MLL;
 	in6->s6_addr8[11] = 2;
-	bcopy(digest, &in6->s6_addr32[3], sizeof(in6->s6_addr32[3]));
+	if (oldmcprefix == 0) {
+		in6->s6_addr8[12] = 0xff;
+	 	/* Copy the first 24 bits of 128-bit hash into the address. */
+		bcopy(digest, &in6->s6_addr8[13], 3);
+	} else {
+	 	/* Copy the first 32 bits of 128-bit hash into the address. */
+		bcopy(digest, &in6->s6_addr32[3], sizeof(in6->s6_addr32[3]));
+	}
 	if (in6_setscope(in6, ifp, NULL))
 		return (-1); /* XXX: should not fail */
 
 	return 0;
 }
 
+int
+in6_nigroup(struct ifnet *ifp, const char *name, int namelen,
+    struct in6_addr *in6)
+{
+
+	return (in6_nigroup0(ifp, name, namelen, in6, 0));
+}
+
+int
+in6_nigroup_oldmcprefix(struct ifnet *ifp, const char *name, int namelen,
+    struct in6_addr *in6)
+{
+
+	return (in6_nigroup0(ifp, name, namelen, in6, 1));
+}
+
 /*
  * XXX multiple loopback interface needs more care.  for instance,
  * nodelocal address needs to be configured onto only one of them.

Modified: head/sys/netinet6/in6_ifattach.h
==============================================================================
--- head/sys/netinet6/in6_ifattach.h	Sat May  4 19:07:22 2013	(r250250)
+++ head/sys/netinet6/in6_ifattach.h	Sat May  4 19:16:26 2013	(r250251)
@@ -40,6 +40,7 @@ int in6_get_tmpifid(struct ifnet *, u_in
 void in6_tmpaddrtimer(void *);
 int in6_get_hw_ifid(struct ifnet *, struct in6_addr *);
 int in6_nigroup(struct ifnet *, const char *, int, struct in6_addr *);
+int in6_nigroup_oldmcprefix(struct ifnet *, const char *, int, struct in6_addr *);
 #endif /* _KERNEL */
 
 #endif /* _NETINET6_IN6_IFATTACH_H_ */

Modified: head/sys/netinet6/in6_proto.c
==============================================================================
--- head/sys/netinet6/in6_proto.c	Sat May  4 19:07:22 2013	(r250250)
+++ head/sys/netinet6/in6_proto.c	Sat May  4 19:16:26 2013	(r250251)
@@ -438,6 +438,7 @@ VNET_DEFINE(int, icmp6errppslim) = 100;	
 /* control how to respond to NI queries */
 VNET_DEFINE(int, icmp6_nodeinfo) =
     (ICMP6_NODEINFO_FQDNOK|ICMP6_NODEINFO_NODEADDROK);
+VNET_DEFINE(int, icmp6_nodeinfo_oldmcprefix) = 1;
 
 /*
  * sysctl related items.
@@ -602,6 +603,11 @@ SYSCTL_VNET_INT(_net_inet6_icmp6, ICMPV6
 	CTLFLAG_RW, &VNET_NAME(nd6_useloopback), 0, "");
 SYSCTL_VNET_INT(_net_inet6_icmp6, ICMPV6CTL_NODEINFO, nodeinfo, CTLFLAG_RW,
 	&VNET_NAME(icmp6_nodeinfo), 0, "");
+SYSCTL_VNET_INT(_net_inet6_icmp6, ICMPV6CTL_NODEINFO_OLDMCPREFIX,
+	nodeinfo_oldmcprefix, CTLFLAG_RW,
+	&VNET_NAME(icmp6_nodeinfo_oldmcprefix), 0, 
+	"Join old IPv6 NI group address in draft-ietf-ipngwg-icmp-name-lookup"
+	" for compatibility with KAME implememtation.");
 SYSCTL_VNET_INT(_net_inet6_icmp6, ICMPV6CTL_ERRPPSLIMIT, errppslimit,
 	CTLFLAG_RW, &VNET_NAME(icmp6errppslim), 0, "");
 SYSCTL_VNET_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MAXNUDHINT, nd6_maxnudhint,


More information about the svn-src-head mailing list