다음을 통해 공유


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 주소 접두사가 반환됩니다.

이 플래그는 WINDOWS XP SP1 이상에서 지원됩니다.

GAA_FLAG_SKIP_FRIENDLY_NAME
0x0020
어댑터 이름을 반환하지 마세요.
GAA_FLAG_INCLUDE_WINS_INFO
0x0040
WINS(Windows Internet Name Service) 서버의 주소를 반환합니다.

이 플래그는 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 매개 변수가 NULL이거나, Address 매개 변수가 AF_INET, AF_INET6 또는 AF_UNSPEC 없거나, 요청된 매개 변수의 주소 정보가 ULONG_MAX 초과되는 조건에 대해 반환됩니다.
ERROR_NOT_ENOUGH_MEMORY
메모리 리소스가 부족하여 작업을 완료할 수 있습니다.
ERROR_NO_DATA
요청된 매개 변수에 대한 주소를 찾을 수 없습니다.
기타
FormatMessage를 사용하여 반환된 오류에 대한 메시지 문자열을 가져옵니다.

설명

The
GetAdaptersAddresses 함수는 IPv4 및 IPv6 주소에 대한 정보를 검색할 수 있습니다.

주소는 AdapterAddresses 매개 변수가 가리키는 버퍼의 IP_ADAPTER_ADDRESSES 구조체의 연결된 목록으로 반환됩니다. GetAdaptersAddresses 함수를 호출하는 애플리케이션은 AdapterAddresses 매개 변수가 가리키는 IP_ADAPTER_ADDRESSES 구조를 반환하는 데 필요한 메모리 양을 할당해야 합니다. 이러한 반환된 구조체가 더 이상 필요하지 않은 경우 애플리케이션은 할당된 메모리를 해제해야 합니다. 이 작업은 HeapAlloc 함수를 호출하여 메모리를 할당하고 나중에 HeapFree 함수를 호출하여 예제 코드와 같이 할당된 메모리를 해제하여 수행할 수 있습니다. 할당 및 사용 가능한 함수 모두에 동일한 함수 제품군이 사용되는 한 다른 메모리 할당 및 사용 가능한 함수를 사용할 수 있습니다.

GetAdaptersAddresses 는 동기 함수 호출로만 구현됩니다. GetAdaptersAddresses 함수는 모든 하위 수준 네트워크 인터페이스 테이블을 트래버스해야 하므로 상당한 양의 네트워크 리소스와 완료 시간이 필요합니다.

AdapterAddresses 매개 변수가 가리키는 IP_ADAPTER_ADDRESSES 구조를 반환하는 데 필요한 메모리를 결정하는 데 사용할 수 있는 한 가지 방법은 GetAdaptersAddresses 함수에 대한 첫 번째 호출에서 SizePointer 매개 변수에 표시된 대로 버퍼 크기를 너무 작게 전달하여 함수가 ERROR_BUFFER_OVERFLOW 실패하는 것입니다. 반환 값이 ERROR_BUFFER_OVERFLOWSizePointer 매개 변수는 어댑터 정보를 보관하는 데 필요한 버퍼 크기를 가리킵니다. 어댑터 주소가 추가되거나 제거된 경우 AdapterAddresses 매개 변수가 가리키는 IP_ADAPTER_ADDRESSES 구조체에 필요한 버퍼 크기가 GetAdaptersAddresses 함수에 대한 후속 호출 간에 변경될 수 있습니다. 그러나 GetAdaptersAddresses 함수를 사용하는 이 메서드는 권장되지 않습니다. 이 메서드를 사용하려면 GetAdaptersAddresses 함수를 여러 번 호출해야 합니다.

GetAdaptersAddresses 함수를 호출하는 권장 방법은 AdapterAddresses 매개 변수가 가리키는 15KB 작업 버퍼를 미리 할당하는 것입니다. 일반적인 컴퓨터에서는 GetAdaptersAddresses 함수가 ERROR_BUFFER_OVERFLOW 반환할 가능성을 크게 줄여 줍니다. 이 경우 GetAdaptersAddresses 함수를 여러 번 호출해야 합니다. 예제 코드는 이 사용 방법을 보여 줍니다.

Windows 10 이전 버전에서는 이 함수가 반환하는 목록에 어댑터가 표시되는 순서를 네트워크 연결 폴더에서 제어할 수 있습니다. 고급 메뉴에서 고급 설정 메뉴 항목을 선택합니다. Windows 10 시작해서 어댑터가 목록에 표시되는 순서는 IPv4 또는 IPv6 경로 메트릭에 의해 결정됩니다.

GAA_FLAG_INCLUDE_ALL_INTERFACES 설정된 경우 모든 NDIS 어댑터는 Family 매개 변수에 지정된 주소 패밀리에 바인딩되지 않은 어댑터와 연결된 주소도 검색됩니다. 이 플래그를 설정하지 않으면 Family 매개 변수에 지정된 주소 패밀리에 대해 사용하도록 설정된 어댑터에 바인딩된 주소만 반환됩니다.

IP_ADAPTER_ADDRESSES 구조의 크기는 Windows XP SP1(서비스 팩 1) 이상에서 변경되었습니다. 이 구조체에 몇 명의 추가 멤버가 추가되었습니다. IP_ADAPTER_ADDRESSES 구조체의 크기도 Windows Vista 이상에서 변경되었습니다. 이 구조체에 추가 멤버 수가 추가되었습니다. sp1(서비스 팩 1) 이상 및Windows Server 2008 이상에서 Windows Vista에서도 IP_ADAPTER_ADDRESSES 구조의 크기가 변경되었습니다. 이 구조체에 하나의 추가 멤버가 추가되었습니다. 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 SDK(Windows 소프트웨어 개발 키트)에서 헤더 파일의 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
라이브러리 Iphlpapi.lib
DLL Iphlpapi.dll

참고 항목

GetIpAddrTable

HeapAlloc

HeapFree

IP 도우미 함수 참조

IP 도우미 시작 페이지

IP_ADAPTER_ADDRESSES

MIB_IPADDRTABLE

SOCKET_ADDRESS

Windows 소켓