I'm writing an app that needs to bind to the loopback interface by interface index. The lazy way to do this would just be to use interface index 1, or even use if_nametoindex("lo0")
.
However, is that technically correct? Is lo0
guaranteed to exist, and be the network interface with index 1? If so, that answers my question, but if not, what's the correct way to get the loopback interface's index?
(Note: This is in regards to Unix-like environments like macOS or Linux, not Windows.)
Given that loopback interfaces can be added and removed, I wrote a function to find the first one and return its index. It returns 0 if there are no loopback interfaces (or it fails to get information about the available interfaces).
#include <ifaddrs.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
uint32_t loopbackInterfaceIndex()
{
uint32_t result = 0;
ifaddrs *interfaces;
// Get information about all network interfaces
if (getifaddrs(&interfaces) == -1) {
return 0;
}
// Iterate over all interfaces:
for(ifaddrs *interface = interfaces; interface; interface = interface->ifa_next) {
// Check to make sure we have a valid ifa_addr (perhaps paranoid,
// but always good to check pointers before deferencing them),
// and then see if the address is for a link layer interface
if (!interface->ifa_addr || interface->ifa_addr->sa_family != AF_LINK) {
// not what we're looking for
continue;
}
sockaddr_dl *addr = (sockaddr_dl *)interface->ifa_addr;
// Is it a loopback interface?
if (addr->sdl_type == IFT_LOOP) {
// We found what we're looking for; get the device's
// interface index and then break of the loop
result = if_nametoindex(interface->ifa_name);
break;
}
}
// Free any memory allocated by getifaddrs:
freeifaddrs(interfaces);
return result;
}