windows下获取mac地址的两种方法

来源:互联网 发布:网络视频监控方案 编辑:程序博客网 时间:2024/05/01 09:16

在Windows下可用用微软的API获取网卡的MAC地址,也可以用WinPcap来获取。

方法一:调用WindowsAPI获取。

#include <winsock2.h>
#include <iphlpapi.h>
#pragma comment(lib, "IPHLPAPI.lib")

#include <string>
#include <iostream>

bool GetMacByGetAdaptersAddresses(std::string& macOUT)
{
bool ret = false;


ULONG outBufLen = sizeof(IP_ADAPTER_ADDRESSES);
PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
if (pAddresses == NULL) 
return false;
// Make an initial call to GetAdaptersAddresses to get the necessary size into the ulOutBufLen variable
if(GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW)
{
free(pAddresses);
pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
if (pAddresses == NULL) 
return false;
}


if(GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen) == NO_ERROR)
{
// If successful, output some information from the data we received
for(PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses; pCurrAddresses != NULL; pCurrAddresses = pCurrAddresses->Next)
{
// 确保MAC地址的长度为 00-00-00-00-00-00
if(pCurrAddresses->PhysicalAddressLength != 6)
continue;
char acMAC[32];
sprintf(acMAC, "%02X-%02X-%02X-%02X-%02X-%02X",
int (pCurrAddresses->PhysicalAddress[0]),
int (pCurrAddresses->PhysicalAddress[1]),
int (pCurrAddresses->PhysicalAddress[2]),
int (pCurrAddresses->PhysicalAddress[3]),
int (pCurrAddresses->PhysicalAddress[4]),
int (pCurrAddresses->PhysicalAddress[5]));
macOUT = acMAC;
ret = true;
break;
}

}
free(pAddresses);
return ret;
}

这种方法只能获取一张网卡的mac地址,如果需要获取所有网卡的mac地址,则可用winPcap,winPcap的example中有获取mac的源代码,我只是稍微做一下修整。

方法二:用WinPcap获取

lpszAdapterName 指的是通过finddevs获取到的网卡信息,ucMacAddr用来输出mac地址。

int GetAdapterMacAddr( char *lpszAdapterName, unsigned char ucMacAddr[] )
{
LPADAPTER lpAdapter = PacketOpenAdapter( lpszAdapterName );
if (!lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE))
{
return -1;
}

PPACKET_OID_DATA oidData = ( PPACKET_OID_DATA )malloc(6 + sizeof(PACKET_OID_DATA));
if ( NULL == oidData ) 
{
PacketCloseAdapter(lpAdapter);
return -1;
}

oidData->Oid = OID_802_3_CURRENT_ADDRESS;
oidData->Length = 6;
memset(oidData->Data, 0, 6 );

BOOLEAN  bStatus = PacketRequest(lpAdapter, FALSE, oidData);
if ( bStatus )
{
for ( int i = 0; i < 6; ++i )
{
ucMacAddr[i] = (oidData->Data)[i];
}
}
else
{
return -1;
free( oidData );
}
free( oidData );
PacketCloseAdapter( lpAdapter );
return 0;
}


有人通过给自己发生ARP来查询自己的mac地址,我觉得这样不可行,在发送arp数据包的时候源主机的mac地址必须要填,但是我们不知道,所以发不出去。

0 0