Skip to content
Advertisement

C/C++: POSIX compatible way to find default network interface up/down

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.)

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement