Condividi tramite


Funzione GetAdaptersAddresses (iphlpapi.h)

La funzione GetAdaptersAddresses recupera gli indirizzi associati alle schede nel computer locale.

Sintassi

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

Parametri

[in] Family

Famiglia di indirizzi degli indirizzi da recuperare. Questo parametro deve essere uno dei valori seguenti.

Valore Significato
AF_UNSPEC
0
Restituisce sia gli indirizzi IPv4 che IPv6 associati alle schede con IPv4 o IPv6 abilitati.
AF_INET
2
Restituisce solo gli indirizzi IPv4 associati alle schede con IPv4 abilitato.
AF_INET6
23
Restituisce solo gli indirizzi IPv6 associati alle schede con IPv6 abilitato.

[in] Flags

Tipo di indirizzi da recuperare. I valori possibili sono definiti nel file di intestazione Iptypes.h . Si noti che il file di intestazione Iptypes.h viene automaticamente incluso in Iphlpapi.h e non deve mai essere usato direttamente.

Questo parametro è una combinazione dei valori seguenti. Se questo parametro è zero, verranno restituiti gli indirizzi IP unicast, anycast e multicast.

Valore Significato
GAA_FLAG_SKIP_UNICAST
0x0001
Non restituire indirizzi unicast.
GAA_FLAG_SKIP_ANYCAST
0x0002
Non restituire indirizzi IPv6 anycast.
GAA_FLAG_SKIP_MULTICAST
0x0004
Non restituire indirizzi multicast.
GAA_FLAG_SKIP_DNS_SERVER
0x0008
Non restituire gli indirizzi dei server DNS.
GAA_FLAG_INCLUDE_PREFIX
0x0010
Restituisce un elenco di prefissi di indirizzi IP in questa scheda. Quando questo flag è impostato, i prefissi degli indirizzi IP vengono restituiti per gli indirizzi IPv6 e IPv4.

Questo flag è supportato in Windows XP con SP1 e versioni successive.

GAA_FLAG_SKIP_FRIENDLY_NAME
0x0020
Non restituire il nome descrittivo dell'adattatore.
GAA_FLAG_INCLUDE_WINS_INFO
0x0040
Indirizzi restituiti dei server WINS (Internet Name Service) di Windows.

Questo flag è supportato in Windows Vista e versioni successive.

GAA_FLAG_INCLUDE_GATEWAYS
0x0080
Restituisce gli indirizzi dei gateway predefiniti.

Questo flag è supportato in Windows Vista e versioni successive.

GAA_FLAG_INCLUDE_ALL_INTERFACES
0x0100
Indirizzi restituiti per tutte le interfacce NDIS.

Questo flag è supportato in Windows Vista e versioni successive.

GAA_FLAG_INCLUDE_ALL_COMPARTMENTS
0x0200
Indirizzi restituiti in tutti i raggruppamenti di routing.

Questo flag non è attualmente supportato e riservato per l'uso futuro.

GAA_FLAG_INCLUDE_TUNNEL_BINDINGORDER
0x0400
Restituisce gli indirizzi dell'adattatore ordinati in ordine di associazione del tunnel. Questo flag è supportato in Windows Vista e versioni successive.

[in] Reserved

Questo parametro non è attualmente utilizzato, ma è riservato per l'uso futuro del sistema. L'applicazione chiamante deve passare NULL per questo parametro.

[in, out] AdapterAddresses

Puntatore a un buffer contenente un elenco collegato di strutture IP_ADAPTER_ADDRESSES in caso di esito positivo.

[in, out] SizePointer

Puntatore a una variabile che specifica le dimensioni del buffer a cui punta AdapterAddresses.

Valore restituito

Se la funzione ha esito positivo, il valore restituito viene ERROR_SUCCESS (definito allo stesso valore di NO_ERROR).

Se la funzione ha esito negativo, il valore restituito è uno dei codici di errore seguenti.

Codice restituito Descrizione
ERROR_ADDRESS_NOT_ASSOCIATED
Un indirizzo non è ancora stato associato all'endpoint di rete. Le informazioni sul lease DHCP erano disponibili.
ERROR_BUFFER_OVERFLOW
La dimensione del buffer indicata dal parametro SizePointer è troppo piccola per contenere le informazioni sull'adattatore o il parametro AdapterAddresses è NULL. Il parametro SizePointer restituisce i punti alle dimensioni necessarie del buffer per contenere le informazioni sull'adattatore.
ERROR_INVALID_PARAMETER
Uno dei parametri non è valido. Questo errore viene restituito per una delle condizioni seguenti: il parametro SizePointer è NULL, il parametro Address non è AF_INET, AF_INET6 o AF_UNSPEC oppure le informazioni sull'indirizzo per i parametri richiesti sono maggiori di ULONG_MAX.
ERROR_NOT_ENOUGH_MEMORY
Per completare l'operazione sono disponibili risorse di memoria insufficienti.
ERROR_NO_DATA
Non sono stati trovati indirizzi per i parametri richiesti.
Altri
Usare FormatMessage per ottenere la stringa del messaggio per l'errore restituito.

Commenti

The
La funzione GetAdaptersAddresses può recuperare informazioni per gli indirizzi IPv4 e IPv6.

Gli indirizzi vengono restituiti come elenco collegato di strutture IP_ADAPTER_ADDRESSES nel buffer a cui punta il parametro AdapterAddresses . L'applicazione che chiama la funzione GetAdaptersAddresses deve allocare la quantità di memoria necessaria per restituire le strutture IP_ADAPTER_ADDRESSES a cui punta il parametro AdapterAddresses . Quando queste strutture restituite non sono più necessarie, l'applicazione deve liberare la memoria allocata. Questa operazione può essere eseguita chiamando la funzione HeapAlloc per allocare memoria e successivamente chiamando la funzione HeapFree per liberare la memoria allocata, come illustrato nel codice di esempio. È possibile usare altre funzioni di allocazione di memoria e libere purché la stessa famiglia di funzioni venga usata sia per l'allocazione che per la funzione libera.

GetAdaptersAddresses viene implementato solo come chiamata di funzione sincrona. La funzione GetAdaptersAddresses richiede una quantità significativa di risorse di rete e tempo da completare perché tutte le tabelle dell'interfaccia di rete di basso livello devono essere attraversate.

Un metodo che può essere usato per determinare la memoria necessaria per restituire le strutture IP_ADAPTER_ADDRESSES a cui punta il parametro AdapterAddresses consiste nel passare una dimensione del buffer troppo piccola, come indicato nel parametro SizePointer nella prima chiamata alla funzione GetAdaptersAddresses , quindi la funzione avrà esito negativo con ERROR_BUFFER_OVERFLOW. Quando il valore restituito è ERROR_BUFFER_OVERFLOW, il parametro SizePointer restituisce punti alle dimensioni necessarie del buffer per contenere le informazioni sull'adattatore. Si noti che è possibile che le dimensioni del buffer necessarie per le strutture IP_ADAPTER_ADDRESSES a cui punta il parametro AdapterAddresses cambino tra le chiamate successive alla funzione GetAdaptersAddresses se viene aggiunto o rimosso un indirizzo dell'adattatore. Tuttavia, questo metodo di utilizzo della funzione GetAdaptersAddresses è fortemente sconsigliato. Questo metodo richiede la chiamata della funzione GetAdaptersAddresses più volte.

Il metodo consigliato per chiamare la funzione GetAdaptersAddresses consiste nell'allocare un buffer di lavoro di 15 KB a cui punta il parametro AdapterAddresses . Nei computer tipici questo riduce notevolmente le probabilità che la funzione GetAdaptersAddresses restituisca ERROR_BUFFER_OVERFLOW, che richiederebbe la chiamata della funzione GetAdaptersAddresses più volte. Il codice di esempio illustra questo metodo di utilizzo.

Nelle versioni precedenti a Windows 10, l'ordine in cui le schede vengono visualizzate nell'elenco restituito da questa funzione può essere controllato dalla cartella Connessioni di rete: selezionare la voce di menu Impostazioni avanzate dal menu Avanzate. A partire da Windows 10, l'ordine in cui gli adattatori vengono visualizzati nell'elenco è determinato dalla metrica di route IPv4 o IPv6.

Se la GAA_FLAG_INCLUDE_ALL_INTERFACES è impostata, tutte le schede NDIS verranno recuperate anche gli indirizzi associati alle schede non associate a una famiglia di indirizzi specificata nel parametro Family . Quando questo flag non è impostato, vengono restituiti solo gli indirizzi associati a un adattatore abilitato per la famiglia di indirizzi specificata nel parametro Family .

Le dimensioni della struttura IP_ADAPTER_ADDRESSES sono state modificate in Windows XP con Service Pack 1 (SP1) e versioni successive. Alla struttura sono stati aggiunti diversi membri aggiuntivi. Le dimensioni della struttura IP_ADAPTER_ADDRESSES sono state modificate anche in Windows Vista e versioni successive. Alla struttura sono stati aggiunti alcuni membri aggiuntivi. Le dimensioni della struttura IP_ADAPTER_ADDRESSES sono state modificate anche in Windows Vista con Service Pack 1 (SP1) e versioni successive e successive e inWindows Server 2008 e versioni successive. A questa struttura è stato aggiunto un membro aggiuntivo. Il membro Length della struttura IP_ADAPTER_ADDRESSES restituito nell'elenco collegato di strutture nel buffer a cui punta il parametro AdapterAddresses deve essere utilizzato per determinare quale versione della struttura IP_ADAPTER_ADDRESSES viene utilizzata.

La funzione GetIpAddrTable recupera la tabella di mapping degli indirizzi da interfaccia a IPv4 in un computer locale e restituisce queste informazioni in una struttura MIB_IPADDRTABLE .

Nella piattaforma Software Development Kit (SDK) rilasciata per Windows Server 2003 e versioni precedenti, il valore restituito per la funzione GetAdaptersAddresses è stato definito come DWORD, anziché come ULONG.

La struttura SOCKET_ADDRESS viene utilizzata nella struttura IP_ADAPTER_ADDRESSES a cui punta il parametro AdapterAddresses . In Microsoft Windows Software Development Kit (SDK) rilasciato per Windows Vista e versioni successive, l'organizzazione dei file di intestazione è stata modificata e la struttura SOCKET_ADDRESS è definita nel file di intestazione Ws2def.h che viene automaticamente incluso dal file di intestazione Winsock2.h . In Platform SDK rilasciato per Windows Server 2003 e Windows XP, la struttura SOCKET_ADDRESS viene dichiarata nel file di intestazione Winsock2.h . Per usare la struttura IP_ADAPTER_ADDRESSES , è necessario includere il file di intestazione Winsock2.h prima del file di intestazione Iphlpapi.h .

Esempio

In questo esempio viene recuperata la struttura IP_ADAPTER_ADDRESSES per gli adattatori associati al sistema e vengono stampati alcuni membri per ogni interfaccia dell'adattatore.

#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;
}

Requisiti

   
Client minimo supportato Windows XP [app desktop | App UWP]
Server minimo supportato Windows Server 2003 [app desktop | App UWP]
Piattaforma di destinazione Windows
Intestazione iphlpapi.h
Libreria Iphlpapi.lib
DLL Iphlpapi.dll

Vedi anche

GetIpAddrTable

HeapAlloc

HeapFree

Informazioni di riferimento sulle funzioni helper IP

Pagina iniziale dell'helper IP

IP_ADAPTER_ADDRESSES

MIB_IPADDRTABLE

SOCKET_ADDRESS

Windows Sockets