Module Name:    src
Committed By:   martin
Date:           Tue Dec 17 20:25:00 UTC 2013

Modified Files:
        src/sys/netinet6: nd6.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.145 -r1.146 src/sys/netinet6/nd6.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.145 src/sys/netinet6/nd6.c:1.146
--- src/sys/netinet6/nd6.c:1.145	Tue May 21 08:37:27 2013
+++ src/sys/netinet6/nd6.c	Tue Dec 17 20:25:00 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: nd6.c,v 1.145 2013/05/21 08:37:27 roy Exp $	*/
+/*	$NetBSD: nd6.c,v 1.146 2013/12/17 20:25:00 martin 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.145 2013/05/21 08:37:27 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.146 2013/12/17 20:25:00 martin Exp $");
 
 #include "opt_ipsec.h"
 
@@ -2385,44 +2385,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;
 
@@ -2432,43 +2431,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) {

Reply via email to