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_INET
和 AF_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_IPv4
和 IFACE_IPv6
的组合(取决于它支持的地址系列)。
为了便于使用,如果没有发生错误,上述函数总是将 errno
设置为零。这样你就可以只使用 return 值(如果 "up" 在 IP/IPv6 意义上非零)。如果它 return 为零,您可以检查 errno
是否有错误。 (如果没有错误,它将为零;接口只是没有用 IPv4/IPv6 列出。)
我正在 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_INET
和 AF_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_IPv4
和 IFACE_IPv6
的组合(取决于它支持的地址系列)。
为了便于使用,如果没有发生错误,上述函数总是将 errno
设置为零。这样你就可以只使用 return 值(如果 "up" 在 IP/IPv6 意义上非零)。如果它 return 为零,您可以检查 errno
是否有错误。 (如果没有错误,它将为零;接口只是没有用 IPv4/IPv6 列出。)