Module Name:    src
Committed By:   bouyer
Date:           Tue Dec 17 20:47:33 UTC 2013

Modified Files:
        src/sys/netinet6 [netbsd-6]: nd6.c
        src/usr.sbin/ndp [netbsd-6]: ndp.c

Log Message:
Pull up following revision(s) (requested by martin in ticket #998):
        usr.sbin/ndp/ndp.c: revision 1.42
        sys/netinet6/nd6.c: revision 1.146
Instead of voodo casts use simple byte pointer arithmetic and memcpy to
create the "packed" binary format we pass out to userland when querying
the router/prefix list.
Simplify code to print the router/prefix list: use memcpy and local structs
properly aligned on the stack to decode the binary format passed by the
kernel - instead of (bogusly) assuming the format will obey all local
alignement requirements.


To generate a diff of this commit:
cvs rdiff -u -r1.141.2.1 -r1.141.2.2 src/sys/netinet6/nd6.c
cvs rdiff -u -r1.40 -r1.40.4.1 src/usr.sbin/ndp/ndp.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netinet6/nd6.c
diff -u src/sys/netinet6/nd6.c:1.141.2.1 src/sys/netinet6/nd6.c:1.141.2.2
--- src/sys/netinet6/nd6.c:1.141.2.1	Mon Jul  8 07:40:07 2013
+++ src/sys/netinet6/nd6.c	Tue Dec 17 20:47:33 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: nd6.c,v 1.141.2.1 2013/07/08 07:40:07 jdc Exp $	*/
+/*	$NetBSD: nd6.c,v 1.141.2.2 2013/12/17 20:47:33 bouyer Exp $	*/
 /*	$KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.141.2.1 2013/07/08 07:40:07 jdc Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.141.2.2 2013/12/17 20:47:33 bouyer Exp $");
 
 #include "opt_ipsec.h"
 
@@ -2387,44 +2387,43 @@ fill_prlist(void *oldp, size_t *oldlenp,
 {
 	int error = 0, s;
 	struct nd_prefix *pr;
-	struct in6_prefix *p = NULL;
-	struct in6_prefix *pe = NULL;
+	uint8_t *p = NULL, *ps = NULL;
+	uint8_t *pe = NULL;
 	size_t l;
 
 	s = splsoftnet();
 
 	if (oldp) {
-		p = (struct in6_prefix *)oldp;
-		pe = (struct in6_prefix *)((char *)oldp + *oldlenp);
+		ps = p = (uint8_t*)oldp;
+		pe = (uint8_t*)oldp + *oldlenp;
 	}
 	l = 0;
 
 	LIST_FOREACH(pr, &nd_prefix, ndpr_entry) {
 		u_short advrtrs;
-		size_t advance;
-		struct sockaddr_in6 *sin6;
-		struct sockaddr_in6 *s6;
+		struct sockaddr_in6 sin6;
 		struct nd_pfxrouter *pfr;
+		struct in6_prefix pfx;
 
-		if (oldp && p + 1 <= pe)
+		if (oldp && p + sizeof(struct in6_prefix) <= pe)
 		{
-			memset(p, 0, sizeof(*p));
-			sin6 = (struct sockaddr_in6 *)(p + 1);
+			memset(&pfx, 0, sizeof(pfx));
+			ps = p;
+			pfx.prefix = pr->ndpr_prefix;
 
-			p->prefix = pr->ndpr_prefix;
-			if (sa6_recoverscope(&p->prefix)) {
+			if (sa6_recoverscope(&pfx.prefix)) {
 				log(LOG_ERR,
 				    "scope error in prefix list (%s)\n",
-				    ip6_sprintf(&p->prefix.sin6_addr));
+				    ip6_sprintf(&pfx.prefix.sin6_addr));
 				/* XXX: press on... */
 			}
-			p->raflags = pr->ndpr_raf;
-			p->prefixlen = pr->ndpr_plen;
-			p->vltime = pr->ndpr_vltime;
-			p->pltime = pr->ndpr_pltime;
-			p->if_index = pr->ndpr_ifp->if_index;
+			pfx.raflags = pr->ndpr_raf;
+			pfx.prefixlen = pr->ndpr_plen;
+			pfx.vltime = pr->ndpr_vltime;
+			pfx.pltime = pr->ndpr_pltime;
+			pfx.if_index = pr->ndpr_ifp->if_index;
 			if (pr->ndpr_vltime == ND6_INFINITE_LIFETIME)
-				p->expire = 0;
+				pfx.expire = 0;
 			else {
 				time_t maxexpire;
 
@@ -2434,43 +2433,48 @@ fill_prlist(void *oldp, size_t *oldlenp,
 				    ((sizeof(maxexpire) * 8) - 1));
 				if (pr->ndpr_vltime <
 				    maxexpire - pr->ndpr_lastupdate) {
-					p->expire = pr->ndpr_lastupdate +
+					pfx.expire = pr->ndpr_lastupdate +
 						pr->ndpr_vltime;
 				} else
-					p->expire = maxexpire;
+					pfx.expire = maxexpire;
 			}
-			p->refcnt = pr->ndpr_refcnt;
-			p->flags = pr->ndpr_stateflags;
-			p->origin = PR_ORIG_RA;
+			pfx.refcnt = pr->ndpr_refcnt;
+			pfx.flags = pr->ndpr_stateflags;
+			pfx.origin = PR_ORIG_RA;
+
+			p += sizeof(pfx); l += sizeof(pfx);
+
 			advrtrs = 0;
 			LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry) {
-				if ((void *)&sin6[advrtrs + 1] > (void *)pe) {
+				if (p + sizeof(sin6) > pe) {
 					advrtrs++;
 					continue;
 				}
-				s6 = &sin6[advrtrs];
-				sockaddr_in6_init(s6, &pfr->router->rtaddr,
+
+				sockaddr_in6_init(&sin6, &pfr->router->rtaddr,
 				    0, 0, 0);
-				if (sa6_recoverscope(s6)) {
+				if (sa6_recoverscope(&sin6)) {
 					log(LOG_ERR,
 					    "scope error in "
 					    "prefix list (%s)\n",
 					    ip6_sprintf(&pfr->router->rtaddr));
 				}
 				advrtrs++;
+				memcpy(p, &sin6, sizeof(sin6));
+				p += sizeof(sin6);
+				l += sizeof(sin6);
 			}
-			p->advrtrs = advrtrs;
+			pfx.advrtrs = advrtrs;
+			memcpy(ps, &pfx, sizeof(pfx));
 		}
 		else {
+			l += sizeof(pfx);
 			advrtrs = 0;
-			LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry)
+			LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry) {
 				advrtrs++;
+				l += sizeof(sin6);
+			}
 		}
-
-		advance = sizeof(*p) + sizeof(*sin6) * advrtrs;
-		l += advance;
-		if (p)
-			p = (struct in6_prefix *)((char *)p + advance);
 	}
 
 	if (oldp) {

Index: src/usr.sbin/ndp/ndp.c
diff -u src/usr.sbin/ndp/ndp.c:1.40 src/usr.sbin/ndp/ndp.c:1.40.4.1
--- src/usr.sbin/ndp/ndp.c:1.40	Wed Aug 31 13:32:38 2011
+++ src/usr.sbin/ndp/ndp.c	Tue Dec 17 20:47:32 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ndp.c,v 1.40 2011/08/31 13:32:38 joerg Exp $	*/
+/*	$NetBSD: ndp.c,v 1.40.4.1 2013/12/17 20:47:32 bouyer Exp $	*/
 /*	$KAME: ndp.c,v 1.121 2005/07/13 11:30:13 keiichi Exp $	*/
 
 /*
@@ -1132,9 +1132,8 @@ plist(void)
 {
 #ifdef ICMPV6CTL_ND6_PRLIST
 	int mib[] = { CTL_NET, PF_INET6, IPPROTO_ICMPV6, ICMPV6CTL_ND6_PRLIST };
-	char *buf;
-	struct in6_prefix *p, *ep, *n;
-	struct sockaddr_in6 *advrtr;
+	char *buf, *p, *ep;
+	struct in6_prefix pfx;
 	size_t l;
 	struct timeval tim;
 	const int niflags = NI_NUMERICHOST;
@@ -1155,17 +1154,17 @@ plist(void)
 		/*NOTREACHED*/
 	}
 
-	ep = (struct in6_prefix *)(void *)(buf + l);
-	for (p = (struct in6_prefix *)(void *)buf; p < ep; p = n) {
-		advrtr = (struct sockaddr_in6 *)(void *)(p + 1);
-		n = (struct in6_prefix *)(void *)&advrtr[p->advrtrs];
+	ep = buf + l;
+	for (p = buf; p < ep; ) {
+		memcpy(&pfx, p, sizeof(pfx));
+		p += sizeof(pfx);
 
-		if (getnameinfo((struct sockaddr *)(void *)&p->prefix,
-		    (socklen_t)p->prefix.sin6_len, namebuf, sizeof(namebuf),
+		if (getnameinfo((struct sockaddr*)&pfx.prefix,
+		    (socklen_t)pfx.prefix.sin6_len, namebuf, sizeof(namebuf),
 		    NULL, 0, niflags) != 0)
 			(void)strlcpy(namebuf, "?", sizeof(namebuf));
-		(void)printf("%s/%d if=%s\n", namebuf, p->prefixlen,
-		    if_indextoname((unsigned int)p->if_index, ifix_buf));
+		(void)printf("%s/%d if=%s\n", namebuf, pfx.prefixlen,
+		    if_indextoname((unsigned int)pfx.if_index, ifix_buf));
 
 		(void)gettimeofday(&tim, 0);
 		/*
@@ -1173,54 +1172,56 @@ plist(void)
 		 * by origin.  notify the difference to the users.
 		 */
 		(void)printf("flags=%s%s%s%s%s",
-		    p->raflags.onlink ? "L" : "",
-		    p->raflags.autonomous ? "A" : "",
-		    (p->flags & NDPRF_ONLINK) != 0 ? "O" : "",
-		    (p->flags & NDPRF_DETACHED) != 0 ? "D" : "",
+		    pfx.raflags.onlink ? "L" : "",
+		    pfx.raflags.autonomous ? "A" : "",
+		    (pfx.flags & NDPRF_ONLINK) != 0 ? "O" : "",
+		    (pfx.flags & NDPRF_DETACHED) != 0 ? "D" : "",
 #ifdef NDPRF_HOME
-		    (p->flags & NDPRF_HOME) != 0 ? "H" : ""
+		    (pfx.flags & NDPRF_HOME) != 0 ? "H" : ""
 #else
 		    ""
 #endif
 		    );
-		if (p->vltime == ND6_INFINITE_LIFETIME)
+		if (pfx.vltime == ND6_INFINITE_LIFETIME)
 			(void)printf(" vltime=infinity");
 		else
-			(void)printf(" vltime=%lu", (unsigned long)p->vltime);
-		if (p->pltime == ND6_INFINITE_LIFETIME)
+			(void)printf(" vltime=%lu", (unsigned long)pfx.vltime);
+		if (pfx.pltime == ND6_INFINITE_LIFETIME)
 			(void)printf(", pltime=infinity");
 		else
-			(void)printf(", pltime=%lu", (unsigned long)p->pltime);
-		if (p->expire == 0)
+			(void)printf(", pltime=%lu", (unsigned long)pfx.pltime);
+		if (pfx.expire == 0)
 			(void)printf(", expire=Never");
-		else if (p->expire >= tim.tv_sec)
+		else if (pfx.expire >= tim.tv_sec)
 			(void)printf(", expire=%s",
-			    sec2str(p->expire - tim.tv_sec));
+			    sec2str(pfx.expire - tim.tv_sec));
 		else
 			(void)printf(", expired");
-		(void)printf(", ref=%d", p->refcnt);
+		(void)printf(", ref=%d", pfx.refcnt);
 		(void)printf("\n");
 		/*
 		 * "advertising router" list is meaningful only if the prefix
 		 * information is from RA.
 		 */
-		if (p->advrtrs) {
+		if (pfx.advrtrs) {
 			int j;
-			struct sockaddr_in6 *sin6;
+			struct sockaddr_in6 sin6;
 
-			sin6 = advrtr;
 			(void)printf("  advertised by\n");
-			for (j = 0; j < p->advrtrs; j++) {
+			for (j = 0; j < pfx.advrtrs && p <= ep; j++) {
 				struct in6_nbrinfo *nbi;
 
-				if (getnameinfo((struct sockaddr *)(void *)sin6,
-				    (socklen_t)sin6->sin6_len, namebuf,
+				memcpy(&sin6, p, sizeof(sin6));
+				p += sizeof(sin6);
+
+				if (getnameinfo((struct sockaddr *)&sin6,
+				    (socklen_t)sin6.sin6_len, namebuf,
 				    sizeof(namebuf), NULL, 0, ninflags) != 0)
 					(void)strlcpy(namebuf, "?", sizeof(namebuf));
 				(void)printf("    %s", namebuf);
 
-				nbi = getnbrinfo(&sin6->sin6_addr,
-				    (unsigned int)p->if_index, 0);
+				nbi = getnbrinfo(&sin6.sin6_addr,
+				    (unsigned int)pfx.if_index, 0);
 				if (nbi) {
 					switch (nbi->state) {
 					case ND6_LLINFO_REACHABLE:
@@ -1234,7 +1235,6 @@ plist(void)
 					}
 				} else
 					(void)printf(" (no neighbor state)\n");
-				sin6++;
 			}
 		} else
 			(void)printf("  No advertising router\n");

Reply via email to