Get a machines MAC address on the local network from its IP in C#

后端 未结 4 783
情深已故
情深已故 2020-12-09 05:34

I am trying write a function that takes a single IP address as a parameter and queries that machine on my local network for it\'s MAC address.

相关标签:
4条回答
  • 2020-12-09 05:52
    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) { }
    

    or with PC Name

    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 讨论(0)
  • 2020-12-09 05:57

    Just a better performing version of the accepted method.

        public string GetMacByIp( string ip )
        {
            var pairs = this.GetMacIpPairs();
    
            foreach( var pair in pairs )
            {
                if( pair.IpAddress == ip )
                    return pair.MacAddress;
            }
    
            throw new Exception( $"Can't retrieve mac address from ip: {ip}" );
        }
    
        public IEnumerable<MacIpPair> GetMacIpPairs()
        {
            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 ) )
            {
                yield return new MacIpPair()
                {
                    MacAddress = m.Groups[ "mac" ].Value,
                    IpAddress = m.Groups[ "ip" ].Value
                };
            }
        }
    
        public struct MacIpPair
        {
            public string MacAddress;
            public string IpAddress;
        }
    
    0 讨论(0)
  • 2020-12-09 06: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";
        }
    }
    

    Very late edit: In open souce project iSpy (https://github.com/ispysoftware/iSpy) they use this code, which is a little nicer

      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

    Update 2 even more late, but I think is best because it uses regex that checks better for exact matches.

    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;
    }
    
    0 讨论(0)
  • 2020-12-09 06:16

    As per Marco Mp's comment above, have used ARP tables. arp class

    0 讨论(0)
提交回复
热议问题