2008-10-09 30 views

Respuesta

23

SendARP P/Invoke es así:

[DllImport("iphlpapi.dll", ExactSpelling=true)] 
public static extern int SendARP(int destIp, int srcIP, byte[] macAddr, ref uint physicalAddrLen); 

PInvoke.NET tiene este ejemplo:

IPAddress dst = IPAddress.Parse("192.168.2.1"); // the destination IP address 

byte[] macAddr = new byte[6]; 
uint macAddrLen = (uint)macAddr.Length; 

if (SendARP(BitConverter.ToInt32(dst.GetAddressBytes(), 0), 0, macAddr, ref macAddrLen) != 0) 
    throw new InvalidOperationException("SendARP failed."); 

string[] str = new string[(int)macAddrLen]; 
for (int i=0; i<macAddrLen; i++) 
    str[i] = macAddr[i].ToString("x2"); 

Console.WriteLine(string.Join(":", str)); 
+2

Lo que debe saber acerca de esta respuesta que he descubierto durante las pruebas en Windows XP utilizando Wireshark: 1) Si el par de direcciones IP/MAC ya está en la caché ARP, el paquete de petición ARP no se enviará a cabo en la red, pero SendARP aún devolverá la macAddress (potencialmente obsoleta) que tiene en su caché. 2) Este método es potencialmente muy lento si se usa solo un hilo. El bucle a través de una subred completa de direcciones IP (por ejemplo, 192.168.1.x) con un solo hilo tomó más de 250 segundos (1 segundo por dirección IP). Hacerlo de múltiples subprocesos tomó menos de un segundo para las más de 250 direcciones. – Pretzel

1

gancho en el subsistema de WMI. Parte del código VBScript para conseguir que va en la dirección correcta es here

1

Para encontrar su propia:

agregar una referencia a System.Management

ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration"); 

ManagementObjectCollection mcCol = mc.GetInstances(); 

foreach (ManagementObject mcObj in mcCol) 
{ 
    Console.WriteLine(mcObj["Caption"].ToString()); 
    Console.WriteLine(mcObj["MacAddress"].ToString()); 
} 

No está seguro de encontrar el de otro dispositivo.

1

Aquí está mi solución.

public static class MacResolver 
{ 
    /// <summary> 
    /// Convert a string into Int32 
    /// </summary> 
    [DllImport("Ws2_32.dll")] 
    private static extern Int32 inet_addr(string ip); 

    /// <summary> 
    /// The main funtion 
    /// </summary> 
    [DllImport("Iphlpapi.dll")] 
    private static extern int SendARP(Int32 dest, Int32 host, ref Int64 mac, ref Int32 len); 

    /// <summary> 
    /// Returns the MACAddress by a string. 
    /// </summary> 
    public static Int64 GetRemoteMAC(string remoteIP) 
    { 
     Int32 ldest = inet_addr(remoteIP); 

     try 
     { 
      Int64 macinfo = 0;   
      Int32 len = 6;   

      int res = SendARP(ldest, 0, ref macinfo, ref len); 

      return macinfo;  
     } 
     catch (Exception e) 
     { 
      return 0; 
     } 
    } 

    /// <summary> 
    /// Format a long/Int64 into string. 
    /// </summary> 
    public static string FormatMac(this Int64 mac, char separator) 
    { 
     if (mac <= 0) 
      return "00-00-00-00-00-00"; 

     char[] oldmac = Convert.ToString(mac, 16).PadLeft(12, '0').ToCharArray(); 

     System.Text.StringBuilder newMac = new System.Text.StringBuilder(17); 

     if (oldmac.Length < 12) 
      return "00-00-00-00-00-00"; 

     newMac.Append(oldmac[10]); 
     newMac.Append(oldmac[11]); 
     newMac.Append(separator); 
     newMac.Append(oldmac[8]); 
     newMac.Append(oldmac[9]); 
     newMac.Append(separator); 
     newMac.Append(oldmac[6]); 
     newMac.Append(oldmac[7]); 
     newMac.Append(separator); 
     newMac.Append(oldmac[4]); 
     newMac.Append(oldmac[5]); 
     newMac.Append(separator); 
     newMac.Append(oldmac[2]); 
     newMac.Append(oldmac[3]); 
     newMac.Append(separator); 
     newMac.Append(oldmac[0]); 
     newMac.Append(oldmac[1]); 

     return newMac.ToString(); 
    } 
} 
+0

Esto devuelve una dirección Mac válida solo cuando se usa una dirección IP, mientras que usando el nombre de host la dirección MAC es incorrecta. –

Cuestiones relacionadas