Функция GetAdaptersAddresses (iphlpapi.h)

Функция GetAdaptersAddresses извлекает адреса, связанные с адаптерами на локальном компьютере.

Синтаксис

IPHLPAPI_DLL_LINKAGE ULONG GetAdaptersAddresses(
  [in]      ULONG                 Family,
  [in]      ULONG                 Flags,
  [in]      PVOID                 Reserved,
  [in, out] PIP_ADAPTER_ADDRESSES AdapterAddresses,
  [in, out] PULONG                SizePointer
);

Параметры

[in] Family

Семейство адресов для извлечения. Этот параметр должен иметь одно из следующих значений.

Значение Значение
AF_UNSPEC
0
Возвращает адреса IPv4 и IPv6, связанные с адаптерами с включенным протоколом IPv4 или IPv6.
AF_INET
2
Возвращает только IPv4-адреса, связанные с адаптерами с включенным протоколом IPv4.
AF_INET6
23
Возвращает только IPv6-адреса, связанные с адаптерами с включенным протоколом IPv6.

[in] Flags

Тип извлекаемых адресов. Возможные значения определяются в файле заголовка Iptypes.h . Обратите внимание, что файл заголовка Iptypes.h автоматически включается в iphlpapi.h и никогда не должен использоваться напрямую.

Этот параметр представляет собой сочетание следующих значений. Если этот параметр равен нулю, будут возвращены IP-адреса одноадресной, любой и многоадресной рассылки.

Значение Значение
GAA_FLAG_SKIP_UNICAST
0x0001
Не возвращайте одноадресные адреса.
GAA_FLAG_SKIP_ANYCAST
0x0002
Не возвращайте адреса IPv6 anycast.
GAA_FLAG_SKIP_MULTICAST
0x0004
Не возвращайте адреса многоадресной рассылки.
GAA_FLAG_SKIP_DNS_SERVER
0x0008
Не возвращайте адреса DNS-серверов.
GAA_FLAG_INCLUDE_PREFIX
0x0010
Возвращает список префиксов IP-адресов для этого адаптера. Если этот флаг установлен, для адресов IPv6 и IPv4 возвращаются префиксы IP-адресов.

Этот флаг поддерживается в Windows XP с пакетом обновления 1 (SP1) и более поздних версий.

GAA_FLAG_SKIP_FRIENDLY_NAME
0x0020
Не возвращайте понятное имя адаптера.
GAA_FLAG_INCLUDE_WINS_INFO
0x0040
Возвращают адреса серверов WINS.

Этот флаг поддерживается в Windows Vista и более поздних версиях.

GAA_FLAG_INCLUDE_GATEWAYS
0x0080
Возвращает адреса шлюзов по умолчанию.

Этот флаг поддерживается в Windows Vista и более поздних версиях.

GAA_FLAG_INCLUDE_ALL_INTERFACES
0x0100
Возвращаемые адреса для всех интерфейсов NDIS.

Этот флаг поддерживается в Windows Vista и более поздних версиях.

GAA_FLAG_INCLUDE_ALL_COMPARTMENTS
0x0200
Обратные адреса во всех секциях маршрутизации.

Этот флаг в настоящее время не поддерживается и зарезервирован для использования в будущем.

GAA_FLAG_INCLUDE_TUNNEL_BINDINGORDER
0x0400
Возвращает адреса адаптеров, отсортированные по порядку привязки туннеля. Этот флаг поддерживается в Windows Vista и более поздних версиях.

[in] Reserved

Этот параметр в настоящее время не используется, но зарезервирован для использования системой в будущем. Вызывающее приложение должно передать значение NULL для этого параметра.

[in, out] AdapterAddresses

Указатель на буфер, содержащий связанный список IP_ADAPTER_ADDRESSES структур при успешном возвращении.

[in, out] SizePointer

Указатель на переменную, указывающую размер буфера, на который указывает AdapterAddresses.

Возвращаемое значение

Если функция выполняется успешно, возвращается значение ERROR_SUCCESS (определяется как то же значение, что и NO_ERROR).

Если функция завершается сбоем, возвращается один из следующих кодов ошибок.

Код возврата Описание
ERROR_ADDRESS_NOT_ASSOCIATED
Адрес еще не связан с конечной точкой сети. Сведения об аренде DHCP были доступны.
ERROR_BUFFER_OVERFLOW
Размер буфера, указанный параметром SizePointer , слишком мал для хранения сведений об адаптере, или параметр AdapterAddresses имеет значение NULL. Возвращаемый параметр SizePointer указывает на требуемый размер буфера для хранения сведений об адаптере.
ERROR_INVALID_PARAMETER
Один из параметров недопустим. Эта ошибка возвращается при любом из следующих условий: параметр SizePointer имеет значение NULL, параметр Address не AF_INET, AF_INET6 или AF_UNSPEC, или сведения об адресе запрошенных параметров больше ULONG_MAX.
ERROR_NOT_ENOUGH_MEMORY
Для завершения операции недостаточно ресурсов памяти.
ERROR_NO_DATA
Адреса для запрошенных параметров не найдены.
Другое
Используйте FormatMessage , чтобы получить строку сообщения для возвращаемой ошибки.

Комментарии

The
Функция GetAdaptersAddresses может извлекать сведения для адресов IPv4 и IPv6.

Адреса возвращаются в виде связанного списка IP_ADAPTER_ADDRESSES структур в буфере, на который указывает параметр AdapterAddresses . Приложение, которое вызывает функцию GetAdaptersAddresses , должно выделить объем памяти, необходимый для возврата IP_ADAPTER_ADDRESSES структур, на которые указывает параметр AdapterAddresses . Если эти возвращаемые структуры больше не требуются, приложение должно освободить выделенную память. Это можно сделать, вызвав функцию HeapAlloc для выделения памяти, а затем вызвав функцию HeapFree для освобождения выделенной памяти, как показано в примере кода. Другие функции выделения памяти и свободные функции можно использовать при условии, что одно и то же семейство функций используется как для функции выделения, так и для функции free.

GetAdaptersAddresses реализуется только как синхронный вызов функции. Для выполнения функции GetAdaptersAddresses требуется значительное количество сетевых ресурсов и времени, так как необходимо пройти все низкоуровневые таблицы сетевого интерфейса.

Один из методов, который можно использовать для определения памяти, необходимой для возврата IP_ADAPTER_ADDRESSES структур, на которые указывает параметр AdapterAddresses , — передать слишком маленький размер буфера, как указано в параметре SizePointer в первом вызове функции GetAdaptersAddresses , поэтому функция завершится сбоем с ERROR_BUFFER_OVERFLOW. Если возвращаемое значение ERROR_BUFFER_OVERFLOW, возвращаемый параметр SizePointer указывает на требуемый размер буфера для хранения сведений об адаптере. Обратите внимание, что размер буфера, необходимый для IP_ADAPTER_ADDRESSES структур, на которые указывает параметр AdapterAddresses , можно изменить между последующими вызовами функции GetAdaptersAddresses при добавлении или удалении адреса адаптера. Однако этот метод использования функции GetAdaptersAddresses настоятельно не рекомендуется. Для этого метода требуется несколько раз вызвать функцию GetAdaptersAddresses .

Рекомендуемый метод вызова функции GetAdaptersAddresses — предварительно выделить рабочий буфер размером 15 КБ, на который указывает параметр AdapterAddresses . На типичных компьютерах это значительно снижает вероятность того, что функция GetAdaptersAddresses возвращает ERROR_BUFFER_OVERFLOW, что потребует многократного вызова функции GetAdaptersAddresses . Пример кода иллюстрирует этот метод использования.

В версиях, предшествующих Windows 10, порядок отображения адаптеров в списке, возвращаемом этой функцией, можно управлять из папки Сетевые подключения: выберите пункт меню Дополнительные параметры в меню Дополнительно. Начиная с Windows 10, порядок отображения адаптеров в списке определяется метрикой маршрута IPv4 или IPv6.

Если задано GAA_FLAG_INCLUDE_ALL_INTERFACES, будут получены все адаптеры NDIS, даже те адреса, которые связаны с адаптерами, не привязанными к семейству адресов, указанному в параметре Family . Если этот флаг не задан, возвращаются только адреса, привязанные к адаптеру, включенного для семейства адресов, указанного в параметре Family .

Размер структуры IP_ADAPTER_ADDRESSES был изменен в Windows XP с пакетом обновления 1 (SP1) и более поздних версий. В эту структуру было добавлено несколько дополнительных элементов. Размер структуры IP_ADAPTER_ADDRESSES также был изменен в Windows Vista и более поздних версиях. В эту структуру было добавлено несколько дополнительных элементов. Размер структуры IP_ADAPTER_ADDRESSES также изменился в Windows Vista с пакетом обновления 1 (SP1) и более поздних версий, а также в Windows Vista 2008 и более поздних версиях. В эту структуру был добавлен еще один элемент. Элемент Lengthструктуры IP_ADAPTER_ADDRESSES , возвращаемый в связанном списке структур в буфере, на который указывает параметр AdapterAddresses , следует использовать для определения используемой версии структуры IP_ADAPTER_ADDRESSES .

Функция GetIpAddrTable извлекает таблицу сопоставления адресов interface-to-IPv4 на локальном компьютере и возвращает эти сведения в MIB_IPADDRTABLE структуре.

В пакете SDK платформы, выпущенном для Windows Server 2003 и более ранних версий, возвращаемое значение функции GetAdaptersAddresses было определено как DWORD, а не ULONG.

Структура SOCKET_ADDRESS используется в структуре IP_ADAPTER_ADDRESSES , на которую указывает параметр AdapterAddresses . В пакете SDK microsoft Windows, выпущенном для Windows Vista и более поздних версий, организация файлов заголовков изменилась, а структура SOCKET_ADDRESS определена в файле заголовка Ws2def.h , который автоматически включается в файл заголовка Winsock2.h . В пакете SDK для платформы, выпущенном для Windows Server 2003 и Windows XP, структура SOCKET_ADDRESS объявляется в файле заголовка Winsock2.h . Чтобы использовать структуру IP_ADAPTER_ADDRESSES , файл заголовка Winsock2.h должен быть включен перед файлом заголовка Iphlpapi.h .

Примеры

В этом примере извлекается структура IP_ADAPTER_ADDRESSES для адаптеров, связанных с системой, и выводится несколько элементов для каждого интерфейса адаптера.

#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>

// Link with Iphlpapi.lib
#pragma comment(lib, "IPHLPAPI.lib")

#define WORKING_BUFFER_SIZE 15000
#define MAX_TRIES 3

#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))

/* Note: could also use malloc() and free() */

int __cdecl main(int argc, char **argv)
{

    /* Declare and initialize variables */

    DWORD dwRetVal = 0;

    unsigned int i = 0;

    // Set the flags to pass to GetAdaptersAddresses
    ULONG flags = GAA_FLAG_INCLUDE_PREFIX;

    // default to unspecified address family (both)
    ULONG family = AF_UNSPEC;

    LPVOID lpMsgBuf = NULL;

    PIP_ADAPTER_ADDRESSES pAddresses = NULL;
    ULONG outBufLen = 0;
    ULONG Iterations = 0;

    PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
    PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
    PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL;
    PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = NULL;
    IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL;
    IP_ADAPTER_PREFIX *pPrefix = NULL;

    if (argc != 2) {
        printf(" Usage: getadapteraddresses family\n");
        printf("        getadapteraddresses 4 (for IPv4)\n");
        printf("        getadapteraddresses 6 (for IPv6)\n");
        printf("        getadapteraddresses A (for both IPv4 and IPv6)\n");
        exit(1);
    }

    if (atoi(argv[1]) == 4)
        family = AF_INET;
    else if (atoi(argv[1]) == 6)
        family = AF_INET6;

    printf("Calling GetAdaptersAddresses function with family = ");
    if (family == AF_INET)
        printf("AF_INET\n");
    if (family == AF_INET6)
        printf("AF_INET6\n");
    if (family == AF_UNSPEC)
        printf("AF_UNSPEC\n\n");

    // Allocate a 15 KB buffer to start with.
    outBufLen = WORKING_BUFFER_SIZE;

    do {

        pAddresses = (IP_ADAPTER_ADDRESSES *) MALLOC(outBufLen);
        if (pAddresses == NULL) {
            printf
                ("Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n");
            exit(1);
        }

        dwRetVal =
            GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen);

        if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
            FREE(pAddresses);
            pAddresses = NULL;
        } else {
            break;
        }

        Iterations++;

    } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES));

    if (dwRetVal == NO_ERROR) {
        // If successful, output some information from the data we received
        pCurrAddresses = pAddresses;
        while (pCurrAddresses) {
            printf("\tLength of the IP_ADAPTER_ADDRESS struct: %ld\n",
                   pCurrAddresses->Length);
            printf("\tIfIndex (IPv4 interface): %u\n", pCurrAddresses->IfIndex);
            printf("\tAdapter name: %s\n", pCurrAddresses->AdapterName);

            pUnicast = pCurrAddresses->FirstUnicastAddress;
            if (pUnicast != NULL) {
                for (i = 0; pUnicast != NULL; i++)
                    pUnicast = pUnicast->Next;
                printf("\tNumber of Unicast Addresses: %d\n", i);
            } else
                printf("\tNo Unicast Addresses\n");

            pAnycast = pCurrAddresses->FirstAnycastAddress;
            if (pAnycast) {
                for (i = 0; pAnycast != NULL; i++)
                    pAnycast = pAnycast->Next;
                printf("\tNumber of Anycast Addresses: %d\n", i);
            } else
                printf("\tNo Anycast Addresses\n");

            pMulticast = pCurrAddresses->FirstMulticastAddress;
            if (pMulticast) {
                for (i = 0; pMulticast != NULL; i++)
                    pMulticast = pMulticast->Next;
                printf("\tNumber of Multicast Addresses: %d\n", i);
            } else
                printf("\tNo Multicast Addresses\n");

            pDnServer = pCurrAddresses->FirstDnsServerAddress;
            if (pDnServer) {
                for (i = 0; pDnServer != NULL; i++)
                    pDnServer = pDnServer->Next;
                printf("\tNumber of DNS Server Addresses: %d\n", i);
            } else
                printf("\tNo DNS Server Addresses\n");

            printf("\tDNS Suffix: %wS\n", pCurrAddresses->DnsSuffix);
            printf("\tDescription: %wS\n", pCurrAddresses->Description);
            printf("\tFriendly name: %wS\n", pCurrAddresses->FriendlyName);

            if (pCurrAddresses->PhysicalAddressLength != 0) {
                printf("\tPhysical address: ");
                for (i = 0; i < (int) pCurrAddresses->PhysicalAddressLength;
                     i++) {
                    if (i == (pCurrAddresses->PhysicalAddressLength - 1))
                        printf("%.2X\n",
                               (int) pCurrAddresses->PhysicalAddress[i]);
                    else
                        printf("%.2X-",
                               (int) pCurrAddresses->PhysicalAddress[i]);
                }
            }
            printf("\tFlags: %ld\n", pCurrAddresses->Flags);
            printf("\tMtu: %lu\n", pCurrAddresses->Mtu);
            printf("\tIfType: %ld\n", pCurrAddresses->IfType);
            printf("\tOperStatus: %ld\n", pCurrAddresses->OperStatus);
            printf("\tIpv6IfIndex (IPv6 interface): %u\n",
                   pCurrAddresses->Ipv6IfIndex);
            printf("\tZoneIndices (hex): ");
            for (i = 0; i < 16; i++)
                printf("%lx ", pCurrAddresses->ZoneIndices[i]);
            printf("\n");

            printf("\tTransmit link speed: %I64u\n", pCurrAddresses->TransmitLinkSpeed);
            printf("\tReceive link speed: %I64u\n", pCurrAddresses->ReceiveLinkSpeed);

            pPrefix = pCurrAddresses->FirstPrefix;
            if (pPrefix) {
                for (i = 0; pPrefix != NULL; i++)
                    pPrefix = pPrefix->Next;
                printf("\tNumber of IP Adapter Prefix entries: %d\n", i);
            } else
                printf("\tNumber of IP Adapter Prefix entries: 0\n");

            printf("\n");

            pCurrAddresses = pCurrAddresses->Next;
        }
    } else {
        printf("Call to GetAdaptersAddresses failed with error: %d\n",
               dwRetVal);
        if (dwRetVal == ERROR_NO_DATA)
            printf("\tNo addresses were found for the requested parameters\n");
        else {

            if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                    FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 
                    NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),   
                    // Default language
                    (LPTSTR) & lpMsgBuf, 0, NULL)) {
                printf("\tError: %s", lpMsgBuf);
                LocalFree(lpMsgBuf);
                if (pAddresses)
                    FREE(pAddresses);
                exit(1);
            }
        }
    }

    if (pAddresses) {
        FREE(pAddresses);
    }

    return 0;
}

Требования

   
Минимальная версия клиента Windows XP [классические приложения | Приложения UWP]
Минимальная версия сервера Windows Server 2003 [классические приложения | Приложения UWP]
Целевая платформа Windows
Header iphlpapi.h
Библиотека Iphlpapi.lib
DLL Iphlpapi.dll

См. также раздел

GetIpAddrTable

HeapAlloc

HeapFree

Справочник по вспомогательным функциям IP

Начальная страница вспомогательного ip-адреса

IP_ADAPTER_ADDRESSES

MIB_IPADDRTABLE

SOCKET_ADDRESS

Сокеты Windows