改变
if (ifa->ifa_addr == NULL)
continue;
family = ifa->ifa_addr->sa_family;
和
if (ifa->ifa_addr == NULL)
continue;
if ((strcmp("lo", ifa->ifa_name) == 0) ||
!(ifa->ifa_flags & (IFF_RUNNING)))
continue;
family = ifa->ifa_addr->sa_family;
并在其他包含之后添加此行
#include <net/if.h>
添加的行只是检查“lo”接口名称,包含在ifa->ifa_name
中,并检查接口的标志。测试 IFF_RUNNING 位(查看net/if.h
更多定义)将只返回正在运行的接口。
如果您想检查接口的其他功能,只需检查此标志(取自net/if.h
)
- IFF_UP 接口正在运行。
- IFF_BROADCAST 有效的广播地址集。
- IFF_DEBUG 内部调试标志。
- IFF_LOOPBACK 接口是一个环回接口。
- IFF_POINTOPOINT 接口是点对点链接。
- IFF_RUNNING 分配的资源。
- IFF_NOARP 无 arp 协议,未设置 L2 目标地址。
- IFF_PROMISC 接口处于混杂模式。
- IFF_NOTRAILERS 避免使用拖车。
- IFF_ALLMULTI 接收所有多播数据包。
- IFF_MASTER 负载平衡包的主控。
- IFF_SLAVE 负载平衡包的从站。
- IFF_MULTICAST 支持多播
- IFF_PORTSEL 能够通过 ifmap 选择媒体类型。
- IFF_AUTOMEDIA 自动媒体选择激活。
- IFF_DYNAMIC 接口关闭时地址丢失。
- IFF_LOWER_UP 驱动程序向 L1 发出信号(自 Linux 2.6.17 起)
- IFF_DORMANT 驱动程序信号休眠(自 Linux 2.6.17 起)
- IFF_ECHO Echo 发送数据包(Linux 2.6.25 起)
编辑
如果您需要区分 IPV6 GUA 和 ULA 地址,请使用此宏
#ifndef IN6_IS_ADDR_GLOBAL
#define IN6_IS_ADDR_GLOBAL(a) \
((((__const uint32_t *) (a))[0] & htonl(0x70000000)) \
== htonl (0x20000000))
#endif /* IS ADDR GLOBAL */
#ifndef IN6_IS_ADDR_ULA
#define IN6_IS_ADDR_ULA(a) \
((((__const uint32_t *) (a))[0] & htonl(0xfe000000)) \
== htonl (0xfc000000))
#endif /* IS ADDR ULA */
参数必须取自((sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;