Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: MAC Address (Mac and Windows)



Permlink Replies: 20 - Last Post: Oct 12, 2014 10:22 AM Last Post By: Brian Hamilton ...
Goffredo Vincenzo

Posts: 68
Registered: 10/1/02
MAC Address (Mac and Windows)
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 8, 2014 10:00 AM
hi,

I have assembled a procedure to obtain the MAC address of my pc, to use it as a reference to identify the machine, as it is one of the few things that you can find in the same way on all devices (Win, Mac, iOS , android), the code is this:

unit Unit1;
 
interface
 
uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Layouts,
  FMX.Memo, FMX.StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    {$IF DEFINED(MSWINDOWS)}
    function IndirizzoMacDiRete_Windows(dispositivo : Integer) : String;
    {$ELSE}
    function IndirizzoMacDiRete_Mac(dispositivo : Integer) : String;
    {$ENDIF}
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.fmx}
 
{$IF DEFINED(MSWINDOWS)}
uses NB30;
{$ELSE}
uses Posix.Base, Posix.SysSocket, Posix.NetIf, Posix.NetinetIn, Posix.ArpaInet;
type
  u_char = UInt8;
  u_short = UInt16;
  sockaddr_dl = record
    sdl_len: u_char;    //* Total length of sockaddr */
    sdl_family: u_char; //* AF_LINK */
    sdl_index: u_short; //* if != 0, system given index for interface */
    sdl_type: u_char;   //* interface type */
    sdl_nlen: u_char;   //* interface name length, no trailing 0 reqd. */
    sdl_alen: u_char;   //* link level address length */
    sdl_slen: u_char;   //* link layer selector length */
    sdl_data: array[0..11] of AnsiChar; //* minimum work area, can be larger;
                                        //contains both if name and ll address */
  end;
  psockaddr_dl = ^sockaddr_dl;
const IFT_ETHER = $6;  //if_types.h
{$ENDIF}
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  {$IF DEFINED(MSWINDOWS)}
  Memo1.Lines.Append(IndirizzoMacDiRete_Windows(0));
  Memo1.Lines.Append(IndirizzoMacDiRete_Windows(1));
  Memo1.Lines.Append(IndirizzoMacDiRete_Windows(2));
  {$ELSE}
  Memo1.Lines.Append(IndirizzoMacDiRete_Mac(0));
  Memo1.Lines.Append(IndirizzoMacDiRete_Mac(1));
  Memo1.Lines.Append(IndirizzoMacDiRete_Mac(2));
  {$ENDIF}
end;
 
{$IF DEFINED(MSWINDOWS)}
function TForm1.IndirizzoMacDiRete_Windows(dispositivo : Integer) : String;
var AdapterList: TLanaEnum; Adapter: TAdapterStatus; NCB1, NCB2: TNCB; Lana: AnsiChar;
begin
  FillChar(NCB1, SizeOf(NCB1), 0);
  NCB1.ncb_command := Char(NCBENUM);
  NCB1.ncb_buffer := @AdapterList;
  NCB1.ncb_length := SizeOf(AdapterList);
  Netbios(@NCB1);
  if Byte(AdapterList.length) > 0 then
  begin
    //AdapterList.lana[] contiene i vari dispositivi hardware
    Lana := AdapterList.lana[dispositivo];
    FillChar(NCB2, SizeOf(NCB2), 0);
    NCB2.ncb_command := Char(NCBRESET);
    NCB2.ncb_lana_num := Lana;
    if Netbios(@NCB2) <> Char(NRC_GOODRET) then begin Result := 'mac non trovato'; Exit; end;
    FillChar(NCB2, SizeOf(NCB2), 0);
    NCB2.ncb_command := Char(NCBASTAT);
    NCB2.ncb_lana_num := Lana;
    NCB2.ncb_callname := '*';
    FillChar(Adapter, SizeOf(Adapter), 0);
    NCB2.ncb_buffer := @Adapter;
    NCB2.ncb_length := SizeOf(Adapter);
    if Netbios(@NCB2) <> Char(NRC_GOODRET) then begin Result := 'mac non trovato'; Exit; end;
    Result := IntToHex(Byte(Adapter.adapter_address[0]), 2) + '-' +
              IntToHex(Byte(Adapter.adapter_address[1]), 2) + '-' +
              IntToHex(Byte(Adapter.adapter_address[2]), 2) + '-' +
              IntToHex(Byte(Adapter.adapter_address[3]), 2) + '-' +
              IntToHex(Byte(Adapter.adapter_address[4]), 2) + '-' +
              IntToHex(Byte(Adapter.adapter_address[5]), 2);
  end
  else Result := 'mac non trovato';
end;
 
{$ELSE}
function getifaddrs(var ifap: pifaddrs): Integer; cdecl; external libc name _PU + 'getifaddrs';
{$EXTERNALSYM getifaddrs}
procedure freeifaddrs(ifp: pifaddrs); cdecl; external libc name _PU + 'freeifaddrs';
{$EXTERNALSYM freeifaddrs}
function TForm1.IndirizzoMacDiRete_Mac(dispositivo : Integer) : String;
var ifap, Next: pifaddrs; sdp : psockaddr_dl; ip: AnsiString;
    MacAddr : array[0..5] of Byte; dispositivi : integer;
begin
  dispositivi := 0;
  try
    if getifaddrs(ifap) <> 0 then RaiseLastOSError;
    try
      SetLength(ip, INET6_ADDRSTRLEN);
      Next := ifap;
      while Next <> nil do
      begin
        case Next.ifa_addr.sa_family of
          AF_LINK :
            begin
              sdp := psockaddr_dl(Next.ifa_addr);
              if sdp.sdl_type = IFT_ETHER then
              begin
                Move(Pointer(PAnsiChar(@sdp^.sdl_data[0]) + sdp.sdl_nlen)^, MacAddr, 6);
                if (dispositivo = dispositivi) then
                begin
                  Result := IntToHex(MacAddr[0], 2) + '-' +
                            IntToHex(MacAddr[1], 2) + '-' +
                            IntToHex(MacAddr[2], 2) + '-' +
                            IntToHex(MacAddr[3], 2) + '-' +
                            IntToHex(MacAddr[4], 2) + '-' +
                            IntToHex(MacAddr[5], 2);
                end;
                dispositivi := dispositivi + 1;
              end;
            end;
        end;
        Next := Next.ifa_next;
      end;
    finally freeifaddrs(ifap);
    end;
  except on E: Exception do Result := 'mac non trovato'; //E.ClassName + ': ' + E.Message;
  end;
  //se non ha trovato nulla
  if (Result = '') then Result := 'mac non trovato';
end;
{$ENDIF}
 
end.


I now have little problem, I have three network adapters in pc:

• a eternet (not connected)
• a WiFi (which I take to be connected to the internet)
• one created by VirtualBox (always connected as standard)

because I need a reference that always remains the same over time, if I run the code I get this

07-00-26-00-C5-40 (VirtualBox)
21-12-5A-22-10-D4 (WiFi)
mac non trovato


if I get disconnected from the internet (WiFi without turning off the device though) I get this

07-00-26-00-C5-40 (VirtualBox)
mac non trovato (WiFi)
mac non trovato


why? the MAC address being serial card should not always be readable? if a device is not internet so I can not see the Mac address?

I serve ONLY the Mac Address of the Ethernet card.
Brian Hamilton ...

Posts: 556
Registered: 10/14/04
Re: MAC Address (Mac and Windows)
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 8, 2014 11:11 AM   in response to: Goffredo Vincenzo in response to: Goffredo Vincenzo
HI
sort of related
but do you (or anyone else) know how to find (with Delphi code) the IP address associated with a Devices MAC address?
:)
Ian Barker Barker

Posts: 98
Registered: 5/18/07
Re: MAC Address (Mac and Windows)
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 8, 2014 12:19 PM   in response to: Brian Hamilton ... in response to: Brian Hamilton ...
The Delphi code in the answer to this linked question seems to cover
pretty much everything you need to know about any adapters on the
machine (and with some work on other machines too).

http://stackoverflow.com/questions/18378630/get-information-about-the-installed-network-adapters

--
IanB.
http://about.me/IanBarker
Brian Hamilton ...

Posts: 556
Registered: 10/14/04
Re: MAC Address (Mac and Windows)
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 8, 2014 1:49 PM   in response to: Ian Barker Barker in response to: Ian Barker Barker
Ian Barker wrote:
The Delphi code in the answer to this linked question seems to cover
pretty much everything you need to know about any adapters on the
machine (and with some work on other machines too).

http://stackoverflow.com/questions/18378630/get-information-about-the-installed-network-adapters

--
IanB.
http://about.me/IanBarker

Hi
thanks for that
The GetNetworkInterfaces (aNetInterfaceList)
does work, it shows this PC's info
but what I was looking for was a way to show all connected to the local router
is that possible?
(i.e what shows in your router window, client list)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: MAC Address (Mac and Windows)
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 8, 2014 2:03 PM   in response to: Brian Hamilton ... in response to: Brian Hamilton ...
Brian wrote:

The GetNetworkInterfaces (aNetInterfaceList)
does work, it shows this PC's info
but what I was looking for was a way to show all connected to the
local router
is that possible?

SIO_GET_INTERFACE_LIST does not provide that information. Again, you need
to use GetAdaptersInfo() or GetAdaptersAddresses() instead. They both provide
the Gateway IP, just match that to your router's IP.

--
Remy Lebeau (TeamB)
Brian Hamilton ...

Posts: 556
Registered: 10/14/04
Re: MAC Address (Mac and Windows)
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 8, 2014 2:14 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi
I did try the last function example in that thread
ie
RetrieveLocalAdapterInformation
but I got an abstract error
(XE6)
?
thanks for your help so far :)
(Maybe I am using it wrong...what would be example code to show the info in a tmemo?)

Edited by: Brian Hamilton on Oct 8, 2014 2:15 PM
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: MAC Address (Mac and Windows) [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 8, 2014 4:35 PM   in response to: Brian Hamilton ... in response to: Brian Hamilton ...
Brian wrote:

I did try the last function example in that thread
ie
RetrieveLocalAdapterInformation
but I got an abstract error
(XE6)
?

The only way you could be getting an abstract error with that code is if
the TStrings parameter is pointing at an actual TStrings object instead of
a descendant like TStringList.

Also, that example is not allocating enough memory to enumerate all of the
adapters.

Maybe I am using it wrong...what would be example code to show
the info in a tmemo?

Try this:

uses
  ..., IpHlpApi, IpTypes;
 
procedure RetrieveLocalAdapterInformation(strings: TStrings);
var
  pAdapterInfo, pTempAdapterInfo: PIP_ADAPTER_INFO;
  BufLen: DWORD;
  Status: DWORD;
  strMAC: String;
  i: Integer;
begin
  strings.Clear;
 
  BufLen := SizeOf(AdapterInfo);
  GetMem(pAdapterInfo, BufLen);
  try
    repeat
      Status := GetAdaptersInfo(pAdapterInfo, BufLen);
      if (Status = ERROR_SUCCESS) then
      begin
        if BufLen <> 0 then Break;
        Status := ERROR_NO_DATA;
      end;
      if (Status = ERROR_BUFFER_OVERFLOW) then
      begin
        ReallocMem(pAdapterInfo, BufLen);
      end else
      begin
        case Status of
          ERROR_NOT_SUPPORTED:
            strings.Add('GetAdaptersInfo is not supported by the operating 
system running on the local computer.');
          ERROR_NO_DATA:
            strings.Add('No network adapter on the local computer.');
        else
            strings.Add('GetAdaptersInfo failed with error #' + IntToStr(Status));
        end;
        Exit;
      end;
    until False;
 
    pTempAdapterInfo := pAdapterInfo;
    while (pTempAdapterInfo <> nil) do
    begin
      strings.Add('Description: ' + pTempAdapterInfo^.Description);
      strings.Add('Name: ' + pTempAdapterInfo^.AdapterName);
 
      strMAC := '';
      for I := 0 to pTempAdapterInfo^.AddressLength - 1 do
        strMAC := strMAC + '-' + IntToHex(pTempAdapterInfo^.Address[I], 2);
 
      Delete(strMAC, 1, 1);
      strings.Add('MAC address: ' + strMAC);
      strings.Add('IP address: ' + pTempAdapterInfo^.IpAddressList.IpAddress.S);
      strings.Add('IP subnet mask: ' + pTempAdapterInfo^.IpAddressList.IpMask.S);
      strings.Add('Gateway: ' + pTempAdapterInfo^.GatewayList.IpAddress.S);
      strings.Add('DHCP enabled: ' + IntToStr(pTempAdapterInfo^.DhcpEnabled));
      strings.Add('DHCP: ' + pTempAdapterInfo^.DhcpServer.IpAddress.S);
      strings.Add('Have WINS: ' + BoolToStr(pTempAdapterInfo^.HaveWins,True));
      strings.Add('Primary WINS: ' + pTempAdapterInfo^.PrimaryWinsServer.IpAddress.S);
      strings.Add('Secondary WINS: ' + pTempAdapterInfo^.SecondaryWinsServer.IpAddress.S);
 
      pTempAdapterInfo := pTempAdapterInfo^.Next;
    end;
  finally
    FreeMem(pAdapterInfo);
  end;
end;


RetrieveLocalAdapterInformation(Memo1.Lines);


--
Remy Lebeau (TeamB)
Brian Hamilton ...

Posts: 556
Registered: 10/14/04
Re: MAC Address (Mac and Windows) [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 8, 2014 6:01 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi
great, thanks very much
that does work
I get this returned (but its not picking up a particular IP device connected to my Router I was interested in (basicly to find its IP address you need to use the client list in your router via a browser window, and so what I was wanting to do is if it showed up via this method then you could match the devices MAC adresss (printed on it) to the its assigned IP address (that I use to connect to it ))
Description: Microsoft Wi-Fi Direct Virtual Adapter
Name: {8A69585C-FD04-4C40-A302-2CCCE40EF2DA}
MAC address: 60-6C-66-1B-01-AD
IP address: 0.0.0.0
IP subnet mask: 0.0.0.0
Gateway: 0.0.0.0
DHCP enabled: 1
DHCP:
Have WINS: False
Primary WINS:
Secondary WINS:
Description: Bluetooth Device (Personal Area Network)
Name: {A54C05D9-46EC-45E6-AEB5-47FE948C5012}
MAC address: 60-6C-66-1B-01-B0
IP address: 0.0.0.0
IP subnet mask: 0.0.0.0
Gateway: 0.0.0.0
DHCP enabled: 1
DHCP:
Have WINS: False
Primary WINS:
Secondary WINS:
Description: Realtek PCIe FE Family Controller
Name: {41E1A598-00D1-4AA9-8B72-8D1E98AF7614}
MAC address: 74-86-7A-0B-BF-8A
IP address: 0.0.0.0
IP subnet mask: 0.0.0.0
Gateway: 192.168.101.1
DHCP enabled: 1
DHCP:
Have WINS: False
Primary WINS:
Secondary WINS:
Description: Intel(R) Centrino(R) Wireless-N 2230
Name: {622863D3-3DCA-4327-BF86-F7C79EC38067}
MAC address: 60-6C-66-1B-01-AC
IP address: 192.168.2.7
IP subnet mask: 255.255.255.0
Gateway: 192.168.2.1
DHCP enabled: 1
DHCP: 192.168.2.1
Have WINS: False
Primary WINS:
Secondary WINS:
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: MAC Address (Mac and Windows) [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 8, 2014 7:44 PM   in response to: Brian Hamilton ... in response to: Brian Hamilton ...
Brian wrote:

I get this returned (but its not picking up a particular IP device
connected to my Router I was interested in (basicly to find its IP
address you need to use the client list in your router via a browser
window, and so what I was wanting to do is if it showed up via this
method then you could match the devices MAC adresss (printed on it)
to the its assigned IP address (that I use to connect to it ))

As I told you earlier, the adapter list includes gateways IPs. Simply look
for the adapters whose gateway IP matches your router's LAN IP. Your "Realtek
PCIe FE Family Controller" and "Intel(R) Centrino(R) Wireless-N 2230" adapters
have gateways assigned to them - 192.168.101.1 and 192.168.2.1, respectively.
I am guessing that 192.168.2.1 is your router's IP.

--
Remy Lebeau (TeamB)
Brian Hamilton ...

Posts: 556
Registered: 10/14/04
Re: MAC Address (Mac and Windows) [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 8, 2014 8:00 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
I am guessing that 192.168.2.1 is your router's IP.

yes, it is

but the IP connected device is has address 192.168.2.2
(its connected to the router)
which shows up via the routers client list

but that IP address or MAC address does not show up with this function ?

thanks for the help :)
(this is actually a bit of a plus for it at least it shows your routers IP address so users of the software can then access that via a browser and get to the client list (half the battle can be just knowing what the IP address the router is connected to)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: MAC Address (Mac and Windows) [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 9, 2014 9:21 AM   in response to: Brian Hamilton ... in response to: Brian Hamilton ...
Brian wrote:

but the IP connected device is has address 192.168.2.2
(its connected to the router)
which shows up via the routers client list
but that IP address or MAC address does not show up with this function
?

An adapter can have multiple IPs, but you are not checking for that. IP_ADAPTER_INFO.IpAddressList
is a linked list, but you are printing out only the first IP in the list.
Same with the Gateway and DHCP addresses. Try this:

var
  ...
  Addr: PIP_ADDR_STRING;
  ...
 
pTempAdapterInfo := pAdapterInfo;
while (pTempAdapterInfo <> nil) do
begin
  strings.Add('Description: ' + pTempAdapterInfo^.Description);
  strings.Add('Name: ' + pTempAdapterInfo^.AdapterName);
 
  strMAC := '';
  for I := 0 to pTempAdapterInfo^.AddressLength - 1 do
    strMAC := strMAC + '-' + IntToHex(pTempAdapterInfo^.Address[I], 2);
  Delete(strMAC, 1, 1);
  strings.Add('MAC address: ' + strMAC);
 
  Addr := @pTempAdapterInfo^.IpAddressList;
  repeat
    strings.Add('IP address: ' + AnsiString(Addr^.IpAddress.S));
    strings.Add('IP subnet mask: ' + AnsiString(Addr^.IpMask.S));
    Addr := Addr^.Next;
  until Addr = nil;
 
  Addr := @pTempAdapterInfo^.GatewayList;
  repeat
    strings.Add('Gateway: ' + AnsiString(Addr^.IpAddress.S));
    Addr := Addr^.Next;
  until Addr = nil;
 
  strings.Add('DHCP enabled: ' + BoolToStr(pTempAdapterInfo^.DhcpEnabled, 
True));
  if pTempAdapterInfo^.DhcpEnabled <> 0 then
  begin
    Addr := @pTempAdapterInfo^.DhcpServer;
    repeat
      strings.Add('DHCP: ' + Addr^.IpAddress.S);
      Addr := Addr^.Next;
    until Addr = nil;
  end;
 
  strings.Add('Have WINS: ' + BoolToStr(pTempAdapterInfo^.HaveWins, True));
  if pTempAdapterInfo^.HaveWins <> 0 then
  begin
    strings.Add('Primary WINS: ' + pTempAdapterInfo^.PrimaryWinsServer.IpAddress.S);
    strings.Add('Secondary WINS: ' + pTempAdapterInfo^.SecondaryWinsServer.IpAddress.S);
  end;
 
  pTempAdapterInfo := pTempAdapterInfo^.Next;
end;


With that said, keep in mind that there are some things that GetAdaptersInfo()
cannot find. Try using GetAdaptersAddresses() instead, it offers more options,
such as IPv6, which GetAdaptersInfo() does not support.

--
Remy Lebeau (TeamB)
Brian Hamilton ...

Posts: 556
Registered: 10/14/04
Re: MAC Address (Mac and Windows) [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 9, 2014 11:38 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi
your changed code did not find it
trying
With that said, keep in mind that there are some things that GetAdaptersInfo()
cannot find. Try using GetAdaptersAddresses() instead, it offers more options,
i.e
Status := GetAdaptersAddresses(pAdapterInfo, BufLen);

I get

E2010 Incompatible types: 'Cardinal' and 'PIP_ADAPTER_INFO'

so looks like I need to change the variables somehow?
var
pAdapterInfo, pTempAdapterInfo: PIP_ADAPTER_INFO;
BufLen: DWORD;
Status: DWORD;
strMAC: String;
i: Integer;

but changing pAdapterInfo to cardinal then just causes more errors

out of my depth here
thanks for the continued help here Remy (hopefully might be help this thread to others needing this functionality (and while I got your ear, is it possible to be able to intercept the IP data sent from a particular IP connected device to the router (I have seen some info about )...but that's a whole new story..
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: MAC Address (Mac and Windows) [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 9, 2014 1:33 PM   in response to: Brian Hamilton ... in response to: Brian Hamilton ...
Brian wrote:

Status := GetAdaptersAddresses(pAdapterInfo, BufLen);
I get

E2010 Incompatible types: 'Cardinal' and 'PIP_ADAPTER_INFO'

Obviously you did not look at the documentation, or even the function signature:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365915.aspx

GetAdaptersAddresses() does not use PIP_ADAPTER_INFO, it uses PIP_ADAPTER_ADDRESSES
instead, and it has more parameters than GetAdaptersInfo().

Try this:

uses
..., IpHlpApi, IpTypes;
 
procedure RetrieveLocalAdapterInformation(strings: TStrings);
var
  pAdapterInfo, pTempAdapterInfo: PIP_ADAPTER_ADDRESSES;
  Unicast: PIP_ADAPTER_UNICAST_ADDRESS;
  AnyCast: PIP_ADAPTER_ANYCAST_ADDRESS;
  Multicast: PIP_ADAPTER_MULTICAST_ADDRESS;
  DnsServer: PIP_ADAPTER_DNS_SERVER_ADDRESS;
  Gateway: PIP_ADAPTER_GATEWAY_ADDRESS;
  WinsServer: PIP_ADAPTER_WINS_SERVER_ADDRESS;
  BufLen: DWORD;
  Status: DWORD;
  strMAC: String;
  i: Integer;
  IPv4: array[0..16] of Char;
  IPv4: array[0..46] of Char;
begin
  strings.Clear;
 
  BufLen := SizeOf(IP_ADAPTER_ADDRESSES);
  GetMem(pAdapterInfo, BufLen);
  try
    repeat
      Status := GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_WINS_INFO 
or GAA_FLAG_INCLUDE_GATEWAYS, nil, pAdapterInfo, BufLen);
      if (Status = ERROR_SUCCESS) then
      begin
        if BufLen <> 0 then Break;
        Status := ERROR_NO_DATA;
      end;
      if (Status = ERROR_BUFFER_OVERFLOW) then
      begin
        ReallocMem(pAdapterInfo, BufLen);
      end else
      begin
        case Status of
          ERROR_NOT_SUPPORTED:
            strings.Add('GetAdaptersAddresses is not supported by the operating 
system running on the local computer.');
          ERROR_NO_DATA:
            strings.Add('No network adapter on the local computer.');
        else
            strings.Add('GetAdaptersAddresses failed with error #' + IntToStr(Status));
        end;
        Exit;
      end;
    until False;
 
    pTempAdapterInfo := pAdapterInfo;
    while (pTempAdapterInfo <> nil) do
    begin
      strings.Add('Description: ' + UnicodeString(pTempAdapterInfo^.Description));
      strings.Add('Name: ' + AnsiString(pTempAdapterInfo^.AdapterName));
 
      strMAC := '';
      for I := 0 to pTempAdapterInfo^.PhysicalAddressLength - 1 do
        strMAC := strMAC + '-' + IntToHex(pTempAdapterInfo^.PhysicalAddress[I], 
2);
      Delete(strMAC, 1, 1);
      strings.Add('MAC address: ' + strMAC);
 
      Unicast := pTempAdapterInfo^.FirstUnicastAddress;
      while Unicast <> nil do
      begin
        case Unicast^.Address.lpSockaddr^.sa_family of
          AF_INET: begin
             RtlIpv4AddressToString(@(PSockaddrIn(Unicast^.Address.lpSockaddr)^.sin_addr), 
IPv4);
             strings.Add('Unicast IPv4 address: ' + String(IPv4));
          end;
          AF_INET6: begin
             RtlIpv6AddressToString(@(PSockaddrIn6(Unicast^.Address.lpSockaddr)^.sin6_addr), 
IPv6);
             strings.Add('Unicast IPv6 address: ' + String(IPv6));
          end;
        end;
        Unicast := Unicast^.Next;
      end;
 
      Anycast := pTempAdapterInfo^.FirstAnycastAddress;
      while Anycast <> nil do
      begin
        case Anycast^.Address.lpSockaddr^.sa_family of
          AF_INET: begin
             RtlIpv4AddressToString(@(PSockaddrIn(Anycast^.Address.lpSockaddr)^.sin_addr), 
IPv4);
             strings.Add('Anycast IPv4 address: ' + String(IPv4));
          end;
          AF_INET6: begin
             RtlIpv6AddressToString(@(PSockaddrIn6(Anycast^.Address.lpSockaddr)^.sin6_addr), 
IPv6);
             strings.Add('Anycast IPv6 address: ' + String(IPv6));
          end;
        end;
        Anycast := Anycast^.Next;
      end;
 
      Multicast := pTempAdapterInfo^.FirstMulticastAddress;
      while Multicast <> nil do
      begin
        case Multicast^.Address.lpSockaddr^.sa_family of
          AF_INET: begin
             RtlIpv4AddressToString(@(PSockaddrIn(Multicast^.Address.lpSockaddr)^.sin_addr), 
IPv4);
             strings.Add('Multicast IPv4 address: ' + String(IPv4));
          end;
          AF_INET6: begin
             RtlIpv6AddressToString(@(PSockaddrIn6(Multicast^.Address.lpSockaddr)^.sin6_addr), 
IPv6);
             strings.Add('Multicast IPv6 address: ' + String(IPv6));
          end;
        end;
        Multicast := Multicast^.Next;
      end;
 
      DnsServer := pTempAdapterInfo^.FirstMulticastAddress;
      while DnsServer <> nil do
      begin
        case DnsServer^.Address.lpSockaddr^.sa_family of
          AF_INET: begin
             RtlIpv4AddressToString(@(PSockaddrIn(DnsServer^.Address.lpSockaddr)^.sin_addr), 
IPv4);
             strings.Add('DNS Server IPv4 address: ' + String(IPv4));
          end;
          AF_INET6: begin
             RtlIpv6AddressToString(@(PSockaddrIn6(DnsServer^.Address.lpSockaddr)^.sin6_addr), 
IPv6);
             strings.Add('DNS Server IPv6 address: ' + String(IPv6));
          end;
        end;
        DnsServer := DnsServer^.Next;
      end;
 
      Gateway := pTempAdapterInfo^.FirstGatewayAddress;
      while Gateway <> nil do
      begin
        case Gateway^.Address.lpSockaddr^.sa_family of
          AF_INET: begin
             RtlIpv4AddressToString(@(PSockaddrIn(Gateway^.Address.lpSockaddr)^.sin_addr), 
IPv4);
             strings.Add('Gateway IPv4 address: ' + String(IPv4));
          end;
          AF_INET6: begin
             RtlIpv6AddressToString(@(PSockaddrIn6(Gateway^.Address.lpSockaddr)^.sin6_addr), 
IPv6);
             strings.Add('Gateway IPv6 address: ' + String(IPv6));
          end;
        end;
        Gateway := Gateway^.Next;
      end;
 
      strings.Add('DHCP enabled: ' + BoolToStr((pTempAdapterInfo^.Flags and 
IP_ADAPTER_DHCP_ENABLED) <> 0, True));
      if (pTempAdapterInfo^.Flags and IP_ADAPTER_DHCP_ENABLED) <> 0 then
      begin
         RtlIpv4AddressToString(@(PSockaddrIn(pTempAdapterInfo^.Dhcpv4Server.lpSockaddr)^.sin_addr), 
IPv4);
         strings.Add('DHCP IPv4 address: ' + String(IPv4));
 
         RtlIpv6AddressToString(@(PSockaddrIn6(pTempAdapterInfo^.Dhcpv6Server.lpSockaddr)^.sin6_addr), 
IPv6);
         strings.Add('Gateway IPv6 address: ' + String(IPv6));
      end;
 
      WinsServer := pTempAdapterInfo^.FirstWinsServerAddress;
      while WinsServer <> nil do
      begin
        case WinsServer^.Address.lpSockaddr^.sa_family of
          AF_INET: begin
             RtlIpv4AddressToString(@(PSockaddrIn(WinsServer^.Address.lpSockaddr)^.sin_addr), 
IPv4);
             strings.Add('WINS Server IPv4 address: ' + String(IPv4));
          end;
          AF_INET6: begin
             RtlIpv6AddressToString(@(PSockaddrIn6(WinsServer^.Address.lpSockaddr)^.sin6_addr), 
IPv6);
             strings.Add('WINS Server IPv6 address: ' + String(IPv6));
          end;
        end;
        WinsServer := WinsServer^.Next;
      end;
 
      pTempAdapterInfo := pTempAdapterInfo^.Next;
    end;
  finally
    FreeMem(pAdapterInfo);
  end;
end;


--
Remy Lebeau (TeamB)
Brian Hamilton ...

Posts: 556
Registered: 10/14/04
Re: MAC Address (Mac and Windows) [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 9, 2014 2:29 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi
I had to change some of the variables ,due to compile error
i.e

Gateway: PIP_ADAPTER_ADDRESSES;
WinsServer: PIP_ADAPTER_ADDRESSES;

instead of

Gateway: PIP_ADAPTER_GATEWAY_ADDRESS;
WinsServer: PIP_ADAPTER_WINS_SERVER_ADDRESS;

and
Status := GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_WINS_INFO or GAA_FLAG_INCLUDE_GATEWAYS, nil, pAdapterInfo,pulong( BufLen)); -< added pulong

instead of
Status := GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_WINS_INFO or GAA_FLAG_INCLUDE_GATEWAYS, nil, pAdapterInfo, BufLen);

and then
case Unicast^.Address.lpSockaddr^.sa_family of
AF_INET: begin

the AF_INET is undeclared so I just put in tha value expected

case Unicast^.Address.lpSockaddr^.sa_family of
2 : begin

then the next error is with

RtlIpv6AddressToString

undeclared...googling does not find much info except:

http://stackoverflow.com/questions/3989446/get-an-ip-address-string-from-getadaptersaddresses

as I say, out of my depth here
but very appreciate your help so far! :)

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: MAC Address (Mac and Windows) [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 9, 2014 3:16 PM   in response to: Brian Hamilton ... in response to: Brian Hamilton ...
Brian wrote:

I had to change some of the variables ,due to compile error
i.e

Gateway: PIP_ADAPTER_ADDRESSES;
WinsServer: PIP_ADAPTER_ADDRESSES;

instead of

Gateway: PIP_ADAPTER_GATEWAY_ADDRESS;
WinsServer: PIP_ADAPTER_WINS_SERVER_ADDRESS;

Those are the wrong types to use. They need to be PIP_ADAPTER_GATEWAY_ADDRESS_LH
and PIP_ADAPTER_WINS_SERVER_ADDRESS_LH, respectively:

Gateway: PIP_ADAPTER_GATEWAY_ADDRESS_LH;
WinsServer: PIP_ADAPTER_WINS_SERVER_ADDRESS_LH;


Status := GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_WINS_INFO
or GAA_FLAG_INCLUDE_GATEWAYS, nil, pAdapterInfo,pulong( BufLen)); -
added pulong
instead of

Status := GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_WINS_INFO
or GAA_FLAG_INCLUDE_GATEWAYS, nil, pAdapterInfo, BufLen);

That is also wrong. Typecasting a DWORD value to a pulong pointer will crash
the code. You need to use the '@' operator instead:

Status := GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_WINS_INFO or GAA_FLAG_INCLUDE_GATEWAYS, 
nil, pAdapterInfo, @BufLen);


case Unicast^.Address.lpSockaddr^.sa_family of
AF_INET: begin
the AF_INET is undeclared

Add the WinSock or WinSock2 unit to your 'uses' clause.

then the next error is with

RtlIpv6AddressToString

undeclared...

Delphi does not declare RtlIpv4AddressToString() or RtlIpv6AddressToString()
in any of its RTL units, so you will have to declare them manually:

function RtlIpv4AddressToString(const Addr: PInAddr; S: PChar): PChar; stdcall; 
external 'Ntdll.dll' name {$IFDEF UNICODE}'RtlIpv4AddressToStringW'{$ELSE}'RtlIpv4AddressToStringA'{$ENDIF};
function RtlIpv6AddressToString(const Addr: PIn6Addr; S: PChar): PChar; stdcall; 
external 'Ntdll.dll' name {$IFDEF UNICODE}'RtlIpv6AddressToStringW'{$ELSE}'RtlIpv6AddressToStringA'{$ENDIF};


--
Remy Lebeau (TeamB)
Brian Hamilton ...

Posts: 556
Registered: 10/14/04
Re: MAC Address (Mac and Windows) [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 9, 2014 5:58 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
making progress
there was a few more compile errors

function RtlIpv6AddressToString(const Addr: PIn6Addr; S: PChar): PChar; stdcall;
erorr with the PIN6addr

not found
(so changed to just PInAddr so as to be able to carry one, which also meant changes at e.g
RtlIpv6AddressToString(@(PSockaddrIn6
changed to
RtlIpv6AddressToString(@(PSockaddrIn


this line
DnsServer := pTempAdapterInfo^.FirstMulticastAddress;

I changed to

DnsServer := pTempAdapterInfo^.FirstDNSserverAddress;

to get it to compile

then when I run it
I get access violation error at
strings.Add('DHCP IPv4 address: ' + String(IPv4));


bracketing out that code make it run without error, but it still does not show the IP device I am wanting to know about connected to my wireless Router

but lets not worry now
thanks!

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: MAC Address (Mac and Windows) [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 9, 2014 6:45 PM   in response to: Brian Hamilton ... in response to: Brian Hamilton ...
Brian wrote:

there was a few more compile errors
function RtlIpv6AddressToString(const Addr: PIn6Addr; S: PChar):
PChar; stdcall; erorr with the PIN6addr

not found

It is in the Winapi.IpExport unit.

so changed to just PInAddr

That is wrong. PInAddr is a pointer to an in_addr record. PIn6Addr is a
pointer to an in6_addr record. in_addr and in6_addr are very different types.

so as to be able to carry one, which also meant changes at e.g
RtlIpv6AddressToString(@(PSockaddrIn6
changed to
RtlIpv6AddressToString(@(PSockaddrIn
this line

That is asking for major trouble. The sockaddr_in.sin_addr field is at offset
4, whereas the sockaddr_in6.sin6_addr field is at offset 8 instead.

When you get a "not found" error - DON'T change the declarations! Fix the
references so they are found correctly.

DnsServer := pTempAdapterInfo^.FirstMulticastAddress;
I changed to

DnsServer := pTempAdapterInfo^.FirstDNSserverAddress;

to get it to compile

OK, I'll give you that one :)

it still does not show the IP device I am wanting to know about connected
to my wireless Router

Look at the various flags that GetAdaptersAddress() offers, you might need
to specify other flag to get your adapter to appear in the list:

GetAdaptersAddresses function
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365915.aspx

BTW, can you see your desired adapter listed when running IPCONFIG on the
command-line? If so, does it show the router's IP as its gateway?

--
Remy Lebeau (TeamB)
Brian Hamilton ...

Posts: 556
Registered: 10/14/04
Re: MAC Address (Mac and Windows) [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 9, 2014 11:25 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
BTW, can you see your desired adapter listed when running IPCONFIG on the
command-line? If so, does it show the router's IP as its gateway?

good idea, I will try that

ps, unrelated, but I was working with some indy components and had an error with socket connection
and the error trace ended up at code that has this easter egg:
If you insist upon requesting help via our email boxes on the 10038 error
that is already answered in the FAQ and you are simply too slothful to
search for your answer and ask your question in the public forums you may be
publicly flogged, tarred and feathered and your name may be added to every
chain letter / EMail in existence today."

Otherwise, if you DID read the FAQ and have further questions, please feel
free to ask using one of the methods (Carefullly note that these methods do
not list email) listed on the Tech Support link at:
http://www.IndyProject.org/

not afraid of a public flogging...only way to learn

Ian Barker Barker

Posts: 98
Registered: 5/18/07
Re: MAC Address (Mac and Windows)
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 8, 2014 2:34 PM   in response to: Brian Hamilton ... in response to: Brian Hamilton ...
Brian Hamilton wrote:


Hi
thanks for that
The GetNetworkInterfaces (aNetInterfaceList)
does work, it shows this PC's info
but what I was looking for was a way to show all connected to the
local router is that possible?
(i.e what shows in your router window, client list)

I think you need to use SNMP. Remy is the genius on this but there's
what appears to be a working example that can be butchered here:

http://borland.newsgroups.archived.at/public.delphi.internet.winsock/200507/0507123299.html

--
IanB.
http://about.me/IanBarker

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: MAC Address (Mac and Windows)
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 8, 2014 12:12 PM   in response to: Goffredo Vincenzo in response to: Goffredo Vincenzo
Goffredo wrote:

I have assembled a procedure to obtain the MAC address of my pc, to
use it as a reference to identify the machine, as it is one of the few
things that you can find in the same way on all devices (Win, Mac, iOS
, android), the code is this:

Why are you using Netbios() on Windows? You should be using GetAdaptersInfo()
or GetAdaptersAddresses() instead.

--
Remy Lebeau (TeamB)
Goffredo Vincenzo

Posts: 68
Registered: 10/1/02
Re: MAC Address (Mac and Windows)
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 8, 2014 12:17 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
I have assembled a procedure to obtain the MAC address of my pc, to
use it as a reference to identify the machine, as it is one of the few
things that you can find in the same way on all devices (Win, Mac, iOS
, android), the code is this:

because I don't have find other example

Edited by: Goffredo Vincenzo on Oct 12, 2014 10:22 AM
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02