在 C (Linux) 中查找虚拟网络接口

Posted

技术标签:

【中文标题】在 C (Linux) 中查找虚拟网络接口【英文标题】:Find Virtual Network Interfaces in C (Linux) 【发布时间】:2019-08-19 09:24:37 【问题描述】:

我试图在 C 代码中找到一种方法来区分网络接口是虚拟的还是物理的。

我在想检查一下网络接口是否映射到驱动,假设如果没有驱动,很可能是虚拟适配器(有没有更相关的方法?)。

示例(在物理适配器上):

$ ethtool -i eth0
driver: e1000
....

示例(在虚拟适配器上):

$ ethtool -i eth10
Cannot get driver information: Operation not supported

当然,我查看了 ethtool 的来源以了解它如何访问驱动程序信息:https://github.com/torvalds/linux/blob/master/net/core/ethtool.c

这是我们感兴趣的部分:

static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev,
                          void __user *useraddr)

    struct ethtool_drvinfo info;
    const struct ethtool_ops *ops = dev->ethtool_ops;

    memset(&info, 0, sizeof(info));
    info.cmd = ETHTOOL_GDRVINFO;
    if (ops->get_drvinfo) 
        ops->get_drvinfo(dev, &info);
     else if (dev->dev.parent && dev->dev.parent->driver) 
        strlcpy(info.bus_info, dev_name(dev->dev.parent),
            sizeof(info.bus_info));
        strlcpy(info.driver, dev->dev.parent->driver->name,
            sizeof(info.driver));
     else 
        return -EOPNOTSUPP;
        
        ...

要获取net_device,需要调用__dev_get_by_name(net, ifr->ifr_name),这个函数显然在

中定义

问题是 __dev_get_by_name() 和所需的结构是在内核文件中定义的,我不确定是否可以从外部程序访问。

除了当我尝试包含诸如 之类的标头时,我会重新定义已经在...中定义的结构。

我想知道是否有更好的方法来获取具有 ifreq 结构 (http://man7.org/linux/man-pages/man7/netdevice.7.html) 的驱动程序信息。

【问题讨论】:

ethtool 是用户空间实用程序。 kernel.googlesource.com/pub/scm/network/ethtool/ethtool/+/refs/… 您正在查看内核源代码。 Ethtool 是一个用户态程序。内核有一个名为 ethtool.c 的文件在这里是无关紧要的。 【参考方案1】:

ifreq 结构主要是一个兼容性的东西,因为 Linux 中的新 API 是 rtnetlink,但我不建议探索它,除非你真的必须这样做。 ip shell 实用程序可以或多或少地访问 API 的整个稳定部分,但我认为它不能向您显示负责该设备的硬件设备。

但是: 我会检查 /sys/class/net/DEVICE_NAME/device 符号链接(它存在吗?)

【讨论】:

以上是关于在 C (Linux) 中查找虚拟网络接口的主要内容,如果未能解决你的问题,请参考以下文章

在c中识别虚拟网络接口

☀️苏州程序大白解析Linux 中的虚拟网络接口☀️《❤️记得收藏❤️》

Windows、Linux和路由器的网络子接口-虚拟IP

Linux网络设置

linux虚拟网络接口---bonding配置

Docker 网络