2009-07-18 8 views
24

Я пытаюсь выяснить, какие устройства находятся в сети и в автономном режиме в нашей локальной сети. Я видел, как многие программы выполняют своего рода графический обзор сети, представляя IP-адреса и MAC-адреса. Я хотел бы узнать, можно ли и как эти данные (ARP?) Извлечь из C# /. NET?Как получить доступ к информации протокола ARP через .NET?

Любые примеры фрагментов кода/ссылок будут оценены по достоинству.

+0

Данные могут, я не знаю, быть доступными через SNMP. – ChrisW

+0

Как вы определяете локальную сеть? Ethernet-сегмент? Все в блоке IP? –

+0

Я определяю локальную сеть как локальный Ethernet, как видно из «моей сетевой карты». Я хочу иметь службу/dll (что-то), с которой я могу позвонить, например. веб-сервер или что-то, что сообщит, какие IP-адреса активны в текущем сегменте IP (без проверки всех комбинаций), а затем получить MAC для каждого активного IP-адреса, к которому подключен WHAT (что позволило бы нам вести журнал/визуализировать текущую сеть .) – BerggreenDK

ответ

30

Если вы знаете, какие устройства находятся там, вы можете использовать Ping Class. Это позволит вам по крайней мере заполнить таблицу ARP. Вы всегда можете выполнить ARP -a и проанализировать вывод, если это необходимо. Здесь также есть ссылка, которая показывает, как вызывать вызов для вызова GetIpNetTable. Я привел примеры ниже Ping Class и как получить доступ к таблице ARP с помощью GetIpNetTable.

Это пример для пинг класса

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); 
      } 
     } 
    } 
} 

Это пример 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); 
     } 
     } 
    } 
} 
+0

Извините, но идея заключалась в том, чтобы узнать, какие машины сейчас в сети. Мы не знаем IP в момент их подключения, поскольку они могут поступать из беспроводной сети и получать IP-адрес через DHCP. Я знаю, что мы могли бы заблокировать маршрутизаторы, но идея заключалась в том, чтобы искать MAC-адрес из ARP +, собирать текущий список устройств, подключенных к сети. – BerggreenDK

+0

Вы знаете, как получить MAC-адрес от IP-номера? – BerggreenDK

+0

Отличный материал! Это я должен проверить. Я отметил это как ответ сейчас. Большое спасибо! Приносит меня вперед ... «один гигантский прыжок»: o) – BerggreenDK

2

Надеюсь, вы пытаетесь получить MAC-адреса с IP-адресов, а не наоборот.

Вот ссылка примера парня:

ARP Resolver

Я не пробовал, дайте нам знать, как это работает.

+0

Спасибо за ссылку, но для этого примера не потребуется следующее: с использованием Tamir.IPLib; с использованием Tamir.IPLib.Packets; с использованием Tamir.IPLib.Util; ??? – BerggreenDK

+0

Я также пытаюсь выяснить, как/если это возможно сделать «C#» версию commandprompt «arp -a» ... не путем вызова скрытого commandprompt, а просто, сделав команду ARP кодом каким-то образом. Как я понял до сих пор, команда ARP перечисляет текущий доступный IP + их MAC-адреса, видимые с «этой сетевой карты» ... и это идеально подойдет нашим потребностям. – BerggreenDK

+1

Команда ARP отправляет необработанные байты через сокет, чтобы выполнить это. Класс в ссылке может разрешить MAC-адрес с IP-адреса, это то, что вам нужно, или вам нужно как-то «обнаружить» IP-адреса? Операторы using наверху принадлежат SharpPcap.dll, который можно загрузить и использовать с открытым исходным кодом из указанной выше ссылки. – jonathanpeppers

-4

Поиск в Google "fingbox". Похоже, вы пытаетесь обнаружить наемников?

Это устройство обнаружения вторжений, которое является полностью законным, и хорошо знать, кто перевозит ваш Wi-Fi, какие порты. Иногда он также показывает MAC-адрес и может пинговать. Имеет кучу других функций.

+0

Речь идет о том, чтобы сделать тест от CODE, не покупая приложение или оборудование. Я знаю о Fingbox, он пришел МНОГО позже моего первоначального вопроса. – BerggreenDK

 Смежные вопросы

  • Нет связанных вопросов^_^