本帖最后由 sensel 于 2009-5-29 19:07 编辑
总算可用了,跟arp.exe说声88~~~
我又乱改pusofalse兄的代码了。。。pusofalse兄请勿见怪
最终结果。。。不玩了
Opt("MustDeclareVars", 1)
Local Const $sIP = "192.168.0.22", $sMac = "00:20:21:22:CC:DD"
Local $aIfTable, $iIndex = 0
$aIfTable = _GetIfTable()
For $i = 1 To $aIfTable[0][0]
If $aIfTable[$i][2] = 6 Then
_FlushIpNetTable($aIfTable[$i][0]) ; 清空ARP表
If $iIndex = 0 Then $iIndex = $aIfTable[$i][0] ; 获取第一个可用网络适配器索引号
EndIf
Next
If $iIndex <> 0 Then ; 绑定 MAC
_SetIpNetEntry($iIndex, $sIP, $sMac)
EndIf
Exit
;===============================================================================
; 说明: 获取 IP地址-物理地址 映射表
; 语法: _GetIpNetTable([$sIPAddr = ""])
; 参数: $sIPAddr - [可选] IP地址
; 需要: 无
; 返回: 成功 - 二维数组, 结构:
; $array[0][0] - ARP项目总数
; $array[1][0] - 网络适配器索引号
; $array[1][1] - IP地址
; $array[1][2] - 物理地址
; $array[1][3] - ARP项目类型: 4 - 静态, 3 - 动态, 2 - 无效, 1 - 其他
; ...
; [n][0] 至 [n][10] - 第 n ARP项目信息
; 失败 - 空列表数组 [0][0] = 0, 并设置 @error 到 1, @extended 到API操作返回值
; 备注: 出处: http://www.autoitx.com/forum.php?mod=viewthread&tid=7308 3#, 作者: pusofalse
;===============================================================================
Func _GetIpNetTable($sIPAddr = "")
Local $aResult, $sAddr, $sPhysAddr, $iPhysAddrLen, $iIndex = 0, $aIpNetTable[1][4] = [[0]]
Local $tBuffer, $pBuffer, $tNum, $tagIpTable = "", $tIpTable, $iNumber
$aResult = DllCall("iphlpapi.dll", "dword", "GetIpNetTable", _
"ptr", 0, "int*", 0, "int", 1)
If $aResult[2] = 0 Then Return SetError(1, $aResult[0], $aIpNetTable)
$tBuffer = DllStructCreate("ubyte[" & $aResult[2] & "]")
$pBuffer = DllStructGetPtr($tBuffer)
$aResult = DllCall("iphlpapi.dll", "dword", "GetIpNetTable", _
"ptr", $pBuffer, "int*", $aResult[2], "int", 1)
$tNum = DllStructCreate("dword", $pBuffer)
$iNumber = DllStructGetData($tNum, 1)
For $i = 1 To $iNumber
$tagIpTable &= ";dword[2];byte[8];dword[2]"
Next
$tIpTable = DllStructCreate("dword" & $tagIpTable, $pBuffer)
For $i = 2 To $iNumber * 3 Step 3
$sAddr = DllStructGetData($tIpTable, $i + 2, 1)
$sAddr = _inet_ntoa($sAddr)
$iPhysAddrLen = DllStructGetData($tIpTable, $i, 2)
$sPhysAddr = DllStructGetData($tIpTable, $i + 1)
$sPhysAddr = StringLeft($sPhysAddr, 2 + $iPhysAddrLen * 2)
$sPhysAddr = _FormatMac($sPhysAddr)
If $sIPAddr <> "" AND $sIPAddr <> $sAddr Then ContinueLoop
$iIndex += 1
ReDim $aIpNetTable[$iIndex + 1][4]
$aIpNetTable[$iIndex][0] = DllStructGetData($tIpTable, $i, 1)
$aIpNetTable[$iIndex][1] = $sAddr
$aIpNetTable[$iIndex][2] = $sPhysAddr
$aIpNetTable[$iIndex][3] = DllStructGetData($tIpTable, $i + 2, 2)
Next
$aIpNetTable[0][0] = $iIndex
Return SetError($aResult[0], 0, $aIpNetTable)
EndFunc ;==>_GetIpNetTable
;===============================================================================
; 说明: 获取 MIB-II 接口表
; 语法: _GetIfTable()
; 参数: 无
; 需要: 无
; 返回: 成功 - 二维数组, 结构:
; $array[0][0] - 接口总数
; $array[1][0] - 第一接口索引号
; $array[1][1] - 第一接口名称
; $array[1][2] - 第一接口类型
; $array[1][3] - 第一接口MTU字节数
; $array[1][4] - 第一接口连接速度
; $array[1][5] - 第一接口物理地址
; $array[1][6] - 第一接口管理状态
; $array[1][7] - 第一接口操作状态
; $array[1][8] - 第一接口持续时间
; $array[1][9] - 第一接口接收字节数
; $array[1][10] - 第一接口接收单播数据包
; $array[1][11] - 第一接口接收广播和组播数据包
; $array[1][12] - 第一接口接收数据包丢弃数
; $array[1][13] - 第一接口接收数据包错误数
; $array[1][14] - 第一接口接收未知协议数据包
; $array[1][15] - 第一接口发送字节数
; $array[1][16] - 第一接口发送单播数据包
; $array[1][17] - 第一接口发送广播和组播数据包
; $array[1][18] - 第一接口发送数据包丢弃数
; $array[1][19] - 第一接口发送数据包错误数
; $array[1][20] - 第一接口传输队列长度
; $array[1][21] - 第一接口描述
; ...
; [n][0] 至 [n][21] - 第 n 接口信息
; 失败 - 空列表数组 [0][0] = 0, 并设置 @error 到 1, @extended 到API操作返回值
; 备注: 参考: http://www.autoitx.com/forum.php?mod=viewthread&tid=7308 3#
;===============================================================================
Func _GetIfTable()
Local $aResult, $sPhysAddr, $iPhysAddrLen, $sDescr, $iDescrLen, $iIndex = 0, $aIfTable[1][22] = [[0]]
Local $tBuffer, $pBuffer, $tNum, $tagIfTable = "", $tIfTable
$aResult = DllCall("iphlpapi.dll", "dword", "GetIfTable", _
"ptr", 0, "int*", 0, "int", 1)
If $aResult[2] = 0 Then Return SetError(1, $aResult[0], $aIfTable)
$tBuffer = DllStructCreate("ubyte[" & $aResult[2] & "]")
$pBuffer = DllStructGetPtr($tBuffer)
$aResult = DllCall("iphlpapi.dll", "dword", "GetIfTable", _
"ptr", $pBuffer, "int*", $aResult[2], "int", 1)
$tNum = DllStructCreate("dword", $pBuffer)
$aIfTable[0][0] = DllStructGetData($tNum, 1)
For $i = 1 To $aIfTable[0][0]
$tagIfTable &= ";wchar[256];dword[5];byte[8];dword[16];byte[256]"
Next
$tIfTable = DllStructCreate("dword" & $tagIfTable, $pBuffer)
ReDim $aIfTable[$aIfTable[0][0] + 1][22]
For $i = 2 To $aIfTable[0][0] * 5 Step 5
$iPhysAddrLen = DllStructGetData($tIfTable, $i + 1, 5)
$sPhysAddr = DllStructGetData($tIfTable, $i + 2)
$sPhysAddr = StringLeft($sPhysAddr, 2 + $iPhysAddrLen * 2)
$sPhysAddr = _FormatMac($sPhysAddr)
$iDescrLen = DllStructGetData($tIfTable, $i + 3, 16)
$sDescr = DllStructGetData($tIfTable, $i + 4)
$sDescr = StringLeft($sDescr, $iDescrLen * 2)
$sDescr = BinaryToString($sDescr)
$iIndex += 1
$aIfTable[$iIndex][0] = DllStructGetData($tIfTable, $i + 1, 1)
$aIfTable[$iIndex][1] = DllStructGetData($tIfTable, $i)
$aIfTable[$iIndex][2] = DllStructGetData($tIfTable, $i + 1, 2)
$aIfTable[$iIndex][3] = DllStructGetData($tIfTable, $i + 1, 3)
$aIfTable[$iIndex][4] = DllStructGetData($tIfTable, $i + 1, 4)
$aIfTable[$iIndex][5] = $sPhysAddr
$aIfTable[$iIndex][6] = DllStructGetData($tIfTable, $i + 3, 1)
$aIfTable[$iIndex][7] = DllStructGetData($tIfTable, $i + 3, 2)
$aIfTable[$iIndex][8] = DllStructGetData($tIfTable, $i + 3, 3)
$aIfTable[$iIndex][9] = DllStructGetData($tIfTable, $i + 3, 4)
$aIfTable[$iIndex][10] = DllStructGetData($tIfTable, $i + 3, 5)
$aIfTable[$iIndex][11] = DllStructGetData($tIfTable, $i + 3, 6)
$aIfTable[$iIndex][12] = DllStructGetData($tIfTable, $i + 3, 7)
$aIfTable[$iIndex][13] = DllStructGetData($tIfTable, $i + 3, 8)
$aIfTable[$iIndex][14] = DllStructGetData($tIfTable, $i + 3, 9)
$aIfTable[$iIndex][15] = DllStructGetData($tIfTable, $i + 3, 10)
$aIfTable[$iIndex][16] = DllStructGetData($tIfTable, $i + 3, 11)
$aIfTable[$iIndex][17] = DllStructGetData($tIfTable, $i + 3, 12)
$aIfTable[$iIndex][18] = DllStructGetData($tIfTable, $i + 3, 13)
$aIfTable[$iIndex][19] = DllStructGetData($tIfTable, $i + 3, 14)
$aIfTable[$iIndex][20] = DllStructGetData($tIfTable, $i + 3, 15)
$aIfTable[$iIndex][21] = $sDescr
Next
Return SetError($aResult[0], 0, $aIfTable)
EndFunc ;==>_GetIfTable
;===============================================================================
; 说明: 更改ARP表项目
; 语法: _SetIpNetEntry($iAdptIndex, $sAddr, $sMac[, $sType = "Static"])
; 参数: $iAdptIndex - 网络适配器索引号
; $sAddr - IP地址
; $sMac - 物理地址
; $sType - [可选] ARP项目类型, "Static" - 静态, "Dynamic" - 动态
; 需要: 无
; 返回: 成功 - 1
; 失败 - 0, 并设置 @error 到 API操作返回值
; 备注: 出处: http://www.autoitx.com/forum.php?mod=viewthread&tid=7308 3#, 作者: pusofalse
;===============================================================================
Func _SetIpNetEntry($iAdptIndex, $sAddr, $sMac, $sType = "Static")
Local $aResult, $iAddr, $iMac, $tIpNetRow, $pIpNetRow, $iType
If $sType = "Dynamic" Then
$iType = 3
Else
$iType = 4
EndIf
$iAddr = _inet_addr($sAddr)
$iMac = _FormatMac($sMac, 0)
$tIpNetRow = DllStructCreate("dword[2];byte[8];dword[2]")
$pIpNetRow = DllStructGetPtr($tIpNetRow)
DllStructSetData($tIpNetRow, 1, $iAdptIndex, 1)
DllStructSetData($tIpNetRow, 1, (StringLen($iMac) - 2) / 2, 2)
DllStructSetData($tIpNetRow, 2, $iMac)
DllStructSetData($tIpNetRow, 3, $iAddr, 1)
DllStructSetData($tIpNetRow, 3, $iType, 2)
$aResult = DllCall("iphlpapi.dll", "long", "SetIpNetEntry", "ptr", $pIpNetRow)
Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc ;==>_SetIpNetEntry
;===============================================================================
; 说明: 删除ARP表项目
; 语法: _DeleteIpNetEntry($iAdptIndex, $sAddr)
; 参数: $iAdptIndex - 网络适配器索引号
; $sAddr - IP地址
; 需要: 无
; 返回: 成功 - 1
; 失败 - 0, 并设置 @error 到 API操作返回值
; 备注: 出处: http://www.autoitx.com/forum.php?mod=viewthread&tid=7308 3#, 作者: pusofalse
;===============================================================================
Func _DeleteIpNetEntry($iAdptIndex, $sAddr)
Local $aResult, $iAddr, $tIpNetRow, $pIpNetRow
$iAddr = _inet_addr($sAddr)
$tIpNetRow = DllStructCreate("dword[2];byte[8];dword[2]")
$pIpNetRow = DllStructGetPtr($tIpNetRow)
DllStructSetData($tIpNetRow, 1, $iAdptIndex, 1)
DllStructSetData($tIpNetRow, 3, $iAddr, 1)
$aResult = DllCall("iphlpapi.dll", "long", "DeleteIpNetEntry", "ptr", $pIpNetRow)
Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc ;==>_DeleteIpNetEntry
;===============================================================================
; 说明: 清空指定网络适配器ARP表项目
; 语法: _FlushIpNetTable($iAdptIndex)
; 参数: $iAdptIndex - 网络适配器索引号
; 需要: 无
; 返回: 成功 - 1
; 失败 - 0, 并设置 @error 到 API操作返回值
; 备注: 出处: http://www.autoitx.com/forum.php?mod=viewthread&tid=7308 3#, 作者: pusofalse
;===============================================================================
Func _FlushIpNetTable($iAdptIndex)
Local $aResult
$aResult = DllCall("iphlpapi.dll", "long", "FlushIpNetTable", "long", $iAdptIndex)
Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc ;==>_FlushIpNetTable
Func _inet_addr($sAddr)
Local $iAddr = DllCall("ws2_32.dll", "long", "inet_addr", "str", $sAddr)
Return $iAddr[0]
EndFunc ;==>_inet_addr
Func _inet_ntoa($iAddr)
Local $sAddr = DllCall("ws2_32.dll", "str", "inet_ntoa", "long", $iAddr)
Return $sAddr[0]
EndFunc ;==>_inet_ntoa
Func _FormatMac($sMac, $iString = True)
If $iString Then
$sMac = StringTrimLeft($sMac, 2)
Return StringTrimRight(StringRegExpReplace($sMac, ".{2}", "\0:"), 1)
Else
Return "0x" & StringReplace($sMac, ":", "")
EndIf
EndFunc ;==>_FormatMac
|