2012-10-09 76 views
7

Estoy intentando escribir una función que toma un solo IP address como parámetro y consulta esa máquina en mi red local para su MAC address.Obtener una dirección MAC de máquinas en la red local desde su IP en C#

he visto muchos ejemplos que obtienen de la propia máquina local MAC address, sin embargo ninguno (que he encontrado) que parecen para consultar una máquina de red local para ello.

Sé que tal tarea es posible ya que este software Wake on LAN scanner escanea el rango de IP local y devuelve la dirección MAC/nombre de host de todas las máquinas.

¿Alguien puede decirme dónde comenzaría tratando de escribir una función para lograr esto en C#? Cualquier ayuda sería apreciada. Gracias

EDIT:

De acuerdo con el comentario de Marco Pf a continuación, se han utilizado las tablas ARP. arp class

+0

No estoy seguro si funciona, pero con una rápida búsqueda en Google me encontré con esta biblioteca, que debe hacer el truco: [http: // www. tamirgal.com/blog/post/ARP-Resolver-C-Class.aspx](http://www.tamirgal.com/blog/post/ARP-Resolver-C-Class.aspx) –

+0

Gracias, creo que He leído que las tablas ARP son inconsistentes y me preguntaba si había una forma de 'ping' para la dirección MAC. –

+1

Pienso ** que si realiza un ping regular (o intenta contactar) la dirección IP provocará que las tablas ARP se actualicen (de lo contrario, la pila de red no podría contactarse con la máquina en primer lugar); por supuesto, esto funcionará (si es que lo hace) solo si la máquina deseada está en línea. No creo que pueda obtener resultados confiables para las direcciones IP sin conexión, especialmente si ha asignado direcciones IP dinámicamente. No soy un experto en redes, por lo que podría estar equivocado (tratando de pensar con usted sobre el problema). –

Respuesta

0

De acuerdo con el comentario de Marco Pf anteriormente, se han utilizado las tablas ARP. arp class

+0

1. Su pregunta pide "para obtener una IP y conocer la dirección MAC" y exige ARP en lugar de RARP (Get MAC y devolver IP/host que está utilizando actualmente). ¿Cómo terminó aquí? 2.El sitio al que se refiere está utilizando la definición errónea del proceso (MAC a IP es RARP en lugar de ARP) ... – Khan

13
public string GetMacAddress(string ipAddress) 
{ 
    string macAddress = string.Empty; 
    System.Diagnostics.Process pProcess = new System.Diagnostics.Process(); 
    pProcess.StartInfo.FileName = "arp"; 
    pProcess.StartInfo.Arguments = "-a " + ipAddress; 
    pProcess.StartInfo.UseShellExecute = false; 
    pProcess.StartInfo.RedirectStandardOutput = true; 
     pProcess.StartInfo.CreateNoWindow = true; 
    pProcess.Start(); 
    string strOutput = pProcess.StandardOutput.ReadToEnd(); 
    string[] substrings = strOutput.Split('-'); 
    if (substrings.Length >= 8) 
    { 
     macAddress = substrings[3].Substring(Math.Max(0, substrings[3].Length - 2)) 
       + "-" + substrings[4] + "-" + substrings[5] + "-" + substrings[6] 
       + "-" + substrings[7] + "-" 
       + substrings[8].Substring(0, 2); 
     return macAddress; 
    } 

    else 
    { 
     return "not found"; 
    } 
} 

Muy tarde editar: En proyecto Souce abierta iSpy (https://github.com/ispysoftware/iSpy) que utilizan este código, que es un poco más agradable

public static void RefreshARP() 
     { 
      _arpList = new Dictionary<string, string>(); 
      _arpList.Clear(); 
      try 
      { 
       var arpStream = ExecuteCommandLine("arp", "-a"); 
       // Consume first three lines 
       for (int i = 0; i < 3; i++) 
       { 
        arpStream.ReadLine(); 
       } 
       // Read entries 
       while (!arpStream.EndOfStream) 
       { 
        var line = arpStream.ReadLine(); 
        if (line != null) 
        { 
         line = line.Trim(); 
         while (line.Contains(" ")) 
         { 
          line = line.Replace(" ", " "); 
         } 
         var parts = line.Trim().Split(' '); 

         if (parts.Length == 3) 
         { 
          string ip = parts[0]; 
          string mac = parts[1]; 
          if (!_arpList.ContainsKey(ip)) 
           _arpList.Add(ip, mac); 
         } 
        } 
       } 
      } 
      catch (Exception ex) 
      { 
       Logger.LogExceptionToFile(ex, "ARP Table"); 
      } 
      if (_arpList.Count > 0) 
      { 
       foreach (var nd in List) 
       { 
        string mac; 
        ARPList.TryGetValue(nd.IPAddress.ToString(), out mac); 
        nd.MAC = mac;  
       } 
      } 
     } 

https://github.com/ispysoftware/iSpy/blob/master/Server/NetworkDeviceList.cs

Actualización 2 aún más tarde, pero creo que es mejor porque usa expresiones regulares que verifica mejor las coincidencias exactas.

public string getMacByIp(string ip) 
{ 
    var macIpPairs = GetAllMacAddressesAndIppairs(); 
    int index = macIpPairs.FindIndex(x => x.IpAddress == ip); 
    if (index >= 0) 
    { 
     return macIpPairs[index].MacAddress.ToUpper(); 
    } 
    else 
    { 
     return null; 
    } 
} 

public List<MacIpPair> GetAllMacAddressesAndIppairs() 
{ 
    List<MacIpPair> mip = new List<MacIpPair>(); 
    System.Diagnostics.Process pProcess = new System.Diagnostics.Process(); 
    pProcess.StartInfo.FileName = "arp"; 
    pProcess.StartInfo.Arguments = "-a "; 
    pProcess.StartInfo.UseShellExecute = false; 
    pProcess.StartInfo.RedirectStandardOutput = true; 
    pProcess.StartInfo.CreateNoWindow = true; 
    pProcess.Start(); 
    string cmdOutput = pProcess.StandardOutput.ReadToEnd(); 
    string pattern = @"(?<ip>([0-9]{1,3}\.?){4})\s*(?<mac>([a-f0-9]{2}-?){6})"; 

    foreach (Match m in Regex.Matches(cmdOutput, pattern, RegexOptions.IgnoreCase)) 
    { 
     mip.Add(new MacIpPair() 
     { 
      MacAddress = m.Groups["mac"].Value, 
      IpAddress = m.Groups["ip"].Value 
     }); 
    } 

    return mip; 
} 
public struct MacIpPair 
{ 
    public string MacAddress; 
    public string IpAddress; 
} 
+2

esta es la respuesta correcta para la publicación en lugar de @Macro Mp ..... ¿por qué? no esta seleccionado como una respuesta? – Khan

+0

¿Por qué no muestra PC MAC propio pero encuentra el resto? – Khan

+1

@Khan probablemente porque no hay necesidad de almacenar su propia IP en la tabla ARP ya que ya conoce su propia IP y MAC –

0
using System.Net; 
using System.Runtime.InteropServices; 

[DllImport("iphlpapi.dll", ExactSpelling = true)] 
public static extern int SendARP(int DestIP, int SrcIP, [Out] byte[] pMacAddr, ref int PhyAddrLen); 

try 
{ 
    IPAddress hostIPAddress = IPAddress.Parse("XXX.XXX.XXX.XX"); 
    byte[] ab = new byte[6]; 
    int len = ab.Length, 
     r = SendARP((int)hostIPAddress.Address, 0, ab, ref len); 
    Console.WriteLine(BitConverter.ToString(ab, 0, 6)); 
} 
catch (Exception ex) { } 

o con nombre de PC

try 
     { 
      Tempaddr = System.Net.Dns.GetHostEntry("DESKTOP-xxxxxx"); 
     } 
     catch (Exception ex) { } 
     byte[] ab = new byte[6]; 
     int len = ab.Length, r = SendARP((int)Tempaddr.AddressList[1].Address, 0, ab, ref len); 
     Console.WriteLine(BitConverter.ToString(ab, 0, 6)); 
+0

Su código es muy complicado. ¡Nunca he visto algo similar! Creo que tienes que aclarar y ordenar tu código para ganar reputación. –

Cuestiones relacionadas