ULONG WINAPIGetAdaptersAddresses
(
__in ULONGFamily,
__in ULONGFlags,
__in PVOIDReserved,
__inout PIP_ADAPTER_ADDRESSESAdapterAddresses,
__inout PULONG SizePointer
);
第一个参数Family是网络协议族,用户可以指定ipv6和ipv4,这是它和GetAdapterInfo接口区别最大的地方。
第二个参数是指定地址类型的,可以指定单播、多播、ipv6、DNS等,用户可以根据需求传不同的参数得到不同的地址。
第三个是保留参数,补足位用的。
第四个参数AdapterAddresses是一个指向网卡信息结构体的指针,该指针类型是PIP_ADAPTER_ADDRESSES类型的,关于这个变量后面再详细介绍。
第五个参数是AdapterAddresses所需数据大小的值。
//网卡的信息结构体
typedef struct _IP_ADAPTER_ADDRESSES { union { ULONGLONG Alignment; struct { ULONG Length; DWORD IfIndex; }; }; struct _IP_ADAPTER_ADDRESSES *Next; PCHAR AdapterName; PIP_ADAPTER_UNICAST_ADDRESS FirstUnicastAddress; PIP_ADAPTER_ANYCAST_ADDRESS FirstAnycastAddress; PIP_ADAPTER_MULTICAST_ADDRESS FirstMulticastAddress; PIP_ADAPTER_DNS_SERVER_ADDRESS FirstDnsServerAddress; PWCHAR DnsSuffix; PWCHAR Description; PWCHAR FriendlyName; BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH]; DWORD PhysicalAddressLength; DWORD Flags; DWORD Mtu; DWORD IfType; IF_OPER_STATUS OperStatus; DWORD Ipv6IfIndex; DWORD ZoneIndices[16]; PIP_ADAPTER_PREFIX FirstPrefix; ULONG64 TransmitLinkSpeed; ULONG64 ReceiveLinkSpeed; PIP_ADAPTER_WINS_SERVER_ADDRESS_LH FirstWinsServerAddress; PIP_ADAPTER_GATEWAY_ADDRESS_LH FirstGatewayAddress; ULONG Ipv4Metric; ULONG Ipv6Metric; IF_LUID Luid; SOCKET_ADDRESS Dhcpv4Server; NET_IF_COMPARTMENT_ID CompartmentId; NET_IF_NETWORK_GUID NetworkGuid; NET_IF_CONNECTION_TYPE ConnectionType; TUNNEL_TYPE TunnelType; SOCKET_ADDRESS Dhcpv6Server; BYTE Dhcpv6ClientDuid[MAX_DHCPV6_DUID_LENGTH]; ULONG Dhcpv6ClientDuidLength; ULONG Dhcpv6Iaid; PIP_ADAPTER_DNS_SUFFIX FirstDnsSuffix; } IP_ADAPTER_ADDRESSES, *PIP_ADAPTER_ADDRESSES;
#include#include #include #include // 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 dwSize = 0; 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; }
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365915(v=vs.85).aspx