question

noumanyosuf-6107 avatar image
0 Votes"
noumanyosuf-6107 asked PetrusKIM-2099 Suspended answered

Getting Mac address using GetAdaptersAddresses

I am using "GetAdaptersAddresses" function (using C++) to get the MAC address of the computer.
GetAdaptersAddresses returns a link list of PIP_ADAPTER_ADDRESSES for all the adapters connected to the system. I want to fetch the physical address of the Ethernet card specifically. Currently it comes at the first node of the list returned by the GetAdaptersAddresses and the MSDN document (https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses) does not specifically mentioned about the order of the adapters in the list, and could be changed based on the connected adapters. The order is not reliable. Moreover, the order is different on different machine.

Ethernet card is assured to be always connected to the device and the mac address is never changed. How to traverse the list to fetch the physical address of Ethernet card?
(I understand that the'Description' and 'Friendly name' can not be used as they can be changed)

c++windows-api-general
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Castorix31 avatar image
0 Votes"
Castorix31 answered

I have this old code in my archives, using GetIpAddrTable (same as GetAdaptersAddresses for IPv4) :

 #include <windows.h>
 #include <stdio.h>
    
 #pragma comment(lib, "WS2_32")
 #include <iphlpapi.h>
 #pragma comment(lib, "iphlpapi")
    
 #define IP_LOCALHOST    0x0100007F
 void print_ip(DWORD nAddr)
 {
   printf("%d.%d.%d.%d\n", nAddr & 0x000000FF, (nAddr & 0x0000FF00) >> 8, (nAddr & 0x00FF0000) >> 16, (nAddr & 0xFF000000) >> 24);
 }
    
 int main()
 {
   ULONG nSize = 0;
   MIB_IPADDRTABLE * ip_table = NULL;
   if (GetIpAddrTable(ip_table, &nSize, 0) == ERROR_INSUFFICIENT_BUFFER)
   {
       ip_table = (MIB_IPADDRTABLE *) malloc(nSize);
       if (GetIpAddrTable(ip_table, &nSize, 0) == NO_ERROR)
       {
           for (int i = 0; i < ip_table->dwNumEntries; ++i)
           {
               print_ip(ip_table->table[i].dwAddr);
               if (IP_LOCALHOST != ip_table->table[i].dwAddr)
               {
                   MIB_IFROW iInfo;
                   BYTE byMAC[6] = { 0, 0, 0, 0, 0, 0 };
                   memset(&iInfo, 0, sizeof(MIB_IFROW));
                   iInfo.dwIndex = ip_table->table[i].dwIndex;
                   GetIfEntry(&iInfo);
                   if (MIB_IF_TYPE_ETHERNET == iInfo.dwType)
                   {
                        memcpy(&byMAC, iInfo.bPhysAddr, iInfo.dwPhysAddrLen);
                       printf("MAC Address = %02x-%02x-%02x-%02x-%02x-%02x\n", byMAC[0],byMAC[1],byMAC[2], byMAC[3],byMAC[4],byMAC[5]);
                   }
               }
           }
       }
       else
           printf("unable to read IP table from system\n");
       free(ip_table);
   }
   else
       printf("unable to determine number of entries in IP table\n");
   return 0;
 }




5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

noumanyosuf-6107 avatar image
0 Votes"
noumanyosuf-6107 answered Castorix31 commented

@Castorix31 Thank for the answer. but unfortunately I does not give correct MAC of the device.


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I tested on Windows 10 and I get same address as with ipconfig / all for example (or getmac)

0 Votes 0 ·
PetrusKIM-2099 avatar image
0 Votes"
PetrusKIM-2099 Suspended answered

REF.
My Old Code...



https://stpetrus27.wordpress.com/2011/03/16/cc-local-network-mac-address/

 #define WIN32_LEAN_AND_MEAN
    
 #include <Windows.h>
 #include <winsock2.h>
 #include <iphlpapi.h>
 #include <stdio.h>
 #pragma comment(lib, "IPHLPAPI.lib")
    
  int main(int argc, char** argv)
 {
         unsigned char* pszBuff = NULL;
         int nCount = 0;
         int idx = 0;
         int chPos = 0;
         nCount = RetriveLocalMacAddress(GAA_FLAG_INCLUDE_ALL_COMPARTMENTS, AF_UNSPEC, &pszBuff);
    
         for (idx = 0; idx < nCount; ++idx)
         {
                chPos = MAX_ADAPTER_ADDRESS_LENGTH * idx;
                printf("%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
                        pszBuff[chPos], pszBuff[1+chPos], pszBuff[2+chPos], pszBuff[3+chPos],
                        pszBuff[4+chPos], pszBuff[5+chPos], pszBuff[6+chPos], pszBuff[7+chPos]);
         }
         HeapFree(GetProcessHeap(), 0x00, pszBuff);
         pszBuff = NULL;
    
         return 0;
 }
    
 int RetriveLocalMacAddress(ULONG ulFlags, ULONG ulFamily, unsigned char** pszAddress)
 {
         PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
         PIP_ADAPTER_ADDRESSES pAddresses = NULL;
    
         int nAddressCount = 0;
         DWORD dwRetVal = 0;
         ULONG ulBufLen = sizeof(IP_ADAPTER_ADDRESSES);
         HANDLE hHeap = NULL;
    
         hHeap = GetProcessHeap();
         pAddresses = (PIP_ADAPTER_ADDRESSES)HeapAlloc(hHeap, 0x00, ulBufLen);
         if (pAddresses == NULL) {
                return 0;
         }      
    
         dwRetVal = GetAdaptersAddresses(ulFamily, ulFlags, NULL, pAddresses, &ulBufLen);
         if (dwRetVal == ERROR_BUFFER_OVERFLOW)
         {
                HeapFree(hHeap, 0x00, pAddresses);
                pAddresses = (PIP_ADAPTER_ADDRESSES)HeapAlloc(hHeap, 0x00, ulBufLen);
         }
    
         if (pAddresses == NULL) {
                return 0;
         }      
     
         dwRetVal = GetAdaptersAddresses(ulFamily, ulFlags, NULL, pAddresses, &ulBufLen);
         if (dwRetVal == NO_ERROR)
         {
                pCurrAddresses = pAddresses;
                while (pCurrAddresses)
                {
                        pCurrAddresses = pCurrAddresses->Next;
                        ++nAddressCount;
                }
    
                *pszAddress = (unsigned char*)HeapAlloc(hHeap, 0x00, MAX_ADAPTER_ADDRESS_LENGTH * nAddressCount);
                pCurrAddresses = pAddresses;
                nAddressCount = 0;
                while (pCurrAddresses)
                {
                        RtlCopyMemory(*pszAddress + (MAX_ADAPTER_ADDRESS_LENGTH * nAddressCount++),
                           pCurrAddresses->PhysicalAddress,
                                                MAX_ADAPTER_ADDRESS_LENGTH);
                        pCurrAddresses = pCurrAddresses->Next;
                }
         }
    
          if (pAddresses) {
                HeapFree(hHeap, 0x00, pAddresses);
                pAddresses = NULL;
         }
         return nAddressCount;
 }
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.