头文件IPApi.h
#pragma once
// Returns number of NICs
// 'address' contains the physical address of index='idx'
int get_physical_address(char * address, int idx);
// Returns number of NICs
// 'address' contains the physical address of index=0
int get_first_physical_address(char * address);
bool is_physical_address(const char * address);
源文件IPApi.cpp
#include "IPApi.h"
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "IPHLPAPI.lib")
#define WORKING_BUFFER_SIZE 15000
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
static void phy_adapter_address2str(PIP_ADAPTER_ADDRESSES paddress, char * saddress) {
int j = 0;
for (int i = 0; i < (int)paddress->PhysicalAddressLength; i++) {
j += sprintf(saddress + j, "%.2X", (int)paddress->PhysicalAddress[i]);
}
}
static ULONG get_adapters_Addresses(PIP_ADAPTER_ADDRESSES * pAddresses) {
DWORD dwRetVal = 0;
ULONG Iterations = 0;
const ULONG MAX_TRIES = 3;
do {
ULONG outBufLen = WORKING_BUFFER_SIZE;
*pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen);
if (*pAddresses == NULL) {
printf("Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n");
exit(1);
}
dwRetVal = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, *pAddresses, &outBufLen);
if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
FREE(*pAddresses);
*pAddresses = NULL;
}
else {
break;
}
Iterations++;
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES));
return dwRetVal;
}
int get_first_physical_address(char * address) {
return get_physical_address(address, 0);
}
int get_physical_address(char * address, int idx) {
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
DWORD dwRetVal = get_adapters_Addresses(&pAddresses);
int countOfAddress(0);
if (dwRetVal == NO_ERROR) {
PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses;
while (pCurrAddresses) {
if (pCurrAddresses->PhysicalAddressLength != 0) {
if (idx == countOfAddress) {
phy_adapter_address2str(pCurrAddresses, address);
}
countOfAddress++;
}
pCurrAddresses = pCurrAddresses->Next;
}
} else {}
if (pAddresses) {
FREE(pAddresses);
}
return countOfAddress;
}
bool is_physical_address(const char * address) {
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
DWORD dwRetVal = get_adapters_Addresses(&pAddresses);
int cmp_out(1); // default not address
if (dwRetVal == NO_ERROR) {
PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses;
while (pCurrAddresses) {
if (pCurrAddresses->PhysicalAddressLength != 0) {
char s[25] = { 0 };
phy_adapter_address2str(pCurrAddresses, s);
cmp_out = strcmp(address, s);
if (cmp_out == 0) {
break;
}
}
pCurrAddresses = pCurrAddresses->Next;
}
}
else {}
if (pAddresses) {
FREE(pAddresses);
}
return (cmp_out == 0 ? true : false);
}