Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

I have seen many examples that get the local machine's own MAC address, however none (I've found) that seem to query a local network machine for it.

I know such a task is achievable as this Wake on LAN scanner software scans the local IP range and returns MAC address/Hostname of all on machines.

Can anyone tell me where I'd get started trying to write a function to achieve this in C#? Any help would be appreciated. Thanks

EDIT:

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

like image 873
Gga Avatar asked Oct 09 '12 14:10

Gga


People also ask

Can you get MAC address from IP address?

It is often impossible to determine a computer's MAC address from its IP address alone because these two addresses originate from different sources. A computer's hardware configuration determines its MAC address, while the network configuration it is connected to determines its IP address.

How do I find the MAC address of a device on my network using CMD?

Windows devices To Find the MAC Address: Open a Command Prompt -> type ipconfig /all and press Enter-> The Physical Address is the MAC address. Click Start or click in the search box and type cmd. Press Enter, or click on the Command Prompt shortcut.

How do I find the MAC address of an IP address?

What to Know. Ping the device you want to find a MAC address for using the local network address. Then, enter the ARP command. Look for the IP address in the results. The Mac address is next to the IP address. This article explains how to find a MAC address using an IP address by using the command line utility ARP.

Is it possible to get the local machine's own MAC address?

I have seen many examples that get the local machine's own MAC address, however none (I've found) that seem to query a local network machine for it. I know such a task is achievable as this Wake on LAN scanner software scans the local IP range and returns MAC address/Hostname of all on machines.

How to find the IP address of a computer in Linux?

Step 1 – Open the Linux terminal and run the following command: You should get the IP and Mac address on the following screen: Step 2 – You can also run the following command to get the IP and Mac address: You should see the following screen:

How to find the MAC address of a device using ARP?

How to Use ARP to Find a MAC Address 1 Start by pinging the device you want the MAC to address for: ping 192.168.86.45 2 Use a local address, so if your network is 10.0.1.x, then use that number to ping. ... 3 Use the following ARP command to get a list that shows the MAC address of the device you pinged: arp -a Plus d'articles...


3 Answers

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));
like image 169
user8338498 Avatar answered Oct 02 '22 03:10

user8338498


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;
}
like image 44
online Thomas Avatar answered Oct 02 '22 02:10

online Thomas


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;
    }
like image 32
Mauro Sampietro Avatar answered Oct 02 '22 02:10

Mauro Sampietro