确定链路层物理媒体类型

时间:2019-01-04 20:19:55

标签: c linux networking ethernet

使用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_PACKETstruct ifreq接口以及ioctl,您可以肯定地通过检查其中的SIOCGIFHWADDR字段来判断特定接口是否为以太网。 sa_family结构中的ifr_hwaddr字段。如果设备是以太网设备,则ifreq字段应设置为sa_family

但是我对为什么这与ARPHRD_ETHER不一致感到困惑,其中对于第二层以太网接口,getifaddrs字段只是ifa_addr->sa_family。与较其他的第2层技术(如WIFI)相比,似乎较新的API(AF_PACKET)没有提供任何方法来区分特定的网络接口是否实际上是以太网。

那么确定特定网络接口是否为以太网(与某些其他第2层技术相对)的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

我们只需检查ifa_addr->sa_family的值,我认为它应该为您提供procotol层2。在stackoverflow上有一些很酷的答案,例如herehere使用{ {1}}。

getifaddrs