网卡设备信息获取

news/2024/10/23 11:28:08/

前言:

网卡工作在OSI七层协议中的链路层,是主机与网络对接的重要接口,它完成了网络连接的物理和电信号之间的转换,同时还对网络数据包帧进行发送、接收、校验等,是上层网络应用的基石。在计算机架构中,通常是CPU通过内部总线(AHB BUS 或者 PCI BUS)与MAC控制单元通信,然后由MAC控制单元通过MII接口协议与PHY设备进行数据交互,PHY设备则负责与外部网络通信(RJ45网络接口)。通常将MAC控制单元与PHY设备集成在一起,构成我们所熟悉的网卡(ethn设备),在嵌入式开发中,经常需要获取网卡设备的一些信息,比如说网卡的工作模式、网卡的带宽等等,虽然有现成的ethtool等开源软件来实现,但是对于存储空间有限的嵌入式设备,我们可以通过代码写socket然后ioctl来实现。下图是参考了网友的MAC控制单元与PHY设备的功能框图

网卡信息

先来了解一下网卡设备信息的结构体内容,里面包括了我们所熟知的网卡模式支持,网卡特性、网卡带宽、全双工模式、PHY地址等等网卡信息。

struct ethtool_cmd {  __u32   cmd;  __u32   supported;      /* Features this interface supports */  __u32   advertising;    /* Features this interface advertises */  __u16   speed;          /* The forced speed, 10Mb, 100Mb, gigabit */  __u8    duplex;         /* Duplex, half or full */  __u8    port;           /* Which connector port */  __u8    phy_address;  __u8    transceiver;    /* Which transceiver to use */  __u8    autoneg;        /* Enable or disable autonegotiation */  __u32   maxtxpkt;       /* Tx pkts before generating tx int */  __u32   maxrxpkt;       /* Rx pkts before generating rx int */  __u32   reserved[4];  
}; 

获取网卡信息的样例如下,它的实现也很简单,首先建立一个UDP Socket,然后对数据进行组装,最后通过ioctl接口来获取网卡的信息。

#include <string.h>  
#include <sys/ioctl.h>  
#include <string.h>  
#include <errno.h>  
#include <linux/sockios.h>  
#include <net/if.h>  
#include <stdio.h>  
#include <stdint.h>  
#include <stddef.h>  
#include <stdlib.h>  
#include <sys/stat.h>  
#include <sys/types.h>  
#include <sys/socket.h>  #define SPEED_10        10  
#define SPEED_100       100  
#define SPEED_1000      1000  
#define SPEED_2500      2500  
#define SPEED_10000     10000  #ifndef SIOCETHTOOL  
#define SIOCETHTOOL     0x8946  
#endif  
#ifndef ARRAY_SIZE  
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))  
#endif  /* CMDs currently supported */  
#define ETHTOOL_GSET        0x00000001 /* Get settings. */  
#define ETHTOOL_SSET        0x00000002 /* Set settings. */  typedef __uint32_t __u32;       /* ditto */  
typedef __uint16_t __u16;       /* ditto */  
typedef __uint8_t __u8;         /* ditto */  
/* This should work for both 32 and 64 bit userland. */  
struct ethtool_cmd {  __u32   cmd;  __u32   supported;      /* Features this interface supports */  __u32   advertising;    /* Features this interface advertises */  __u16   speed;          /* The forced speed, 10Mb, 100Mb, gigabit */  __u8    duplex;         /* Duplex, half or full */  __u8    port;           /* Which connector port */  __u8    phy_address;  __u8    transceiver;    /* Which transceiver to use */  __u8    autoneg;        /* Enable or disable autonegotiation */  __u32   maxtxpkt;       /* Tx pkts before generating tx int */  __u32   maxrxpkt;       /* Rx pkts before generating rx int */  __u32   reserved[4];  
};  int Get_NetCard_Speed(char *eth_name)  
{   struct ifreq ifr, *ifrp;  int fd;   int ret;  memset(&ifr, 0, sizeof(ifr));  strcpy(ifr.ifr_name, eth_name);    fd = socket(AF_INET, SOCK_DGRAM, 0);  if (fd < 0) {  perror("Cannot get control socket");  return -1;  }       struct ethtool_cmd ep;   ep.cmd = ETHTOOL_GSET; // ethtool-copy.h:380:#define ETHTOOL_GSET  0x00000001 /* Get settings. */  ifr.ifr_data = (caddr_t)&ep;  ret = ioctl(fd, SIOCETHTOOL, &ifr);    if (ret != 0) {   printf(" ioctl is erro .\n");  close(fd);return -1;  }  fprintf(stdout, "%s Speed: ", devname );  switch (ep.speed) {  case SPEED_10:  fprintf(stdout, "10Mb/s\n");  return SPEED_10;break;  case SPEED_100:  fprintf(stdout, "100Mb/s\n");  return SPEED_100;break;  case SPEED_1000:  fprintf(stdout, "1000Mb/s\n");  return SPEED_1000;break;  case SPEED_2500:  fprintf(stdout, "2500Mb/s\n");  return SPEED_1000;break;  case SPEED_10000:  fprintf(stdout, "10000Mb/s\n");  return SPEED_10000;break;  default:  fprintf(stdout, "Unknown! (%i)\n", ep.speed);  break;  } close(fd);return 0;   
}  int main(int argc, char* argv[])
{Get_NetCard_Speed(argv[1]);  return 0;
}

在Ubuntu16.04下运行的样例打印输出

总结

在一些嵌入式设备中常常需要对网卡设备信息获取,以对设备的网络运行环境有所了解,不过现在的网卡大多数支持全双工,10M/100M/1000M模式自适应,很少再需要用户进行手动干预。最近工作中遇到了MA控制C单元与PHY设备配置的一些问题,参考了一些资料,做了一些整理成此文,以作备忘。

参考文章

http://www.cnblogs.com/chengqi521/p/7837588.html

https://www.cnblogs.com/jason-lu/articles/3195473.html


http://www.ppmy.cn/news/811647.html

相关文章

【配置网卡简单详解】

1.打开终端&#xff0c;如果你的用户不是root用户&#xff0c;用su root命令切换到root用户 2.打开网络编辑器 3.点击更改设置 4.选择模式&#xff0c;查看虚拟网段 5. 点击dhcp设置&#xff0c;起始地址设为192.168.110.0&#xff0c;结束地址设为192.168.110.254 6.点击net设…

超出本地计算机网络,超出本地计算机网络适配器卡的名称限制怎么解决?

解决方法&#xff1a;1、修改WINDOWS的注册表&#xff0c;将端口号从最大5000个开放到6万多&#xff1b; 2、修改注册表&#xff0c;将连接超时的时间缩短为30秒&#xff0c;避免过多的死连接。 关于WINDOWS操作系统安装服务软件应初始化TCP参数的问题通知 主要影响&#xff1a…

VC之获取计算机网卡mac地址

【原文网址&#xff1a;http://blog.sina.com.cn/s/blog_612b382d0100eezf.html】 网卡的物理地址即mac地址全球唯一&#xff0c;占用六个字节。&#xff08;正规厂家的网卡mac地址全球唯一&#xff0c;盖因有统一的委员会进行分配&#xff0c;一般前3个字节为生产厂商ID&…

一台计算机有几块网卡,如何在计算机(服务器)中安装多块网卡

如果网络在扩大时服务器只装一块网卡、所有工作站采用总线结构上网,那么访问速度会很慢。另外,如果上网时某台工作站出了故障,所有的工作站都受其影响,不能工作。 我们可以在服务器中安装多块网卡来解决问题。这样,服务器不但工作稳定,工作站上网速度会大幅度提高,而且若…

网卡速率适配

交换机端口灯颜色 一般情况下&#xff0c;网卡速率是操作系统与交换机协商进行的。 有时候我们将PC机或其它服务器连接到交换机上&#xff0c;发现交换机对应端口的灯是橙黄色而不是熟悉的亮绿色&#xff0c;但并不影响PC的网络连接。 本着严谨的科学态度&#xff0c;我们需…

计算机网络---网卡,交换机和路由器|CSDN创作打卡

一、网卡 1、网卡的表示 网卡是计算机与网络的必备连接设备&#xff0c;有唯一的MAC地址&#xff0c;MAC地址由12位16进制数表示&#xff0c;前6位是厂商标识&#xff0c;后6位为网卡标识。 2、网卡的功能 网卡是工作在链路层的网络组件&#xff0c;是局域网中连接计算机和传…

网络 启动计算机,电脑进入bios怎么设置网卡启动

当我们的网卡被禁用的时候&#xff0c;会导致我们上不了网&#xff0c;这个时候我们需要进bios开启网卡启动。不过很多人不知道电脑进入bios怎么设置网卡启动&#xff1f;今天小编就教下大家在bios中设置网卡启动的方法。注意不同的电脑操作会有不同&#xff0c;不过可以参考。…

计算机网卡ip怎么设置,怎样为网卡配置ip地址 电脑给网卡设置IP地址的方法有哪些...

今天给大家带来怎样为网卡配置ip地址&#xff0c;电脑给网卡设置IP地址的方法有哪些&#xff0c;让您轻松解决问题。 如何为网卡配置ip地址吗 电脑怎样给网卡设置IP地址方法技巧。我们在使用电脑的时候&#xff0c;总是会遇到很多的电脑难题。当我们在遇到了需要给网卡配置IP地…