Не желая красть гром 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.
EDIT Как указывает RRUZ в комментарии, документация winsock явно не освобождает inet_addr от WSAStartup / WSACleanup, поэтому я убираю эту точку зрения.В Vista проще просто вызвать RtlIpv4StringToAddress.Сказав все это, inet_addr настолько прост в реализации, что может быть проще накатить вашу собственную.
Во-вторых, объявление inet_addr в WinSock.pas неверно.Он объявляет возвращаемое значение типа u_long, который определен в WinSock.pas как Longint.Это 4-байтовое целое число со знаком, но оно должно быть 4-байтовым целым числом без знака, ULONG.Без явного приведения вы можете получить ошибки диапазона.