如何确定实际物理网卡的 MAC 地址——不是由 *** (.NET C#) 创建的虚拟网络接口
Posted
技术标签:
【中文标题】如何确定实际物理网卡的 MAC 地址——不是由 *** (.NET C#) 创建的虚拟网络接口【英文标题】:How to determine MAC Address of the actual physical network card -- not virtual network interfaces created by ***'s (.NET C#) 【发布时间】:2010-12-06 17:53:51 【问题描述】:背景
我正在尝试从计算机中获取唯一标识符,并希望每次都能可靠地返回相同的 MAC 地址。相信我,我有使用 MAC 地址的理由,并且阅读了许多关于替代唯一 ID 方法的帖子(是的,我考虑过他们是否没有任何网卡)。
问题
问题出在 .NET 中,我看不出特定的 NetworkInterface 是否是来自诸如“Nortel IPSECSHM Adapter - Packet Scheduler Miniport”之类的物理硬件网卡,当您连接到某些 *** 或WiFi 网络。
我知道如何使用类似下面的代码获取 Mac 地址:
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
log.Debug("NIC " + nic.OperationalStatus + " " + nic.NetworkInterfaceType + " " + nic.Speed + " " + nic.GetPhysicalAddress() + " " + nic.Description);
可以理解,没有 100% 的方法来确保我会获得内部网卡,但 我想选择 MAC 地址以返回给定机器最不可能更改的 MAC 地址强>。与诸如是否连接到 wifi...等因素无关...通过某种类型的系绳连接...或者他们安装了一些新的 *** 软件来添加新界面。
考虑的策略
1) 选择“Up”的第一个界面。这在我的笔记本电脑上失败了,因为“数据包微型端口”始终处于启动状态。此外,如果我将手机连接到笔记本电脑,这也会显示为第一张卡。
2) 选择最合适的类型...这失败了 b/c 基本上所有东西都显示为“以太网”,包括 WiFi 适配器和我的 iPHone 网络共享互联网连接。
3) 选择具有 IP 地址的 NIC。失败有几个原因:1)网卡可能没有连接到 LAN 2)有多个网卡可能有 IP 地址。
4) 只需发送所有 MAC 地址...问题是列表会根据安装的软件而变化,并且很难比较。
5) 选择速度最快的mac地址。我想这可能是我最好的选择。我认为可以肯定地说,最快的界面通常是最永久的。
或者,在 .NET 中可能有其他方法可以检测物理卡,或者如果您可以推荐一种可以提供不同信息的 API 调用,我会考虑调用其他 API。
还有其他想法吗?
在这里演示的是我的 iphone 系留时上面示例代码的输出:
DEBUG - NIC Down Ethernet 500000 0021E98BFBEF Apple Mobile Device Ethernet - Packet Scheduler Miniport
DEBUG - NIC Up Ethernet 10000000 444553544200 Nortel IPSECSHM Adapter - Packet Scheduler Miniport
DEBUG - NIC Down Ethernet 54000000 00166FAC94C7 Intel(R) PRO/Wireless 2200BG Network Connection - Packet Scheduler Miniport
DEBUG - NIC Down Ethernet 1000000000 0016D326E957 Broadcom NetXtreme Gigabit Ethernet - Packet Scheduler Miniport
DEBUG - NIC Up Loopback 10000000 MS TCP Loopback interface
没有连接 Iphone:
DEBUG - NIC Up Ethernet 10000000 444553544200 Nortel IPSECSHM Adapter - Packet Scheduler Miniport
DEBUG - NIC Down Ethernet 54000000 00166FAC94C7 Intel(R) PRO/Wireless 2200BG Network Connection - Packet Scheduler Miniport
DEBUG - NIC Down Ethernet 1000000000 0016D326E957 Broadcom NetXtreme Gigabit Ethernet - Packet Scheduler Miniport
DEBUG - NIC Up Loopback 10000000 MS TCP Loopback interface
【问题讨论】:
您还应该考虑具有多个相同类型 NIC 的计算机。 您不能依赖 MAC 地址作为唯一标识符。如果您想要一个唯一标识符,请生成一个 GUID,对其进行加密并将其存储在计算机上。 @John Saunders,我确实使用 GUID。 MAC 地址是一个备份,以防 GUID 的存储位置被删除。 查看我的回答***.com/a/40088578/1498252 以检查物理设备。 【参考方案1】:这是我的方法: 它利用物理卡连接到PCI接口的事实
ManagementObjectSearcher searcher = new ManagementObjectSearcher
("Select MACAddress,PNPDeviceID FROM Win32_NetworkAdapter WHERE MACAddress IS NOT NULL AND PNPDeviceID IS NOT NULL");
ManagementObjectCollection mObject = searcher.Get();
foreach (ManagementObject obj in mObject)
string pnp = obj["PNPDeviceID"].ToString();
if (pnp.Contains("PCI\\"))
string mac = obj["MACAddress"].ToString();
mac = mac.Replace(":", string.Empty);
return mac;
【讨论】:
我不认为这会满足这样的需求:amazon.co.uk/Belkin-Ethernet-Adapter-Patch-Cable/dp/B0002AFKN0 - 但是它们并不是那么普遍。 是的,这是个问题。我没有这样的设备,有趣的是,在这种情况下,“PNPDeviceID”中写的是什么。第二个问题是当有不止一张卡时。因为我总是取“第一张”牌,所以在“选择”运算符中的牌顺序不确定的情况下可能会导致错误。我没有在这个“SQL for WMI”方言中找到“order by”结构:) 我有一个适配器,其标题为“Broadcom BCM5709C NetXtreme II GigE(NDIS VBD 客户端)”和没有“PCI\”的 PNPDeviceID。它是物理的。 如何获取物理适配器的 IPv4 地址? (远程计算机)PhysicalAdapter
?网络适配器属性名称:NetEnabled - 值:True 网络适配器属性名称:PhysicalAdapter - 值:True 网络适配器属性名称:PNPDeviceID -值:PCI\VEN_15AD&DE【参考方案2】:
MAC 地址的前三个字节是制造商 ID。您可以将某些已知不适合您的制造商 ID 列入黑名单,并忽略这些接口。
依赖速度可能不是一个好主意,因为 *** 接口没有理由不能报告自己具有千兆速度。
【讨论】:
我考虑过列入黑名单...我认为根据描述中出现的字符串(例如:“***”、“IPSECSHM”...但是认为这很难想出。或者,我想我可以创建一个最流行的网络接口的白名单......“Realtek”,“Gigabit” - 我真的想避免创建和维护一个白名单。【参考方案3】:MAC 地址是物理硬件地址。我无法在这台电脑上进行测试,但我认为如果添加虚拟连接,您将不会获得新的 MAC 地址,因为它不是实际的硬件。这将是另一个连接,但不是另一个 MAC 地址。
因此,确保您每次都获得相同的 MAC 地址取决于连接到机器的相同硬件,并且您使用相同的算法从该硬件中进行选择。
【讨论】:
@Brian - MAC 地址也用于虚拟接口......在我的例子中是 Nortel Packet 接口。【参考方案4】:我也一直在研究这个问题,并且相信如果没有持久状态,就很难维持稳定的 MAC。
我正在玩弄的解决方案是获取在适配器顺序中找到的第一个 NIC,然后使用它并保存它。然后在后续的 UUID 生成中,如果在堆栈中的任何位置找到保存的 MAC,即使不是第一个,也要使用它。这样适配器订单可以移动,我们不用担心会炸毁任何依赖于稳定 MAC(例如许可模块)的东西。
如果在堆栈中找不到保存的 MAC,则将其丢弃,我们只需使用绑定顺序中的第一个 MAC 并重新开始。
【讨论】:
【参考方案5】: public static string GetMacAddressPhysicalNetworkInterface()
ManagementObjectSearcher searcher = new ManagementObjectSearcher
("Select MACAddress,PNPDeviceID FROM Win32_NetworkAdapter WHERE MACAddress IS NOT NULL AND" +
" PNPDeviceID IS NOT NULL AND" +
" PhysicalAdapter = true");
ManagementObjectCollection mObject = searcher.Get();
string macs = (from ManagementObject obj in mObject
let pnp = obj["PNPDeviceID"].ToString()
where !(pnp.Contains("ROOT\\"))
//where pnp.Contains("PCI\\") || pnp.Contains("USB\\")
select obj).Select(obj => obj["MACAddress"].ToString())
.Aggregate<string, string>(null, (mac, currentMac) => mac + currentMac.Replace(":", string.Empty) + ",");
return !string.IsNullOrEmpty(macs) ? macs.Substring(0, macs.Length - 1) : macs;
public static NetworkInterface GetPhysicalNetworkInterface(string macAddressPhysicalNetworkInterface)
return NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(currentNetworkInterface => string.Equals(currentNetworkInterface.GetPhysicalAddress().ToString(), macAddressPhysicalNetworkInterface, StringComparison.CurrentCultureIgnoreCase));
【讨论】:
一些解释/文档链接解释了为什么这个答案比其他答案更好会有所帮助。我确实喜欢“physicaladapter = true”检查,但可以依赖它吗? 勾选这个属性也够了 如何使用scope = "\\\\" + ip + "\\root\\cimv2";
获取GetPhysicalNetworkInterface
?以上是关于如何确定实际物理网卡的 MAC 地址——不是由 *** (.NET C#) 创建的虚拟网络接口的主要内容,如果未能解决你的问题,请参考以下文章