我正在使用Delphi,我想确定网络中网络设备的物理MAC地址,在本例中是路由器本身。
我的代码:
var
idsnmp: tidsnmp;
val:string;
begin
idsnmp := tidsnmp.create;
try
idsnmp.QuickSend('.1.3.6.1.2.1.4.22.1.2', 'public', '10.0.0.1', val);
showmessage(val);
finally
idsnmp.free;
end;
end;
其中10.0.0.1是我的路由器。
唉,QuickSend总是发送“由#10054连接重置”。我试图修改MIB-OID,我也尝试了IP 127.0.0.1,哪个连接永远不会失败。我没有在Google上找到任何关于TIdSNMP的可用教程。 : - (
此致 丹尼尔马歇尔
答案 0 :(得分:14)
您可以使用SendARP
功能获取Mac地址。
检查此示例
uses
Windows,
WinSock,
SysUtils;
function SendArp(DestIP,SrcIP:ULONG;pMacAddr:pointer;PhyAddrLen:pointer) : DWord; StdCall; external 'iphlpapi.dll' name 'SendARP';
function GetMacAddr(const IPAddress: string; var ErrCode : DWORD): string;
var
MacAddr : Array[0..5] of Byte;
DestIP : ULONG;
PhyAddrLen : ULONG;
WSAData : TWSAData;
begin
Result :='';
WSAStartup($0101, WSAData);
try
ZeroMemory(@MacAddr,SizeOf(MacAddr));
DestIP :=inet_addr(PAnsiChar(IPAddress));
PhyAddrLen:=SizeOf(MacAddr);
ErrCode :=SendArp(DestIP,0,@MacAddr,@PhyAddrLen);
if ErrCode = S_OK then
Result:=Format('%2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x',[MacAddr[0], MacAddr[1],MacAddr[2], MacAddr[3], MacAddr[4], MacAddr[5]])
finally
WSACleanup;
end;
end;
答案 1 :(得分:5)
不希望窃取RRUZ的雷声,我提供了以下变体,取自我的代码库,并提供了一些观察结果。为了包含代码,我把它作为答案而非评论。
type
TMacAddress = array [0..5] of Byte;
function inet_addr(const IPAddress: string): ULONG;
begin
Result := ULONG(WinSock.inet_addr(PAnsiChar(AnsiString(IPAddress))));
end;
function SendARP(DestIP, SrcIP: ULONG; pMacAddr: Pointer; var PhyAddrLen: ULONG): DWORD; stdcall; external 'Iphlpapi.dll';
function GetMacAddress(const IPAddress: string): TMacAddress;
var
MaxMacAddrLen: ULONG;
begin
MaxMacAddrLen := SizeOf(Result);
if SendARP(inet_addr(IPAddress), 0, @Result, MaxMacAddrLen)<>NO_ERROR then begin
raise EMacAddressError.CreateFmt('Unable to do SendARP on address: ''%s''', [IPAddress]);
end;
end;
有几点要做。
无需调用WSAStartup / WSACleanup。
编辑正如RRUZ在评论中指出的那样,winsock文档并没有明确地从WSAStartup / WSACleanup中免除inet_addr,因此我撤回了这一点。在Vista上,调用RtlIpv4StringToAddress更简单。说了这么多,inet_addr很容易实现,它可能更容易推出自己的。
其次,WinSock.pas中的inet_addr声明不正确。它声明返回值为u_long类型,在WinSock.pas中定义为Longint。这是带符号的4字节整数,但它应该是无符号的4字节整数ULONG。如果没有明确的强制转换,您可以获得范围错误。