Linux下获取网卡列表(/proc/net/dev & ioctl()

转自:http://blog.sina.com.cn/mailofzxf  

在Linux下有两个方法获取网卡列表:分析文件/proc/net/dev 和 通过ioctl()调用。代码如下。

#define MAX_INTERFACES  100
#define FIRST_INTERFACE 0
#define PROC_NET_DEV    "/proc/net/dev"

// interfaces related:  man netdevice(7)
int           interfaces_count = -1;    // we do not know the count at first,
                                        //  but this varies according to modules loaded!
struct ifreq  interfaces       [MAX_INTERFACES FIRST_INTERFACE]; // name/ip
struct ifreq  interfaces_mask  [MAX_INTERFACES FIRST_INTERFACE]; // netmask
struct ifreq  interfaces_index [MAX_INTERFACES FIRST_INTERFACE]; // ifr_ifindex
struct ifreq  interfaces_hwaddr[MAX_INTERFACES FIRST_INTERFACE]; // hwaddr
struct ifreq  interfaces_flag  [MAX_INTERFACES FIRST_INTERFACE]; // flags


static int get_interface_names_by_proc_file()
{
  #define SKIP_BLANK(p, end) while(isspace(*p) && (p < buf end)) p ;
  #define GOTO_EOL(p, end)   while((*p!='\n' && *p!='\r') && (p < buf end))  p ;
  #define ZERO_EOL(p, end)   while((*p=='\n' || *p=='\r') && (p < buf end)) *p = 0;
  #define IS_EOL(c)          (c=='\n' || c=='\r')
  int            net_inf_count = 0;
  int            alloc_size = 4096;
  char          *buf = NULL;
  char          *p, *head, *tail;
  int            fd, read_count;

  fd = open(PROC_NET_DEV, O_RDONLY);
  if(fd < 0) {
     ERR("open: %s\n", strerror(errno));
     return -11;
  }

  while(1) {
     buf = (char*)realloc(buf, alloc_size);
     if(buf == NULL) {
        close(fd);
        return -12;
     }
     lseek(fd, 0, SEEK_SET);
     read_count = read(fd, buf, alloc_size);
     if(read_count <= 0) {
        free(buf);
        close(fd);
        return -13;
     }
     if(read_count < alloc_size)
        break;
     alloc_size <<= 1;
  }
  buf[read_count] = 0;  // to terminate the string

  head = buf;
  while(head < buf read_count) {
     p = head;
     GOTO_EOL(p, read_count)
     ZERO_EOL(p, read_count)
     tail = p;

     p = strchr(head, ':');
     if(p) {
       // a line containing a interface device:
       *p = 0;
       SKIP_BLANK(head, read_count)
       strncpy_0(interfaces[net_inf_count].ifr_name, head, IFNAMSIZ);
       //RPT(" #intf_No: - -- %s\n", net_inf_count, head);
       net_inf_count ;
     } else {
       // This is the header line.
     }
     head = tail;
  }
  free(buf);
  close(fd);
  return net_inf_count;
}


static int get_interface_confs_by_ioctl()
{
  struct ifreq  ioctl_devs[MAX_INTERFACES FIRST_INTERFACE];
  int           inf_count, idx, pos;
  struct ifconf ifc;
  int           fd, res;

  fd = socket(AF_INET, SOCK_DGRAM, 0);  // any family, any type!
  if(fd < 0) {
     ERR("socket error: %s\n", strerror(errno));
     return -1;
  }
  ifc.ifc_len =   sizeof(ioctl_devs);
  ifc.ifc_buf = (caddr_t)ioctl_devs;
  res = ioctl (fd, SIOCGIFCONF, (char*) &ifc);
  if (!res) {
     inf_count = ifc.ifc_len / sizeof(struct ifreq);
  } else {
     close(fd);
     ERR("%s(%d): ioctl(SIOCGIFCONF): %s. Are you ROOT?\n", __FILE__, __LINE__, strerror(errno));
     return -1;
  }

  if(interfaces_count < 0) {
     interfaces_count = inf_count;
     memcpy((char*)interfaces, (char*)ioctl_devs, inf_count*sizeof(ioctl_devs[0]));
  } else {
     // copy the IP addr:
     for(pos=0; pos<inf_count; pos ) {
         for(idx=FIRST_INTERFACE; idx<interfaces_count FIRST_INTERFACE; idx ) {
             if(!strcmp( interfaces[idx].ifr_name, ioctl_devs[pos].ifr_name )) {
                memcpy((char*)&interfaces[idx].ifr_addr,
                       (char*)&ioctl_devs[pos].ifr_addr,
                        sizeof(ioctl_devs[pos].ifr_addr)
                      );
                break;
             }
         }
     }
  }

     #if 0   // To ensure that intf_name & IP are assigned in interfaces!
     for(idx=FIRST_INTERFACE; idx<interfaces_count FIRST_INTERFACE; idx ) {
       char   ip_addr_str[IPADDR_STR_LEN];
       RPT("#- dev=%s, IP=%s\n", idx, interfaces[idx].ifr_name,
                               inet_ntoa(inaddrr(interfaces[idx])));
     }
     #endif

  // to get other conf of interfaces...
  {
     // to get ifr_netmask:
     for(idx=FIRST_INTERFACE; idx<interfaces_count FIRST_INTERFACE; idx ) {
        memcpy(interfaces_mask[idx].ifr_name, interfaces[idx].ifr_name, \
                                       sizeof(interfaces[idx].ifr_name) );
        if(ioctl(fd, SIOCGIFNETMASK, (char*) &interfaces_mask[idx]) < 0) {
           //ERR("%s(%d): ioctl(SIOCGIFNETMASK) err: %s\n", __FILE__, __LINE__,
       //            strerror(errno));
       memset((char*)&(interfaces_index[idx].ifr_netmask), 0, sizeof(interfaces_index[idx].ifr_netmask));
    }
     }

     // to get ifr_ifindex:
     for(idx=FIRST_INTERFACE; idx<interfaces_count FIRST_INTERFACE; idx ) {
        memcpy(interfaces_index[idx].ifr_name, interfaces[idx].ifr_name, \
                                        sizeof(interfaces[idx].ifr_name) );
        if(ioctl(fd, SIOCGIFINDEX, (char*) &interfaces_index[idx]) < 0) {
           ERR("%s(%d): ioctl(SIOCGIFINDEX) err: %s\n", __FILE__, __LINE__, strerror(errno));
       interfaces_index[idx].ifr_ifindex = -1;
    }
     }

     // to get HW addr:
     for(idx=FIRST_INTERFACE; idx<interfaces_count FIRST_INTERFACE; idx ) {
        memcpy(interfaces_hwaddr[idx].ifr_name, interfaces[idx].ifr_name, \
                                     sizeof(interfaces[idx].ifr_name) );
        if(ioctl(fd, SIOCGIFHWADDR, (char*) &interfaces_hwaddr[idx]) < 0) {
          ERR("%s(%d): ioctl(SIOCGIFHWADDR): %s\n", __FILE__, __LINE__, strerror(errno));
      for(pos=0; pos<ETH_ALEN; pos )
         INTF_MAC(idx)[pos] = 0;
    }
     }

     // to get flags:
     for(idx=FIRST_INTERFACE; idx<interfaces_count FIRST_INTERFACE; idx ) {
        memcpy(interfaces_flag[idx].ifr_name, interfaces[idx].ifr_name, \
                                   sizeof(interfaces[idx].ifr_name) );
        if(ioctl(fd, SIOCGIFFLAGS, (char*) &interfaces_flag[idx]) < 0) {
          ERR("%s(%d): ioctl(SIOCGIFHWADDR): %s\n", __FILE__, __LINE__, strerror(errno));
      interfaces_flag[idx].ifr_flags = 0;
    }
     }
  }
  close(fd);
  return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值