Función GetAdaptersAddresses (iphlpapi.h)
La función GetAdaptersAddresses recupera las direcciones asociadas a los adaptadores del equipo local.
Sintaxis
IPHLPAPI_DLL_LINKAGE ULONG GetAdaptersAddresses(
[in] ULONG Family,
[in] ULONG Flags,
[in] PVOID Reserved,
[in, out] PIP_ADAPTER_ADDRESSES AdapterAddresses,
[in, out] PULONG SizePointer
);
Parámetros
[in] Family
Familia de direcciones de las direcciones que se van a recuperar. Este parámetro puede ser uno de los siguientes valores.
[in] Flags
Tipo de direcciones que se van a recuperar. Los valores posibles se definen en el archivo de encabezado Iptypes.h . Tenga en cuenta que el archivo de encabezado Iptypes.h se incluye automáticamente en Iphlpapi.h y nunca se debe usar directamente.
Este parámetro es una combinación de los valores siguientes. Si este parámetro es cero, se devolverán las direcciones IP de unidifusión, anycast y multidifusión.
[in] Reserved
Este parámetro no se usa actualmente, pero está reservado para uso futuro del sistema. La aplicación que llama debe pasar NULL para este parámetro.
[in, out] AdapterAddresses
Puntero a un búfer que contiene una lista vinculada de estructuras de IP_ADAPTER_ADDRESSES en la devolución correcta.
[in, out] SizePointer
Puntero a una variable que especifica el tamaño del búfer al que apunta AdapterAddresses.
Valor devuelto
Si la función se ejecuta correctamente, el valor devuelto se ERROR_SUCCESS (definido en el mismo valor que NO_ERROR).
Si se produce un error en la función, el valor devuelto es uno de los siguientes códigos de error.
Código devuelto | Descripción |
---|---|
|
Todavía no se ha asociado una dirección al punto de conexión de red. La información de concesión dhcp estaba disponible. |
|
El tamaño del búfer indicado por el parámetro SizePointer es demasiado pequeño para contener la información del adaptador o el parámetro AdapterAddresses es NULL. El parámetro SizePointer devuelto apunta al tamaño necesario del búfer para contener la información del adaptador. |
|
Uno de los parámetros no es válido. Este error se devuelve para cualquiera de las condiciones siguientes: el parámetro SizePointer es NULL, el parámetro Address no es AF_INET, AF_INET6 o AF_UNSPEC, o la información de dirección de los parámetros solicitados es mayor que ULONG_MAX. |
|
Los recursos de memoria insuficientes están disponibles para completar la operación. |
|
No se encontraron direcciones para los parámetros solicitados. |
|
Use FormatMessage para obtener la cadena de mensaje para el error devuelto. |
Comentarios
The
La función GetAdaptersAddresses puede recuperar información de direcciones IPv4 e IPv6.
Las direcciones se devuelven como una lista vinculada de estructuras de IP_ADAPTER_ADDRESSES en el búfer a las que apunta el parámetro AdapterAddresses . La aplicación que llama a la función GetAdaptersAddresses debe asignar la cantidad de memoria necesaria para devolver las estructuras de IP_ADAPTER_ADDRESSES a las que apunta el parámetro AdapterAddresses . Cuando estas estructuras devueltas ya no son necesarias, la aplicación debe liberar la memoria asignada. Esto se puede lograr llamando a la función HeapAlloc para asignar memoria y, posteriormente, llamar a la función HeapFree para liberar la memoria asignada, como se muestra en el código de ejemplo. Se pueden usar otras funciones libres y de asignación de memoria siempre que se use la misma familia de funciones para la asignación y la función libre.
GetAdaptersAddresses solo se implementa como una llamada de función sincrónica. La función GetAdaptersAddresses requiere una cantidad significativa de recursos de red y tiempo para completarse, ya que todas las tablas de interfaz de red de bajo nivel deben atravesarse.
Un método que se puede usar para determinar la memoria necesaria para devolver las estructuras de IP_ADAPTER_ADDRESSES a las que apunta el parámetro AdapterAddresses es pasar un tamaño de búfer demasiado pequeño, como se indica en el parámetro SizePointer en la primera llamada a la función GetAdaptersAddresses , por lo que la función producirá un error con ERROR_BUFFER_OVERFLOW. Cuando el valor devuelto es ERROR_BUFFER_OVERFLOW, el parámetro SizePointer devuelve puntos al tamaño necesario del búfer para contener la información del adaptador. Tenga en cuenta que es posible que el tamaño del búfer necesario para las estructuras de IP_ADAPTER_ADDRESSES a las que apunta el parámetro AdapterAddresses cambie entre las llamadas posteriores a la función GetAdaptersAddresses si se agrega o quita una dirección del adaptador. Sin embargo, no se recomienda encarecidamente usar este método para usar la función GetAdaptersAddresses . Este método requiere llamar a la función GetAdaptersAddresses varias veces.
El método recomendado para llamar a la función GetAdaptersAddresses es asignar previamente un búfer de trabajo de 15 KB al que apunta el parámetro AdapterAddresses . En equipos típicos, esto reduce considerablemente las posibilidades de que la función GetAdaptersAddresses devuelva ERROR_BUFFER_OVERFLOW, lo que requeriría llamar a la función GetAdaptersAddresses varias veces. El código de ejemplo muestra este método de uso.
En versiones anteriores a Windows 10, el orden en que aparecen los adaptadores en la lista devuelta por esta función se puede controlar desde la carpeta Conexiones de red: seleccione el elemento de menú Configuración avanzada en el menú Opciones avanzadas. A partir de Windows 10, el orden en que aparecen los adaptadores en la lista viene determinado por la métrica de ruta IPv4 o IPv6.
Si se establece el GAA_FLAG_INCLUDE_ALL_INTERFACES, todos los adaptadores NDIS se recuperarán incluso las direcciones asociadas a adaptadores no enlazados a una familia de direcciones especificada en el parámetro Family . Cuando no se establece esta marca, solo se devuelven las direcciones enlazadas a un adaptador habilitado para la familia de direcciones especificada en el parámetro Family .
El tamaño de la estructura de IP_ADAPTER_ADDRESSES se cambió en Windows XP con Service Pack 1 (SP1) y versiones posteriores. Se agregaron varios miembros adicionales a esta estructura. El tamaño de la estructura de IP_ADAPTER_ADDRESSES también se cambió en Windows Vista y versiones posteriores. Se agregaron varios miembros adicionales a esta estructura. El tamaño de la estructura de IP_ADAPTER_ADDRESSES también cambió en Windows Vista con Service Pack 1 (SP1) y versiones posteriores y enWindows Server 2008 y versiones posteriores. Se agregó un miembro adicional a esta estructura. El miembro Length de la estructura de IP_ADAPTER_ADDRESSES devuelto en la lista vinculada de estructuras del búfer al que apunta el parámetro AdapterAddresses se debe usar para determinar qué versión de la estructura de IP_ADAPTER_ADDRESSES se está usando.
La función GetIpAddrTable recupera la tabla de asignación de direcciones de interfaz a IPv4 en un equipo local y devuelve esta información en una estructura MIB_IPADDRTABLE .
En el Kit de desarrollo de software de plataforma (SDK) publicado para Windows Server 2003 y versiones anteriores, el valor devuelto para la función GetAdaptersAddresses se definió como DWORD, en lugar de un ULONG.
La estructura SOCKET_ADDRESS se usa en la estructura IP_ADAPTER_ADDRESSES a la que apunta el parámetro AdapterAddresses . En el Kit de desarrollo de software (SDK) de Microsoft Windows publicado para Windows Vista y versiones posteriores, la organización de los archivos de encabezado ha cambiado y la estructura de SOCKET_ADDRESS se define en el archivo de encabezado Ws2def.h que el archivo de encabezado Winsock2.h incluye automáticamente. En el SDK de plataforma publicado para Windows Server 2003 y Windows XP, la estructura de SOCKET_ADDRESS se declara en el archivo de encabezado Winsock2.h . Para usar la estructura IP_ADAPTER_ADDRESSES , el archivo de encabezado Winsock2.h debe incluirse antes del archivo de encabezado Iphlpapi.h .
Ejemplos
En este ejemplo se recupera la estructura de IP_ADAPTER_ADDRESSES para los adaptadores asociados al sistema e imprime algunos miembros para cada interfaz de adaptador.
#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;
}
Requisitos
Cliente mínimo compatible | Windows XP [aplicaciones de escritorio | aplicaciones para UWP] |
Servidor mínimo compatible | Windows Server 2003 [aplicaciones de escritorio | aplicaciones para UWP] |
Plataforma de destino | Windows |
Encabezado | iphlpapi.h |
Library | Iphlpapi.lib |
Archivo DLL | Iphlpapi.dll |
Consulte también
Referencia de la función auxiliar de IP