-struct addr_info {
- int ifindex;
- struct odhcpd_ipaddr *addrs;
- size_t addrs_sz;
- int pending;
- ssize_t ret;
-};
-
-static int cb_valid_handler(struct nl_msg *msg, void *arg)
-{
- struct addr_info *ctxt = (struct addr_info *)arg;
- struct nlmsghdr *hdr = nlmsg_hdr(msg);
- struct ifaddrmsg *ifa;
- struct nlattr *nla[__IFA_MAX];
-
- if (hdr->nlmsg_type != RTM_NEWADDR || ctxt->ret >= (ssize_t)ctxt->addrs_sz)
- 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;
-
- memset(&ctxt->addrs[ctxt->ret], 0, sizeof(ctxt->addrs[ctxt->ret]));
- ctxt->addrs[ctxt->ret].prefix = ifa->ifa_prefixlen;
-
- nla_memcpy(&ctxt->addrs[ctxt->ret].addr, nla[IFA_ADDRESS],
- sizeof(ctxt->addrs[ctxt->ret].addr));
-
- if (nla[IFA_CACHEINFO]) {
- struct ifa_cacheinfo *ifc = nla_data(nla[IFA_CACHEINFO]);
-
- ctxt->addrs[ctxt->ret].preferred = ifc->ifa_prefered;
- ctxt->addrs[ctxt->ret].valid = ifc->ifa_valid;
- }
-
- if (ifa->ifa_flags & IFA_F_DEPRECATED)
- ctxt->addrs[ctxt->ret].preferred = 0;
-
- ctxt->ret++;
-
- return NL_OK;
-}
-
-static int cb_finish_handler(_unused struct nl_msg *msg, void *arg)
-{
- struct addr_info *ctxt = (struct addr_info *)arg;
-
- ctxt->pending = 0;
-
- return NL_STOP;
-}
-
-static int cb_error_handler(_unused struct sockaddr_nl *nla, struct nlmsgerr *err,
- void *arg)
-{
- struct addr_info *ctxt = (struct addr_info *)arg;
-
- ctxt->pending = 0;
- ctxt->ret = err->error;
-
- return NL_STOP;
-}