linux 下C语言实现 读取网卡速度

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

有时间再转成perl的:)

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

源码如下:

 

// filename: getNet.c
// command sample: ./getNet eth0
// compile command: gcc -p -g  getNet.c && gcc -o getNet getNet.c


#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>


#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. */

/* hack, so we may include kernel's ethtool.h */
//typedef unsigned long long __u64;
typedef __uint32_t __u32;       /* ditto */
typedef __uint16_t __u16;       /* ditto */
typedef __uint8_t __u8;         /* ditto */


/* The forced speed, 10Mb, 100Mb, gigabit, 2.5Gb, 10GbE. */
#define SPEED_10        10
#define SPEED_100       100
#define SPEED_1000      1000
#define SPEED_2500      2500
#define SPEED_10000     10000

/* 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 main(int argc, char *argp[])
{
    if(argc != 2)
    {
        fprintf(stdout, "parameter is erro . usage : getNet ethXX!\n");
        return 1;
    }
    char *devname;
    devname = argp[1] ; // 取得网卡名
    //devname = "eth0" ; // 取得网卡名

/* http://topic.csdn.net/u/20070104/12/e57086ff-1a48-477b-b672-91e4ba3b6da4.html
    ifreq结构定义在/usr/include\net/if.h,用来配置ip地址,激活接口,配置MTU等接口信息的。
    其中包含了一个接口的名字和具体内容——(是个共用体,有可能是IP地址,广播地址,子网掩码,MAC号,MTU或其他内容)。
    ifreq包含在ifconf结构中。而ifconf结构通常是用来保存所有接口的信息的。
*/
    struct ifreq ifr, *ifrp;  // 接口请求结构
    int fd;   // to  access socket  通过socket访问网卡的 文件描述符号fd

    /* Setup our control structures. */
    memset(&ifr, 0, sizeof(ifr));
    strcpy(ifr.ifr_name, devname);

    /* Open control socket. */
    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd < 0) {
        perror("Cannot get control socket");
        return 70;
    }
    
    int err;
    struct ethtool_cmd ep;
    //fprintf(stdout, "Settings for %s:\n", devname);

    ep.cmd = ETHTOOL_GSET; // ethtool-copy.h:380:#define ETHTOOL_GSET         0x00000001 /* Get settings. */
    ifr.ifr_data = (caddr_t)&ep;  //   caddr_t 是void类型,而这句话是什么意思
    err = ioctl(fd, SIOCETHTOOL, &ifr);  //  int ioctl(int handle, int cmd,[int *argdx, int argcx]);
    if (err != 0) { // 如果出错退出; 
        printf(" ioctl is erro .\n");
        return -1;
    }

    // ===========  输出 网卡速度;============
    fprintf(stdout, "%s Speed: ", devname );
    switch (ep.speed) {
    case SPEED_10:
        fprintf(stdout, "10Mb/s\n");
        break;
    case SPEED_100:
        fprintf(stdout, "100Mb/s\n");
        break;
    case SPEED_1000:
        fprintf(stdout, "1000Mb/s\n");
        break;
    case SPEED_2500:
        fprintf(stdout, "2500Mb/s\n");
        break;
    case SPEED_10000:
        fprintf(stdout, "10000Mb/s\n");
        break;
    default:
        fprintf(stdout, "Unknown! (%i)\n", ep.speed);
        break;
    };

    return 0; 
}


 

 

 

 

你可能感兴趣的:(c,linux,socket,语言,features,interface)