How to get a Mac-Address from a LAN IP using .NET Core on Linux?

4

I already have tools that can identify the Mac-Address of the devices in my network, as long as the 'server' or the application is running in Windows and .NET Framework.

I have used the following:

using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
namespace Yordi.Ferramentas
{
    /// <summary>
    /// Ferramentas para rede local
    /// </summary>
    public static class Rede
    {
        private static string _erro;
        public static string ErrorMessage { get { return _erro; } }
        [DllImport("iphlpapi.dll", ExactSpelling = true)]
        public static extern int SendARP(int DestIP, int SrcIP, byte[] pMacAddr, ref uint PhyAddrLen);
        /// <summary>
        /// Recupera o MAC Address de um equipamento na rede local baseado em seu IP
        /// </summary>
        /// <param name="ip">IP em formato string (Ex: 192.168.0.10)</param>
        /// <returns>String com o MAC Address no formato XX-XX-XX-XX-XX</returns>
        public static string TryGetMacAddress(string ip)
        {
            try
            {
                IPAddress IP = IPAddress.Parse(ip);
                byte[] macAddr = new byte[6];
                uint macAddrLen = (uint)macAddr.Length;
                if (SendARP((int)IP.Address, 0, macAddr, ref macAddrLen) != 0)
                {
                    _erro = "Não foi possível executar comando ARP";
                    return String.Empty;
                }
                string[] str = new string[(int)macAddrLen];
                for (int i = 0; i < macAddrLen; i++)
                    str[i] = macAddr[i].ToString("x2");
                return string.Join("-", str);
            }
            catch (Exception e)
            {
                _erro = e.Message;
            }
            return String.Empty;
        }
        /// <summary>
        /// Dado um ip que pertença a mesma rede, o MAC Address será dado 
        /// </summary>
        /// <param name="ip">IP que pertença à rede</param>
        /// <returns>string com os bytes separados por hífen</returns>
        public static string GetMyMacAddress(string ip)
        {
            NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
            foreach (NetworkInterface adapter in nics)
            {
                foreach (UnicastIPAddressInformation unip in adapter.GetIPProperties().UnicastAddresses)
                {
                    if (unip.Address.AddressFamily == AddressFamily.InterNetwork)
                    {
                        if (unip.Address.ToString() == ip)
                        {
                            PhysicalAddress address = adapter.GetPhysicalAddress();
                            return BitConverter.ToString(address.GetAddressBytes());
                        }
                    }
                }
            }
            return null;
        }
    }
}

The way to get Mac-Address from the machine itself is to use the .NET NetworkInterface class (in use in the GetMyMacAddress (string ip) method). To try to get Mac-Address from another device on the local network is by using the command arp . To call it in Windows I have to import a dll from the system: [DllImport("iphlpapi.dll", ExactSpelling = true)] I refer to it: public static extern int SendARP(int DestIP, int SrcIP, byte[] pMacAddr, ref uint PhyAddrLen); And I use it here: SendARP((int)IP.Address, 0, macAddr, ref macAddrLen)

As I'm porting the .NET Core application to run on a Raspberry PI 3 on Linux, I want to know how to do the same process on Linux (this is the correct way to do it on that system).

The NetworkInterface class also exists in the .NET Core, under the System.Net.NetworkInformation namespace.

But how to get Mac-Address from an IP of another machine (on Linux with .NET Core)?

    
asked by anonymous 26.10.2017 / 21:32

1 answer

2

Friend, sorry to not answer .NET but in Linux you can find the mac of an ip with the command arping .

Syntax: arping -S -w2000 -i -C1 -R -r | tail -n1

arping -S 192.168.0.8 192.168.0.170 -w2000 -i eth0 -C1 -R -r | tail -n1

Where "IP1" is the IP of the machine that is sending the request, and IP2 is the destination machine. With the syntax above you will have the result down

9c:2a:83:21:4e:91 192.168.0.170

Read the link below to adjust the command as needed.

link

Create an auxiliary class as follows:

using System;
using System.Diagnostics;
    public static class ShellHelper
    {
        public static string Bash(this string cmd)
        {
            var escapedArgs = cmd.Replace("\"", "\\"");

            var process = new Process()
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = "/bin/bash",
                    Arguments = $"-c \"{escapedArgs}\"",
                    RedirectStandardOutput = true,
                    UseShellExecute = false,
                    CreateNoWindow = true,
                }
            };
            process.Start();
            string result = process.StandardOutput.ReadToEnd();
            process.WaitForExit();
            return result;
        }
    }

Now you can execute any command in bash as follows

var output = "arping -S 192.168.0.8 192.168.0.170 -w2000 -i eth0 -C1 -R -r | tail -n1".Bash();

This should work.

    
27.10.2017 / 14:56