如何以编程方式查找 Linux 中为特定网络设备配置的 IP 地址/网络掩码/网关?

2023-11-26

我想编写一段代码来检查每个网络设备(例如 eth0、lo、主设备)有关该设备的一些统计数据和配置数据。
我可以在 /sys/class/net/... 中找到统计数据(以及大部分配置数据),但是,我找不到任何 C/C++ API 或 procfs/sysfs 中列出 inet addr 的任何条目,网络掩码和网关。

我检查过的一些替代方案:

  • 解析 ifconfig/route/其他一些实用程序的输出:我不想每次需要进行检查时都启动子进程。
  • 解析 /etc/sysconfig/network-scripts/: 只会给我启动配置,而不是当前状态。

另外,由于此代码适用于我工作场所中的产品,其中每个外部库都经过彻底检查(这意味着我将永远无法添加任何外部库),因此我更喜欢依赖 Linux 本机 API 而不是外部库的解决方案。

Thanks!


当然,使用 ifreq 和 ioctl() 调用的结构可以获取所有接口信息:

手册页在这里Ifreq 联机帮助页

/* local interface info */
    typedef struct{
        char *iface;
        struct ether_addr hwa;
        struct in_addr ipa;
        struct in_addr bcast;
        struct in_addr nmask;
        u_short mtu;
    } ifcfg_t; 
    /*
     * Grabs local network interface information and stores in a ifcfg_t 
     * defined in network.h, returns 0 on success -1 on failure
    */
    int get_local_info(int rsock, ifcfg_t *ifcfg)
    {
        struct ifreq ifr;

        memset(&ifr, 0, sizeof(ifr));
        strncpy(ifr.ifr_name, ifcfg->iface, IF_NAMESIZE);
        if((ioctl(rsock, SIOCGIFHWADDR, &ifr)) == -1){
            perror("ioctl():");
            return -1;
        }
        memcpy(&(ifcfg->hwa), &ifr.ifr_hwaddr.sa_data, 6);

        memset(&ifr, 0, sizeof(ifr));
        strncpy(ifr.ifr_name, ifcfg->iface, IF_NAMESIZE);
        if((ioctl(rsock, SIOCGIFADDR, &ifr)) == -1){
            perror("ioctl():");
            return -1;
        }
        memcpy(&ifcfg->ipa, &(*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr, 4);

        memset(&ifr, 0, sizeof(ifr));
        strncpy(ifr.ifr_name, ifcfg->iface, IF_NAMESIZE);
        if((ioctl(rsock, SIOCGIFBRDADDR, &ifr)) == -1){
            perror("ioctl():");
            return -1;
        }
        memcpy(&ifcfg->bcast, &(*(struct sockaddr_in *)&ifr.ifr_broadaddr).sin_addr, 4);

        memset(&ifr, 0, sizeof(ifr));
        strncpy(ifr.ifr_name, ifcfg->iface, IF_NAMESIZE);
        if((ioctl(rsock, SIOCGIFNETMASK, &ifr)) == -1){
            perror("ioctl():");
            return -1;
        }
        memcpy(&ifcfg->nmask.s_addr, &(*(struct sockaddr_in *)&ifr.ifr_netmask).sin_addr, 4);

        memset(&ifr, 0, sizeof(ifr));
        strncpy(ifr.ifr_name, ifcfg->iface, IF_NAMESIZE);
        if((ioctl(rsock, SIOCGIFMTU, &ifr)) == -1){
            perror("ioctl():");
            return -1;
        }
        ifcfg->mtu = ifr.ifr_mtu;

        return 0;
    }

快速编辑,该函数需要在调用之前分配接口,如下所示:

strcpy(if_cfg->iface, iface)

确保您已经分配了内存,然后像这样调用

if((get_local_info(sock, if_cfg)) != 0){
    printf("Unable to get network device info\n");
    return -1;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何以编程方式查找 Linux 中为特定网络设备配置的 IP 地址/网络掩码/网关? 的相关文章

随机推荐