Page 1 of 1
Forum

Welcome to the Tweaking4All community forums!
When participating, please keep the Forum Rules in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
For example “MacOS X – Your question“, or “MS Word – Your Tip or Trick“.

Please note that switching to another language when reading a post will not bring you to the same post, in Dutch, as there is no translation for that post!



Share:
Notifications
Clear all

[Solved] Lazarus - MacOS X - Retrieve MAC Address of a network client in your network

2 Posts
1 Users
0 Reactions
2,384 Views
 Hans
(@hans)
Famed Member Admin
Joined: 12 years ago
Posts: 2822
Topic starter  

This function will try to retrieve the MAC address of a network client (desktop, server, laptop, ipad, etc) in your network based on machine name or IP address.

The return value ie a string in the format of 00:00:00:00:00:00 and can be as GetMACAddress('machinename'); or GetMacAddres('192.168.1.1');
If the Mac Address cannot be found, the result will be "00:00:00:00:00:00". 

This works only under MacOS X, for Windows and Linux, "arp" might not give the expected answer and fails.
You can try to modify the code for those systems - please post if you did!

You will need to include the "process" unit in your Uses clause.
The "Ping" function is used to wake things up a little (not the same as Wake On LAN) - which seems to help.

function TForm1.Ping(Host:string):boolean;
var s : ansistring;
const PingCount = '1'; // number of pings
      PingTimeout = '2'; // timout for each ping
begin
  {$IFDEF Darwin}
    RunCommand('/sbin/ping',['-c '+PingCount,'-t '+PingTimeout,'-q',Host],s);
  {$ELSE}
    RunCommand('/bin/ping',['-c '+PingCount,'-w '+PingTimeout,'-q',Host],s);
  {$ENDIF}
  Result := (pos('100.0% packet loss',S)=0) and (pos('100% packet loss',S)=0);
end; 
function TForm1.GetMACAddress(Host:string):string;
var s : ansistring;
    MacAddress, MacNo:string;
    Counter:integer;
begin
  if ping(Host) then
    begin
      RunCommand('/usr/sbin/arp',[Host],s);
      if (pos(':',s)=0) or (pos('(incomplete)',s)>0) or (pos(' -- no entry',s)>0) then
        Result := '00:00:00:00:00:00'
      else
        begin
          s := copy(s,pos(' at ',s)+4,Length(s));
          s := copy(s,0,pos(' on ',s)-1);
          MacAddress:='';
          for Counter:=1 to 5 do
            begin
              MacNo:=Copy(S, 0, pos(':',S)-1);
              s:=Copy(s,pos(':',S)+1,Length(S));
              if Length(MacNo)=1 then MacNo:='0'+MacNo;
              MacAddress:=MacAddress+MacNo+':';
            end;
          MacAddress:=MacAddress+s;
          Result:=UpperCase(MacAddress);
        end;
    end
  else
    Result:='00:00:00:00:00:00';
end;

   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 12 years ago
Posts: 2822
Topic starter  

An expanded version which should work for both MacOS X (tested with El Capitan) and Windows (tested with Windows 10), Windows users will see a shell window popup briefly.

function Ping(Host:string):boolean;
var s : ansistring;
const PingCount = '2'; // number of pings
      PingTimeout = '2'; // timout for each ping
begin
  s:='';
  {$IFDEF Darwin}
  RunCommand('/sbin/ping',['-c '+PingCount,'-t '+PingTimeout,'-q',Host],s);
  {$ENDIF}
  {$IFDEF Windows}
  RunCommand('ping.exe',['-n ',PingCount,'-w ',PingTimeout,Host],s);
  {$ENDIF}
  Result := (pos('100.0% packet loss',S)=0) and (pos('100% packet loss',S)=0) and (pos('100% loss',S)=0);
end;
function GetMACAddress(Host:string):string;
var s : ansistring;
    MacAddress, MacNo:string;
    Counter:integer;
    ArpExe:string;
begin
  if ping(Host) then
    begin
      s:='';
      {$IFDEF Darwin}
      RunCommand('/usr/sbin/arp',[Host],s);
      {$ENDIF}
      {$IFDEF Windows}
      RunCommand('arp.exe',['-a',Host],s);
      {$ENDIF}
      {$IFDEF Darwin}
      if (pos(':',s)=0) or (pos('(incomplete)',s)>0) or (pos(' -- no entry',s)>0) then
      {$ENDIF}
      {$IFDEF Windows}
      if (pos('Physical Address',s)=0) or (pos('No ARP Entries Found',s)>0) then
      {$ENDIF}
        Result := BlankMACAddress
      else
        begin
          {$IFDEF Darwin}
          s := copy(s,pos(' at ',s)+4,Length(s));
          s := copy(s,0,pos(' on ',s)-1);
          MacAddress:='';
          for Counter:=1 to 5 do
            begin
              MacNo:=Copy(S, 0, pos(':',S)-1);
              s:=Copy(s,pos(':',S)+1,Length(S));
              if Length(MacNo)=1 then MacNo:='0'+MacNo;
              MacAddress:=MacAddress+MacNo+':';
            end;
          MacAddress:=MacAddress+s;
          {$ENDIF}
          {$IFDEF Windows}
          // Windows stuff here
          s:=Copy(s,pos(Host,s)+Length(Host),Length(s));
          s:=trim(s);
          MacAddress:='';
          for Counter:=1 to 5 do
            begin
              MacNo:=Copy(S, 0, pos('-',S)-1);
              s:=Copy(s,pos('-',S)+1,Length(S));
              if Length(MacNo)=1 then MacNo:='0'+MacNo;
              MacAddress:=MacAddress+MacNo+':';
            end;
          MacAddress:=MacAddress+Copy(s,0,2);
          {$ENDIF}
          Result:=UpperCase(MacAddress);
        end;
    end
  else
    Result:=BlankMACAddress;
end;    

   
ReplyQuote
Share: