这几天要写一个监控之类东东,其中网卡一项要计算利用率,那就要取得网卡本身速度才能计算出来,本来想用perl实现,但发现网上没有现成的东东,后来几经辗转,最后想起ethtool能取到,就参考了此源码,贴出来供大家以后有个思路吧,

有时间再转成perl的:)

直接编译命令:gcc -p -g  getNet.c && gcc -o getNet getNet.c && ./getNet eth0

源码如下:

 

  1. // filename: getNet.c   
  2. // command sample: ./getNet eth0   
  3. // compile command: gcc -p -g  getNet.c && gcc -o getNet getNet.c   
  4.   
  5.   
  6. #include <string.h>   
  7. #include <sys/ioctl.h>   
  8. #include <string.h>   
  9. #include <errno.h>   
  10. #include <linux/sockios.h>   
  11. #include <net/if.h>   
  12. #include <stdio.h>   
  13. #include <stdint.h>   
  14. #include <stddef.h>   
  15. #include <stdlib.h>   
  16. #include <sys/stat.h>   
  17. #include <sys/types.h>   
  18. #include <sys/socket.h>   
  19.   
  20.   
  21. #ifndef SIOCETHTOOL   
  22. #define SIOCETHTOOL     0x8946   
  23. #endif   
  24. #ifndef ARRAY_SIZE   
  25. #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))   
  26. #endif   
  27.   
  28. /* CMDs currently supported */  
  29. #define ETHTOOL_GSET        0x00000001 /* Get settings. */   
  30. #define ETHTOOL_SSET        0x00000002 /* Set settings. */   
  31.   
  32. /* hack, so we may include kernel's ethtool.h */  
  33. //typedef unsigned long long __u64;   
  34. typedef __uint32_t __u32;       /* ditto */  
  35. typedef __uint16_t __u16;       /* ditto */  
  36. typedef __uint8_t __u8;         /* ditto */  
  37.   
  38.   
  39. /* The forced speed, 10Mb, 100Mb, gigabit, 2.5Gb, 10GbE. */  
  40. #define SPEED_10        10   
  41. #define SPEED_100       100   
  42. #define SPEED_1000      1000   
  43. #define SPEED_2500      2500   
  44. #define SPEED_10000     10000   
  45.   
  46. /* This should work for both 32 and 64 bit userland. */  
  47. struct ethtool_cmd {  
  48.         __u32   cmd;  
  49.         __u32   supported;      /* Features this interface supports */  
  50.         __u32   advertising;    /* Features this interface advertises */  
  51.         __u16   speed;          /* The forced speed, 10Mb, 100Mb, gigabit */  
  52.         __u8    duplex;         /* Duplex, half or full */  
  53.         __u8    port;           /* Which connector port */  
  54.         __u8    phy_address;  
  55.         __u8    transceiver;    /* Which transceiver to use */  
  56.         __u8    autoneg;        /* Enable or disable autonegotiation */  
  57.         __u32   maxtxpkt;       /* Tx pkts before generating tx int */  
  58.         __u32   maxrxpkt;       /* Rx pkts before generating rx int */  
  59.         __u32   reserved[4];  
  60. };  
  61.   
  62. int main(int argc, char *argp[])  
  63. {  
  64.     if(argc != 2)  
  65.     {  
  66.         fprintf(stdout, "parameter is erro . usage : getNet ethXX!\n");  
  67.         return 1;  
  68.     }  
  69.     char *devname;  
  70.     devname = argp[1] ; // 取得网卡名   
  71.     //devname = "eth0" ; // 取得网卡名   
  72.   
  73. /* http://topic.csdn.net/u/20070104/12/e57086ff-1a48-477b-b672-91e4ba3b6da4.html 
  74.     ifreq结构定义在/usr/include\net/if.h,用来配置ip地址,激活接口,配置MTU等接口信息的。 
  75.     其中包含了一个接口的名字和具体内容——(是个共用体,有可能是IP地址,广播地址,子网掩码,MAC号,MTU或其他内容)。 
  76.     ifreq包含在ifconf结构中。而ifconf结构通常是用来保存所有接口的信息的。 
  77. */  
  78.     struct ifreq ifr, *ifrp;  // 接口请求结构   
  79.     int fd;   // to  access socket  通过socket访问网卡的 文件描述符号fd   
  80.   
  81.     /* Setup our control structures. */  
  82.     memset(&ifr, 0, sizeof(ifr));  
  83.     strcpy(ifr.ifr_name, devname);  
  84.   
  85.     /* Open control socket. */  
  86.     fd = socket(AF_INET, SOCK_DGRAM, 0);  
  87.     if (fd < 0) {  
  88.         perror("Cannot get control socket");  
  89.         return 70;  
  90.     }  
  91.       
  92.     int err;  
  93.     struct ethtool_cmd ep;  
  94.     //fprintf(stdout, "Settings for %s:\n", devname);   
  95.   
  96.     ep.cmd = ETHTOOL_GSET; // ethtool-copy.h:380:#define ETHTOOL_GSET         0x00000001 /* Get settings. */   
  97.     ifr.ifr_data = (caddr_t)&ep;  //   caddr_t 是void类型,而这句话是什么意思   
  98.     err = ioctl(fd, SIOCETHTOOL, &ifr);  //  int ioctl(int handle, int cmd,[int *argdx, int argcx]);   
  99.     if (err != 0) { // 如果出错退出;    
  100.         printf(" ioctl is erro .\n");  
  101.         return -1;  
  102.     }  
  103.   
  104.     // ===========  输出 网卡速度;============   
  105.     fprintf(stdout, "%s Speed: ", devname );  
  106.     switch (ep.speed) {  
  107.     case SPEED_10:  
  108.         fprintf(stdout, "10Mb/s\n");  
  109.         break;  
  110.     case SPEED_100:  
  111.         fprintf(stdout, "100Mb/s\n");  
  112.         break;  
  113.     case SPEED_1000:  
  114.         fprintf(stdout, "1000Mb/s\n");  
  115.         break;  
  116.     case SPEED_2500:  
  117.         fprintf(stdout, "2500Mb/s\n");  
  118.         break;  
  119.     case SPEED_10000:  
  120.         fprintf(stdout, "10000Mb/s\n");  
  121.         break;  
  122.     default:  
  123.         fprintf(stdout, "Unknown! (%i)\n", ep.speed);  
  124.         break;  
  125.     };  
  126.   
  127.     return 0;   
  128. }  
Logo

更多推荐