使用struct ifreq实现ifconfig

来源:互联网 发布:heading标签优化 编辑:程序博客网 时间:2024/06/13 01:46

转自:http://blog.csdn.net/joker0910/article/details/7855998

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

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

[cpp] view plain copy
  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.   
  17. #define MAX_INTERFACE   (16)  
  18.   
  19. void port_status(unsigned int flags);  
  20.   
  21. /* set == 0: do clean , set == 1: do set! */  
  22. int set_if_flags(char *pif_name, int sock, int staus, int set)  
  23. {  
  24.     struct ifreq ifr;  
  25.     int ret = 0;  
  26.       
  27.     strncpy(ifr.ifr_name, pif_name, strlen(pif_name) + 1);  
  28.     ret = ioctl(sock, SIOCGIFFLAGS, &ifr);  
  29.     if(ret)  
  30.         return -1;  
  31.     /* set or clean */    
  32.     if(set)  
  33.         ifr.ifr_flags |= status;  
  34.     else   
  35.         ifr.ifr_flags &= ~status;  
  36.     /* set flags */  
  37.     ret = ioctl(sock, SIOCSIFFLAGS, &ifr);  
  38.     if(ret)  
  39.         return -1;  
  40.       
  41.     return 0;  
  42. }  
  43.   
  44. int get_if_info(int fd)  
  45. {  
  46.     struct ifreq buf[MAX_INTERFACE];      
  47.     struct ifconf ifc;  
  48.     int ret = 0;  
  49.     int if_num = 0;  
  50.   
  51.     ifc.ifc_len = sizeof(buf);  
  52.     ifc.ifc_buf = (caddr_t) buf;  
  53.       
  54.     ret = ioctl(fd, SIOCGIFCONF, (char*)&ifc);  
  55.     if(ret)  
  56.     {  
  57.         printf("get if config info failed");  
  58.         return -1;  
  59.     }  
  60.     /* 网口总数 ifc.ifc_len 应该是一个出入参数 */      
  61.     if_num = ifc.ifc_len/sizeof(struct ifreq);  
  62.     printf("interface num is interface = %d\n", if_num);  
  63.     while(if_num-- > 0)  
  64.     {  
  65.         printf("net device: %s\n", buf[if_num].ifr_name);     
  66.         /* 获取第n个网口信息 */  
  67.         ret = ioctl(fd, SIOCGIFFLAGS, (char*)&buf[if_num]);  
  68.         if(ret)  
  69.             continue;  
  70.   
  71.         /* 获取网口状态 */  
  72.         port_status(buf[if_num].ifr_flags);  
  73.           
  74.         /* 获取当前网卡的ip地址 */  
  75.         ret = ioctl(fd, SIOCGIFADDR, (char*)&buf[if_num]);  
  76.         if(ret)  
  77.             continue;  
  78.         printf("IP address is: \n%s\n", inet_ntoa(((struct sockaddr_in *)(&buf[if_num].ifr_addr))->sin_addr));  
  79.   
  80.         /* 获取当前网卡的mac */  
  81.         ret = ioctl(fd, SIOCGIFHWADDR, (char*)&buf[if_num]);  
  82.         if(ret)  
  83.             continue;  
  84.   
  85.         printf("%02x:%02x:%02x:%02x:%02x:%02x\n\n",  
  86.             (unsigned char)buf[if_num].ifr_hwaddr.sa_data[0],  
  87.             (unsigned char)buf[if_num].ifr_hwaddr.sa_data[1],  
  88.             (unsigned char)buf[if_num].ifr_hwaddr.sa_data[2],  
  89.             (unsigned char)buf[if_num].ifr_hwaddr.sa_data[3],  
  90.             (unsigned char)buf[if_num].ifr_hwaddr.sa_data[4],  
  91.             (unsigned char)buf[if_num].ifr_hwaddr.sa_data[5]  
  92.             );  
  93.     }  
  94. }  
  95.   
  96. void port_status(unsigned int flags)  
  97. {  
  98.     if(flags & IFF_UP)    
  99.     {  
  100.         printf("is up\n");        
  101.     }  
  102.     if(flags & IFF_BROADCAST)     
  103.     {  
  104.         printf("is broadcast\n");     
  105.     }  
  106.     if(flags & IFF_LOOPBACK)      
  107.     {  
  108.         printf("is loop back\n");     
  109.     }  
  110.     if(flags & IFF_POINTOPOINT)   
  111.     {  
  112.         printf("is point to point\n");    
  113.     }  
  114.     if(flags & IFF_RUNNING)   
  115.     {  
  116.         printf("is running\n");   
  117.     }  
  118.     if(flags & IFF_PROMISC)   
  119.     {  
  120.         printf("is promisc\n");   
  121.     }  
  122. }  
  123.   
  124. int main()  
  125. {  
  126.     int fd;  
  127.   
  128.     fd = socket(AF_INET, SOCK_DGRAM, 0);  
  129.     if(fd > 0)  
  130.     {  
  131.         get_if_info(fd);  
  132.         close(fd);  
  133.     }  
  134.   
  135.     return 0;  

0 0
原创粉丝点击