Skip to content

Instantly share code, notes, and snippets.

@NattyNarwhal
Created June 6, 2018 18:50
Show Gist options
  • Save NattyNarwhal/96c02589ff4ff94187095f72a9f76bd2 to your computer and use it in GitHub Desktop.
Save NattyNarwhal/96c02589ff4ff94187095f72a9f76bd2 to your computer and use it in GitHub Desktop.
Try 3 of PAL networking hack
// 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