通过IP获取局域网MAC地址

uses winsock;
function sendarp(ipaddr:ulong;temp:dword;ulmacaddr:pointer;ulmacaddrleng:pointer) : Dword; StdCall;
External 'Iphlpapi.dll' Name 'SendARP';

function GetMACByIP(const Ip:string):string;
var
MyIp:ulong;
MyMac:array[0..5] of byte;
MyMacLength:ulong;
ErrCode:integer;
begin
Myip:=inet_addr(PChar(Ip));
MyMacLength:=Length(MyMac);
ErrCode:=SendArp(MyIp,0,@MyMac,@MyMacLength);
if ErrCode = 0 then
Result := Format('%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x',[MyMac[0],MyMac[1],MyMac[2],MyMac[3],MyMac[4],MyMac[5]])
else
Result := ''; //EorrCode: ErrCode
end;

又一函数:
下面的函数以'XX-XX-XX-XX-XX-XX' 的格式返回远程或本地机器的MAC地址。

Function to return the MAC address of a remote or local machine in the format 'XX-XX-XX-XX-XX-XX'


返回的MAC地址是一个能用在多个方面的唯一标识。使用方法:
ShowMessage(GetMacAddress('//MHEYDON');

输出'00-02-08-E7-99-6B'// ======================================================================
//返回值是主机AServerName的MAC地址
//AServerName参数的格式为'//ServerName' 或者 'ServerName'
//参数ServerName为空时返回本机的MAC地址
//MAC地址以'XX-XX-XX-XX-XX-XX'的格式返回
// ======================================================================
function GetMacAddress(const AServerName: string): string;
type
TNetTransportEnum = function (pszServer: PWideChar;
Level: DWORD;
var pbBuffer: pointer;
PrefMaxLen: LongInt;
var EntriesRead: DWORD;
var TotalEntries: DWORD;
var ResumeHandle: DWORD): DWORD; stdcall;

TTransportInfo = record
quality_of_service: DWord;
number_of_vcs: DWORD;
transport_name: PWChar;
transport_address: PWChar;
wan_ish: boolean;
end;

TNetApiBufferFree = function(Buffer: pointer): DWORD; stdcall;

PTransportInfo = ^TTransportInfo;
var
E,ResumeHandle,
EntriesRead,
TotalEntries: DWORD;
FLibHandle: THandle;
sMachineName,
sMacAddr,
Retvar: string;
pBuffer: pointer;
pInfo: PTransportInfo;
FNetTransportEnum: TNetTransportEnum;
FNetApiBufferFree: TNetApiBufferFree;
pszServer: array[0..128] of WideChar;
i,ii,iIdx: integer;
begin
sMachineName := Trim(AServerName);
Retvar := '00-00-00-00-00-00';

//Add leading // if missing
if (sMachineName <> '') and (length(sMachineName) >= 2) then begin
if copy(sMachineName,1,2) <> '//' then
sMachineName := '//' + sMachineName;
end;

//Setup and load from DLL
pBuffer := nil;
ResumeHandle := 0;
FLibHandle := LoadLibrary('NETAPI32.DLL');

// Execute the external function
if FLibHandle <> 0 then begin
@FNetTransportEnum := GetProcAddress(FLibHandle,'NetWkstaTransportEnum');
@FNetApiBufferFree := GetProcAddress(FLibHandle,'NetApiBufferFree');
E := FNetTransportEnum(StringToWideChar(sMachineName,pszServer,129),0,
pBuffer,-1,EntriesRead,TotalEntries,Resumehandle);

if E = 0 then begin
pInfo := pBuffer;

// Enumerate all protocols - look for TCPIP
for i := 1 to EntriesRead do begin
if pos('TCPIP',UpperCase(pInfo^.transport_name)) <> 0 then begin
// Got It - now format result 'xx-xx-xx-xx-xx-xx'
iIdx := 1;
sMacAddr := pInfo^.transport_address;
for ii := 1 to 12 do begin
Retvar[iIdx] := sMacAddr[ii];
inc(iIdx);
if iIdx in [3,6,9,12,15] then inc(iIdx);
end;
end;

inc(pInfo);
end;
if pBuffer <> nil then FNetApiBufferFree(pBuffer);
end;

try
FreeLibrary(FLibHandle);
except
// 错误处理
end;
end;
result:=Retvar;
end;