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