0

I have an application made with C# for Android, which searches for all devices connected on my local network by pinging.

With the IPs that exist response, I get the HostName of each device as follows:

private string GetHostName(string ipAddress)
{
   try
   {
      IPHostEntry entry = Dns.GetHostEntry(ipAddress);
      if (entry != null)
      {
       return entry.HostName;
      }
   }
   catch (SocketException)
   {
      return "n/n";
   }

   return "";
}

I also need to get the MAC address from the IP address. I can't get an example in C# for android (Xamarin)

Is there a way to do it?

UPDATE:

In the first comment to the question, someone has provided a link to a similar thread.

The solution is the next:

public string GetMacByIP(string ipAddress)
{
   try 
   { 
    // grab all online interfaces
    var query = NetworkInterface.GetAllNetworkInterfaces()
       .Where(n =>
              n.OperationalStatus == OperationalStatus.Up && // only grabbing what's online
              n.NetworkInterfaceType != NetworkInterfaceType.Loopback)
             .Select(_ => new
             {
                 PhysicalAddress = _.GetPhysicalAddress(),
                 IPProperties = _.GetIPProperties(),
             });
            // grab the first interface that has a unicast address that matches your search string
            var mac = query
                .Where(q => q.IPProperties.UnicastAddresses
                    .Any(ua => ua.Address.ToString() == ipAddress))
                .FirstOrDefault()
                .PhysicalAddress;

            // return the mac address with formatting (eg "00-00-00-00-00-00")
            return String.Join("-", mac.GetAddressBytes().Select(b => b.ToString("X2")));
        }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

But it only works from the device from where the query is being made, for all the others an exception is thrown in var mac = query .Where(q => q.IPProperties.UnicastAddresses and the error is: 'Object reference not set to an instance of an object

Without try and catch:

enter image description here

Plc Worker
  • 101
  • 7
  • https://stackoverflow.com/questions/44225868/c-sharp-get-local-mac-address-by-local-ip-multiple-interfaces – Jason Dec 14 '21 at 20:40
  • I got to that example and in var mac = query.Where (q => q.IPProperties.UnicastAddresses, etc etc an exception occurs: System.NullReferenceException: 'Object reference not set to an instance of an object.' It seems to me that the example works only for PC. – Plc Worker Dec 14 '21 at 20:47
  • @Jason I put a try and catch to determine if this problem occurs for all IPs, and for some addresses the MAC is obtained, for others not. – Plc Worker Dec 14 '21 at 20:58
  • What **specifically** is causing the nullref? `NetworkInterface` should exist. However, there are many other questions out there about doing this natively in Android that you could refer to. – Jason Dec 14 '21 at 21:08
  • @jason I updated the question, only from my mobile, can I get my own MAC, for other devices, the exception occurs. – Plc Worker Dec 14 '21 at 21:09
  • 2
    Be aware. In later versions of Android it will randomize the mac address – Cheesebaron Dec 14 '21 at 21:11
  • Does this answer your question? [How do I access ARP-protocol information through .NET?](https://stackoverflow.com/questions/1148778/how-do-i-access-arp-protocol-information-through-net) – Charlieface Dec 14 '21 at 22:07
  • @Charlieface For the code part: internal static extern int SendARP(int destinationIp, int sourceIp, byte[] macAddress, ref int physicalAddrLength); exception occurs: System.DllNotFoundException Mensaje = iphlpapi.dll assembly: type: member:(null) – Plc Worker Dec 15 '21 at 16:27
  • Are you running this in Windows? It's a Windows DLL. For Android you would need a different method to get the ARP table. Perhaps read `/proc/net/arp` as in this answer https://stackoverflow.com/a/56139739/14868997 – Charlieface Dec 15 '21 at 16:29
  • @Charlieface Yes, I got to this example, but I also have problems using Java.IO.BufferedReader (Java.IO.BufferedReader br = new Java.IO.BufferedReader(new Java.IO.FileReader(new Java.IO.File("/proc/net/arp")));) The exception is: Java.IO.FileNotFoundException Mensaje = /proc/net/arp: open failed: EACCES (Permission denied) – Plc Worker Dec 15 '21 at 16:39
  • 1
    See https://stackoverflow.com/questions/62550498/permission-denied-for-access-proc-net-arp-arp-table-in-android-10 You really need to up your googling skills, I'm finding these in about 30 seconds – Charlieface Dec 15 '21 at 16:41
  • @Charlieface I have partially succeeded, but it is already a breakthrough. I will publish your suggestion as an answer – Plc Worker Dec 15 '21 at 18:50

1 Answers1

0

Thanks to the suggestion of @Charlieface,Permission Denied for access /proc/net/arp ARP table in Android 10 I have written the following code:

public static PhysicalAddress Lookup(IPAddress ip)
{
   var runtime = Java.Lang.Runtime.GetRuntime();
   var proc = runtime.Exec("ip neigh show");
   proc.WaitFor();
   var x = new Java.IO.InputStreamReader(proc.InputStream);
   var reader = new Java.IO.BufferedReader(x);
   String line;
   while ((line = reader.ReadLine()) != null)
   {
      String[] clientInfo = line.Split(" +");
      //if (!clientInfo[3].equalsIgnoreCase("type"))
      //{
      //    String mac = clientInfo[3];
      //    String ip = clientInfo[0];
      //    //textView.append("\n\nip: " + ip + " Mac: " + mac);
      //    //Log.d("IP : ", ip);
      //    //Log.d("Mac : ", mac);
      //}
   }
}

It still needs to be improved, but it is already a great advance:

enter image description here

Plc Worker
  • 101
  • 7