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.

Value Significado
AF_UNSPEC
0
Devuelve las direcciones IPv4 e IPv6 asociadas a adaptadores con IPv4 o IPv6 habilitados.
AF_INET
2
Devuelve solo direcciones IPv4 asociadas a adaptadores con IPv4 habilitado.
AF_INET6
23
Devuelve solo las direcciones IPv6 asociadas a adaptadores con IPv6 habilitado.

[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.

Valor Significado
GAA_FLAG_SKIP_UNICAST
0x0001
No devuelva direcciones de unidifusión.
GAA_FLAG_SKIP_ANYCAST
0x0002
No devuelva direcciones de difusión IPv6.
GAA_FLAG_SKIP_MULTICAST
0x0004
No devuelva direcciones de multidifusión.
GAA_FLAG_SKIP_DNS_SERVER
0x0008
No devuelva direcciones de servidores DNS.
GAA_FLAG_INCLUDE_PREFIX
0x0010
Devuelve una lista de prefijos de dirección IP en este adaptador. Cuando se establece esta marca, se devuelven prefijos de dirección IP para las direcciones IPv6 e IPv4.

Esta marca se admite en Windows XP con SP1 y versiones posteriores.

GAA_FLAG_SKIP_FRIENDLY_NAME
0x0020
No devuelva el nombre descriptivo del adaptador.
GAA_FLAG_INCLUDE_WINS_INFO
0x0040
Devuelve direcciones de los servidores del Servicio de nombres de Internet (WINS) de Windows.

Esta marca se admite en Windows Vista y versiones posteriores.

GAA_FLAG_INCLUDE_GATEWAYS
0x0080
Devuelve las direcciones de las puertas de enlace predeterminadas.

Esta marca se admite en Windows Vista y versiones posteriores.

GAA_FLAG_INCLUDE_ALL_INTERFACES
0x0100
Devuelve direcciones para todas las interfaces NDIS.

Esta marca se admite en Windows Vista y versiones posteriores.

GAA_FLAG_INCLUDE_ALL_COMPARTMENTS
0x0200
Devuelve direcciones en todos los compartimientos de enrutamiento.

Esta marca no se admite actualmente y está reservada para su uso futuro.

GAA_FLAG_INCLUDE_TUNNEL_BINDINGORDER
0x0400
Devuelve las direcciones del adaptador ordenadas en orden de enlace de túnel. Esta marca se admite en Windows Vista y versiones posteriores.

[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
ERROR_ADDRESS_NOT_ASSOCIATED
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.
ERROR_BUFFER_OVERFLOW
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.
ERROR_INVALID_PARAMETER
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.
ERROR_NOT_ENOUGH_MEMORY
Los recursos de memoria insuficientes están disponibles para completar la operación.
ERROR_NO_DATA
No se encontraron direcciones para los parámetros solicitados.
Otros
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

GetIpAddrTable

HeapAlloc

HeapFree

Referencia de la función auxiliar de IP

Página de inicio del asistente de IP

IP_ADAPTER_ADDRESSES

MIB_IPADDRTABLE

SOCKET_ADDRESS

Windows Sockets