当前位置: 首页 > 面试题库 >

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

勾学博
2023-03-14
问题内容

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

我检查了一些替代方法

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

另外,由于此代码是针对我的工作场所中的产品而设计的,因此这里的每个外部库都经过全面检查(这意味着我将永远需要添加任何外部库),因此我更喜欢依赖Linux本机API而非外部库的解决方案。

谢谢!


问题答案:

确保使用了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;
}


 类似资料:
  • 问题内容: 我需要确定给定的IP地址是否来自某个特殊的网络才能自动进行身份验证。 问题答案: Apache的百科全书网有出现,以满足您的需求。看起来您正在执行以下操作: 请注意,正如carson所指出的那样,Apache Commons Net有一个错误,使它在某些情况下无法提供正确的答案。卡森建议使用SVN版本来避免此错误。

  • 问题内容: 它可以在Android 2.3之前运行。但是,在更高的API级别上没有运气。例如,我把设置 但是我回过头来检查: 该IP Settings字段仍然说明,DHCP但没有Static。 我确实可以用来找回设定的东西。证明该设置保存在某个地方,但是系统只是忽略它。 系统使用除和4.x上的设置以外的其他设置,因为该设置是根据访问点SSID设置的。我可以像在Android 2.3上一样修改一个S

  • Linux提供了许多虚拟设备,这些虚拟设备有助于构建复杂的网络拓扑,满足各种网络需求。 网桥(bridge) 网桥是一个二层设备,工作在链路层,主要是根据MAC学习来转发数据到不同的port。 # 创建网桥 brctl addbr br0 # 添加设备到网桥 brctl addif br0 eth1 # 查询网桥mac表 brctl showmacs br0 veth veth pair是一对虚拟

  • 问题内容: 给定CIDR地址,例如 如何确定面膜长度?() 如何确定掩码地址?() 如何确定网络地址?() 问题答案: 它由apache utils涵盖。 请参阅以下URL:http : //commons.apache.org/proper/commons- net/apidocs/org/apache/commons/net/util/SubnetUtils.html 注意:对于使用// 32

  • 问题内容: 如何在Android 5.x上以编程方式配置静态IP地址,网络掩码,网关,DNS以进行Wi- Fi连接?是否有开放的API(找不到它)或隐藏的API可以用于此目的?如果可能的话,还请您举一些例子。 我知道在Android4.0以上版本中可能,但在Android 5.0上无效 问题答案: 不幸的是,仍然没有开放的API。 Android 4.0的解决方案在LOLLIPOP中不起作用,因为

  • Linux网络配置方法简介。 配置IP地址 # 使用ifconfig ifconfig eth0 192.168.1.3 netmask 255.255.255.0 # 使用用ip命令增加一个IP ip addr add 192.168.1.4/24 dev eth0 # 使用ifconfig增加网卡别名 ifconfig eth0:0 192.168.1.10 这样配置的IP地址重启机器后会丢失