How to get the MAC address of the network adapter, which is used by default, i.e. through which the traffic goes to / from the Internet when using a socket?

Update: Found a code to output all network adapters via NetBios , example:

 bool GetAdapterInfo(int nAdapterNum, std::string & sMAC) { // Reset the LAN adapter so that we can begin querying it NCB Ncb; memset(&Ncb, 0, sizeof(Ncb)); Ncb.ncb_command = NCBRESET; Ncb.ncb_lana_num = nAdapterNum; if (Netbios(&Ncb) != NRC_GOODRET) return false; // Prepare to get the adapter status block memset(&Ncb, 0, sizeof(Ncb)); Ncb.ncb_command = NCBASTAT; Ncb.ncb_lana_num = nAdapterNum; strcpy((char *)Ncb.ncb_callname, "*"); struct ASTAT { ADAPTER_STATUS adapt; NAME_BUFFER NameBuff[30]; } Adapter; memset(&Adapter, 0, sizeof(Adapter)); Ncb.ncb_buffer = (unsigned char *)&Adapter; Ncb.ncb_length = sizeof(Adapter); // Get the adapter's info and, if this works, return it in standard, // colon-delimited form. if (Netbios(&Ncb) == 0) { char acMAC[18]; sprintf(acMAC, "%02X:%02X:%02X:%02X:%02X:%02X", int(Adapter.adapt.adapter_address[0]), int(Adapter.adapt.adapter_address[1]), int(Adapter.adapt.adapter_address[2]), int(Adapter.adapt.adapter_address[3]), int(Adapter.adapt.adapter_address[4]), int(Adapter.adapt.adapter_address[5])); sMAC = acMAC; return true; } else { return false; } } std::vector<std::wstring> GetMac() { std::vector<std::wstring> result; LANA_ENUM AdapterList; NCB Ncb; memset(&Ncb, 0, sizeof(NCB)); Ncb.ncb_command = NCBENUM; Ncb.ncb_buffer = (unsigned char *)&AdapterList; Ncb.ncb_length = sizeof(AdapterList); Netbios(&Ncb); std::string sMAC; for (int i = 0; i < AdapterList.length; ++i) { if (GetAdapterInfo(AdapterList.lana[i], sMAC)) result.push_back(std::wstring(sMAC.begin(), sMAC.end())); } return result; } 

But the question remains - how to get the default MAC address of the adapter?

  • one
    And here c++11 ? - αλεχολυτ
  • @alexolut, C++11 standard tools are available. - Alexis
  • 2
    In c++ is still nothing to work with the network. At least 11, at least some other. This is either boost\asio or winsock . - αλεχολυτ
  • one
    Trying to compose MAC authorization and bindings? The idea is inherently flawed. Strictly speaking (and considering the general case), there is no such adapter. Because the decision on which adapter to go through is made on the basis of the routing table, which can be quite confusing. Moreover, the aggregation of interfaces can be configured on the machine, then the packets go through different adapters (depending on the balancing algorithm, which are a dozen and which are combined). Total, the normal decision for all occasions you will not bring. Crutches remain. - gbg
  • one
    As a rule, there is one active interface on the user's machine, and take it. If there are a lot of interfaces, you need to look at the routing table - look in it for which adapter the default route is hung on. If there is something more complicated, for example, the default route is assigned to a virtual adapter - you are not lucky. The idea of ​​using a MAC for authorization is flawed, it’s not for this purpose. - gbg

1 answer 1

Since no one wanted to help, I rolled my bike and spread it to help others, maybe the code was incorrect, I checked it only on my system:

 #pragma comment(lib, "IPHLPAPI.lib") #include <winsock2.h> #include <iphlpapi.h> #include <algorithm> #include <sstream> #include <iomanip> #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) #define FREE(x) HeapFree(GetProcessHeap(), 0, (x)) template<typename T> static std::string HexToString(T uval) { std::stringstream ss; ss << std::setw(sizeof(uval) * 2) << std::setfill('0') << std::hex << +uval; std::string strToConvert = ss.str(); std::transform(strToConvert.begin(), strToConvert.end(), strToConvert.begin(), ::toupper); return strToConvert; } std::wstring GetMac() { std::wstring result; unsigned int i = 0; DWORD dwRetVal = 0; ULONG flags = GAA_FLAG_INCLUDE_PREFIX; ULONG family = AF_INET; PIP_ADAPTER_ADDRESSES pAddresses = NULL; ULONG outBufLen = sizeof(IP_ADAPTER_ADDRESSES); pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen); if (GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW) { FREE(pAddresses); pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen); } if (pAddresses == NULL) return L""; dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen); if (dwRetVal == NO_ERROR) { if (pAddresses->PhysicalAddressLength != 0) { std::string str; for (i = 0; i < pAddresses->PhysicalAddressLength; i++) { if (i == (pAddresses->PhysicalAddressLength - 1)) str += HexToString((unsigned char)pAddresses->PhysicalAddress[i]); else str += HexToString((unsigned char)pAddresses->PhysicalAddress[i]) + ":"; } result = std::wstring(str.begin(), str.end()); } } FREE(pAddresses); return result; } 

ps refused the version with NetBios due to the lack of it on Windows Vista , Windows Server 2008 by default.

  • To the one who put a minus - write your answer or indicate errors or minuses of the above code. - Alexis