You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过编程过滤掉虚拟机的IP地址?

过滤虚拟机网卡以获取物理以太网IP地址的解决方案

问题背景

现有一段用于获取以太网IP地址的代码,但系统安装虚拟机时可能返回虚拟机的IP地址:

public static IPAddress GetEthernetIpAddress()
{
    foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
    {
        if (ni.OperationalStatus == OperationalStatus.Up)
        {
            if (ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
            {
                foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses)
                {
                    if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
                    {
                        return ip.Address;
                    }
                }
            }
        }
    }

    return default;
}

尝试过两种不可靠的过滤方案:

  • 检查网卡是否存在网关:网上称虚拟机网卡无网关,但实际验证不准确,代码如下:
    if (ni.GetIPProperties().GatewayAddresses.FirstOrDefault() == null)
    
  • 检查网卡名称包含“vEthernet”:依赖名称关键词的方式稳定性差,无法覆盖所有虚拟机场景。

在NetworkInterface或UnicastIPAddressInformation官方文档中未找到有效过滤方法,以下是可行的解决思路:

可行过滤方案

1. 通过硬件ID(PnP设备ID)识别虚拟网卡

虚拟机网卡的硬件描述或PnP设备ID通常包含厂商标识(如VMware、VirtualBox、Hyper-V),可通过WMI查询网卡的硬件信息进行过滤:

using System.Management;

public static bool IsPhysicalNetworkInterface(NetworkInterface ni)
{
    var physicalAddress = ni.GetPhysicalAddress().ToString();
    if (string.IsNullOrEmpty(physicalAddress)) return false;

    var query = new ObjectQuery($"SELECT * FROM Win32_NetworkAdapter WHERE MACAddress = '{physicalAddress.Replace("-", ":")}'");
    using (var searcher = new ManagementObjectSearcher(query))
    {
        foreach (ManagementObject obj in searcher.Get())
        {
            // 检查设备描述是否包含虚拟机厂商关键词
            string description = obj["Description"]?.ToString() ?? "";
            if (description.Contains("VMware") || description.Contains("VirtualBox") || description.Contains("Hyper-V"))
            {
                return false;
            }
            // 检查PNPDeviceID是否包含虚拟设备标识
            string pnpId = obj["PNPDeviceID"]?.ToString() ?? "";
            if (pnpId.Contains("VMware") || pnpId.Contains("VMS_VSP") || pnpId.Contains("VirtualBox"))
            {
                return false;
            }
        }
    }
    return true;
}

在原代码中加入该过滤条件:

public static IPAddress GetEthernetIpAddress()
{
    foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
    {
        if (ni.OperationalStatus == OperationalStatus.Up
            && ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet
            && IsPhysicalNetworkInterface(ni))
        {
            foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses)
            {
                if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
                {
                    return ip.Address;
                }
            }
        }
    }

    return default;
}

2. 结合网卡连接状态过滤

物理以太网网卡通常处于MediaConnectionState.Connected状态,虚拟机网卡(如Host-Only模式)可能处于断开或虚拟连接状态:

using System.Net.NetworkInformation;

public static bool IsConnectedPhysicalEthernet(NetworkInterface ni)
{
    if (ni.NetworkInterfaceType != NetworkInterfaceType.Ethernet) return false;
    var ifEntry = ni.GetIfEntry();
    return ifEntry.MediaConnectionState == MediaConnectionState.Connected;
}

3. 通过默认路由验证物理网卡

物理网卡通常关联默认路由,虚拟机网卡(如内部网络模式)可能没有默认路由:

using System.Net.NetworkInformation;

public static bool IsDefaultRouteInterface(NetworkInterface ni)
{
    var ipProps = ni.GetIPProperties();
    foreach (var route in ipProps.GetIPv4Properties().GetIPv4Routes())
    {
        // 默认路由的目标网络为0.0.0.0
        if (route.DestinationPrefix.Equals(IPAddress.Parse("0.0.0.0")) && route.NextHop.Equals(IPAddress.Parse("0.0.0.0")))
        {
            return true;
        }
    }
    return false;
}

总结

最可靠的方案是结合硬件ID(PnP设备ID)的检查,虚拟机网卡的硬件标识具有唯一性,不易被伪造或变更;可再结合连接状态和路由信息进行二次验证,确保获取的是物理以太网的IP地址。

内容的提问来源于stack exchange,提问作者Mickael Bergeron Néron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 07:53:13