2

(vb).NETのARPプロトコルの能力を活用して、自宅のLAN上のすべてのネットワークデバイスとそのハードウェア(MAC)アドレスのリストを作成しようとしています。サブネット上のすべてのIPアドレスを計算する方法はすでに理解していますが、ARP要求を送信して応答を読み取るためのクリーンな方法を見つけるのに行き詰まっています。

すべてのネットワークデバイスには、Windows以外のデバイス(スマートフォンなど)が含まれることに注意してください。これは、WMIが問題外であることを意味します。

どちらの方法がより面倒かわかりません。A)ネイティブIPヘルパーAPIをマネージコードでラップしてSendArpメソッドを使用するか、B)ARPキャッシュを埋めるために各ホストにpingリクエストを送信してからからの出力を解析しますarp.exe -a

マネージコードのみを使用してARP要求/応答を処理する方法を知っている人はいますか?ソケットオブジェクトと少しの魔法を使って実装するのはそれほど難しいことではないようですが、ARPAPIを提供するサードパーティのネットワークライブラリは見つかりませんでした。自分で作成するのに十分な知識がないのではないかと思います。

4

3 に答える 3

1

そのため、Windows API をラップすることが最も面倒な解決策ではないと判断し、次のようにまとめました。

最初に、IPHelperという名前のサブクラス (これも静的内部) を持つNativeMethodsFriend NotInheritable Class (C# の静的内部クラスとほぼ同等)という名前のプライベート コンストラクターを使用してを作成しました。これは、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

その上で、SendARP メソッドを使用するパブリック クラスArpRequestを作成しました。

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()
于 2012-11-30T14:56:17.433 に答える
0

関連している:

受け入れられた回答はCOMを使用していますが、C#ベースのパケットキャプチャライブラリを作成したように見える開発者への非常に興味深いリンクと、それを使用してARP情報を取得する方法の例も引用されています。多分それはあなたのために働くでしょうか?

「SharpPcap」がアンマネージコードをラップするかどうかはわかりません。

ARPAFAIKを直接処理できる組み込みのマネージコードはありません。

于 2012-11-29T22:01:38.460 に答える