Что нового

[Сеть, интернет] Узнать MAC-адрес удаленного компьютера

erlik

Продвинутый
Сообщения
317
Репутация
84
Функция для получения MAC-адреса удаленного компьютера в вашей локальной сети(MAC своей машины также возвращает).

Код:
; #FUNCTION# ====================================================================================================================
; Name...........: _GetRemoteMAC
; Description ...: Gets the MAC address of the remote computer
; Parameters ....: $sAddrDst   - IP address of the destination computer
;                  $sAddrSrc   - IP address of the source computer (by default localhost, value -0)
;				   $sSeparator - character to separate octets
; Return values .: On Success - Returns a string containing the MAC address
;                  On Failure - Returns blank string and the error number from the table $aERRORS
; Author ........: Erlik (Garry Galler)
; ===============================================================================================================================

Func _GetRemoteMAC($sAddrDst,$sAddrSrc=0, $sSeparator=':')
   If @OSType <> 'WIN32_NT' Then Return SetError(1,'Not supported version OS','')

Dim $aERRORS[8][2]=[ _
['NO_ERROR',                     0], _          ;Function succeeds
['ERROR_BAD_NET_NAME',          67], _          ;The network name cannot be found.
['ERROR_BUFFER_OVERFLOW',      111], _          ;The file name is too long.
['ERROR_GEN_FAILURE',           31], _          ;A device attached to the system is not functioning.
['ERROR_INVALID_PARAMETER',     87], _          ;One of the parameters is invalid.
['ERROR_INVALID_USER_BUFFER', 1784], _          ;The supplied user buffer is not valid for the requested operation.
['ERROR_NOT_FOUND',           1168], _          ;Element not found.
['ERROR_NOT_SUPPORTED',         50] _           ;The SendARP function is not supported by the operating system running on the local computer.
]

   Local $aRet, $iAddrDst, $iAddrSrc, $tMacAddr, $pMacAddr, $iMacAddr, $iPhysAddrLen, $sResult	= '',$sErrorDesc

	$aRet = DllCall ("Ws2_32.dll", "int", "inet_addr", "str", $sAddrDst)
	If @error Then Return SetError(2, 0, '')
	$iAddrDst = $aRet[0]

	If $sAddrSrc <> 0 Then
        $aRet = DllCall ("Ws2_32.dll", "int", "inet_addr", "str", $sAddrSrc)
        If @error Then Return SetError(3, 0, '')
		$iAddrSrc = $aRet[0]
	EndIf

	$tMacAddr      = DllStructCreate ('byte[6]')
    $pMacAddr      = DllStructGetPtr($tMacAddr)
	$iPhysAddrLen  = DllStructGetSize($tMacAddr)
	$aRet = DllCall ("iphlpapi.dll", "int", "SendARP", _
					"int",         $iAddrDst, _
					"int",         $iAddrSrc, _
					"uint64*",     $pMacAddr, _
					"int*",        $iPhysAddrLen)

    If $aRet[0] <> 0 Then
	    For $i=0 To 7
		    If $aERRORS[$i][1] = $aRet[0] Then
			$sErrorDesc=$aERRORS[$i][0]
			 ExitLoop
			EndIf
		Next
	    Return SetError($aRet[0], $sErrorDesc, '')
	EndIf

	$iMacAddr = Hex($aRet[3],12)

    For $i = 1 To 6
	$sResult&= StringMid($iMacAddr,13-$i*2,2); переворачиваем байты в обратный порядок
	   If $i<>6 Then $sResult&=$sSeparator
	Next

	Return SetError($aRet[0], 0, $sResult)
EndFunc


Пример вызова:
Код:
$Result=_GetRemoteMAC('192.168.0.1') 
If Not @error Then
   ConsoleWrite($Result & @CRLF)
Else
   ConsoleWrite(@extended & '=' & @error & @CRLF)
EndIf

PS: в @extended почему-то не устанавливается строковой идентификатор ошибки из массива...
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
у меня выпадает ошибка 0=67. при неправильном адресе
то есть судя по коду 0 это значит, что ошибки вызова dll не было, а 67 значит что такого адреса нет.
если сделать ошибку вызова библиотеки, то получается так 0=2
то есть 0 это второй параметр в
Код:
SetError(2, 0, '')

а 2 это первый параметр
то есть все вроде верно
 
Автор
E

erlik

Продвинутый
Сообщения
317
Репутация
84
joiner
У меня только 31-ая ошибка вылезает, когда ARP запрос недостижим.
то есть судя по коду 0 это значит, что ошибки вызова dll не было
На первый параметр в
Код:
ConsoleWrite(@extended & '=' & @error & @CRLF)
не обращай внимания - в нем должно выводится строковое описание ошибки, но так как 'в
Код:
@extended
почему-то не устанавливается строковой идентификатор' - выводится всегда (при любых значениях @error) 0. Так что имеет смысл только значение
Код:
@error
(первый параметр в
Код:
SetError()
).
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
erlik
насколько я понял из справки, то @extended возвращает только число..
поэтому будет так
Код:
If $aRet[0] <> 0 Then
		For $i = 0 To 7
			If $aERRORS[$i][1] = $aRet[0] Then
				$sErrorDesc = $aERRORS[$i][0]
				ExitLoop
			EndIf
		Next
		Return SetError($aRet[0], '', $sErrorDesc)
	EndIf

а вначале так
Код:
$Result = _GetRemoteMAC('132.168.0.101')
If Not @error Then
	ConsoleWrite($Result & @CRLF)
Else
	ConsoleWrite( @error & ' - ' & $Result & @CRLF)
EndIf


чтобы установить макрос @extended, то тогда так
Код:
If $aRet[0] <> 0 Then
		For $i = 0 To 7
			If $aERRORS[$i][1] = $aRet[0] Then
				$sErrorDesc = $aERRORS[$i][0]
				ExitLoop
			EndIf
		Next
		Return  SetExtended(0,$sErrorDesc)
	EndIf

будет возвращена строка
 
Верх