diff options
author | hrs <hrs@FreeBSD.org> | 2013-08-17 22:13:26 +0000 |
---|---|---|
committer | hrs <hrs@FreeBSD.org> | 2013-08-17 22:13:26 +0000 |
commit | a4ad03957c9e4d1a979969ba9330827e96448199 (patch) | |
tree | ad71e269d6786ea133ba973d6698ad8773bdce85 /usr.sbin/rtsold | |
parent | 58170e2ce592ec9ff76d80a6f9c60ef36857ed03 (diff) | |
download | FreeBSD-src-a4ad03957c9e4d1a979969ba9330827e96448199.zip FreeBSD-src-a4ad03957c9e4d1a979969ba9330827e96448199.tar.gz |
Use sysctl(ICMPV6CTL_ND6_DRLIST) instead of SIOCGDRLST_IN6 ioctl.
Diffstat (limited to 'usr.sbin/rtsold')
-rw-r--r-- | usr.sbin/rtsold/probe.c | 67 |
1 files changed, 39 insertions, 28 deletions
diff --git a/usr.sbin/rtsold/probe.c b/usr.sbin/rtsold/probe.c index ac733c9..5ec54aa 100644 --- a/usr.sbin/rtsold/probe.c +++ b/usr.sbin/rtsold/probe.c @@ -35,6 +35,7 @@ #include <sys/types.h> #include <sys/ioctl.h> #include <sys/socket.h> +#include <sys/sysctl.h> #include <sys/uio.h> #include <sys/queue.h> @@ -102,41 +103,51 @@ probe_init(void) void defrouter_probe(struct ifinfo *ifinfo) { - u_char ntopbuf[INET6_ADDRSTRLEN]; - struct in6_drlist dr; - int s, i; - int ifindex = ifinfo->sdl->sdl_index; + struct in6_defrouter *p, *ep; + int ifindex, mib[4]; + char *buf, ntopbuf[INET6_ADDRSTRLEN]; + size_t l; - if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { - warnmsg(LOG_ERR, __func__, "socket: %s", strerror(errno)); + ifindex = ifinfo->sdl->sdl_index; + if (ifindex == 0) + return; + mib[0] = CTL_NET; + mib[1] = PF_INET6; + mib[2] = IPPROTO_ICMPV6; + mib[3] = ICMPV6CTL_ND6_DRLIST; + if (sysctl(mib, nitems(mib), NULL, &l, NULL, 0) < 0) { + warnmsg(LOG_ERR, __func__, "sysctl(ICMPV6CTL_ND6_DRLIST): %s", + strerror(errno)); return; } - memset(&dr, 0, sizeof(dr)); - strlcpy(dr.ifname, "lo0", sizeof dr.ifname); /* dummy interface */ - if (ioctl(s, SIOCGDRLST_IN6, (caddr_t)&dr) < 0) { - warnmsg(LOG_ERR, __func__, "ioctl(SIOCGDRLST_IN6): %s", + if (l == 0) + return; + buf = malloc(l); + if (buf == NULL) { + warnmsg(LOG_ERR, __func__, "malloc(): %s", strerror(errno)); + return; + } + if (sysctl(mib, nitems(mib), buf, &l, NULL, 0) < 0) { + warnmsg(LOG_ERR, __func__, "sysctl(ICMPV6CTL_ND6_DRLIST): %s", strerror(errno)); - goto closeandend; + free(buf); + return; } - - for (i = 0; i < DRLSTSIZ && dr.defrouter[i].if_index; i++) { - if (ifindex && dr.defrouter[i].if_index == ifindex) { - /* sanity check */ - if (!IN6_IS_ADDR_LINKLOCAL(&dr.defrouter[i].rtaddr)) { - warnmsg(LOG_ERR, __func__, - "default router list contains a " - "non-link-local address(%s)", - inet_ntop(AF_INET6, - &dr.defrouter[i].rtaddr, - ntopbuf, INET6_ADDRSTRLEN)); - continue; /* ignore the address */ - } - sendprobe(&dr.defrouter[i].rtaddr, ifinfo); + ep = (struct in6_defrouter *)(void *)(buf + l); + for (p = (struct in6_defrouter *)(void *)buf; p < ep; p++) { + if (ifindex != p->if_index) + continue; + if (!IN6_IS_ADDR_LINKLOCAL(&p->rtaddr.sin6_addr)) { + warnmsg(LOG_ERR, __func__, + "default router list contains a " + "non-link-local address(%s)", + inet_ntop(AF_INET6, &p->rtaddr.sin6_addr, ntopbuf, + INET6_ADDRSTRLEN)); + continue; /* ignore the address */ } + sendprobe(&p->rtaddr.sin6_addr, ifinfo); } - -closeandend: - close(s); + free(buf); } static void |