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] ); } } }