2009-07-18 48 views
24

我想弄清楚在我們的局域網中有哪些設備在線和離線。我看過很多程序在做一種圖形化的網絡概述,介紹局域網IP和MAC地址。我想知道是否以及如何從C#/ .NET中提取這些(ARP?)信息?如何通過.NET訪問ARP協議信息?

任何示例代碼片斷/鏈接,將不勝感激。

+0

可能通過SNMP提供數據,我不知道。 – ChrisW 2009-07-19 01:06:58

+0

你如何定義局域網?以太網段? IP塊中的所有內容? – 2009-07-20 16:08:08

+0

我把局域網定義爲本地以太網,從「我的網卡」看 - 我想有一個服務/ DLL(東西),我可以從例如。一個網絡服務器或者一些能夠報告哪些IP在當前IP段中處於活動狀態(不需要ping所有組合),然後獲取每個活動IP的MAC來查找連接的網絡(這將允許我們輕鬆地記錄/可視化當前網絡) – BerggreenDK 2009-07-21 03:32:39

回答

30

如果您知道哪些設備在那裏,您可以使用Ping Class。這將允許您至少填寫ARP表。如果必須的話,你總是可以執行ARP -a並解析輸出。這裏也是一個鏈接,顯示如何撥打電話GetIpNetTable。我已經包含了Ping類的示例以及如何使用GetIpNetTable訪問ARP表。

這是坪類

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

希望你試圖從IP地址獲取MAC地址,而不是反過來。

這裏有一個傢伙的例子的鏈接:

ARP Resolver

我還沒有嘗試過,讓我們知道它是如何工作的。

-4

Google搜索「fingbox」。似乎你正在試圖檢測事件?

這是一個入侵者探測器設備,它是完全合法的,它很好地知道誰在使用您的無線網絡在哪些端口上進行傳輸。有時它也顯示MAC地址並可以ping通。有堆其他功能。