Come determinare l'indirizzo MAC della scheda di rete fisica attuale - interfacce di rete non virtuali create con VPN (NET C #)

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

Domanda

Sfondo

Sto cercando di ottenere ottenere un identificatore univoco di un computer e vogliono essere in grado di restituire in modo affidabile lo stesso indirizzo MAC di volta in volta. Fidati di me Ho le mie ragioni per l'utilizzo di indirizzo MAC e ho letto molti post sui metodi di identificazione unici alternati (e sì che ho considerato se non hanno alcuna carta di rete).

Problema

Il problema è in .NET non vedo comunque per dire se un NetworkInterface specifico è una scheda di rete hardware fisico da qualcosa come un "Nortel IPSECSHM Adapter - Utilità di pianificazione pacchetti Miniport" che vengono aggiunti quando ci si connette a certi VPN o reti WiFi.

So come ottenere gli indirizzi MAC utilizzando il codice simile a questo:

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

Comprensibilmente non c'è modo al 100% per essere sicuri che sarei diventando una scheda di rete interna, ma mi piacerebbe raccogliere l'indirizzo MAC di restituire, che per un dato macchina che è meno probabilità di cambiare . Indipendente da fattori come -. Se è collegato al WiFi ... viene collegati mediante un certo tipo di collegamento cavezza ... o installano un nuovo software VPN che aggiunge una nuova interfaccia

strategie considerate

1) Scegliere la prima interfaccia che è "Up". Ciò non è riuscito sul mio computer portatile, perché il "Packet Miniport" è sempre alto. Inoltre, se Tether mio telefono al mio portatile questo dimostra anche come la prima carta.

2) Scegliere il tipo più appropriato ... Questa non b / c in fondo tutto si presenta come "Ethernet", tra cui adattatori WiFi e la mia connessione internet iPhone legare.

3) Scegliere la scheda di rete che ha un indirizzo IP. Non riesce per diversi motivi: 1) Scheda di rete potrebbe non essere collegato alla LAN 2) Non ci sono più schede di rete che potrebbero avere indirizzi IP

.

4) Basta inviare tutti gli indirizzi MAC ... Il problema è che la lista sarebbe cambiare in base software installato e sarà difficile confrontare.

5) Scegliere l'indirizzo MAC con la massima velocità. Penso che questa è probabilmente la mia scommessa migliore. Penso che sia giusto dire che l'interfaccia più veloce è di solito sta per essere il più permanente.

In alternativa, ci può essere qualche altro modo per rilevare le schede fisiche in .NET o mi piacerebbe prendere in considerazione come invocare altre chiamate API se si potrebbe raccomandare uno che fornirà informazioni diverse.

Tutte le altre idee?

Per dimostrare qui è l'uscita del mio codice di esempio sopra quando ho il mio iphone legato:

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

Senza Iphone Connesso:

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
È stato utile?

Soluzione

Questo è il mio metodo: usa il fatto che la carta fisica è collegata all'interfaccia 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;
    }
}

Altri suggerimenti

I primi tre byte dell'indirizzo MAC sono un ID produttore. Si potrebbe inserire nella blacklist alcune ID produttore note per essere inadatto per i vostri scopi, e ignorare queste interfacce.

Basandosi sulla velocità non è probabile che sia una buona idea, perché non c'è alcun motivo per cui un'interfaccia VPN non si potrebbe riferire ad avere velocità gigabit.

indirizzi MAC sono indirizzi hardware fisico. Non posso provare su questo pc, ma non credo si otterrà un nuovo indirizzo MAC, se si aggiunge una connessione virtuale, perché non è un pezzo reale di hardware. Sarà un altro collegamento, ma non un altro indirizzo MAC.

Quindi, garantendo che si ottiene lo stesso indirizzo MAC ogni volta dipende dagli stessi pezzi di hardware di essere attaccato alla macchina e si utilizza lo stesso algoritmo per scegliere da che l'hardware.

Ho cercato in questo problema come bene, e credo che senza stato persistente che sta per essere difficile da mantenere un MAC stabile.

La soluzione che sto giocando con è prendere la prima scheda di rete trovata nell'ordine adattatore e l'uso che e salvarlo . Poi nelle successive generazioni UUID, usare il MAC salvato se è trovato in qualsiasi parte dello stack, anche se non il primo. In questo modo l'ordine adattatore può muoversi e noi non preoccuparsi di far saltare in aria tutto ciò dipende dal MAC stabile (ad esempio un modulo di autorizzazione).

Se il MAC salvato non si trova nello stack, è scartato e noi basta usare il primo MAC nell'ordine di binding e ricominciare da capo.

 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));
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top