So bestimmen Sie die MAC -Adresse der tatsächlichen physischen Netzwerkkarte - nicht virtuelle Netzwerkschnittstellen, die von VPNs (.NET C#) erstellt wurden.

StackOverflow https://stackoverflow.com/questions/1567377

Frage

Hintergrund

Ich versuche, eine eindeutige Kennung aus einem Computer zu erhalten und möchte jedes Mal die gleiche MAC -Adresse zuverlässig zurückgeben. Vertrauen Sie mir, ich habe meine Gründe für die Verwendung von MAC -Adresse und habe viele Beiträge zu alternativen eindeutigen ID -Methoden gelesen (und ja, ich habe darüber nachgedacht, ob sie keine Netzwerkkarten haben).

Problem

Das Problem ist in .NET. Ich sehe sowieso nicht fest, ob ein bestimmtes Netzwerkinterface eine physische Hardware -Netzwerkkarte von so etwas wie einem "Nortel Ipsecshm Adapter - Paket Scheduler Miniport" ist, das hinzugefügt wird, wenn Sie eine Verbindung zu bestimmten VPNs oder WLI -Netzwerken herstellen.

Ich weiß, wie man die MAC -Adressen bekommt, indem sie einen ähnlichen Code verwenden:

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

Verständlicherweise gibt es keine 100% ige Möglichkeit, sicherzustellen, dass ich aber eine interne Netzwerkkarte erhalten würde Ich möchte die MAC -Adresse auswählen, um die für eine bestimmte Maschine zurückzugeben, die sich am wenigsten ändert. Unabhängig von Faktoren wie - ob es mit WLAN verbunden ist ... wird über eine Art von Tether -Verbindung verbunden ... oder sie installieren eine neue VPN -Software, die eine neue Schnittstelle hinzufügt.

Strategien berücksichtigt

1) Wählen Sie die erste Schnittstelle "Up". Dies scheitert an meinem Laptop, da das "Packet Miniport" immer abgelaufen ist. Wenn ich mein Handy an meinen Laptop verbinde, wird dies außerdem als erste Karte angezeigt.

2) Wählen Sie den am besten geeigneten Typ ... Dies schlägt b/c im Grunde genommen alles als "Ethernet", einschließlich WLAN -Adapter und meiner iPhone -Tethering -Internetverbindung.

3) Wählen Sie die NIC, die eine IP -Adresse hat. Aus mehreren Gründen schlägt aus mehreren Gründen aus: 1) Die Netzwerkkarte ist möglicherweise nicht an LAN 2) Es gibt mehrere NICs, die möglicherweise IP -Adressen haben.

4) Senden Sie einfach alle MAC -Adressen ... Problem ist, dass sich die Liste basierend auf installierter Software ändern würde und es schwierig zu vergleichen ist.

5) Wählen Sie die MAC -Adresse mit der schnellsten Geschwindigkeit. Ich denke, das ist wahrscheinlich meine beste Wahl. Ich denke, es ist sicher zu sagen, dass die schnellste Schnittstelle normalerweise die dauerhafteste sein wird.

Alternativ kann es eine andere Möglichkeit geben, physische Karten in .NET zu erkennen, oder ich würde in Betracht ziehen, andere API -Anrufe aufzurufen, wenn Sie einen empfehlen könnten, der unterschiedliche Informationen liefert.

Irgendwelche anderen Ideen?

Hier zu demonstrieren ist die Ausgabe meines Beispielcodes oben, wenn ich mein iPhone gebunden habe:

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

Ohne iPhone angeschlossen:

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
War es hilfreich?

Lösung

Dies ist meine Methode: Sie verwendet die Tatsache, dass die physische Karte mit der PCI -Schnittstelle verbunden ist

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;
    }
}

Andere Tipps

Die ersten drei Bytes der MAC -Adresse sind eine Hersteller -ID. Sie können bestimmte Hersteller -IDs, von denen bekannt ist, dass sie für Ihre Zwecke ungeeignet sind, schwarze Liste und ignorieren diese Schnittstellen.

Es ist wahrscheinlich keine gute Idee, sich auf die Geschwindigkeit zu verlassen, da es keinen Grund gibt, warum sich eine VPN -Schnittstelle nicht als Gigabit -Geschwindigkeit angeben kann.

MAC -Adressen sind physische Hardwareadressen. Ich kann nicht auf diesem PC testen, aber ich glaube nicht, dass Sie eine neue MAC -Adresse erhalten, wenn eine virtuelle Verbindung hinzugefügt wird, da es sich nicht um ein tatsächliches Stück Hardware handelt. Es wird eine andere Verbindung sein, aber keine andere MAC -Adresse.

Wenn Sie also garantieren, dass Sie jedes Mal dieselbe MAC -Adresse erhalten, hängt davon ab, dass dieselben Hardware -Teile an der Maschine angebracht werden und Sie denselben Algorithmus verwenden, um diese Hardware auszuwählen.

Ich habe mir auch dieses Problem angesehen und glaube, dass es ohne anhaltenden Zustand schwierig sein wird, einen stabilen Mac aufrechtzuerhalten.

Die Lösung, mit der ich spiele, ist die erste NIC, die in der Adapterreihenfolge gefunden wird, und nutze das und rette es. Verwenden Sie dann nach den nachfolgenden UUID -Generationen den gespeicherten Mac, wenn er irgendwo im Stapel gefunden wird, auch wenn nicht der erste. Auf diese Weise kann sich die Adapterreihenfolge bewegen, und wir machen uns keine Sorgen, dass das, was vom stabilen Mac abhängt (z. B. ein Lizenzmodul), in die Luft sprengen kann.

Wenn der gespeicherte Mac nicht im Stapel gefunden wird, wird er verworfen und wir verwenden nur den ersten Mac in der Bindungsreihenfolge und beginnen von vorne.

 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));
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top