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获取,设置接口 MTUstruct 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. 总结

  • 掌握获取接口配置的方法
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值