用已知MAC地址返回IP地址的方案探讨,高手进
本帖最后由 txm888 于 2016-4-17 10:26 编辑最近很苦恼的烦心事儿,在局域网内有一大批路由器需要管理,且路由器的wan接口是动态获取IP的,这些路由器是跨网段的,想登陆路由器管理,得去现场。
脑洞大开,想要是能用每个路由器的mac地址返回IP再登陆管理界面操作不是更方便吗?
在论坛搜索了2天,只有ip mac扫描工具,1-255尽然最快也要花3/4秒,如果跨网段速度慢得不惊人,
请问大师们,能否进行UDP广播包的方式,套出IP对应mac的IP地址?
如果有思路,可付费索取,期待,谢谢!
mac地址扫描的有很多,如纯au3 P版大侠杰作:http://www.autoitx.com/forum.php?mod=viewthread&tid=39847&highlight=mac%2B%C9%A8%C3%E8
如下代码可能是个办法,但是JAVA的办法,要是能翻译为AU3的就好了Java远程获取MAC地址代码
java
Java代码
package com.thunisoft.shxt.support.macAddr;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* 主机A向主机B发送“UDP-NetBIOS-NS”询问包,即向主机B的137端口,发Query包来询问主机B的NetBIOS Names信息。
* 其次,主机B接收到“UDP-NetBIOS-NS”询问包,
* 假设主机B正确安装了NetBIOS服务........... 而且137端口开放,
* 则主机B会向主机A发送一个“UDP-NetBIOS-NS”应答包,即发Answer包给主机A。
* 并利用UDP(NetBIOS Name Service)来快速获取远程主机MAC地址的方法
* @author lijt
*/
public class UdpGetClientMacAddr {
private static Log log = LogFactory.getLog(UdpGetClientMacAddr.class);
private String remoteAddr;
private int remotePort = 137;
private byte[] buffer = new byte;
private DatagramSocket ds = null;
public UdpGetClientMacAddr(String strAddr) throws Exception {
remoteAddr = strAddr;
ds = new DatagramSocket();
}
//发送数据包
protected final DatagramPacket send(final byte[] bytes) throws IOException {
DatagramPacket dp = new DatagramPacket(bytes, bytes.length, InetAddress.getByName(remoteAddr), remotePort);
ds.send(dp);
return dp;
}
//接收数据包
protected final DatagramPacket receive() {
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
try {
ds.setSoTimeout(3000);
ds.receive(dp);
}catch(SocketTimeoutExceptionex) {
log.info("接收数据超时...,不能获取客户端MAC地址");
//throw new SocketTimeoutException("连接超时");
}catch (SocketException e1) {
log.error("发生Sorcket异常..."+e1.getMessage());
e1.printStackTrace();
}catch (IOException e2) {
log.error("发生IO异常..."+e2.getMessage());
}
return dp;
}
// 询问包结构:
// Transaction ID 两字节(16位) 0x00 0x00
// Flags 两字节(16位) 0x00 0x10
// Questions 两字节(16位) 0x00 0x01
// AnswerRRs 两字节(16位) 0x00 0x00
// AuthorityRRs 两字节(16位) 0x00 0x00
// AdditionalRRs 两字节(16位) 0x00 0x00
// Name:array 0x20 0x43 0x4B 0x41(30个) 0x00 ;
// Type:NBSTAT 两字节 0x00 0x21
// Class:INET 两字节(16位)0x00 0x01
protected byte[] getQueryCmd() throws Exception {
byte[] t_ns = new byte;
t_ns = 0x00;
t_ns = 0x00;
t_ns = 0x00;
t_ns = 0x10;
t_ns = 0x00;
t_ns = 0x01;
t_ns = 0x00;
t_ns = 0x00;
t_ns = 0x00;
t_ns = 0x00;
t_ns = 0x00;
t_ns = 0x00;
t_ns = 0x20;
t_ns = 0x43;
t_ns = 0x4B;
for (int i = 15; i < 45; i++) {
t_ns = 0x41;
}
t_ns = 0x00;
t_ns = 0x00;
t_ns = 0x21;
t_ns = 0x00;
t_ns = 0x01;
return t_ns;
}
// 表1 “UDP-NetBIOS-NS”应答包的结构及主要字段一览表
// 序号 字段名 长度
// 1 Transaction ID 两字节(16位)
// 2 Flags 两字节(16位)
// 3 Questions 两字节(16位)
// 4 AnswerRRs 两字节(16位)
// 5 AuthorityRRs 两字节(16位)
// 6 AdditionalRRs 两字节(16位)
// 7 Name<Workstation/Redirector> 34字节(272位)
// 8 Type:NBSTAT 两字节(16位)
// 9 Class:INET 两字节(16位)
// 10 Time To Live 四字节(32位)
// 11 Length 两字节(16位)
// 12 Number of name 一个字节(8位)
// NetBIOS Name Info 18×Number Of Name字节
// Unit ID 6字节(48位
protected final String getMacAddr(byte[] brevdata) throws Exception {
// 获取计算机名
// System.out.println(new String(brevdata, 57, 18));
// System.out.println(new String(brevdata, 75, 18));
// System.out.println(new String(brevdata, 93, 18));
int i = brevdata * 18 + 56;
String sAddr = "";
StringBuffer sb = new StringBuffer(17);
// 先从第56字节位置,读出Number Of Names(NetBIOS名字的个数,其中每个NetBIOS Names Info部分占18个字节)
// 然后可计算出“Unit ID”字段的位置=56+Number Of Names×18,最后从该位置起连续读取6个字节,就是目的主机的MAC地址。
for (int j = 1; j < 7; j++) {
sAddr = Integer.toHexString(0xFF & brevdata);
if (sAddr.length() < 2) {
sb.append(0);
}
sb.append(sAddr.toUpperCase());
if (j < 6) sb.append('-');
}
return sb.toString();
}
public final void close() {
try {
ds.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* 获取远程主机的mac地址
* @return
* @throws Exception
*/
public final String getRemoteMacAddr() throws Exception {
byte[] bqcmd = getQueryCmd();
this.send(bqcmd);
DatagramPacket dp = receive();
String smac ="";
smac = getMacAddr(dp.getData());
this.close();
return smac;
}
public static voidmain(String[] args) throws Exception
{
UdpGetClientMacAddradd = new UdpGetClientMacAddr("172.16.26.52");
System.out.println(add.getRemoteMacAddr());
}
}http://thinkblog.iteye.com/blog/1499877 找到了下面这篇文章,但不知道如何弄:
http://bbs.csdn.net/topics/70071564 插WAN口 要把路由器的远程管理开起来才可以管理的吧 回复 3# lin6051
发现也不是个办法,上级把wan口各IP隔立起来了,扫描不到
只有一个办法,拨号成功后,向某台电脑发个消息,但需要路由器支持 [参考如下代码(转自官网)]
#include <Date.au3>
;===============================================================================
;
; Description: Get DHCP Client Attributes by IP Address, MAC or Name
; Parameter(s): $sDHCP - IP Address of DHCP Server
; $ClientID - Client IP, MAC or Name (String or Native Format)
; Integer - native format for IP Address/Mask
; Binary- native format for MAC Address (6 bytes)
; $iIDType - type of ClientID information:
; 0 - Auto-define by value
; 1 - Client IP address
; 2 - Client Hardware (MAC) address
; 3 - Client Name
; $iFlags - Config Flags:
; 0x1- Output Format (0-Text, 1-Native)
; Requirement(s): Testing
; Return Value(s):On Success - The array of parameters with indexes
; 0 - Client IP address
; 1 - Client IP subnet mask
; 2 - Client MAC address
; 3 - Client Name
; 4 - Client Comment
; 5 - Client Lease Expires Time
; On Failure - Null, @error set to
; 1 - Client not found on DHCP server
; 2 - Invalid ClientID parameter
; 3 - Operating System not supported
; 4 - Any Runtime Error, API Error Code set to @extended
; Author(s): amel27 (Alexander Melnichuk)
; Note(s): Client Name is case sensitive
;
;===============================================================================
Func _DHCP_GetClientInfo($sDHCP, $ClientID, $iIDType=0, $iFlags=0)
; Create DHCP_SEARCH_INFO Structure
Local $tSearchInfo= DllStructCreate("int SearchType;int DataLength;ptr DataPtr")
Local $iSearchInfoPtr = DllStructGetPtr($tSearchInfo), $aSubnets=, $iType=0
Local $tBinaryData = DllStructCreate("dword SubnetIPAddress;ubyte HardwareID;ubyte MACAddress")
; Check Client ID Parameter and Define SearchInfo Type
If IsInt($ClientID) Then
If $iIDType=0 Or $iIDType=1 Then $iType = 1
ElseIf IsBinary($ClientID) Then
If BinaryLen($ClientID)=6 And ($iIDType=0 Or $iIDType=2) Then $iType = 2
ElseIf IsString($ClientID) Then
If StringRegExp($ClientID, "^(\d+\.){3}\d+$") Then
; Get IP DWord type from String
Local $aOctets = StringSplit($ClientID, "."), $iClientIP = 0
For $i=1 To 4
If BitAND($aOctets[$i], 0xFFFFFF00) Then Return SetError(2) ; ERR: Invalid Client IP Address
$iClientIP = BitOR(BitRotate($iClientIP, 8, "D"), $aOctets[$i])
Next
$ClientID = $iClientIP
If $iIDType=0 Or $iIDType=1 Then $iType = 1
ElseIf StringRegExp($ClientID,"^(0)?[[:xdigit:]]{2}((:|-)?[[:xdigit:]]{2}){5}$") Then
$ClientID = Binary("0x"& StringRegExpReplace($ClientID,"(0|:|-)",""))
If $iIDType=0 Or $iIDType=2 Then $iType = 2
Else
If $iIDType=0 Or $iIDType=3 Then $iType = 3
EndIf
EndIf
If $iType =0 Then Return SetError(2)
; Route the filling of DHCP_SEARCH_INFO structure
Switch $iType
Case 1
; Filling DHCP_SEARCH_INFO for search by client IP address
Local $tSearchInfo_IP = DllStructCreate("int SearchType;dword ClientIPAddress", $iSearchInfoPtr)
DllStructSetData($tSearchInfo_IP, "SearchType", 0)
DllStructSetData($tSearchInfo_IP, "ClientIPAddress", $ClientID)
Case 2
; Filling DHCP_SEARCH_INFO for search by client MAC address
DllStructSetData($tSearchInfo, "SearchType", 1)
DllStructSetData($tSearchInfo, "DataLength", 11)
DllStructSetData($tSearchInfo, "DataPtr", DllStructGetPtr($tBinaryData))
; Filling DHCP_BINARY_DATA
DllStructSetData($tBinaryData, "HardwareID", 0x01)
DllStructSetData($tBinaryData, "MACAddress", $ClientID)
; Get Array of DHCP Subnets
$aSubnets = _DHCP_EnumSubnets($sDHCP, 1)
If @error=1 Then Return SetError(1)
If @error=2 Then Return SetError(4, @extended)
Case 3
; Filling DHCP_SEARCH_INFO for search by client Name
Local $tSearchInfo_Name = DllStructCreate("int SearchType;ptr ClientNamePtr", $iSearchInfoPtr)
Local $tClientNameString= DllStructCreate("wchar ClientName["& StringLen($ClientID)+1 &"]")
DllStructSetData($tSearchInfo_Name, "SearchType", 2)
DllStructSetData($tSearchInfo_Name, "ClientNamePtr", DllStructGetPtr($tClientNameString))
DllStructSetData($tClientNameString, "ClientName", $ClientID)
EndSwitch
; CallDhcpGetClientInfo API function
Local $tClientInfo_Ptr = DllStructCreate("ptr"), $aRet, $aRes
For $i=1 To $aSubnets
DllStructSetData($tBinaryData, "SubnetIPAddress", $aSubnets[$i])
$aRet = DllCall("Dhcpsapi.dll", "int", "DhcpGetClientInfo", _
"wstr", $sDHCP, _
"ptr", $iSearchInfoPtr, _
"ptr", DllStructGetPtr($tClientInfo_Ptr) )
If @error Then Return SetError(3, @error) ; ERR: Invalid DLL or Function Name
If $aRet<>20013 Then ExitLoop
Next
If $aRet=20013 Then Return SetError(1, $aRet) ; ERR: Client not found
If $aRet Then Return SetError(4, $aRet) ; ERR: Any runtime errors
; DHCP_CLIENT_INFO structure
Local $tClientInfo = DllStructCreate("dword ClientIpAddress;dword SubnetMask;int BinaryLen;ptr BinaryPtr;" & _
"ptr ClientNamePtr;ptr ClientCommentPtr;ubyte ClientLeaseExpires;dword OwnerHostIPAddress;" & _
"ptr OwnerHostNetBiosNamePtr;ptr OwnerHostNamePtr", DllStructGetData($tClientInfo_Ptr,1))
Local $tClientBinary = DllStructCreate("ubyte BinaryData", DllStructGetData($tClientInfo, "BinaryPtr"))
; Get IP Address
$aRes = DllStructGetData($tClientInfo, "ClientIpAddress")
If BitAND($iFlags,1)=0 Then $aRes = BitRotate(BitAND($aRes,0xFF000000), 8,"D") &"."& _
BitRotate(BitAND($aRes,0x00FF0000),16,"D") &"."& _
BitRotate(BitAND($aRes,0x0000FF00),-8,"W") &"."& BitAND($aRes,0x000000FF)
; Get IP Mask
$aRes = DllStructGetData($tClientInfo, "SubnetMask")
If BitAND($iFlags,1)=0 Then $aRes=BitRotate(BitAND($aRes,0xFF000000), 8,"D") &"."& _
BitRotate(BitAND($aRes,0x00FF0000),16,"D") &"."& _
BitRotate(BitAND($aRes,0x0000FF00),-8,"W") &"."& BitAND($aRes,0x000000FF)
; Get MAC Address
$aRes = DllStructGetData($tClientBinary, "BinaryData")
If BitAND($iFlags,1)=0 Then $aRes = String($aRes)
; Get Client Name
Local $tClientNameString = DllStructCreate("wchar ClientName", DllStructGetData($tClientInfo, "ClientNamePtr"))
$aRes = DllStructGetData($tClientNameString, "ClientName")
; Get Client Comment
Local $tClientNameString = DllStructCreate("wchar ClientComment", DllStructGetData($tClientInfo, "ClientCommentPtr"))
$aRes = DllStructGetData($tClientNameString, "ClientComment")
; Get Client Lease Expire Time
$aRes = DllStructGetData($tClientInfo, "ClientLeaseExpires")
If BitAND($iFlags,1)=0 Then
$aRes = _Date_Time_FileTimeToLocalFileTime(DllStructGetPtr($tClientInfo, "ClientLeaseExpires"))
$aRes = _Date_Time_FileTimeToStr($aRes)
EndIf
; Freeing a memory
DllCall("Dhcpsapi.dll", "none", "DhcpRpcFreeMemory", "ptr", DllStructGetData($tClientInfo_Ptr,1))
Return $aRes
EndFunc ;==> _DHCP_GetClientInfo
;===============================================================================
;
; Description: Get List of DHCP Scopes
; Parameter(s): $sDHCP - IP Address of DHCP Server
; $iFlags - Config Flags:
; 0x1- Output Format (0-Text, 1-Native)
; Requirement(s): Testing
; Return Value(s):On Success - The array subnet of IP Addresses
; element with index 0 is count of scopes
; On Failure - @error set to
; 1 - Scopes not defined, returned empty array
; 2 - Any Runtime Error, invalid array,
; API Error Code set to @extended
; Author(s): amel27 (Alexander Melnichuk)
; Note(s):
;
;===============================================================================
Func _DHCP_EnumSubnets($sDHCP, $iFlags=0)
Local $tEnumSubnetsParms = DllStructCreate("hwnd ResumeHandle;ptr EnumInfoPtr;int ElementsRead;int ElementsTotal")
Local $aSubnets=, $tIPArray, $tAddress, $aRet
Do
$aRet = DllCall("Dhcpsapi.dll", "int", "DhcpEnumSubnets", _
"wstr", $sDHCP, _
"ptr" , DllStructGetPtr($tEnumSubnetsParms, "ResumeHandle"), _
"int", 100, _
"ptr" , DllStructGetPtr($tEnumSubnetsParms, "EnumInfoPtr") , _
"ptr" , DllStructGetPtr($tEnumSubnetsParms, "ElementsRead"), _
"ptr" , DllStructGetPtr($tEnumSubnetsParms, "ElementsTotal") )
If $aRet Then Return SetError(2, $aRet) ; ERR: Any runtime errors
If DllStructGetData($tEnumSubnetsParms,"EnumInfoPtr")=0 Then Return SetError(1, 0, $aSubnets) ; ERR: Not Found
$tIPArray = DllStructCreate("int NumElements;ptr Elements", DllStructGetData($tEnumSubnetsParms,"EnumInfoPtr"))
ReDim $aSubnets[$aSubnets + DllStructGetData($tIPArray,"NumElements") +1]
For $i=$aSubnets+1 To UBound($aSubnets)-1
$tAddress = DllStructCreate("dword SubNetAddess", DllStructGetData($tIPArray,2) + ($i-$aSubnets-1)*4)
$aSubnets[$i]=DllStructGetData($tAddress, "SubNetAddess")
If BitAND($iFlags,1)=0 Then $aSubnets[$i] = BitRotate(BitAND($aSubnets[$i],0xFF000000), 8,"D") _
&"."& BitRotate(BitAND($aSubnets[$i],0x00FF0000),16,"D") _
&"."& BitRotate(BitAND($aSubnets[$i],0x0000FF00),-8,"W") _
&"."& BitAND($aSubnets[$i],0x000000FF)
Next
$aSubnets += DllStructGetData($tIPArray,"NumElements")
Until DllStructGetData($tEnumSubnetsParms,"ElementsRead") = DllStructGetData($tEnumSubnetsParms,"ElementsTotal")
; Freeing a memory
DllCall("Dhcpsapi.dll", "none", "DhcpRpcFreeMemory", "ptr", DllStructGetData($tEnumSubnetsParms,"EnumInfoPtr"))
Return $aSubnets
EndFunc ; => _DHCP_EnumSubnets
回复 5# 虫子樱桃
老大,没明白上面代码是操作什么的,能解释下或示范下吗?TKS
页:
[1]