Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I access ARP-protocol information through .NET?

Tags:

c#

.net

ip

lan

arp

I try to figure out which devices are online and which are offline in our LAN.
I have seen many programs doing a kind of graphical network overview, presenting LAN IP and MAC addresses.

I would like to know if and how those (ARP?) information can be pulled from C#/.NET ?

like image 745
BerggreenDK Avatar asked Jul 18 '09 22:07

BerggreenDK


People also ask

How do you access ARP entries?

To display the ARP table in this system, enter “arp -a.” This command will also show the ARP table in the Windows command prompt.

How do you view the ARP address table?

To display the ARP table, enter the show arp command. The command displays all ARP entries in the system.

What is ARP net?

Address Resolution Protocol (ARP) is a protocol or procedure that connects an ever-changing Internet Protocol (IP) address to a fixed physical machine address, also known as a media access control (MAC) address, in a local-area network (LAN).

What is the command to see the ARP table in a PC?

arp -a: This command is used to display the ARP table for a particular IP address. It also shows all the entries of the ARP cache or table. arp -g: This command works the same as the arp -a command.


1 Answers

If you know which devices are out there you can use the Ping Class. This will allow you to at least fill up the ARP table. You can always execute ARP -a and parse the output if you have to. Here is also a link that shows how to pinvoke to call GetIpNetTable. I have included examples below of Ping Class and how to access the ARP table using the GetIpNetTable.

This is an example for the Ping Class

using System; using System.Net; using System.Net.NetworkInformation; using System.Text;  namespace Examples.System.Net.NetworkInformation.PingTest {     public class PingExample     {         // args[0] can be an IPaddress or host name.         public static void Main (string[] args)         {             Ping pingSender = new Ping ();             PingOptions options = new PingOptions ();              // Use the default Ttl value which is 128,             // but change the fragmentation behavior.             options.DontFragment = true;              // Create a buffer of 32 bytes of data to be transmitted.             string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";             byte[] buffer = Encoding.ASCII.GetBytes (data);             int timeout = 120;             PingReply reply = pingSender.Send (args[0], timeout, buffer, options);             if (reply.Status == IPStatus.Success)             {                 Console.WriteLine ("Address: {0}", reply.Address.ToString ());                 Console.WriteLine ("RoundTrip time: {0}", reply.RoundtripTime);                 Console.WriteLine ("Time to live: {0}", reply.Options.Ttl);                 Console.WriteLine ("Don't fragment: {0}", reply.Options.DontFragment);                 Console.WriteLine ("Buffer size: {0}", reply.Buffer.Length);             }         }     } } 

This is an example of the GetIpNetTable.

using System; using System.Runtime.InteropServices; using System.ComponentModel;  using System.Net;  namespace GetIpNetTable {    class Program    {       // The max number of physical addresses.       const int MAXLEN_PHYSADDR = 8;        // Define the MIB_IPNETROW structure.       [StructLayout(LayoutKind.Sequential)]       struct MIB_IPNETROW       {          [MarshalAs(UnmanagedType.U4)]          public int dwIndex;          [MarshalAs(UnmanagedType.U4)]          public int dwPhysAddrLen;          [MarshalAs(UnmanagedType.U1)]          public byte mac0;          [MarshalAs(UnmanagedType.U1)]          public byte mac1;          [MarshalAs(UnmanagedType.U1)]          public byte mac2;          [MarshalAs(UnmanagedType.U1)]          public byte mac3;          [MarshalAs(UnmanagedType.U1)]          public byte mac4;          [MarshalAs(UnmanagedType.U1)]          public byte mac5;          [MarshalAs(UnmanagedType.U1)]          public byte mac6;          [MarshalAs(UnmanagedType.U1)]          public byte mac7;          [MarshalAs(UnmanagedType.U4)]          public int dwAddr;          [MarshalAs(UnmanagedType.U4)]          public int dwType;       }        // Declare the GetIpNetTable function.       [DllImport("IpHlpApi.dll")]       [return: MarshalAs(UnmanagedType.U4)]       static extern int GetIpNetTable(          IntPtr pIpNetTable,          [MarshalAs(UnmanagedType.U4)]          ref int pdwSize,          bool bOrder);        [DllImport("IpHlpApi.dll", SetLastError = true, CharSet = CharSet.Auto)]       internal static extern int FreeMibTable(IntPtr plpNetTable);        // The insufficient buffer error.       const int ERROR_INSUFFICIENT_BUFFER = 122;        static void Main(string[] args)       {          // The number of bytes needed.          int bytesNeeded = 0;           // The result from the API call.          int result = GetIpNetTable(IntPtr.Zero, ref bytesNeeded, false);           // Call the function, expecting an insufficient buffer.          if (result != ERROR_INSUFFICIENT_BUFFER)          {             // Throw an exception.             throw new Win32Exception(result);          }           // Allocate the memory, do it in a try/finally block, to ensure          // that it is released.          IntPtr buffer = IntPtr.Zero;           // Try/finally.          try          {             // Allocate the memory.             buffer = Marshal.AllocCoTaskMem(bytesNeeded);              // Make the call again. If it did not succeed, then             // raise an error.             result = GetIpNetTable(buffer, ref bytesNeeded, false);              // If the result is not 0 (no error), then throw an exception.             if (result != 0)             {                // Throw an exception.                throw new Win32Exception(result);             }              // Now we have the buffer, we have to marshal it. We can read             // the first 4 bytes to get the length of the buffer.             int entries = Marshal.ReadInt32(buffer);              // Increment the memory pointer by the size of the int.             IntPtr currentBuffer = new IntPtr(buffer.ToInt64() +                Marshal.SizeOf(typeof(int)));              // Allocate an array of entries.             MIB_IPNETROW[] table = new MIB_IPNETROW[entries];              // Cycle through the entries.             for (int index = 0; index < entries; index++)             {                // Call PtrToStructure, getting the structure information.                table[index] = (MIB_IPNETROW) Marshal.PtrToStructure(new                   IntPtr(currentBuffer.ToInt64() + (index *                   Marshal.SizeOf(typeof(MIB_IPNETROW)))), typeof(MIB_IPNETROW));             }              for (int index = 0; index < entries; index++)             {                MIB_IPNETROW row = table[index];                IPAddress ip=new IPAddress(BitConverter.GetBytes(row.dwAddr));                Console.Write("IP:"+ip.ToString()+"\t\tMAC:");                 Console.Write( row.mac0.ToString("X2") + '-');                Console.Write( row.mac1.ToString("X2") + '-');                Console.Write( row.mac2.ToString("X2") + '-');                Console.Write( row.mac3.ToString("X2") + '-');                Console.Write( row.mac4.ToString("X2") + '-');                Console.WriteLine( row.mac5.ToString("X2"));              }          }          finally          {             // Release the memory.             FreeMibTable(buffer);          }       }    } } 
like image 159
Rex Logan Avatar answered Sep 23 '22 20:09

Rex Logan