【发布时间】:2020-10-28 12:20:46
【问题描述】:
对于我目前正在用 Delphi 编写的安全产品。我正在使用以下解决方案来使用 ARP 表从设备获取 MAC 地址以检测网络上的内容。
How to find MAC addresses from arp -a scan
我只是执行一系列 Ping 命令来填充 ARP 表并从 ARP 表中读取结果。
但是,当计算机上的防火墙阻止 Ping 时。有时 MAC 仍然暴露在 ARP 中,但并非总是如此。检测网络上的所有设备并从中获取 MAC 地址的更好解决方案是什么?
//-----------------------------------------------------------------------------
{ ARP-table lists relations between remote IP and remote MAC-address.
NOTE: these are cached entries;when there is no more network traffic to a
node, entry is deleted after a few minutes.
}
//-----------------------------------------------------------------------------
procedure Get_ARPTable( aList: TStrings; aDeviceList : TObjectList<TNetworkDevice>);
var
lIPNetRow : TMibIPNetRow;
lTableSize : DWORD;
lNumEntries : DWORD;
lErrorCode : DWORD;
lIdx : Integer;
lPBuf : PAnsiChar;
lPhysAddr : TMACAddress;
lMacAddr2Str : string;
ldwAddr : string;
ldwType : string;
lNewDevice : TNetworkDevice;
begin
if not LoadIpHlp then Exit;
if not Assigned( aList ) then Exit;
if not Assigned( aDeviceList) then Exit;
Get_LocalNetworkDevices(aDeviceList);
aList.Clear;
lTableSize := 0;
lErrorCode := GetIPNetTable( Nil, @lTableSize, False );
//
if lErrorCode = ERROR_NO_DATA then
begin
aList.Add( ' ARP-cache empty.' );
EXIT;
end;
// get table
GetMem( lPBuf, lTableSize );
lNumEntries := 0;
try
lErrorCode := GetIpNetTable( PTMIBIPNetTable( lPBuf ), @lTableSize, False );
if lErrorCode = NO_ERROR then
begin
lNumEntries := PTMIBIPNetTable( lPBuf )^.dwNumEntries;
if lNumEntries > 0 then
begin
Inc( lPBuf, SizeOf( DWORD ) );
for lIdx := 1 to lNumEntries do
begin
lIPNetRow := PTMIBIPNetRow( lPBuf )^;
lMacAddr2Str := MacAddr2Str( lIPNetRow.bPhysAddr, lIPNetRow.dwPhysAddrLen );
lPhysAddr := lIPNetRow.bPhysAddr;
ldwAddr := IPAddr2StrTrunc(lIPNetRow.dwAddr);
ldwType := ARPEntryType[lIPNetRow.dwType];
lNewDevice := SeekDevice(aDeviceList, lMacAddr2Str);
if Assigned(lNewDevice) then
begin
lNewDevice.IP := ldwAddr;
lNewDevice.IsNew := False;
lNewDevice.EntryType := ARPEntryType[lIPNetRow.dwType];
if (lNewDevice.EntryType = 'Dynamic') or
(lNewDevice.EntryType = 'Static') then
lNewDevice.SetStamp;
end
else
begin
lNewDevice := TNetworkDevice.Create;
lNewDevice.IP := ldwAddr;
lNewDevice.EntryType := ARPEntryType[lIPNetRow.dwType];
lNewDevice.AddOrUpdate(lMacAddr2Str);
lNewDevice.SetFirstSeen;
lNewDevice.SetStamp;
lNewDevice.State := dtRogue;
lNewDevice.IsNew := True;
aDeviceList.Add(lNewDevice);
end;
with lIPNetRow do
begin
aList.Add( Format( '%8x | %12s | %16s| %10s',
[dwIndex, MacAddr2Str( bPhysAddr, dwPhysAddrLen ),
IPAddr2Str( dwAddr ), ARPEntryType[dwType]
]));
end;
Inc( lPBuf, SizeOf( lIPNetRow ) );
end;
end
else
aList.Add( ' ARP-cache empty.' );
end
else
aList.Add( SysErrorMessage( lErrorCode ) );
// we _must_ restore Pointer!
finally
Dec( lPBuf, SizeOf( DWORD ) + lNumEntries * SizeOf( lIPNetRow ) );
FreeMem( lPBuf );
end;
end;
【问题讨论】:
标签: ping delphi-2010 mac-address