ifconfig是我们查看/设定网口状态常用的命令,其实这个命令就是对一些系统函数的封装,通过对struct ifreq的修改,我们可以很轻易地设定网口状态,获取网口状态。

这个结构体位于<net/if.h>头文件中,打开去看看吧,对照着英文注释,很容易找到自己想要的东西。而网卡相关的一些ioctl操作, 也就是用于查询/修改状态的标记位,都在<linux/sockios.h>中,很清晰的,找份源码看看吧。下面是一个小示例,演示了获取信息的过程,如果有需要,也可以启用那个修改状态的函数,注意,修改状态标记位的时候,需要用到超级用户的权限。

  1. /**

  2. * \file getifstat.c

  3. * \author  wzj

  4. * \brief 访问这个struct ifconf 修改,查询状态

  5. * \version

  6. * \note  

  7. * \date: 2012年08月11日星期六22:55:25

  8. */

  9. #include <net/if.h>       /* for ifconf */

  10. #include <linux/sockios.h>    /* for net status mask */

  11. #include <netinet/in.h>       /* for sockaddr_in */

  12. #include <sys/socket.h>

  13. #include <sys/types.h>

  14. #include <sys/ioctl.h>

  15. #include <stdio.h>

  16. #define MAX_INTERFACE   (16)

  17. void port_status(unsigned int flags);  

  18. /* set == 0: do clean , set == 1: do set! */

  19. int set_if_flags(char *pif_name, int sock, int staus, int set)  

  20. {  

  21. struct ifreq ifr;  

  22. int ret = 0;  

  23.    strncpy(ifr.ifr_name, pif_name, strlen(pif_name) + 1);  

  24.    ret = ioctl(sock, SIOCGIFFLAGS, &ifr);  

  25. if(ret)  

  26. return -1;  

  27. /* set or clean */

  28. if(set)  

  29.        ifr.ifr_flags |= status;  

  30. else

  31.        ifr.ifr_flags &= ~status;  

  32. /* set flags */

  33.    ret = ioctl(sock, SIOCSIFFLAGS, &ifr);  

  34. if(ret)  

  35. return -1;  

  36. return 0;  

  37. }  

  38. int get_if_info(int fd)  

  39. {  

  40. struct ifreq buf[MAX_INTERFACE];      

  41. struct ifconf ifc;  

  42. int ret = 0;  

  43. int if_num = 0;  

  44.    ifc.ifc_len = sizeof(buf);  

  45.    ifc.ifc_buf = (caddr_t) buf;  

  46.    ret = ioctl(fd, SIOCGIFCONF, (char*)&ifc);  

  47. if(ret)  

  48.    {  

  49.        printf("get if config info failed");  

  50. return -1;  

  51.    }  

  52. /* 网口总数 ifc.ifc_len 应该是一个出入参数 */

  53.    if_num = ifc.ifc_len/sizeof(struct ifreq);  

  54.    printf("interface num is interface = %d\n", if_num);  

  55. while(if_num-- > 0)  

  56.    {  

  57.        printf("net device: %s\n", buf[if_num].ifr_name);    

  58. /* 获取第n个网口信息 */

  59.        ret = ioctl(fd, SIOCGIFFLAGS, (char*)&buf[if_num]);  

  60. if(ret)  

  61. continue;  

  62. /* 获取网口状态 */

  63.        port_status(buf[if_num].ifr_flags);  

  64. /* 获取当前网卡的ip地址 */

  65.        ret = ioctl(fd, SIOCGIFADDR, (char*)&buf[if_num]);  

  66. if(ret)  

  67. continue;  

  68.        printf("IP address is: \n%s\n", inet_ntoa(((struct sockaddr_in *)(&buf[if_num].ifr_addr))->sin_addr));  

  69. /* 获取当前网卡的mac */

  70.        ret = ioctl(fd, SIOCGIFHWADDR, (char*)&buf[if_num]);  

  71. if(ret)  

  72. continue;  

  73.        printf("%02x:%02x:%02x:%02x:%02x:%02x\n\n",  

  74.            (unsigned char)buf[if_num].ifr_hwaddr.sa_data[0],  

  75.            (unsigned char)buf[if_num].ifr_hwaddr.sa_data[1],  

  76.            (unsigned char)buf[if_num].ifr_hwaddr.sa_data[2],  

  77.            (unsigned char)buf[if_num].ifr_hwaddr.sa_data[3],  

  78.            (unsigned char)buf[if_num].ifr_hwaddr.sa_data[4],  

  79.            (unsigned char)buf[if_num].ifr_hwaddr.sa_data[5]  

  80.            );  

  81.    }  

  82. }  

  83. void port_status(unsigned int flags)  

  84. {  

  85. if(flags & IFF_UP)    

  86.    {  

  87.        printf("is up\n");        

  88.    }  

  89. if(flags & IFF_BROADCAST)    

  90.    {  

  91.        printf("is broadcast\n");    

  92.    }  

  93. if(flags & IFF_LOOPBACK)      

  94.    {  

  95.        printf("is loop back\n");    

  96.    }  

  97. if(flags & IFF_POINTOPOINT)  

  98.    {  

  99.        printf("is point to point\n");    

  100.    }  

  101. if(flags & IFF_RUNNING)  

  102.    {  

  103.        printf("is running\n");  

  104.    }  

  105. if(flags & IFF_PROMISC)  

  106.    {  

  107.        printf("is promisc\n");  

  108.    }  

  109. }  

  110. int main()  

  111. {  

  112. int fd;  

  113.    fd = socket(AF_INET, SOCK_DGRAM, 0);  

  114. if(fd > 0)  

  115.    {  

  116.        get_if_info(fd);  

  117.        close(fd);  

  118.    }  

  119. return 0;  

  120. }