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
검색할 주소의 주소 패밀리입니다. 이 매개 변수는 다음 값 중 하나여야 합니다.
값 | 의미 |
---|---|
|
IPv4 또는 IPv6을 사용하도록 설정된 어댑터와 연결된 IPv4 및 IPv6 주소를 모두 반환합니다. |
|
IPv4를 사용하도록 설정된 어댑터와 연결된 IPv4 주소만 반환합니다. |
|
IPv6이 사용하도록 설정된 어댑터와 연결된 IPv6 주소만 반환합니다. |
[in] Flags
검색할 주소의 유형입니다. 가능한 값은 Iptypes.h 헤더 파일에 정의됩니다. Iptypes.h 헤더 파일은 Iphlpapi.h에 자동으로 포함되며 직접 사용하면 안 됩니다.
이 매개 변수는 다음 값의 조합입니다. 이 매개 변수가 0이면 유니캐스트, 애니캐스트 및 멀티캐스트 IP 주소가 반환됩니다.
[in] Reserved
이 매개 변수는 현재 사용되지 않지만 향후 시스템 사용을 위해 예약되어 있습니다. 호출하는 애플리케이션은 이 매개 변수에 대해 NULL 을 전달해야 합니다.
[in, out] AdapterAddresses
성공적으로 반환되는 IP_ADAPTER_ADDRESSES 구조체의 연결된 목록을 포함하는 버퍼에 대한 포인터입니다.
[in, out] SizePointer
AdapterAddresses가 가리키는 버퍼의 크기를 지정하는 변수에 대한 포인터입니다.
반환 값
함수가 성공하면 반환 값이 ERROR_SUCCESS ( NO_ERROR 동일한 값으로 정의됨).
함수가 실패하면 반환 값은 다음 오류 코드 중 하나입니다.
반환 코드 | 설명 |
---|---|
|
주소가 아직 네트워크 엔드포인트와 연결되지 않았습니다. DHCP 임대 정보를 사용할 수 있었습니다. |
|
SizePointer 매개 변수로 표시된 버퍼 크기가 너무 작아 어댑터 정보를 보유할 수 없거나 AdapterAddresses 매개 변수가 NULL입니다. SizePointer 매개 변수는 어댑터 정보를 보관하는 데 필요한 버퍼 크기를 가리킵니다. |
|
매개 변수 중 하나가 잘못되었습니다. 이 오류는 SizePointer 매개 변수가 NULL이거나, Address 매개 변수가 AF_INET, AF_INET6 또는 AF_UNSPEC 없거나, 요청된 매개 변수의 주소 정보가 ULONG_MAX 초과되는 조건에 대해 반환됩니다. |
|
메모리 리소스가 부족하여 작업을 완료할 수 있습니다. |
|
요청된 매개 변수에 대한 주소를 찾을 수 없습니다. |
|
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 |