static void probe_free_cb(void *vpt) { probe_t *pt = vpt; if(pt == NULL) return; if(pt->buf != NULL && pt->buf != pktbuf) free(pt->buf); if(pt->rt != NULL) scamper_route_free(pt->rt); if(pt->dlhdr != NULL) scamper_dlhdr_free(pt->dlhdr); free(pt); return; }
static void rtsock_parsemsg(uint8_t *buf, size_t len) { struct nlmsghdr *nlmsg; struct nlmsgerr *nlerr; struct rtmsg *rtmsg; struct rtattr *rta; void *gwa = NULL; int ifindex = -1; scamper_addr_t *gw = NULL; rtsock_pair_t *pair = NULL; scamper_route_t *route = NULL; if(len < sizeof(struct nlmsghdr)) { scamper_debug(__func__, "len %d != %d", len, sizeof(struct nlmsghdr)); return; } nlmsg = (struct nlmsghdr *)buf; /* if the message isn't addressed to this pid, drop it */ if(nlmsg->nlmsg_pid != pid) return; if((pair = rtsock_pair_get(nlmsg->nlmsg_seq)) == NULL) return; route = pair->route; rtsock_pair_free(pair); if(nlmsg->nlmsg_type == RTM_NEWROUTE) { rtmsg = NLMSG_DATA(nlmsg); /* this is the payload length of the response packet */ len = nlmsg->nlmsg_len - NLMSG_LENGTH(sizeof(struct rtmsg)); /* hunt through the payload for the RTA_OIF entry */ rta = RTM_RTA(rtmsg); while(RTA_OK(rta, len)) { switch(rta->rta_type) { case RTA_OIF: ifindex = *(unsigned *)RTA_DATA(rta); break; case RTA_GATEWAY: gwa = RTA_DATA(rta); break; } rta = RTA_NEXT(rta, len); } if(gwa != NULL) { if(rtmsg->rtm_family == AF_INET) gw = scamper_addrcache_get_ipv4(addrcache, gwa); else if(rtmsg->rtm_family == AF_INET6) gw = scamper_addrcache_get_ipv6(addrcache, gwa); else route->error = EINVAL; } } else if(nlmsg->nlmsg_type == NLMSG_ERROR) { nlerr = NLMSG_DATA(nlmsg); route->error = nlerr->error; } else goto skip; route->gw = gw; route->ifindex = ifindex; route->cb(route); return; skip: if(route != NULL) scamper_route_free(route); return; }