/* * Probe if each router in the default router list is still alive. */ void defrouter_probe(struct ifinfo *ifinfo) { struct in6_defrouter *p, *ep; int ifindex, mib[4]; char *buf, ntopbuf[INET6_ADDRSTRLEN]; size_t l; 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; } 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)); free(buf); return; } 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); } free(buf); }
/* * Probe if each router in the default router list is still alive. */ void defrouter_probe(int ifindex) { struct in6_drlist dr; int s, i; u_char ntopbuf[INET6_ADDRSTRLEN]; if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { warnmsg(LOG_ERR, __FUNCTION__, "socket: %s", strerror(errno)); return; } bzero(&dr, sizeof(dr)); strlcpy(dr.ifname, "lo0", sizeof(dr.ifname)); /* dummy interface */ if (ioctl(s, SIOCGDRLST_IN6, (caddr_t)&dr) < 0) { warnmsg(LOG_ERR, __FUNCTION__, "ioctl(SIOCGDRLST_IN6): %s", strerror(errno)); goto closeandend; } for(i = 0; dr.defrouter[i].if_index && i < PRLSTSIZ; i++) { if (ifindex && dr.defrouter[i].if_index == ifindex) { /* sanity check */ if (!IN6_IS_ADDR_LINKLOCAL(&dr.defrouter[i].rtaddr)) { warnmsg(LOG_ERR, __FUNCTION__, "default router list contains a " "non-linklocal address(%s)", inet_ntop(AF_INET6, &dr.defrouter[i].rtaddr, (char *)ntopbuf, INET6_ADDRSTRLEN)); continue; /* ignore the address */ } sendprobe(&dr.defrouter[i].rtaddr, dr.defrouter[i].if_index); } } closeandend: close(s); return; }