static int fd_addr_cmp(int type, void *a, void *b) { assert(type == SCAMPER_FD_TYPE_TCP4 || type == SCAMPER_FD_TYPE_TCP6 || type == SCAMPER_FD_TYPE_UDP4 || type == SCAMPER_FD_TYPE_UDP6 || type == SCAMPER_FD_TYPE_UDP4DG || type == SCAMPER_FD_TYPE_ICMP4 || type == SCAMPER_FD_TYPE_ICMP6); if(a == NULL && b != NULL) return -1; if(a != NULL && b == NULL) return 1; if(a == NULL && b == NULL) return 0; if(type == SCAMPER_FD_TYPE_TCP4 || type == SCAMPER_FD_TYPE_UDP4 || type == SCAMPER_FD_TYPE_UDP4DG || type == SCAMPER_FD_TYPE_ICMP4) return addr4_cmp(a, b); else return addr6_cmp(a, b); }
int scamper_if_getifindex_byaddr(const struct sockaddr *addr, int *ifindex) { struct ifaddrs *ifa = NULL, *ifp; int rc; if(getifaddrs(&ifa) != 0) goto err; for(ifp = ifa; ifp != NULL; ifp = ifp->ifa_next) { if(ifp->ifa_addr == NULL || ifp->ifa_addr->sa_family != addr->sa_family) continue; if(addr->sa_family == AF_INET) rc = addr4_cmp(&((struct sockaddr_in *)addr)->sin_addr, &((struct sockaddr_in *)ifp->ifa_addr)->sin_addr); else if(addr->sa_family == AF_INET6) rc = addr6_cmp(&((struct sockaddr_in6 *)addr)->sin6_addr, &((struct sockaddr_in6 *)ifp->ifa_addr)->sin6_addr); else goto err; if(rc == 0) break; } if(ifp == NULL) { errno = ENOENT; goto err; } rc = scamper_if_getifindex(ifp->ifa_name, ifindex); freeifaddrs(ifa); return rc; err: if(ifa != NULL) freeifaddrs(ifa); return -1; }