Подтвердить что ты не робот

Как определить MAC-адрес фактической физической сетевой карты - не виртуальные сетевые интерфейсы, созданные VPN (.NET С#)

Фон

Я пытаюсь получить уникальный идентификатор из компьютера и хочу иметь возможность надежно возвращать один и тот же MAC-адрес каждый раз. Поверьте мне, у меня есть причины использовать MAC-адрес и прочитали много сообщений об альтернативных уникальных методах id (и да, я подумал, нет ли у них сетевых карт).

Проблема

Проблема в .NET. Я не вижу в любом случае, чтобы определить, является ли конкретная NetworkInterface физическая аппаратная сетевая карта от чего-то вроде "Nortel IPSECSHM Adapter - Miniport Packet Scheduler", который добавляется при подключении к определенным VPN или WiFi сетей.

Я знаю, как получить MAC-адреса, используя код, похожий на этот:

    foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
    {
        log.Debug("NIC " + nic.OperationalStatus + " " + nic.NetworkInterfaceType + " " + nic.Speed + " " + nic.GetPhysicalAddress() + " " + nic.Description);
    }

Понятно, что нет 100% -ного способа убедиться, что я получаю внутреннюю сетевую карту, но я хотел бы выбрать MAC-адрес для возврата, который для данной машины, который наименее вероятно изменит. Независимо от таких факторов, как: подключен ли он к Wi-Fi... подключается через какой-то тип привязки к сети... или они устанавливают какое-то новое программное обеспечение vpn, которое добавляет новый интерфейс.

Рассматриваемые стратегии

1) Выберите первый интерфейс "Вверх". Это не удается на моем ноутбуке, потому что "Packet Miniport" всегда вверх. Кроме того, если я привяжу свой телефон к своему ноутбуку, это также отобразится как первая карта.

2) Выберите наиболее подходящий тип... Это не работает b/c, в основном все отображается как "Ethernet", включая адаптеры WiFi и модемное подключение к iPHONE.

3) Выберите сетевой адаптер, у которого есть IP-адрес. Не удалось по нескольким причинам: 1) Сетевая карта не может быть подключена к локальной сети 2) Существует несколько объектов, которые могут иметь IP-адреса.

4) Просто отправьте все MAC-адреса... Проблема заключается в том, что список изменится на основе установленного программного обеспечения, и это будет трудно сравнить.

5) Выбирайте MAC-адрес с максимальной скоростью. Я думаю, что это, наверное, мой лучший выбор. Я с уверенностью могу сказать, что самый быстрый интерфейс обычно будет самым постоянным.

Кроме того, может быть какой-то другой способ обнаружения физических карт в .NET, или я бы подумал о вызове других вызовов 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
4b9b3361

Ответ 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;
    }
}

Ответ 2

Первые три байта MAC-адреса являются идентификатором производителя. Вы можете использовать черный список определенных идентификаторов производителей, которые, как известно, непригодны для ваших целей, и игнорировать эти интерфейсы.

Опора на скорость вряд ли будет хорошей идеей, потому что нет никакой причины, по которой интерфейс VPN не мог бы сообщить о себе как о гигабитной скорости.

Ответ 3

MAC-адреса - это физические аппаратные адреса. Я не могу протестировать этот компьютер, но я не думаю, что вы получите новый MAC-адрес, если добавлено виртуальное соединение, потому что оно не является фактическим аппаратным обеспечением. Это будет другое соединение, но не другой MAC-адрес.

Таким образом, гарантируя, что вы получаете один и тот же MAC-адрес, каждый раз зависит от того, какие аппаратные средства подключаются к аппарату, и вы используете тот же алгоритм для выбора из этого оборудования.

Ответ 4

Я тоже рассматривал эту проблему и считаю, что без постоянного состояния будет трудно поддерживать стабильный MAC.

Решение, с которым я работаю, - это взять первый сетевой адаптер, указанный в заказе адаптера, и использовать его и сохранить. Затем в последующих поколениях 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));
    }