Created
June 6, 2018 18:50
-
-
Save NattyNarwhal/96c02589ff4ff94187095f72a9f76bd2 to your computer and use it in GitHub Desktop.
Try 3 of PAL networking hack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Works on AIX, but doesn't on i because ifr_name is NOT THE DEVICE NAME ON i! | |
// On i, ifr_name returns the IP address; if_nameindex returns the real OS/400 | |
// names, but SIOCGIFCONF won't, and thus we need a new way to enumerate... | |
#elif HAVE_SIOCGIFCONF | |
// Adapted from Mono's networking-posix.c. | |
packetInfo->InterfaceIndex = 0; | |
struct ifconf ifc; | |
struct ifreq *ifr; | |
int fd; | |
fd = socket (AF_INET, SOCK_DGRAM, 0); | |
if (fd == -1) | |
return 1; // just assume 0, like the getifaddrs case | |
// heap alloc instead of stack because there's a lot | |
memset (&ifc, 0, sizeof (ifc)); | |
ifc.ifc_len = 1024; | |
ifc.ifc_buf = (char *)malloc (1024); | |
if (ioctl (fd, SIOCGIFCONF, &ifc) < 0) | |
goto done; | |
for (ifr = ifc.ifc_req; | |
ifr < (struct ifreq*)((char*)(ifc).ifc_req + (ifc).ifc_len); | |
ifr = (struct ifreq*)((char*)(ifr) + sizeof (struct ifreq))) | |
{ | |
in_addr_t ipv4; | |
sa_family_t family; | |
// ifr_link and fd2 are for getting the IP if it's an AF_LINK, | |
// and we can't declare them inside of the switch block. | |
struct ifreq ifr_link; | |
int fd2, if_idx; | |
ipv4 = 0; | |
if_idx = if_nametoindex(ifr->ifr_name); | |
if (!if_idx) // 0 index is error, so a skippable interface | |
continue; | |
family = ifr->ifr_addr.sa_family; | |
if (!(family == AF_INET || family == AF_LINK)) | |
continue; // we want interfaces that have IPv4 and what could be v4 | |
switch (family) | |
{ | |
// HACK: AIX has en* interfaces as AF_LINK; you can't get a sockaddr_in | |
// out of them without having to perform this extra step | |
case AF_LINK: | |
strncpy (ifr_link.ifr_name, ifr->ifr_name, IFNAMSIZ); | |
fd2 = socket (AF_INET, SOCK_DGRAM, 0); | |
if (fd2 != -1) | |
if (ioctl(fd2, SIOCGIFADDR, &ifr_link) >= 0) | |
ipv4 = ((struct sockaddr_in*)&ifr_link.ifr_addr)->sin_addr.s_addr; | |
close (fd2); | |
break; | |
case AF_INET: | |
ipv4 = ((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr.s_addr; | |
break; | |
} | |
if (ipv4 == pktinfo->ipi_addr.s_addr) | |
{ | |
packetInfo->InterfaceIndex = if_idx; | |
goto done; | |
} | |
} | |
done: | |
free (ifc.ifc_buf); | |
close (fd); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment