2008-10-09 236 views

回答

23

SendARP P /调用是这样的:

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

PInvoke.NET具有这个例子:

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

事情知道这个答案,我在使用Wireshark的Windows XP上测试发现: 1)如果IP/MAC地址对已存在的ARP缓存,ARP请求报文会不会出上发送网络,但SendARP仍然会返回它的缓存中的(可能过时的)macAddress。 2)如果仅使用单个线程,此方法可能非常慢。使用单线程遍历IP地址的完整子网(例如192.168.1.x)花费了250+秒(每个IP地址1秒)。对于所有250个以上的地址,大规模地使用多线程需要不到一秒的时间。 – Pretzel 2009-07-20 18:23:13

1

钩入WMI子系统。一些VBScript代码以获得正确的方向前进是here

1

要找出你自己:

添加一个参考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()); 
} 

不知道要找到另一个设备。

1

这是我的解决方案。

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

仅当使用IP地址时才返回有效的Mac地址,而使用主机名时MAC地址错误。 – 2017-03-27 06:28:12