110-获取接口信息(二)

1. 获取接口其它信息

前面我们已经了解了 ioctl 的使用方法,现在我们希望获取更多的接口信息,最后将其封装成一个独立函数,名为 getIfiInfo.

我们先来看看这个函数的演示示例,后面再给出详细过程。getIfiInfo 获取所有接口的配置信息,并保存在数组 ifi 中。该函数返回值是数组大小,也就是接口的个数。


这里写图片描述
图1 getIfiInfo 函数使用示例

上面的程序只是获取了接口信息,并将所有接口信息输出到了屏幕。经过编译运行后,结果如图 2 所示。


这里写图片描述
图2 getIfiInfo 获取到的接口信息

我们的目的就是写出 getIfiInfo 这个函数。

所有代码托管在:http://git.oschina.net/ivan_allen/unp
本文程序路径:unp/program/interface/getifinfo

2. ioctl 接口相关的其他命令

从图 2 中我们看到打印的信息有:

  • 接口功能,即标志位
  • 接口索引号
  • MTU
  • MAC 地址
  • 配置的 IP 地址
  • 子网掩码
  • 广播地址

每一个信息都需要通过 ioctl 函数来获取,有点麻烦,这也是封装 getIfiInfo 的初衷。

下表列举了操作接口的常用的 ioctl 命令:

命令 说明 数据类型
SIOCGIFCONF, SIOCSIFCONF 获取,设置所有接口列表 struct ifconf
SIOCGIFADDR, SIOCSIFADDR 获取,设置接口地址 struct ifreq
SIOCGIFINDEX 获取接口索引号 struct ifreq
SIOCGIFFLAGS, SIOCSIFFLAGS 获取,设置接口标志 struct ifreq
SIOCGIFMTU, SIOCSIFMTU 获取,设置接口 MTU struct ifreq
SIOCGIFDSTADDR, SIOCSIFDSTADDR 获取,设置P2P地址 struct ifreq
SIOCGIFBRDADDR, SIOCSIFBRDADDR 获取,设置广播地址 struct ifreq
SIOCGIFNETMASK, SIOCSIFNETMASK 获取,设置子网掩码 struct ifreq
SIOCGIFMETRIC, SIOCSIFMETRIC 获取,设置接口管理距离 struct ifreq
SIOCGIFHWADDR, SIOCSIFHWADDR 获取,设置接口 MAC 地址 struct ifreq

3. 封装 getIfiInfo 函数

首先需要定义一个新的结构体,如下:

struct ifi_info {                 char ifi_name[IFI_NAMESIZE]; // 接口名称 16 字节   short ifi_index; // 接口索引    short ifi_mtu; // 接口 MTU      unsigned char ifi_haddr[IFI_HADDRSIZE]; // 物理地址 8 字节   unsigned short ifi_hlen; // 物理地址长度    short ifi_flags;                        struct sockaddr *ifi_addr; // 主地址   struct sockaddr *ifi_netmask; // 子网掩码   struct sockaddr *ifi_brdaddr; // 广播地址   struct sockaddr *ifi_dstaddr; // 目标地址 };

接下来,定义 getIfiInfo 函数:

// 该函数通过参数返回一个struct ifi_info 类型数组地址,将地址保存在 ifi 中。 // 返回值:数组大小 int getIfiInfo(struct ifi_info **ifi);

我不打算把 getIfiInfo 函数的完整代码贴在这里,想要看完整代码,可以在 unp/program/util/common.cc 这个文件中找到它。这里我以获取接口 mac 地址为例:

int getIfiInfo(struct ifi_info **ifi) {     struct ifi_info *_ifi = malloc(/*...*/);     // ...      struct ifreq ifrcopy;     // 给 ifrcopy 填充接口名称。      // 获取 mac 地址     ret = ioctl(sockfd, SIOCGIFHWADDR, &ifrcopy);     if (ret < 0) ERR_EXIT("ioctl");       // 将 mac 地址保存到申请的内存中去     memcpy(_ifi[k].ifi_haddr, ((struct sockaddr*)&ifrcopy.ifr_hwaddr)->sa_data, 6);     _ifi[k].ifi_hlen = 6;      // ...      *ifi = _ifi;      return count; }

4. 总结

  • 掌握获取接口配置的方法
说明:本文转自--Allen--,用于学习交流分享,仅代表原文作者观点。如有侵权,请联系我们删除~