2009-07-18 60 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通。有堆其他功能。