在C中以编程方式获取网络链接类型和速度
我想知道是否有一种更简洁的方法可以在Linux中找到链接速度和网络接口的类型(无线、以太网),而不仅仅是打开并读取在C中以编程方式获取网络链接类型和速度,c,linux,networking,network-programming,C,Linux,Networking,Network Programming,我想知道是否有一种更简洁的方法可以在Linux中找到链接速度和网络接口的类型(无线、以太网),而不仅仅是打开并读取/sys/class/net/eth0/type和/sys/class/net/eth0/speed文件 如果没有,有人能告诉我在哪里可以找到/sys/class/net/eth0/type返回的号码,哪些网络类型对应 编辑:情况变得更糟!在对无线进行一些实验后,/sys/class/net/wlan0/type也返回1,/sys/class/net/wlan0/speed不存在,我
/sys/class/net/eth0/type
和/sys/class/net/eth0/speed
文件
如果没有,有人能告诉我在哪里可以找到/sys/class/net/eth0/type
返回的号码,哪些网络类型对应
编辑:情况变得更糟!在对无线进行一些实验后,/sys/class/net/wlan0/type
也返回1,/sys/class/net/wlan0/speed
不存在,我不得不从/sys/class/net/wlan0/wireless/link
中获取链路速度,有时返回的速度不正确。例如,在54Mbits卡中,有时返回55
提前谢谢 这只解决了一半的问题,但使用libpcap库,您可以打开一个实时pcap,然后调用pcap\u数据链路。这将为您提供链接类型。(DLT_IEEE802_11、DLT_EN10MB等)
SIOCGIFWADR
ioctl。ioctl返回struct sockaddr
的sa_族中的ARPHRD
值之一(在net/if\u arp.h
中定义)。有关更多详细信息,请参阅
参见示例(未测试):
/**
*获取网络接口链接类型
*@param name网络接口名称
*@return=IFNAMSIZ){
fprintf(stderr,“名称'%s'太长,\n”,名称);
返回-搪瓷;
}
strncpy(ifr.ifr_名称、名称、IFNAMSIZ);
fd=插座(AF INET、SOCK DGRAM、IPPROTO IP);
如果(fd<0)
返回fd;
rv=ioctl(fd、SIOCGIFHWADDR和ifr);
关闭(fd);
如果(rv<0)
返回rv;
{
char*type=“未知”;
交换机(ifr.ifr\U hwaddr.sa\U系列)
{
案例ARPHRD_Ethernet:type=“Ethernet”中断;
案例ARPHRD_IEEE80211:type=“802.11”中断;
/*在此处添加更多案例*/
}
printf(“链接类型为:%s\n”,类型);
}
返回ifr.ifr_hwaddr.sa_家族;
}
要获得链接速度,您需要SIOCETHTOOL
ioctl,例如前面讨论过的。这里有人问了类似的问题:是的,但这个问题与以太网的速度有关。在我的情况下,我的链接也是无线的。不管怎样,我想我找到了一个方法。我会在我完成我的程序后发布。你有没有找到解决方案?不幸的是,我结束了对iw和ethtool输出的解析。。。不是最好的解决方案,但我没有空闲时间…我认为链接类型DLT_IEEE802_11只有在接口处于监控模式时才可用。否则,libpcap会将其作为标准以太网链路返回。但我会试试看,只是为了确定!谢谢
/**
* Get network interface link type
* @param name the network interface name
* @return <0 error code on error, the ARPHRD_ link type otherwise
*/
int get_link_type(const char* name)
{
int rv;
int fd;
struct ifreq ifr;
if (strlen(name) >= IFNAMSIZ) {
fprintf(stderr, "Name '%s' is too long\n", name);
return -ENAMETOOLONG;
}
strncpy(ifr.ifr_name, name, IFNAMSIZ);
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (fd < 0)
return fd;
rv = ioctl(fd, SIOCGIFHWADDR, &ifr);
close(fd);
if (rv < 0)
return rv;
{
char *type = "Unknown";
switch (ifr.ifr_hwaddr.sa_family)
{
case ARPHRD_ETHER: type = "Ethernet"; break;
case ARPHRD_IEEE80211: type = "802.11"; break;
/* add more cases here */
}
printf("Link type is: %s\n", type);
}
return ifr.ifr_hwaddr.sa_family;
}