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 に自動的に含まれるので、直接使用しないでください。

このパラメーターは、次の値の組み合わせです。 このパラメーターが 0 の場合は、ユニキャスト、エニーキャスト、およびマルチキャスト IP アドレスが返されます。

説明
GAA_FLAG_SKIP_UNICAST
0x0001
ユニキャスト アドレスを返さないでください。
GAA_FLAG_SKIP_ANYCAST
0x0002
IPv6 エニーキャスト アドレスを返さないでください。
GAA_FLAG_SKIP_MULTICAST
0x0004
マルチキャスト アドレスを返さないでください。
GAA_FLAG_SKIP_DNS_SERVER
0x0008
DNS サーバーのアドレスを返さないでください。
GAA_FLAG_INCLUDE_PREFIX
0x0010
このアダプターの IP アドレス プレフィックスの一覧を返します。 このフラグを設定すると、IPv6 アドレスと IPv4 アドレスの両方に対して IP アドレス プレフィックスが返されます。

このフラグは、SP1 以降の Windows XP でサポートされています。

GAA_FLAG_SKIP_FRIENDLY_NAME
0x0020
アダプターのフレンドリ名を返さないでください。
GAA_FLAG_INCLUDE_WINS_INFO
0x0040
Windows インターネット ネーム サービス (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 パラメーターが NULLAddress パラメーターがAF_INET、AF_INET6、またはAF_UNSPECではない、または要求されたパラメーターのアドレス情報がULONG_MAXを超えています。
ERROR_NOT_ENOUGH_MEMORY
操作を完了するために使用できるメモリ リソースが不足しています。
ERROR_NO_DATA
要求されたパラメーターのアドレスが見つかりませんでした。
その他
FormatMessage を使用して、返されたエラーのメッセージ文字列を取得します。

解説

次に、
GetAdaptersAddresses 関数は、IPv4 および IPv6 アドレスの情報を取得できます。

アドレスは、AdapterAddresses パラメーターによって指されるバッファー内のIP_ADAPTER_ADDRESSES構造体のリンクされたリストとして返されます。 GetAdaptersAddresses 関数を呼び出すアプリケーションは、AdapterAddresses パラメーターが指すIP_ADAPTER_ADDRESSES構造体を返すために必要なメモリ量を割り当てる必要があります。 これらの返される構造体が不要になった場合、アプリケーションは割り当てられたメモリを解放する必要があります。 これを実現するには、 HeapAlloc 関数を呼び出してメモリを割り当て、後で HeapFree 関数を呼び出して割り当てられたメモリを解放します (コード例を参照)。 割り当て関数と free 関数の両方に同じ関数ファミリが使用されている限り、他のメモリ割り当て関数と空き関数を使用できます。

GetAdaptersAddresses は、同期関数呼び出しとしてのみ実装されます。 GetAdaptersAddresses 関数では、すべての低レベルのネットワーク インターフェイス テーブルを走査する必要があるため、完了するには大量のネットワーク リソースと時間が必要です。

AdapterAddresses パラメーターが指すIP_ADAPTER_ADDRESSES構造体を返すために必要なメモリを確認するために使用できるメソッドの 1 つは、GetAdaptersAddresses 関数の最初の呼び出しで SizePointer パラメーターに示されているようにバッファー サイズが小さすぎるため、関数がERROR_BUFFER_OVERFLOWで失敗します。 戻り値が ERROR_BUFFER_OVERFLOWされると、返される SizePointer パラメーターは、アダプター情報を保持するためにバッファーの必要なサイズを指します。 アダプター アドレスが追加または削除された場合、AdapterAddresses パラメーターが指すIP_ADAPTER_ADDRESSES構造体に必要なバッファー サイズが、GetAdaptersAddresses 関数の後続の呼び出し間で変更される可能性があることに注意してください。 ただし、 GetAdaptersAddresses 関数を使用するこのメソッドは、強くお勧めしません。 このメソッドでは、 GetAdaptersAddresses 関数を複数回呼び出す必要があります。

GetAdaptersAddresses 関数を呼び出すには、AdapterAddresses パラメーターが指す 15 KB の作業バッファーを事前に割り当てることをお勧めします。 一般的なコンピューターでは、 これにより、GetAdaptersAddresses 関数が ERROR_BUFFER_OVERFLOWを返す可能性が大幅に低下します。この場合、 GetAdaptersAddresses 関数を複数回呼び出す必要があります。 コード例は、この使用方法を示しています。

Windows 10より前のバージョンでは、この関数によって返される一覧にアダプターが表示される順序は、[ネットワーク接続] フォルダーから制御できます。[詳細設定] メニューの [詳細設定] メニュー項目を選択します。 Windows 10以降、一覧にアダプターが表示される順序は、IPv4 または IPv6 ルート メトリックによって決まります。

GAA_FLAG_INCLUDE_ALL_INTERFACESが設定されている場合、 Family パラメーターで 指定されたアドレス ファミリにバインドされていないアダプターに関連付けられているアドレスであっても、すべての NDIS アダプターが取得されます。 このフラグが設定されていない場合は、 Family パラメーターで指定されたアドレス ファミリに対して有効になっているアダプターにバインドされているアドレスのみが返されます。

IP_ADAPTER_ADDRESSES 構造体のサイズは、Service Pack 1 (SP1) 以降の Windows XP で変更されました。 この構造体には、いくつかの追加メンバーが追加されました。 IP_ADAPTER_ADDRESSES構造のサイズは、Windows Vista 以降でも変更されました。 この構造体には、多数の追加メンバーが追加されました。 IP_ADAPTER_ADDRESSES構造のサイズは、Windows Vista Service Pack 1 (SP1) 以降および Windows Server 2008 以降でも変更されました。 この構造体に 1 つの追加メンバーが追加されました。 AdapterAddresses パラメーターが指すバッファー内の構造体のリンクリストで返されるIP_ADAPTER_ADDRESSES構造体の Length メンバーを使用して、使用されているIP_ADAPTER_ADDRESSES構造体のバージョンを確認する必要があります。

GetIpAddrTable 関数は、ローカル コンピューター上のインターフェイスから IPv4 へのアドレス マッピング テーブルを取得し、この情報をMIB_IPADDRTABLE構造で返します。

Windows Server 2003 以前用にリリースされたプラットフォーム ソフトウェア開発キット (SDK) では、GetAdaptersAddresses 関数の戻り値は ULONG ではなく DWORD として定義されていました。

SOCKET_ADDRESS構造体は、AdapterAddresses パラメーターが指すIP_ADAPTER_ADDRESSES構造体で使用されます。 Windows Vista 以降用にリリースされた Microsoft Windows ソフトウェア開発キット (SDK) では、ヘッダー ファイルのorganizationが変更され、SOCKET_ADDRESS構造は、Winsock2.h ヘッダー ファイルによって自動的に含まれる Ws2def.h ヘッダー ファイルで定義されます。 Windows Server 2003 および Windows XP 用にリリースされたプラットフォーム SDK では、 SOCKET_ADDRESS 構造が Winsock2.h ヘッダー ファイルで宣言されています。 IP_ADAPTER_ADDRESSES構造体を使用するには、Iphlpapi.h ヘッダー ファイルの前に Winsock2.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
ヘッダー iphlpapi.h
Library Iphlpapi.lib
[DLL] Iphlpapi.dll

関連項目

GetIpAddrTable

HeapAlloc

HeapFree

IP ヘルパー関数リファレンス

IP ヘルパーの開始ページ

IP_ADAPTER_ADDRESSES

MIB_IPADDRTABLE

SOCKET_ADDRESS

Windows ソケット