一开始使用的是GetAdaptersInfo,不过只能获取IPV4的信息。网上一顿搜索之后发现需要用GetAdaptersAddresses。直接上代码。
#include <WinSock2.h>
#include <WS2TCPIP.H>
typedef ULONG (WINAPI *pGetAdaptersAddresses)(
IN ULONG Family,
IN ULONG Flags,
IN PVOID Reserved,
INOUT PIP_ADAPTER_ADDRESSES AdapterAddresses,
INOUT PULONG SizePointer
);
bool GetNetworkCardMac_IPV6(char Mac[6], char *pIPAddr /*= NULL*/, int nIPBuffLen /*= 0*/)
{
HMODULE m_hInst = LoadLibrary("Iphlpapi.dll");
if (m_hInst < (HINSTANCE)HINSTANCE_ERROR)
{
m_hInst = NULL;
return false;
}
pGetAdaptersAddresses fGetAdaptersAddress = (pGetAdaptersAddresses)GetProcAddress(m_hInst, "GetAdaptersAddresses");
if (NULL == fGetAdaptersAddress)
{
FreeLibrary(m_hInst);
return false;
}
//关于这个标志,查 MSDN 吧。。。
ULONG flags = 0x0010 | 0x0080;//包括 IPV4 ,IPV6 网关
ULONG family = AF_UNSPEC;//返回包括 IPV4 和 IPV6 地址
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
ULONG outBufLen = 0;
DWORD dwRetVal = 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;
outBufLen = 15000;
do
{
pAddresses = (IP_ADAPTER_ADDRESSES *)malloc(outBufLen);
if (pAddresses == NULL)
return false ;
dwRetVal = fGetAdaptersAddress(family, flags, NULL, pAddresses, &outBufLen);
if (dwRetVal == ERROR_BUFFER_OVERFLOW)
{
free(pAddresses);
pAddresses = NULL;
}
else
break;
} while (dwRetVal == ERROR_BUFFER_OVERFLOW);
CString info;
if (dwRetVal == NO_ERROR)
{
pCurrAddresses = pAddresses;
while (pCurrAddresses)
{
info += CString(_T("Adapter name:")) + pCurrAddresses->AdapterName + CString(_T("\r\n"));
info += CString(_T("Description:")) + CString(pCurrAddresses->Description) + CString(_T("\r\n"));
info += CString(_T("Friendly name:")) + CString(pCurrAddresses->FriendlyName) + CString(_T("\r\n"));
if (pCurrAddresses->PhysicalAddressLength != 0)
{
CString mac;//其实 MAC 地址的长度存在 PhysicalAddressLength 中,最好用它来确定格式化的长度
mac.Format(_T("%02X%02X%02X%02X%02X%02X"), pCurrAddresses->PhysicalAddress[0], pCurrAddresses->PhysicalAddress[1], \
pCurrAddresses->PhysicalAddress[2], pCurrAddresses->PhysicalAddress[3], pCurrAddresses->PhysicalAddress[4], \
pCurrAddresses->PhysicalAddress[5]);
info += CString(_T("Adapter Mac:")) + mac + CString(_T("\r\n"));//MAC地址
}
CString type;
switch (pCurrAddresses->IfType) //类型,列举了几种
{
case MIB_IF_TYPE_ETHERNET:
type = _T("以太网接口");
break;
case MIB_IF_TYPE_PPP:
type = _T("PPP接口");
break;
case MIB_IF_TYPE_LOOPBACK:
type = _T("软件回路接口");
break;
case MIB_IF_TYPE_SLIP:
type = _T("ATM网络接口");
break;
}
info += CString(_T("网卡类型:")) + type + CString(_T("\r\n"));
pUnicast = pCurrAddresses->FirstUnicastAddress;
while (pUnicast)//单播IP
{
CHAR IP[130] = { 0 };
if (AF_INET == pUnicast->Address.lpSockaddr->sa_family)// IPV4 地址,使用 IPV4 转换
inet_ntop(PF_INET, &((sockaddr_in*)pUnicast->Address.lpSockaddr)->sin_addr, IP, sizeof(IP));
else if (AF_INET6 == pUnicast->Address.lpSockaddr->sa_family)// IPV6 地址,使用 IPV6 转换
inet_ntop(PF_INET6, &((sockaddr_in6*)pUnicast->Address.lpSockaddr)->sin6_addr, IP, sizeof(IP));
info += CString(_T("单播IP:")) + CString(IP) + CString(_T("\r\n"));
pUnicast = pUnicast->Next;
}
pDnServer = pCurrAddresses->FirstDnsServerAddress;
while (pDnServer)//DNS
{
CHAR DNS[130] = { 0 };
if (AF_INET == pDnServer->Address.lpSockaddr->sa_family)
inet_ntop(PF_INET, &((sockaddr_in*)pDnServer->Address.lpSockaddr)->sin_addr, DNS, sizeof(DNS));
else if (AF_INET6 == pDnServer->Address.lpSockaddr->sa_family)
inet_ntop(PF_INET6, &((sockaddr_in6*)pDnServer->Address.lpSockaddr)->sin6_addr, DNS, sizeof(DNS));
info += CString(_T("DNS:")) + CString(DNS) + CString(_T("\r\n"));
pDnServer = pDnServer->Next;
}
CString MTU;// MTU
MTU.Format(_T("MTU:%d\r\n"), pCurrAddresses->Mtu);
info += MTU;
info += CString(_T("\r\n"));
pCurrAddresses = pCurrAddresses->Next;
}
}
else
{
CString s;
s.Format(_T("fGetAdaptersAddress failed,error code:%d"), GetLastError());
AfxMessageBox(s);
}
if (pAddresses)
free(pAddresses);
return true;
}