Функция 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
Семейство адресов для извлечения. Этот параметр должен иметь одно из следующих значений.
[in] Flags
Тип извлекаемых адресов. Возможные значения определяются в файле заголовка Iptypes.h . Обратите внимание, что файл заголовка Iptypes.h автоматически включается в iphlpapi.h и никогда не должен использоваться напрямую.
Этот параметр представляет собой сочетание следующих значений. Если этот параметр равен нулю, будут возвращены IP-адреса одноадресной, любой и многоадресной рассылки.
[in] Reserved
Этот параметр в настоящее время не используется, но зарезервирован для использования системой в будущем. Вызывающее приложение должно передать значение NULL для этого параметра.
[in, out] AdapterAddresses
Указатель на буфер, содержащий связанный список IP_ADAPTER_ADDRESSES структур при успешном возвращении.
[in, out] SizePointer
Указатель на переменную, указывающую размер буфера, на который указывает AdapterAddresses.
Возвращаемое значение
Если функция выполняется успешно, возвращается значение ERROR_SUCCESS (определяется как то же значение, что и NO_ERROR).
Если функция завершается сбоем, возвращается один из следующих кодов ошибок.
Код возврата | Описание |
---|---|
|
Адрес еще не связан с конечной точкой сети. Сведения об аренде DHCP были доступны. |
|
Размер буфера, указанный параметром SizePointer , слишком мал для хранения сведений об адаптере, или параметр AdapterAddresses имеет значение NULL. Возвращаемый параметр SizePointer указывает на требуемый размер буфера для хранения сведений об адаптере. |
|
Один из параметров недопустим. Эта ошибка возвращается при любом из следующих условий: параметр SizePointer имеет значение NULL, параметр Address не AF_INET, AF_INET6 или AF_UNSPEC, или сведения об адресе запрошенных параметров больше ULONG_MAX. |
|
Для завершения операции недостаточно ресурсов памяти. |
|
Адреса для запрошенных параметров не найдены. |
|
Используйте 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 |
См. также раздел
Справочник по вспомогательным функциям IP