如何通过.NET访问ARP协议信息?

我试图弄清楚局域网中哪些设备在线和离线。我见过许多程序在做一种图形化的网络概述,显示了LAN

IP和MAC地址。我想知道是否以及如何从C#/。NET中提取那些(ARP?)信息?

任何示例代码段/链接将不胜感激。

回答:

如果您知道那里有哪些设备,则可以使用Ping类。这样至少可以填充ARP表。您始终可以执行ARP

-a并根据需要解析输出。这也是一个链接,该链接显示了如何点选以调用GetIpNetTable。我在下面提供了Ping类的示例,以及如何使用GetIpNetTable访问ARP表的示例。

这是Ping类的一个示例

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

}

}

}

}

以上是 如何通过.NET访问ARP协议信息? 的全部内容, 来源链接: utcz.com/qa/405114.html

回到顶部