Dan*_*all 8 delphi networking snmp indy
我正在使用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;
Run Code Online (Sandbox Code Playgroud)
其中10.0.0.1是我的路由器.
唉,QuickSend总是发送"由#10054连接重置".我试图修改MIB-OID,我也尝试了IP 127.0.0.1,哪个连接永远不会失败.我没有在Google上找到任何关于TIdSNMP的可用教程.:-(
关心Daniel Marschall
RRU*_*RUZ 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;
Run Code Online (Sandbox Code Playgroud)
不希望窃取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;
Run Code Online (Sandbox Code Playgroud)
有几点要做.
无需调用WSAStartup/WSACleanup.
编辑 正如RRUZ在评论中指出的那样,winsock文档并没有明确地从WSAStartup/WSACleanup中免除inet_addr,因此我撤回了这一点.在Vista上,调用RtlIpv4StringToAddress更简单.说了这么多,inet_addr很容易实现,它可能更容易推出自己的.
其次,WinSock.pas中的inet_addr声明不正确.它声明返回值为u_long类型,在WinSock.pas中定义为Longint.这是带符号的4字节整数,但它应该是无符号的4字节整数ULONG.如果没有显式转换,您可以获得范围错误.