2012-11-29 43 views
2

我试图利用(vb).NET中ARP协议的功能来构建我家庭局域网上所有联网设备以及它们的硬件(MAC)地址的列表。我已经计算出如何计算子网上的所有IP地址,但我坚持找到一种干净的方式来发送ARP请求并阅读响应。托管代码中的ARP请求

请注意,全部联网设备包括非windows设备(如智能手机)。这意味着WMI不存在问题

现在我不知道哪个方法更麻烦:A)将本机IP helper API封装在托管代码中以便使用它的SendArp方法,或者B)向每个主机发送ping请求以填充ARP缓存,然后解析arp.exe -a的输出。

有谁知道一种方法来处理ARP请求/响应只使用托管代码?使用套接字对象和一点魔力来实现似乎并不困难,但我找不到任何提供ARP API的第三方网络库。我担心自己没有足够的知识来创造一个。

回答

0

相关:

接受的答案使用COM,但引用也有一个相当有趣的链接,谁似乎已经创建了一个C#为基础的数据包捕获库的开发人员,以及如何使用它来获取ARP信息的例子。也许这对你有用?

请注意,我不知道“SharpPcap”是否包装非托管代码。

http://www.tamirgal.com/blog/post/ARP-Resolver-C-Class.aspx

没有内置托管代码,可以直接与ARP AFAIK处理。

1

所以我已经决定,包裹窗口API将是最混乱的解决方案,并与下面上来给大家看:

首先,我创建了一个Friend NotInheritable Class名为私有构造NativeMethods(约相当于C#中的静态内部类)与名为IPHelper的子类(也是静态内部)。这是我把我无耻地从pinvoke.net(source)复制的DllImport的地方。

Friend NotInheritable Class NativeMethods 
    Private Sub New() 
    End Sub 

    Friend NotInheritable Class IPHelper 
      Private Sub New() 
      End Sub 

      ' Possible return values 
      Friend Const NO_ERROR As Integer = 0 
      Friend Const ERROR_BAD_NET_NAME As Integer = 67 
      Friend Const ERROR_BUFFER_OVERFLOW As Integer = 111 
      Friend Const ERROR_GEN_FAILURE As Integer = 31 
      Friend Const ERROR_INVALID_PARAMETER As Integer = 87 
      Friend Const ERROR_INVALID_USER_BUFFER As Integer = 1784 
      Friend Const ERROR_NOT_FOUND As Integer = 1168 
      Friend Const ERROR_NOT_SUPPORTED As Integer = 50 

      ' API function declaration. 
      <DllImport("iphlpapi.dll", SetLastError:=True)> 
      Friend Shared Function SendARP(
        DestIP As UInt32, 
        SrcIP As UInt32, 
        pMacAddr() As Byte, 
        ByRef PhyAddrLen As Int32) As UInt32 
      End Function 

    End Class 
End Class 

现在最重要的是我写了一个公共类ArpRequest消耗的SendARP方法。

Imports System.Net 
Imports System.Runtime.InteropServices 
Imports System.ComponentModel 
Imports System.IO 
Imports System.Net.NetworkInformation 

Public Class ArpRequest 

    Private _address As IPAddress 

    Public Sub New(address As IPAddress) 
      _address = address 
    End Sub 

    ''' <summary> 
    ''' Gets the MAC address that belongs to the specified IP address. 
    ''' </summary> 
    ''' <remarks>This uses a native method and should be replaced when a managed alternative becomes available.</remarks> 
    Public Function GetResponse() As PhysicalAddress 
      Dim ip As UInteger = BitConverter.ToUInt32(_address.GetAddressBytes(), 0) 
      Dim mac() As Byte = New Byte(5) {} 

      Dim ReturnValue As Integer = CInt(NativeMethods.IPHelper.SendARP(CUInt(ip), 0, mac, mac.Length)) 

      If ReturnValue = NativeMethods.IPHelper.NO_ERROR Then 
        Return New PhysicalAddress(mac) 
      Else 
        ' TODO: handle various SendARP errors 
        ' http://msdn.microsoft.com/en-us/library/windows/desktop/aa366358(v=vs.85).aspx 
        Throw New Win32Exception(CInt(ReturnValue)) 
      End If 
    End Function 
End Class 

用法很简单(但要注意Win32Exceptions):

Dim ip = System.Net.IPAddress.Parse("0.0.0.0") ' replace with actual ip 
    Dim arp = New ArpRequest(ip) 
    Dim hardwareAddress = arp.GetResponse()