利用IP位置取得對方的Mac

要取得本機的MAC位置我們可以利用WMI或是.Net framework提供的相關功能來作,例如下面這兩篇

那如果要得知遠端的MAC位址應該怎麼做,雖然可以利用arp的指令並將結果輸出到文字檔,但這樣有點麻煩,找了些參考資料後,我們可以用下面的程式碼來取得
首先是一些參考資料
下面是測試的程式碼
Private Const No_ERROR = 0

_
Private Shared Function inet_addr(ByVal s As String) As Integer
End Function

_
Private Shared Function SendARP(ByVal DestIp As Integer, _
ByVal ScrIP As Integer, _
ByRef pMacAddr As Long, _
ByRef PhyAddrLen As Long) As Integer
End Function

_
Private Shared Sub CopyMemory(ByVal dst As Byte(), ByRef src As Long, ByVal bcount As Integer)
End Sub

Private Function GetRemoteMACAddress(ByVal sRemoteIP As String, ByRef sRemoteMacAddress As String) As Boolean
Dim dwRemoteIp As Integer
Dim pMacAddr As Long = 0
Dim bpMacAddr() As Byte
Dim PhyAddrLen As Long = 0
Dim cnt As Long
Dim tmp As String = ""

dwRemoteIp = inet_addr(sRemoteIP)
If dwRemoteIp <> 0 Then
PhyAddrLen = 6
If SendARP(dwRemoteIp, 0&, pMacAddr, PhyAddrLen) = No_ERROR Then
If pMacAddr <> 0 And PhyAddrLen <> 0 Then
ReDim bpMacAddr(0 To PhyAddrLen - 1)
CopyMemory(bpMacAddr, pMacAddr, PhyAddrLen)
For cnt = 0 To PhyAddrLen - 1
tmp &= Hex(bpMacAddr(cnt) + 256).Substring(1, 2) & "-"
Next

If Len(tmp) > 0 Then
sRemoteMacAddress = tmp.Substring(0, tmp.Length - 1)
GetRemoteMACAddress = True
End If

Exit Function
Else
GetRemoteMACAddress = False
End If
Else
GetRemoteMACAddress = False
End If
Else
GetRemoteMACAddress = False
End If
End Function

留言

匿名表示…
我使用.net 但我無法成功使用
SendARP(dwRemoteIp, 0&, pMacAddr, PhyAddrLen) 這個function
產生這個錯誤
對 PInvoke 函式 'GetMAC!GetMAC.Module1::SendARP' 的呼叫已使堆疊失去平衡。這可能是因為 Managed PInvoke 簽名碼和 Unmanaged 目標簽名碼不相符。請確認 PInvoke 簽名碼的呼叫慣例及參數與目標 Unmanaged 簽名碼是否相符。

如果大大有空可以幫我測試一下
非常謝謝
bauann寫道…
Hi,你的API宣告是怎麼宣告的呢?
Wolke寫道…
Module下的code
Option Explicit On
Module Module1


Private Const No_ERROR = 0


Private Declare Function inet_addr Lib "wsock32.dll" (ByVal s As String) As Long

Private Declare Function SendARP Lib "iphlpapi.dll" (ByVal DestIp As Long, ByVal ScrIP As Long, ByVal pMacAddr As Long, ByVal PhyAddrLen As Long) As Long

Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByVal dst As Object, ByVal src As Object, ByVal bcount As Long)



Public Function GetRemoteMACAddress(ByVal sRemoteIP As String, ByVal sRemoteMacAddress As String) As Boolean

Dim dwRemoteIp As Long

Dim pMacAddr As Long

Dim bpMacAddr() As Byte

Dim PhyAddrLen As Long

Dim cnt As Long

Dim tmp As String



dwRemoteIp = inet_addr(sRemoteIP)

If dwRemoteIp <> 0 Then

PhyAddrLen = 6

If SendARP(dwRemoteIp, 0&, pMacAddr, PhyAddrLen) = No_ERROR Then

If pMacAddr <> 0 And PhyAddrLen <> 0 Then
ReDim bpMacAddr(0 To PhyAddrLen - 1)

CopyMemory(bpMacAddr(0), pMacAddr, PhyAddrLen)
For cnt = 0 To PhyAddrLen - 1

If bpMacAddr(cnt) = 0 Then

tmp = tmp & "00-"

Else
tmp = tmp & Hex$(bpMacAddr(cnt)) & "-"

End If

Next



If Len(tmp) > 0 Then

sRemoteMacAddress = Left$(tmp, Len(tmp) - 1)

GetRemoteMACAddress = True
End If



Exit Function

Else

GetRemoteMACAddress = False

End If

Else

GetRemoteMACAddress = False
End If

Else

GetRemoteMACAddress = False

End If

End Function

End Module


Form下的code
Public Class Form1


Private Sub lblMacAddress_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblMacAddress.Click

Dim sRemoteMacAddress As String

If Len(txtIpAddress.Text) > 0 Then

If GetRemoteMACAddress(txtIpAddress.Text, sRemoteMacAddress) Then

lblMacAddress.Text = sRemoteMacAddress

Else

lblMacAddress.Text = "(SendARP call failed)"

End If

End If
End Sub
End Class
bauann寫道…
Hi,
SendARP 後面兩個參數是byRef,你修正一下測試看看 ~
Wolke寫道…
改了byRef
還是產生一樣的錯誤~

1.有source Code 可以下載嗎?

2.其實我本來是用 .NET 下的Socket 物件做的。
但傳回來的Socket 沒有對方的Mac值。但我用抓封包軟體,可以看到原始的Packet含有雙方的Mac值
。就綁在原始封包的前12位,
還是大大有其他的方法,可以還原原本的Packet 就可以取出遠端的MAC了

或是.net 有其他抓遠端MAC值的物件

感謝回答

這個網誌中的熱門文章

開啟cshtml檔案時,出現『並未將物件參考設定為物件執行個體』的錯誤訊息

無法設定中斷點 尚未載入符號檔

DataGridView欄位計算總合