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.
This commit is contained in:
parent
3b480d7c2c
commit
89c87ea341
@ -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 $ */
|
/* $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -31,7 +31,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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"
|
#include "opt_ipsec.h"
|
||||||
|
|
||||||
@ -2385,44 +2385,43 @@ fill_prlist(void *oldp, size_t *oldlenp, size_t ol)
|
|||||||
{
|
{
|
||||||
int error = 0, s;
|
int error = 0, s;
|
||||||
struct nd_prefix *pr;
|
struct nd_prefix *pr;
|
||||||
struct in6_prefix *p = NULL;
|
uint8_t *p = NULL, *ps = NULL;
|
||||||
struct in6_prefix *pe = NULL;
|
uint8_t *pe = NULL;
|
||||||
size_t l;
|
size_t l;
|
||||||
|
|
||||||
s = splsoftnet();
|
s = splsoftnet();
|
||||||
|
|
||||||
if (oldp) {
|
if (oldp) {
|
||||||
p = (struct in6_prefix *)oldp;
|
ps = p = (uint8_t*)oldp;
|
||||||
pe = (struct in6_prefix *)((char *)oldp + *oldlenp);
|
pe = (uint8_t*)oldp + *oldlenp;
|
||||||
}
|
}
|
||||||
l = 0;
|
l = 0;
|
||||||
|
|
||||||
LIST_FOREACH(pr, &nd_prefix, ndpr_entry) {
|
LIST_FOREACH(pr, &nd_prefix, ndpr_entry) {
|
||||||
u_short advrtrs;
|
u_short advrtrs;
|
||||||
size_t advance;
|
struct sockaddr_in6 sin6;
|
||||||
struct sockaddr_in6 *sin6;
|
|
||||||
struct sockaddr_in6 *s6;
|
|
||||||
struct nd_pfxrouter *pfr;
|
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));
|
memset(&pfx, 0, sizeof(pfx));
|
||||||
sin6 = (struct sockaddr_in6 *)(p + 1);
|
ps = p;
|
||||||
|
pfx.prefix = pr->ndpr_prefix;
|
||||||
|
|
||||||
p->prefix = pr->ndpr_prefix;
|
if (sa6_recoverscope(&pfx.prefix)) {
|
||||||
if (sa6_recoverscope(&p->prefix)) {
|
|
||||||
log(LOG_ERR,
|
log(LOG_ERR,
|
||||||
"scope error in prefix list (%s)\n",
|
"scope error in prefix list (%s)\n",
|
||||||
ip6_sprintf(&p->prefix.sin6_addr));
|
ip6_sprintf(&pfx.prefix.sin6_addr));
|
||||||
/* XXX: press on... */
|
/* XXX: press on... */
|
||||||
}
|
}
|
||||||
p->raflags = pr->ndpr_raf;
|
pfx.raflags = pr->ndpr_raf;
|
||||||
p->prefixlen = pr->ndpr_plen;
|
pfx.prefixlen = pr->ndpr_plen;
|
||||||
p->vltime = pr->ndpr_vltime;
|
pfx.vltime = pr->ndpr_vltime;
|
||||||
p->pltime = pr->ndpr_pltime;
|
pfx.pltime = pr->ndpr_pltime;
|
||||||
p->if_index = pr->ndpr_ifp->if_index;
|
pfx.if_index = pr->ndpr_ifp->if_index;
|
||||||
if (pr->ndpr_vltime == ND6_INFINITE_LIFETIME)
|
if (pr->ndpr_vltime == ND6_INFINITE_LIFETIME)
|
||||||
p->expire = 0;
|
pfx.expire = 0;
|
||||||
else {
|
else {
|
||||||
time_t maxexpire;
|
time_t maxexpire;
|
||||||
|
|
||||||
@ -2432,43 +2431,48 @@ fill_prlist(void *oldp, size_t *oldlenp, size_t ol)
|
|||||||
((sizeof(maxexpire) * 8) - 1));
|
((sizeof(maxexpire) * 8) - 1));
|
||||||
if (pr->ndpr_vltime <
|
if (pr->ndpr_vltime <
|
||||||
maxexpire - pr->ndpr_lastupdate) {
|
maxexpire - pr->ndpr_lastupdate) {
|
||||||
p->expire = pr->ndpr_lastupdate +
|
pfx.expire = pr->ndpr_lastupdate +
|
||||||
pr->ndpr_vltime;
|
pr->ndpr_vltime;
|
||||||
} else
|
} else
|
||||||
p->expire = maxexpire;
|
pfx.expire = maxexpire;
|
||||||
}
|
}
|
||||||
p->refcnt = pr->ndpr_refcnt;
|
pfx.refcnt = pr->ndpr_refcnt;
|
||||||
p->flags = pr->ndpr_stateflags;
|
pfx.flags = pr->ndpr_stateflags;
|
||||||
p->origin = PR_ORIG_RA;
|
pfx.origin = PR_ORIG_RA;
|
||||||
|
|
||||||
|
p += sizeof(pfx); l += sizeof(pfx);
|
||||||
|
|
||||||
advrtrs = 0;
|
advrtrs = 0;
|
||||||
LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry) {
|
LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry) {
|
||||||
if ((void *)&sin6[advrtrs + 1] > (void *)pe) {
|
if (p + sizeof(sin6) > pe) {
|
||||||
advrtrs++;
|
advrtrs++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
s6 = &sin6[advrtrs];
|
|
||||||
sockaddr_in6_init(s6, &pfr->router->rtaddr,
|
sockaddr_in6_init(&sin6, &pfr->router->rtaddr,
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (sa6_recoverscope(s6)) {
|
if (sa6_recoverscope(&sin6)) {
|
||||||
log(LOG_ERR,
|
log(LOG_ERR,
|
||||||
"scope error in "
|
"scope error in "
|
||||||
"prefix list (%s)\n",
|
"prefix list (%s)\n",
|
||||||
ip6_sprintf(&pfr->router->rtaddr));
|
ip6_sprintf(&pfr->router->rtaddr));
|
||||||
}
|
}
|
||||||
advrtrs++;
|
advrtrs++;
|
||||||
|
memcpy(p, &sin6, sizeof(sin6));
|
||||||
|
p += sizeof(sin6);
|
||||||
|
l += sizeof(sin6);
|
||||||
}
|
}
|
||||||
p->advrtrs = advrtrs;
|
pfx.advrtrs = advrtrs;
|
||||||
|
memcpy(ps, &pfx, sizeof(pfx));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
l += sizeof(pfx);
|
||||||
advrtrs = 0;
|
advrtrs = 0;
|
||||||
LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry)
|
LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry) {
|
||||||
advrtrs++;
|
advrtrs++;
|
||||||
|
l += sizeof(sin6);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
advance = sizeof(*p) + sizeof(*sin6) * advrtrs;
|
|
||||||
l += advance;
|
|
||||||
if (p)
|
|
||||||
p = (struct in6_prefix *)((char *)p + advance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldp) {
|
if (oldp) {
|
||||||
|
Loading…
Reference in New Issue
Block a user