使用struct ifreq实现ifconfig

本文介绍了一个简单的C程序,该程序通过ioctl系统调用获取Linux系统中所有网络接口的状态信息,包括接口名称、是否激活、是否为广播接口、是否为回环接口等,并展示如何读取每个接口的IP地址和MAC地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自: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(