One network card with multiple IPs, how to get the preferred IP

Table of contents

1. Idea

Use Windows API functions to obtain adapter information, and traverse the adapter list to find non-loopback adapters whose IP addresses are not 0. It then traverses the list of IP addresses for that adapter, finds an IP address that matches the gateway address, and returns it as the local IP address.

The main steps are as follows:

  1. Create a structure instance of adapter information.
  2. Get the size of the adapter information, if the obtained size exceeds the initially allocated buffer size, reallocate a larger buffer.
  3. Get adapter information and traverse the adapter list.
  4. For each non-loopback adapter whose IP address is not 0, obtain its gateway address and convert it to an integer.
  5. Iterates through the list of IP addresses for this adapter, and for each IP address, converts it to integer form and compares it to the gateway address.
  6. If an IP address is found that matches the gateway address, it is returned as the local IP address.

2. API introduction

DWORD GetAdaptersInfo(
  PIP_ADAPTER_INFO pAdapterInfo,
  PULONG           pOutBufLen
);

GetAdaptersInfo is a Windows API function used to get information about all adapters in the system. It is defined in the IPHlpApi.h header file for Windows.
Parameter Description:

  • pAdapterInfo: A pointer to the PIP_ADAPTER_INFO structure, used to store the obtained adapter information.
  • pOutBufLen: A pointer to a variable used to pass the size of the pAdapterInfo buffer. It needs to be set to the size of the pAdapterInfo buffer before calling the function. When the function returns, it will contain the number of bytes actually written to the pAdapterInfo buffer.

The function returns an error code of DWORD type. If the function is executed successfully, the return value is ERROR_SUCCESS.

The GetAdaptersInfo function fills the pAdapterInfo buffer with each adapter's information by traversing the adapter list in the system. By calling this function multiple times, information about all adapters in the system can be obtained.

Note: Here, the IP with the same first three digits of the IP address and the first three digits of the gateway is considered as the preferred IP address

typedef struct _IP_ADAPTER_INFO {
    
    
    struct _IP_ADAPTER_INFO* Next;
    DWORD ComboIndex;
    char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
    char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];
    UINT AddressLength;
    BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];
    DWORD Index;
    UINT Type;
    UINT DhcpEnabled;
    PIP_ADDR_STRING CurrentIpAddress;
    IP_ADDR_STRING IpAddressList;
    IP_ADDR_STRING GatewayList;
    IP_ADDR_STRING DhcpServer;
    BOOL HaveWins;
    IP_ADDR_STRING PrimaryWinsServer;
    IP_ADDR_STRING SecondaryWinsServer;
    time_t LeaseObtained;
    time_t LeaseExpires;
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;

This structure defines the adapter information, including adapter name, description, physical address, IP address, etc. The meaning of specific members is as follows:

  • Next: A pointer to the next adapter information structure, used to traverse the adapter list.
  • ComboIndex: The combo index of the adapter.
  • AdapterName: The name of the adapter.
  • Description: A description of the adapter.
  • AddressLength: The length of the adapter address.
  • Address: The physical address of the adapter.
  • Index: The index of the adapter.
  • Type: The type of adapter.
  • DhcpEnabled: Indicates whether the adapter is DHCP enabled.
  • CurrentIpAddress: The IP address of the current adapter.
  • IpAddressList: List of IP addresses for the adapter.
  • GatewayList: A list of gateway addresses for the adapter.
  • DhcpServer: IP address of the DHCP server.
  • HaveWins: Indicates whether the adapter has a WINS server.
  • PrimaryWinsServer: The IP address of the primary WINS server.
  • SecondaryWinsServer: The IP address of the secondary WINS server.
  • LeaseObtained: Lease acquisition time.
  • LeaseExpires: Lease expiration time.

By traversing the adapter list, the information of all adapters in the system can be obtained, so as to realize the management and configuration of network connections.

2. Code

#include <string>
#include <iphlpapi.h>
#include <iostream>
#include <windows.h>
#include <mmsystem.h>

#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "ws2_32.lib")

using namespace std;

int AIUtils::GetLocalIp(std::string &ip) 
{
    
    
     PIP_ADAPTER_INFO adapterInfo;
     ULONG bufferSize = sizeof(IP_ADAPTER_INFO);
     adapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(new char[bufferSize]);

     if (GetAdaptersInfo(adapterInfo, &bufferSize) == ERROR_BUFFER_OVERFLOW) {
    
    
         delete[] reinterpret_cast<char*>(adapterInfo);
         adapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(new char[bufferSize]);
     }

     if (GetAdaptersInfo(adapterInfo, &bufferSize) == NO_ERROR) {
    
    
         IP_ADAPTER_INFO* adapter = adapterInfo;
         while (adapter) {
    
    
             if (adapter->Type != MIB_IF_TYPE_LOOPBACK && adapter->IpAddressList.IpAddress.String[0] != '0') {
    
    
                 std::string gateway_addr = adapter->GatewayList.IpAddress.String;
                 int a, b, c, d;
                 sscanf(gateway_addr.c_str(), "%d.%d.%d.%d", &a, &b, &c, &d);
                 IP_ADDR_STRING *addr = &adapter->IpAddressList;
                 while(addr) {
    
    
                     std::cout << "Primary IP address: " << addr->IpAddress.String << std::endl;
                     int a1, b1, c1, d1;
                     std::string ip_addr(addr->IpAddress.String);
                     sscanf(ip_addr.c_str(), "%d.%d.%d.%d", &a1, &b1, &c1, &d1);
                     if (a == a1 && b == b1 && c == c1) {
    
    
                         ip = ip_addr;
                         break;
                     }
                     addr = addr->Next;
                 }
                 break;
             }
             adapter = adapter->Next;
         }
     }

     if (adapterInfo) {
    
    
         delete[] reinterpret_cast<char*>(adapterInfo);
     }

     return 0;
}

Guess you like

Origin blog.csdn.net/wyw0000/article/details/131673156