- struct {
- struct nlmsghdr nhm;
- struct ifaddrmsg ifa;
- } req = {{sizeof(req), RTM_GETADDR, NLM_F_REQUEST | NLM_F_DUMP,
- ++rtnl_seq, 0}, {AF_INET6, 0, 0, 0, ifindex}};
- if (send(rtnl_socket, &req, sizeof(req), 0) < (ssize_t)sizeof(req)) {
- syslog(LOG_WARNING, "Request failed to dump IPv6 addresses (%s)", strerror(errno));
- return 0;
+ struct addr_info *ctxt = (struct addr_info *)arg;
+ struct odhcpd_ipaddr *addrs = *(ctxt->addrs);
+ struct nlmsghdr *hdr = nlmsg_hdr(msg);
+ struct ifaddrmsg *ifa;
+ struct nlattr *nla[__IFA_MAX];
+
+ if (hdr->nlmsg_type != RTM_NEWADDR)
+ return NL_SKIP;
+
+ ifa = NLMSG_DATA(hdr);
+ if (ifa->ifa_scope != RT_SCOPE_UNIVERSE ||
+ (ctxt->ifindex && ifa->ifa_index != (unsigned)ctxt->ifindex))
+ return NL_SKIP;
+
+ nlmsg_parse(hdr, sizeof(*ifa), nla, __IFA_MAX - 1, NULL);
+ if (!nla[IFA_ADDRESS])
+ return NL_SKIP;
+
+ addrs = realloc(addrs, sizeof(*addrs)*(ctxt->ret + 1));
+ if (!addrs)
+ return NL_SKIP;
+
+ memset(&addrs[ctxt->ret], 0, sizeof(addrs[ctxt->ret]));
+ addrs[ctxt->ret].prefix = ifa->ifa_prefixlen;
+
+ nla_memcpy(&addrs[ctxt->ret].addr, nla[IFA_ADDRESS],
+ sizeof(addrs[ctxt->ret].addr));
+
+ if (nla[IFA_CACHEINFO]) {
+ struct ifa_cacheinfo *ifc = nla_data(nla[IFA_CACHEINFO]);
+
+ addrs[ctxt->ret].preferred = ifc->ifa_prefered;
+ addrs[ctxt->ret].valid = ifc->ifa_valid;