I’m working on POSIX platform (PSE51 to be exact). I want to get notified when the default network interface goes up/down (via a callback or through continuous poll). The challenge is that I could find a linux specific way to get the default interface here and found a linux specific way to find the network is up or down here but not able figure out a POSIX way to get notified when default network interface goes up or down in C/C++. Please suggest.
Advertisement
Answer
POSIX does not provide such an interface.
Many POSIXy systems – Linux, BSDs, many Unixes – do provide a C function getifaddrs()
, which provides a pointer to a linked list of struct ifaddrs
structures. If the list contains an entry whose ->if_name
matches your interface name and ->if_addr->sa_family
matches your address family (usually AF_INET
and AF_INET6
), then the interface is up. Otherwise the interface is down.
Consider the following example:
#include <sys/types.h> #include <sys/socket.h> #include <ifaddrs.h> #include <string.h> #include <errno.h> enum { IFACE_IPv4 = (1<<0), IFACE_IPv6 = (1<<1), IFACE_IP = (1<<0) | (1<<1), }; int iface_check(const char *name) { struct ifaddrs *curr, *list = NULL; int result = 0; if (!name || !(*name)) { errno = EINVAL; return 0; } if (getifaddrs(&list) == -1) return 0; for (curr = list; curr != NULL; curr = curr->ifa_next) { if (!strcmp(name, curr->ifa_name)) { if (curr->ifa_addr->sa_family == AF_INET) result |= IFACE_IPv4; if (curr->ifa_addr->sa_family == AF_INET6) result |= IFACE_IPv6; } } freeifaddrs(list); errno = 0; return result; }
If the getifaddrs()
and freeifaddrs()
functions are supported on your system (they are widely available), calling ifa_check(name)
with name
containing the interface name, should return 0 if the interface is down, and a combination of IFACE_IPv4
and IFACE_IPv6
if up (depending on which address families are supported on it).
For ease of use, the above function always sets errno
to zero if no errors occurred. This way you can just use the return value (nonzero if “up” in the IP/IPv6 sense). If it returns zero, you can check errno
if there was an error. (It will be zero if there was no error; the interface just wasn’t listed with IPv4/IPv6.)