static void nl_parse_link_msg(struct nlmsghdr *nlp, struct nl_cb *cb) { nl_link_cb link_cb; struct ifinfomsg *ifinfo; struct rtattr *rtap; struct nl_link link; size_t len; memset(&link, 0, sizeof(struct nl_link)); ifinfo = NLMSG_DATA(nlp); rtap = IFLA_RTA(ifinfo); len = IFLA_PAYLOAD(nlp); for (; RTA_OK(rtap, len); rtap = RTA_NEXT(rtap, len)) { switch (rtap->rta_type) { case IFLA_IFNAME: link.ifname = (char *)RTA_DATA(rtap); break; case IFLA_ADDRESS: if (RTA_PAYLOAD(rtap) != sizeof(struct ether_addr)) { XLOG_ERR("invalid ll address for %u", ifinfo->ifi_index); return; } link.ifaddr = (struct ether_addr *)RTA_DATA(rtap); break; default: /* XLOG_DEBUG("attr: %u", rtap->rta_type); */ break; } } if (!link.ifname) { XLOG_ERR("could not get name for link %u", ifinfo->ifi_index); return; } if (!link.ifaddr) { XLOG_ERR("could not get ll addr for link %u", ifinfo->ifi_index); return; } link.ifindex = ifinfo->ifi_index; link.iftype = ifinfo->ifi_type; link.ifflags = ifinfo->ifi_flags; link_cb = (nl_link_cb) cb->parse_cb; link_cb(&link, cb->aux); }
void const * algae_list_elimination( algae_list_t const * const xs, algae_list_nil_callback_t const nil_cb, algae_list_link_callback_t const link_cb) { ALGAE_LIST_VALIDATE(xs); assert(nil_cb != NULL); assert(link_cb != NULL); switch (xs->constructor) { /* e₀ : cRT (nil A). e₁ : (Π x : A . (Π xs : List A . (Π ⌊xs⌋ : cRT xs . cRT (link A x xs) ) ) ). A (nil A) cRT e₀ e₁ ↦ e₀, A (link A x xs) cRT e₀ e₁ ↦ e₁ x xs (List-elimination A xs cRT e₀ e₁) */ case ALGAE_LIST_NIL_CONSTRUCTOR: return nil_cb(); case ALGAE_LIST_LINK_CONSTRUCTOR: return link_cb(algae_list_elimination( xs->data.link.ws, nil_cb, link_cb), xs->data.link.w); default: abort(); /* not reached */ } abort(); /* not reached */ }