Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-6-0]: src Pull up following revision(s) (requested by martin in t...



details:   https://anonhg.NetBSD.org/src/rev/2099c49edf99
branches:  netbsd-6-0
changeset: 774890:2099c49edf99
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Tue Dec 17 20:47:43 2013 +0000

description:
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.

diffstat:

 sys/netinet6/nd6.c |  78 ++++++++++++++++++++++++++++-------------------------
 usr.sbin/ndp/ndp.c |  68 +++++++++++++++++++++++-----------------------
 2 files changed, 75 insertions(+), 71 deletions(-)

diffs (279 lines):

diff -r 5a2683fb0dfe -r 2099c49edf99 sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c        Sat Dec 14 19:37:40 2013 +0000
+++ b/sys/netinet6/nd6.c        Tue Dec 17 20:47:43 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6.c,v 1.141.6.1 2013/07/08 07:40:34 jdc Exp $        */
+/*     $NetBSD: nd6.c,v 1.141.6.2 2013/12/17 20:47:43 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.6.1 2013/07/08 07:40:34 jdc Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.141.6.2 2013/12/17 20:47:43 bouyer Exp $");
 
 #include "opt_ipsec.h"
 
@@ -2387,44 +2387,43 @@
 {
        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 @@
                                    ((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) {
diff -r 5a2683fb0dfe -r 2099c49edf99 usr.sbin/ndp/ndp.c
--- a/usr.sbin/ndp/ndp.c        Sat Dec 14 19:37:40 2013 +0000
+++ b/usr.sbin/ndp/ndp.c        Tue Dec 17 20:47:43 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ndp.c,v 1.40 2011/08/31 13:32:38 joerg Exp $   */
+/*     $NetBSD: ndp.c,v 1.40.10.1 2013/12/17 20:47:43 bouyer Exp $     */
 /*     $KAME: ndp.c,v 1.121 2005/07/13 11:30:13 keiichi Exp $  */
 
 /*
@@ -1132,9 +1132,8 @@
 {
 #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 @@
                /*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 @@
                 * 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 @@
                                        }
                                } else
                                        (void)printf(" (no neighbor state)\n");
-                               sin6++;
                        }
                } else
                        (void)printf("  No advertising router\n");



Home | Main Index | Thread Index | Old Index