C/C++:POSIX 查找默认网络接口的兼容方式 up/down

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

我正在 POSIX 平台上工作(确切地说是 PSE51)。我想在默认网络接口变为 up/down 时收到通知(通过回调或通过连续轮询)。挑战在于我可以找到一种 linux 特定的方法来获取默认接口 here and found a linux specific way to find the network is up or down here 但无法找到一种 POSIX 方法来在默认网络接口在 C/C++。请提出建议。

POSIX没有提供这样的接口。

许多 POSIXy 系统 – Linux、BSD、许多 Unix – 确实提供了一个 C 函数 getifaddrs(),它提供了指向 struct ifaddrs 的链表的指针结构。如果该列表包含一个条目,其 ->if_name 与您的接口名称匹配且 ->if_addr->sa_family 与您的地址族匹配(通常为 AF_INETAF_INET6),则该接口已启动。不然接口down了。

考虑以下示例:

#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;
}

如果您的系统支持 getifaddrs()freeifaddrs() 函数(它们被广泛使用),使用包含接口名称的 name 调用 ifa_check(name),应该 return 0 如果接口关闭,IFACE_IPv4IFACE_IPv6 的组合(取决于它支持的地址系列)。

为了便于使用,如果没有发生错误,上述函数总是将 errno 设置为零。这样你就可以只使用 return 值(如果 "up" 在 IP/IPv6 意义上非零)。如果它 return 为零,您可以检查 errno 是否有错误。 (如果没有错误,它将为零;接口只是没有用 IPv4/IPv6 列出。)