Для опроса сетевых устройств с помощью ARP-запроса в C# необходимо использовать классы из пространства имен System.Net.NetworkInformation.
Прежде всего, нужно получить список всех устройств в локальной сети. Для этого используется класс NetworkInterface:
using System; using System.Net.NetworkInformation; class Program { static void Main() { NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface ni in interfaces) { if (ni.OperationalStatus == OperationalStatus.Up) { Console.WriteLine("Interface: {0}", ni.Name); IPInterfaceProperties ipProps = ni.GetIPProperties(); foreach (UnicastIPAddressInformation ip in ipProps.UnicastAddresses) { if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { Console.WriteLine("IP: {0}", ip.Address); } } } } } }
Получив список устройств, можно перебрать все возможные IP-адреса в локальной сети и отправить ARP-запрос каждому из них. Для этого используется класс Ping и его метод Send:
using System; using System.Diagnostics; using System.Net; using System.Net.NetworkInformation; class Program { static void Main() { NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface ni in interfaces) { if (ni.OperationalStatus == OperationalStatus.Up) { IPInterfaceProperties ipProps = ni.GetIPProperties(); foreach (UnicastIPAddressInformation ip in ipProps.UnicastAddresses) { if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { byte[] macBytes = new byte[6]; new Random().NextBytes(macBytes); IPAddress ipAddress = ip.Address; IPAddress subnetMask = ip.IPv4Mask; for (uint i = 2; i < 255; i++) { byte[] ipBytes = ipAddress.GetAddressBytes(); byte[] subnetBytes = subnetMask.GetAddressBytes(); byte[] targetBytes = new byte[4]; for (int j = 0; j < 4; j++) { targetBytes[j] = (byte)((ipBytes[j] & subnetBytes[j]) | (i & ~subnetBytes[j])); } IPAddress targetAddress = new IPAddress(targetBytes); PingReply reply = new Ping().Send(targetAddress.ToString(), 1000); if (reply.Status == IPStatus.Success) { Console.WriteLine("IP: {0}", reply.Address); Console.WriteLine("MAC: {0}", GetMacAddress(reply.Address.ToString())); } } } } } } } public static string GetMacAddress(string ipAddress) { ProcessStartInfo psi = new ProcessStartInfo("arp", "-a " + ipAddress); psi.RedirectStandardOutput = true; psi.UseShellExecute = false; psi.CreateNoWindow = true; Process p = Process.Start(psi); string output = p.StandardOutput.ReadToEnd(); p.Close(); int index = output.IndexOf(':'); if (index != -1 && index + 3 < output.Length) { return output.Substring(index - 2, 17); } return null; } }
Этот код проходит по всем устройствам в списке, получает IP-адреса и маски подсети, а затем перебирает все возможные IP-адреса в текущей подсети. Для каждого IP-адреса отправляется ARP-запрос с помощью Ping.Send, и, если получен ответ, выводится IP-адрес и MAC-адрес устройства.
Функция GetMacAddress использует команду arp -a для получения MAC-адреса устройства по его IP-адресу. Это сделано для того, чтобы получить MAC-адресы не только локальных устройств, но и устройств, находящихся в других подсетях.
Обратите внимание, что для выполнения данного кода требуются привилегии администратора, так как использование ARP-запросов требует определенных системных прав.