2012-10-09 174 views
7

我正在尝试编写一个函数,它将单个IP address作为参数,并在本地网络上查询该机器的地址为MAC address从本地网络的IP地址获取本机网络上的机器MAC地址#

我见过很多例子,得到本地机器自己MAC address,但是没有(我发现),似乎查询本地网络机器。

我知道这样的任务是可以实现的,因为这Wake on LAN scanner软件扫描本地IP范围和返回所有的机器的MAC地址/主机名。

谁能告诉我在哪里,我开始试图写一个函数在C#来实现这一目标?任何帮助,将不胜感激。由于

编辑:

按照下面的Marco熔点的评论,已经使用ARP表。 arp class

+0

不知道它的工作原理,但有一个快速谷歌搜索,我发现这个库,它应该做的伎俩:HTTP:// WWW。 tamirgal.com/blog/post/ARP-Resolver-C-Class.aspx](http://www.tamirgal.com/blog/post/ARP-Resolver-C-Class.aspx) –

+0

谢谢你,我相信我读过ARP表是不一致的,并想知道是否有办法为MAC地址“ping”。 –

+1

我**认为**如果您定期ping(或以其他方式尝试联系)IP地址,则会导致ARP表刷新(否则网络堆栈将无法首先与机器联系);当然这(如果有的话)只有当所需的机器在线时才起作用。我不认为你可以得到离线IP地址的可靠结果,特别是如果你有动态分配的IP地址。 虽然我不是网络专家,但我可能是错的(试着和你一起思考问题)。 –

回答

0

根据上面的Marco Mp的评论,使用了ARP表。 arp class

+0

贵国的问题问的“获取IP,并找到MAC地址”,并要求ARP代替RARP(MAC得到并返回你当前使用的IP /主机)。你最终在这里结束了吗? 2. 网站你指的是使用过程中的错误definiton(MAC到IP是RARP的替代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"; 
    } 
} 

很晚编辑: 在开放的烃源项目ISPY(https://github.com/ispysoftware/iSpy),他们使用此代码,这是一个更好一点

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

更新2甚至更多晚了,但我认为最好,因为它使用正则表达式来更好地检查完全匹配。

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

这是。对于后代替@Macro熔点答案.....为什么正确的答不是这个选择作为答案? – Khan

+0

为什么它不显示自己的PC MAC,但发现其他所有? – Khan

+1

@Khan可能是因为您不需要将自己的IP存储在ARP表中,因为您已经知道了您自己的IP和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) { } 

或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

你的代码非常混乱。我从来没有见过类似的东西!我认为你必须澄清并整理你的代码才能赢得一些声誉。 –