使用getifaddrs
,我们可以遍历机器上所有可用的网络接口。对于这个问题,我只关心第2层(链接层)接口-即AF_PACKET
系列的接口。
当我们遍历从getifaddrs
返回的所有接口时,我们发现一个struct ifaddrs
字段为ifa_addr->sa_family
的{{1}}实例,看来我们仍然需要更多信息关于我们正在处理哪种类型的第2层接口。
我们可以通过检查AF_PACKET
字段来排除回送接口和点对点接口。但是除此之外,我们如何分辨某个特定的ifa_flags
接口是以太网还是其他接口?据推测,它也可能是其他一些第二层技术,例如WiFi,令牌环或蓝牙。那么我们怎么知道是以太网还是其他呢?
读取documentation for struct sockaddr_ll
时,似乎出现一个字段AF_PACKET
,其中包含“按网络字节顺序的标准以太网协议类型”。这让我有些困惑,因为现在我不确定sll_protocol
是否应该仅用于以太网,还是应该用作通用链接层套接字对象。该文档说sockaddr_ll
包含标准的 ethernet 协议,这一事实向我表明sll_protocol
应该仅用于以太网。但是sockaddr_ll
字段似乎更通用(它最多可以包含8个字节的长度,而不仅仅是6个字节的MAC地址)。
我也不确定sll_addr
系列本身是否应该告诉我物理媒体必须是以太网。
我能找到的唯一其他线索来自http://www.microhowto.info/howto/get_the_mac_address_of_an_ethernet_interface_in_c_using_siocgifhwaddr.html。这似乎暗示着,通过使用较旧的AF_PACKET
和struct ifreq
接口以及ioctl
,您可以肯定地通过检查其中的SIOCGIFHWADDR
字段来判断特定接口是否为以太网。 sa_family
结构中的ifr_hwaddr
字段。如果设备是以太网设备,则ifreq
字段应设置为sa_family
。
但是我对为什么这与ARPHRD_ETHER
不一致感到困惑,其中对于第二层以太网接口,getifaddrs
字段只是ifa_addr->sa_family
。与较其他的第2层技术(如WIFI)相比,似乎较新的API(AF_PACKET
)没有提供任何方法来区分特定的网络接口是否实际上是以太网。
那么确定特定网络接口是否为以太网(与某些其他第2层技术相对)的最佳方法是什么?