English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

C++Implementation method to obtain all network card IP and MAC address information on the local machine

A machine may not have only one network card, but each network card has only one MAC address, and each network card may be configured with multiple IP addresses; for example, in a common laptop, there will be both wireless network cards and wired network cards (wired interface); therefore, if you want to get the IP and MAC address information of all network cards on the machine, you must sequentially obtain each network card and then sequentially obtain its information, etc.; in the Windows SDK, the IP_ADAPTER_INFO structure is used to store network card information, including network card name, network card description, network card MAC address, network card IP, etc., and the main description of this structure is as follows:

typedef struct _IP_ADAPTER_INFO {
  struct _IP_ADAPTER_INFO* Next;//Pointer to the next adapter information in the list
  DWORD ComboIndex;//Reserved value
  char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];//Adapter name expressed by an ANSI string
  char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];//Adapter description expressed by an ANSI string
  UINT AddressLength;//The length of the adapter hardware address calculated in bytes
  BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];//Hardware address represented by a BYTE array
  DWORD Index;//Adapter index
  UINT Type;//Adapter types, mainly the following kinds:
  /*
   *  MIB_IF_TYPE_OTHER   1
   *  MIB_IF_TYPE_ETHERNET   6
   *  MIB_IF_TYPE_TOKENRING   9
   *  MIB_IF_TYPE_FDDI   15
   *  MIB_IF_TYPE_PPP   23
   *  MIB_IF_TYPE_LOOPBACK   24
   *  MIB_IF_TYPE_SLIP   28
   */
  UINT DhcpEnabled;//Specify whether this adapter is enabled for DHCP
  PIP_ADDR_STRING CurrentIpAddress;//Reserved value
  IP_ADDR_STRING IpAddressList;//The IPv of this adapter4Address list
  IP_ADDR_STRING GatewayList;//The gateway IPv of this adapter4Address list
  IP_ADDR_STRING DhcpServer;//The IPv of the DHCP server for this adapter4 Address list
  BOOL HaveWins;
  IP_ADDR_STRING PrimaryWinsServer;
  IP_ADDR_STRING SecondaryWinsServer;
  time_t LeaseObtained;
  time_t LeaseExpires;
  } IP_ADAPTER_INFO,*PIP_ADAPTER_INFO;

Since there may be multiple network cards, struct _IP_ADAPTER_INFO* The Next field is a pointer to a linked list structure. Since a network card may have multiple IPs, the IP_ADDR_STRING field should also be a linked list structure, and the information is as follows:

typedef struct _IP_ADDR_STRING
{
  struct _IP_ADDR_STRING* Next; //Points to the same type of node, that is, the next IP (if there are multiple IPs)
  IP_ADDRESS_STRING IpAddress; //IP address information
  IP_MASK_STRING IpMask; //IP subnet mask
  DWORD Context;// The entry of the network table. This value corresponds to the NTEContext parameter in the AddIPAddress and DeleteIPAddress functions
} IP_ADDR_STRING;

In summary, the following diagram may be more clear to describe the structure of the network card storage information:

After a basic understanding of the above information, you can call the GetAdaptersInfo function to obtain the information of the relevant network card, and the general code is as follows:

#include <WinSock2.h>
#include <Iphlpapi.h>
#include <iostream>
using namespace std;
#pragma comment(lib,"Iphlpapi.lib") //It is necessary to add the Iphlpapi.lib library
int main(int argc, char* argv[])
{
  //The pointer of PIP_ADAPTER_INFO structure stores the information of the local network card
  PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();
  //Obtain the size of the structure, used as the parameter for GetAdaptersInfo
  unsigned long stSize = sizeof(IP_ADAPTER_INFO);
  //Call the GetAdaptersInfo function to fill the pIpAdapterInfo pointer variable; where stSize is both an input and an output parameter
  int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
  //Record the number of network cards
  int netCardNum = 0;
  //Record the number of IP addresses on each network card
  int IPnumPerNetCard = 0;
  if (ERROR_BUFFER_OVERFLOW == nRel)
  {
    //If the function returns ERROR_BUFFER_OVERFLOW
    //This indicates that the memory space passed to GetAdaptersInfo is insufficient, and its output stSize indicates the required space size
    //This is why stSize is both an input and an output parameter
    //Release the original memory space
    delete pIpAdapterInfo;
    //Reallocate memory space to store all network card information
    pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize];
    //Call the GetAdaptersInfo function again to fill the pIpAdapterInfo pointer variable
    nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);  
  }
  if (ERROR_SUCCESS == nRel)
  {
    //Output network card information
     //There may be multiple network cards, so we use a loop to determine
  while (pIpAdapterInfo)
  {
    cout << "Number of network cards: " <<++netCardNum<<endl;
    cout << "Network card name: " << pIpAdapterInfo->AdapterName<<endl;
    cout << "Network card description: " << pIpAdapterInfo->Description<<endl;
    switch(pIpAdapterInfo->Type)
    {
    case MIB_IF_TYPE_OTHER:
      cout << "Network card type: " << "OTHER" << endl;
      break;
    case MIB_IF_TYPE_ETHERNET:
      cout << "Network card type: " << "ETHERNET" << endl;
      break;
    case MIB_IF_TYPE_TOKENRING:
      cout << "Network card type: " << "TOKENRING" << endl;
      break;
    case MIB_IF_TYPE_FDDI:
      cout<<"Network card type: "<<"FDDI"<<endl;
      break;
    case MIB_IF_TYPE_PPP:
      printf("PP\n");
      cout<<"Network card type: "<<"PPP"<<endl;
      break;
    case MIB_IF_TYPE_LOOPBACK:
      cout<<"Network card type: "<<"LOOPBACK"<<endl;
      break;
    case MIB_IF_TYPE_SLIP:
      cout<<"Network card type: "<<"SLIP"<<endl;
      break;
    default:
      break;
    }
    cout<<"Network card MAC address: ";
    for (DWORD i = 0; i < pIpAdapterInfo->AddressLength; i++)
      if (i < pIpAdapterInfo->AddressLength-1)
      {
        printf("%02X-", pIpAdapterInfo->Address[i]);
      }
      else
      {
        printf("%02X\n", pIpAdapterInfo->Address[i]);
      }
      cout<<"The following are the network card IP addresses:"<<endl;
      //Since there may be multiple IPs on a network card, iterate through to judge
      IP_ADDR_STRING *pIpAddrString = &(pIpAdapterInfo->IpAddressList);
      do 
      {
        cout<<"The number of IPs on this network card: "<<++IPnumPerNetCard<<endl;
        cout<<"IP address: "<<pIpAddrString->IpAddress.String<<endl;
        cout<<"Subnet address: "<<pIpAddrString->IpMask.String<<endl;
        cout<<"Gateway address: "<<pIpAdapterInfo->GatewayList.IpAddress.String<<endl;
        pIpAddrString=pIpAddrString->Next;
      } while (pIpAddrString);
      pIpAdapterInfo = pIpAdapterInfo->Next;
      cout<<"--------------------------------------------------------------------"<<endl;
  }
  }
  //Release memory space
  if (pIpAdapterInfo)
  {
    delete pIpAdapterInfo;
  }
  return 0;
}

Execution result:

The second method to obtain the IP address is:

#include <winsock.h>
#include <stdio.h>
#pragma comment(lib,"ws")2_32.lib") //Used to link to ws2_32.lib this library
void CheckIP(void)//CheckIP function, used to get the local machine IP address
{
 WORD wVersionRequested;//WORD type variable, used to store the value of the Winsock version
 WSADATA wsaData;
 char name[255];//Used to store the hostname
 PHOSTENT hostinfo;
 wVersionRequested=MAKEWORD(2,0);
 //Call the MAKEWORD() function to obtain the Winsock version, which is used to load the Winsock library
 if(WSAStartup(wVersionRequested,&wsaData) == 0)
 {
 //Load the Winsock library, if the return value of the WSAStartup() function is 0, it means that the loading is successful
 if(gethostname(name,sizeof(name))==0)
 {
  if((hostinfo = gethostbyname(name) )!= NULL)
  {
  //If the hostname is obtained successfully, call the inet_ntoa() function to obtain the IP address
  LPCSTR ip = inet_ntoa(*(struct in_addr *)*hostinfo->h_addr_list);
  printf("The IP address of the local machine is:%s\n",ip);//Output IP address
  printf("The name of the local machine is:%s\n",name);
  }
 }
 WSACleanup();
 }
}
int main()
{
 CheckIP();//Call the CheckIP() function to obtain and output the IP address
 return 0;
}

That's all the C++The implementation method for obtaining all network card IP and MAC addresses on the local machine is all included, and I hope everyone will support and cheer for the tutorial~

You May Also Like