I'd like to get a MAC address from an IP of a host in the same local network. I'd prefer to get this information from the local cache instead of sending a new ARP ARP request. I found that ResolveIpNetEntry2 should be what I need.
Unfortunately I didn't find any code sample for Delphi with that function. Even worse I didn't even find any Delphi headers for that function and its data types. So I tried converting them myself. Well, it compiles, but I get ERROR_INVALID_PARAMETER (87), so apparently I converted something wrong.
Could someone please tell me how to correct it?
const
IF_MAX_PHYS_ADDRESS_LENGTH = 32;
type
NET_LUID = record
case Word of
1: (Value: Int64;);
2: (Reserved: Int64;);
3: (NetLuidIndex: Int64;);
4: (IfType: Int64;);
end;
NL_NEIGHBOR_STATE = (
NlnsUnreachable=0,
NlnsIncomplete,
NlnsProbe,
NlnsDelay,
NlnsStale,
NlnsReachable,
NlnsPermanent,
NlnsMaximum);
PMIB_IPNET_ROW2 = ^MIB_IPNET_ROW2;
MIB_IPNET_ROW2 = record
Address: LPSOCKADDR; //SOCKADDR_INET
InterfaceIndex: ULONG; //NET_IFINDEX
InterfaceLuid: NET_LUID;
PhysicalAddress: array [0..IF_MAX_PHYS_ADDRESS_LENGTH - 1] of UCHAR;
PhysicalAddressLength: ULONG;
State: NL_NEIGHBOR_STATE;
Union: record
case Integer of
0: (IsRouter: Boolean;
IsUnreachable: Boolean);
1: (Flags: UCHAR);
end;
ReachabilityTime: record
case Integer of
0: (LastReachable: ULONG);
1: (LastUnreachable: ULONG);
end;
end;
function ResolveIp(const AIp: String; AIfIndex: ULONG): String;
type
TResolveIpNetEntry2Func = function (Row: PMIB_IPNET_ROW2; const SourceAddress: LPSOCKADDR): DWORD; stdcall; //NETIOAPI_API
const
IphlpApiDll = 'iphlpapi.dll';
var
hIphlpApiDll: THandle;
ResolveIpNetEntry2: TResolveIpNetEntry2Func;
dw: DWORD;
Row: PMIB_IPNET_ROW2;
SourceAddress: LPSOCKADDR;
IpAddress: LPSOCKADDR;
begin
hIphlpApiDll := LoadLibrary(IphlpApiDll);
if hIphlpApiDll = 0 then
Exit;
ResolveIpNetEntry2 := GetProcAddress(hIphlpApiDll, 'ResolveIpNetEntry2');
if (@ResolveIpNetEntry2 = nil) then
Exit;
IpAddress := AllocMem(SizeOf(IpAddress));
IpAddress.sa_family := AF_INET;
IpAddress.sa_data := PAnsiChar(AIp);
Row := AllocMem(SizeOf(Row));
Row.Address := IpAddress;
Row.InterfaceIndex := AIfIndex;
SourceAddress := 0;
dw := ResolveIpNetEntry2(Row, SourceAddress);
//...
end;