1、发送ARP包获取MAC地址:
#include <windows.h>
#include <stdio.h>
#include "Iphlpapi.h"
#pragma comment(lib, "IpHlpApi.lib")
#pragma comment(lib, "ws2_32.lib")
int main(int argc,char * argv[])
{
int iReturn;
DWORD dwIP;
BYTE byMAC[6];
DWORD dwLen;
WSADATA WsaData;
WSAStartup(MAKEWORD(2, 0), &WsaData);
__try
{
printf("IP2MAC Ver 1.0 -- Get MAC address from IP address though ARP request.\n\n");
if (argc != 2)
{
printf("Usage: %s <IP>\n", argv[0]);
__leave;
}
dwIP = inet_addr(argv[1]);
if (dwIP == INADDR_NONE)
{
printf("Invalid IP address: %s.\n", argv[1]);
__leave;
}
// 发送ARP查询包获得 MAC 地址
dwLen = 6;
iReturn = SendARP(dwIP, 0, (PULONG) &byMAC, &dwLen);
if (iReturn != NO_ERROR)
{
printf("Error: Send ARP request. \nBe sure that connectting to %s need no gateway.\n", argv[1]);
__leave;
}
printf("%02X-%02X-%02X-%02X-%02X-%02X\n", byMAC[0], byMAC[1], byMAC[2], byMAC[3], byMAC[4], byMAC[5]);
}
__finally
{
WSACleanup();
}
return 0;
}
2、NDIS(DDK)通过驱动程序获取MAC地址
ndis规范中说明,网卡驱动程序支持ioctl_ndis_query_stats接口
参数如下:
OID_802_3_PERMANENT_ADDRESS :物理地址
OID_802_3_CURRENT_ADDRESS :mac地址
于是我们的方法就得到了。
首先,看看注册表,找一找网卡有几块,分别是什么设备名。
具体位置和os有关,2000下在hlm\software\microsoft\windows nt\current version\networkcards。
然后createfile(devicename,...)注意,要用linkname,因此
还要加上"////.//device//".
接着
deviceiocontrol(hmac,IOCTL_NDIS_QUERY_STATS,
OID_802_3_PERMANENT_ADDRESS/OID_802_3_CURRENT_ADDRESS...)
#include <windows.h>
#include <stdio.h>
//#include <iptypes.h>
#include <iphlpapi.h>
#include <NtDDNdis.h>
#pragma comment ( lib, "iphlpapi.lib" )
BOOL WINAPI GetPhyMacAddress(char* strServiceName)
{
BOOL bRet = FALSE;
char pstrBuf[512];
wsprintfA(pstrBuf, "\\\\.\\%s", strServiceName);
HANDLE hDev = CreateFile(pstrBuf, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
if ( hDev != INVALID_HANDLE_VALUE )
{
int inBuf;
BYTE outBuf[256] = { 0 };
DWORD BytesReturned;
inBuf = OID_802_3_PERMANENT_ADDRESS;
if ( DeviceIoControl(hDev, IOCTL_NDIS_QUERY_GLOBAL_STATS, (LPVOID)&inBuf, 4, outBuf, 256, &BytesReturned, NULL) )
{
sprintf(pstrBuf, "物理mac:%02X-%02X-%02X-%02X-%02X-%02X\n",
outBuf[0], outBuf[1], outBuf[2], outBuf[3], outBuf[4], outBuf[5]);
printf(pstrBuf);
bRet = TRUE;
}
inBuf = OID_802_3_CURRENT_ADDRESS;
if ( DeviceIoControl(hDev, IOCTL_NDIS_QUERY_GLOBAL_STATS, (LPVOID)&inBuf, 4, outBuf, 256, &BytesReturned, NULL) )
{
sprintf(pstrBuf, "当前mac:%02X-%02X-%02X-%02X-%02X-%02X\n",
outBuf[0], outBuf[1], outBuf[2], outBuf[3], outBuf[4], outBuf[5]);
printf(pstrBuf);
bRet = TRUE;
}
CloseHandle(hDev);
}
return bRet;
}
// 网卡 MAC 地址
BOOL GetMacAddress()
{
UINT uErrorCode = 0;
PIP_ADAPTER_INFO pAda;
ULONG uSize = 0;
DWORD dwResult = GetAdaptersInfo(NULL, &uSize);
if ( dwResult == ERROR_BUFFER_OVERFLOW )
{
pAda = (PIP_ADAPTER_INFO)new BYTE[uSize];
PIP_ADAPTER_INFO piai = pAda ;
dwResult = GetAdaptersInfo(piai, &uSize);
if ( ERROR_SUCCESS == dwResult )
{
while ( piai )
{
printf("名称:%s\n", piai->AdapterName);
printf("描述:%s\n", piai->Description);
printf("类型:%d\n", piai->Type);
GetPhyMacAddress(piai->AdapterName);
printf("\n");
piai = piai->Next;
}
}
delete[] pAda;
}
return TRUE;
}
int main(void)
{
GetMacAddress() ;
return 0 ;
}
3、NetAPI使用得到MAC
#include <windows.h>
//#include <wincon.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#pragma comment(lib, "NetAPI32.Lib")
typedef struct _ASTAT_
{
ADAPTER_STATUS adapt;
NAME_BUFFER NameBuff [30];
}ASTAT, * PASTAT;
ASTAT Adapter;
int main (void)
{
NCB Ncb;
UCHAR uRetCode;
char NetName[50];
LANA_ENUM lenum;
int i;
memset( &Ncb, 0, sizeof(Ncb) );
Ncb.ncb_command = NCBENUM;
Ncb.ncb_buffer = (UCHAR *)&lenum;
Ncb.ncb_length = sizeof(lenum);
uRetCode = Netbios( &Ncb );
printf( "The NCBENUM return code is: 0x%x \n", uRetCode );
for(i=0; i < lenum.length ;i++)
{
memset( &Ncb, 0, sizeof(Ncb) );
Ncb.ncb_command = NCBRESET;
Ncb.ncb_lana_num = lenum.lana[i];
uRetCode = Netbios( &Ncb );
printf( "The NCBRESET on LANA %d return code is: 0x%x \n",
lenum.lana, uRetCode );
memset( &Ncb, 0, sizeof (Ncb) );
Ncb.ncb_command = NCBASTAT;
Ncb.ncb_lana_num = lenum.lana[i];
strcpy((char*)Ncb.ncb_callname, "* " );
Ncb.ncb_buffer = (UCHAR *) &Adapter;
Ncb.ncb_length = sizeof(Adapter);
uRetCode = Netbios( &Ncb );
printf( "The NCBASTAT on LANA %d return code is: 0x%x \n",
lenum.lana, uRetCode );
if ( uRetCode == 0 )
{
printf( "The Ethernet Number on LANA %d is:%02X-%02X-%02X-%02X-%02X-%02X\n",
lenum.lana,
Adapter.adapt.adapter_address[0],
Adapter.adapt.adapter_address[1],
Adapter.adapt.adapter_address[2],
Adapter.adapt.adapter_address[3],
Adapter.adapt.adapter_address[4],
Adapter.adapt.adapter_address[5] );
}
}
}