diff options
-rw-r--r-- | sys/netinet6/nd6.c | 82 | ||||
-rw-r--r-- | usr.sbin/ndp/ndp.c | 68 |
2 files changed, 76 insertions, 74 deletions
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 31110312523..1f6dca27246 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6.c,v 1.145 2015/08/19 13:27:38 bluhm Exp $ */ +/* $OpenBSD: nd6.c,v 1.146 2015/08/23 14:12:05 naddy Exp $ */ /* $KAME: nd6.c,v 1.280 2002/06/08 19:52:07 itojun Exp $ */ /* @@ -1865,45 +1865,43 @@ fill_prlist(void *oldp, size_t *oldlenp, size_t ol) { int error = 0, s; struct nd_prefix *pr; - struct in6_prefix *p = NULL; - struct in6_prefix *pe = NULL; + char *p = NULL, *ps = NULL; + char *pe = NULL; size_t l; s = splsoftnet(); if (oldp) { - p = (struct in6_prefix *)oldp; - pe = (struct in6_prefix *)((caddr_t)oldp + *oldlenp); + ps = p = (char *)oldp; + pe = (char *)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; char addr[INET6_ADDRSTRLEN]; - if (oldp && p + 1 <= pe) - { - bzero(p, sizeof(*p)); - sin6 = (struct sockaddr_in6 *)(p + 1); + if (oldp && p + sizeof(struct in6_prefix) <= pe) { + memset(&pfx, 0, sizeof(pfx)); + ps = p; - p->prefix = pr->ndpr_prefix; - if (in6_recoverscope(&p->prefix, - &p->prefix.sin6_addr, pr->ndpr_ifp) != 0) + pfx.prefix = pr->ndpr_prefix; + if (in6_recoverscope(&pfx.prefix, + &pfx.prefix.sin6_addr, pr->ndpr_ifp) != 0) log(LOG_ERR, "scope error in prefix list (%s)\n", - inet_ntop(AF_INET6, &p->prefix.sin6_addr, + inet_ntop(AF_INET6, &pfx.prefix.sin6_addr, addr, sizeof(addr))); - 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; @@ -1912,40 +1910,44 @@ fill_prlist(void *oldp, size_t *oldlenp, size_t ol) ((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]; - s6->sin6_family = AF_INET6; - s6->sin6_len = sizeof(struct sockaddr_in6); - s6->sin6_addr = pfr->router->rtaddr; - in6_recoverscope(s6, &pfr->router->rtaddr, + sin6.sin6_family = AF_INET6; + sin6.sin6_len = sizeof(struct sockaddr_in6); + sin6.sin6_addr = pfr->router->rtaddr; + in6_recoverscope(&sin6, &pfr->router->rtaddr, pfr->router->ifp); 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 *)((caddr_t)p + advance); } if (oldp) { diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c index 46c12698287..881d897d940 100644 --- a/usr.sbin/ndp/ndp.c +++ b/usr.sbin/ndp/ndp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ndp.c,v 1.61 2015/06/03 08:10:53 mpi Exp $ */ +/* $OpenBSD: ndp.c,v 1.62 2015/08/23 14:12:05 naddy Exp $ */ /* $KAME: ndp.c,v 1.101 2002/07/17 08:46:33 itojun Exp $ */ /* @@ -1043,9 +1043,8 @@ void plist(void) { 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 now; const int niflags = NI_NUMERICHOST; @@ -1066,17 +1065,17 @@ plist(void) /*NOTREACHED*/ } - ep = (struct in6_prefix *)(buf + l); - for (p = (struct in6_prefix *)buf; p < ep; p = n) { - advrtr = (struct sockaddr_in6 *)(p + 1); - n = (struct in6_prefix *)&advrtr[p->advrtrs]; + ep = buf + l; + for (p = buf; p < ep; ) { + memcpy(&pfx, p, sizeof(pfx)); + p += sizeof(pfx); - if (getnameinfo((struct sockaddr *)&p->prefix, - p->prefix.sin6_len, namebuf, sizeof(namebuf), + if (getnameinfo((struct sockaddr *)&pfx.prefix, + pfx.prefix.sin6_len, namebuf, sizeof(namebuf), NULL, 0, niflags) != 0) strlcpy(namebuf, "?", sizeof(namebuf)); - printf("%s/%d if=%s\n", namebuf, p->prefixlen, - if_indextoname(p->if_index, ifix_buf)); + printf("%s/%d if=%s\n", namebuf, pfx.prefixlen, + if_indextoname(pfx.if_index, ifix_buf)); gettimeofday(&now, 0); /* @@ -1084,50 +1083,52 @@ plist(void) * by origin. notify the difference to the users. */ 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" : "", - (p->flags & NDPRF_HOME) != 0 ? "H" : "" + pfx.raflags.onlink ? "L" : "", + pfx.raflags.autonomous ? "A" : "", + (pfx.flags & NDPRF_ONLINK) != 0 ? "O" : "", + (pfx.flags & NDPRF_DETACHED) != 0 ? "D" : "", + (pfx.flags & NDPRF_HOME) != 0 ? "H" : "" ); - if (p->vltime == ND6_INFINITE_LIFETIME) + if (pfx.vltime == ND6_INFINITE_LIFETIME) printf(" vltime=infinity"); else - printf(" vltime=%lu", (unsigned long)p->vltime); - if (p->pltime == ND6_INFINITE_LIFETIME) + printf(" vltime=%lu", (unsigned long)pfx.vltime); + if (pfx.pltime == ND6_INFINITE_LIFETIME) printf(", pltime=infinity"); else - printf(", pltime=%lu", (unsigned long)p->pltime); - if (p->expire == 0) + printf(", pltime=%lu", (unsigned long)pfx.pltime); + if (pfx.expire == 0) printf(", expire=Never"); - else if (p->expire >= now.tv_sec) + else if (pfx.expire >= now.tv_sec) printf(", expire=%s", - sec2str(p->expire - now.tv_sec)); + sec2str(pfx.expire - now.tv_sec)); else printf(", expired"); - printf(", ref=%d", p->refcnt); + printf(", ref=%d", pfx.refcnt); 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; 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 *)sin6, - sin6->sin6_len, namebuf, sizeof(namebuf), + memcpy(&sin6, p, sizeof(sin6)); + p += sizeof(sin6); + + if (getnameinfo((struct sockaddr *)&sin6, + sin6.sin6_len, namebuf, sizeof(namebuf), NULL, 0, ninflags) != 0) strlcpy(namebuf, "?", sizeof(namebuf)); printf(" %s", namebuf); - nbi = getnbrinfo(&sin6->sin6_addr, - p->if_index, 0); + nbi = getnbrinfo(&sin6.sin6_addr, + pfx.if_index, 0); if (nbi) { switch (nbi->state) { case ND6_LLINFO_REACHABLE: @@ -1141,7 +1142,6 @@ plist(void) } } else printf(" (no neighbor state)\n"); - sin6++; } } else printf(" No advertising router\n"); |