取得MAC地址的4種方法_第1頁(yè)
取得MAC地址的4種方法_第2頁(yè)
取得MAC地址的4種方法_第3頁(yè)
取得MAC地址的4種方法_第4頁(yè)
取得MAC地址的4種方法_第5頁(yè)
已閱讀5頁(yè),還剩12頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、51彩虹或進(jìn)入 取得MAC地址的4種方法1.創(chuàng)建一個(gè)無(wú)名管道。2.創(chuàng)建一個(gè)IPCONFIG的進(jìn)程,并將輸出重定向到管道。3.從管道獲取命令行返回的所有信息放入緩沖區(qū)lpszBuffer。4.從緩沖區(qū)lpszBuffer中獲得抽取出MAC地址串。通過(guò)我這個(gè)列子你也可以用來(lái)獲取可以通過(guò)命令行方式來(lái)取得的信息,比如說(shuō)主機(jī)名,IP地址等等。源代碼:文件 GetMac.cpp:/ 描述: 通過(guò)命令行方式得到MAC地址/ 作者: 郭洪鋒/ 日期: 2005年7月1日/ email: guohongfeng/#include <string>#include <iostream>us

2、ing namespace std;/命令行輸出緩沖大小const long MAX_COMMAND_SIZE = 10000;/獲取MAC命令行char szFetCmd = "ipconfig /all"/網(wǎng)卡MAC地址的前導(dǎo)信息const string str4Search = "Physical Address. . . . . . . . . : "/用命令行方式獲取網(wǎng)卡MAC地址BOOL GetMacByCmd(char *lpszMac);/ 函數(shù)名: GetMacByCmd(char *lpszMac)/ 參數(shù):/ 輸入: void/ 輸

3、出: lpszMac,返回的MAC地址串/ 返回值:/ TRUE: 獲得MAC地址。/ FALSE: 獲取MAC地址失敗。/ 過(guò)程:/ 1. 創(chuàng)建一個(gè)無(wú)名管道。/ 2. 創(chuàng)建一個(gè)IPCONFIG 的進(jìn)程,并將輸出重定向到管道。/ 3. 從管道獲取命令行返回的所有信息放入緩沖區(qū)lpszBuffer。/ 4. 從緩沖區(qū)lpszBuffer中獲得抽取出MAC串。/ 提示:可以方便的由此程序獲得IP地址等其他信息。/ 對(duì)于其他的可以通過(guò)其他命令方式得到的信息只需改變strFetCmd 和 / str4Search的內(nèi)容即可。/BOOL GetMacByCmd(char *lpszMac)/初始化返回M

4、AC地址緩沖區(qū)memset(lpszMac, 0x00, sizeof(lpszMac);BOOL bret;SECURITY_ATTRIBUTES sa; HANDLE hReadPipe,hWritePipe;sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; /創(chuàng)建管道bret = CreatePipe(&hReadPipe, &hWritePipe, &sa, 0);if(!bret)return FALSE;/控制

5、命令行窗口信息STARTUPINFO si; /返回進(jìn)程信息PROCESS_INFORMATION pi;si.cb = sizeof(STARTUPINFO); GetStartupInfo(&si); si.hStdError = hWritePipe; si.hStdOutput = hWritePipe; si.wShowWindow = SW_HIDE; /隱藏命令行窗口si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;/創(chuàng)建獲取命令行進(jìn)程bret = CreateProcess (NULL, szFetCmd,

6、 NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi ); char szBufferMAX_COMMAND_SIZE+1; /放置命令行輸出緩沖區(qū)string strBuffer;if (bret) WaitForSingleObject (pi.hProcess, INFINITE); unsigned long count;CloseHandle(hWritePipe);memset(szBuffer, 0x00, sizeof(szBuffer);bret = ReadFile(hReadPipe, szBuffer, MAX_COMMA

7、ND_SIZE, &count, 0);if(!bret)/關(guān)閉所有的句柄CloseHandle(hWritePipe);CloseHandle(pi.hProcess); CloseHandle(pi.hThread); CloseHandle(hReadPipe);return FALSE;elsestrBuffer = szBuffer;long ipos;ipos = strBuffer.find(str4Search);/提取MAC地址串strBuffer = strBuffer.substr(ipos+str4Search.length();ipos = strBuffer

8、.find("n");strBuffer = strBuffer.substr(0, ipos);memset(szBuffer, 0x00, sizeof(szBuffer);strcpy(szBuffer, strBuffer.c_str();/去掉中間的“00-50-EB-0F-27-82”中間的'-'得到0050EB0F2782int j = 0;for(int i=0; i<strlen(szBuffer); i+)if(szBufferi != '-')lpszMacj = szBufferi;j+;/關(guān)閉所有的句柄Clos

9、eHandle(hWritePipe);CloseHandle(pi.hProcess); CloseHandle(pi.hThread); CloseHandle(hReadPipe);return TRUE;文件GetMacByCmd.cpp:#include "stdafx.h"#include <iostream.h>#include <string>#include "windows.h"using namespace std;extern BOOL GetMacByCmd(char *lpszMac);void mai

10、n (int argc, char *argv)char lpszMac128;memset(lpszMac, 0x00, sizeof(lpszMac);/獲取MACGetMacByCmd(lpszMac);/打印出MACcout << lpszMac << endl;FILE *fp = NULL;fp = fopen("c:1.txt", "w");fwrite(lpszMac, sizeof(char), strlen(lpszMac), fp);fclose(fp);取得系統(tǒng)中網(wǎng)卡MAC地址的三種方法做好的程序員一如做人

11、。多看多想或許他山之石可以攻玉,但永遠(yuǎn)不要成為代碼的奴隸。 CKER原著:Borland翻譯:CKERTranslated byCKER 第一種方法使用Microsoft的Netbios API。 這是一套通過(guò)Winsock提供底層網(wǎng)絡(luò)支持的命令。使用Netbios的最大缺點(diǎn)是您必須在系統(tǒng)中安裝了Netbios服務(wù)(如果您在windows網(wǎng)絡(luò)中啟用了文件共享的話,這就不是問(wèn)題了)。除此此外,這種方法又快又準(zhǔn)確。Netbios API只包括了一個(gè)函數(shù),就叫做Netbios。這個(gè)函數(shù)使用網(wǎng)絡(luò)控制塊(network control block)結(jié)構(gòu)作為參數(shù),這個(gè)結(jié)構(gòu)告訴函數(shù)要做什么。結(jié)構(gòu)的定義如下:

12、 typedef struct _NCB UCHAR ncb_command; UCHAR ncb_retcode; UCHAR ncb_lsn; UCHAR ncb_num; PUCHAR ncb_buffer; WORD ncb_length; UCHAR ncb_callnameNCBNAMSZ; UCHAR ncb_nameNCBNAMSZ; UCHAR ncb_rto; UCHAR ncb_sto; void (CALLBACK *ncb_post) (struct _NCB *); UCHAR ncb_lana_num; UCHAR ncb_cmd_cplt; #ifdef _WI

13、N64 UCHAR ncb_reserve18; #else UCHAR ncb_reserve10; #endif HANDLE ncb_event; NCB, *PNCB;重點(diǎn)在于ncb_command 成員。這個(gè)成員告訴Netbios該作什么。我們使用三個(gè)命令來(lái)探測(cè)MAC地址。他們?cè)贛SDN的定義如下:命令描述:NCBENUM Windows NT/2000: 列舉系統(tǒng)中網(wǎng)卡的數(shù)量。使用此命令后,ncb_buffer成員指向由LANA_ENUM結(jié)構(gòu)填充的緩沖區(qū)。NCBENUM 不是標(biāo)準(zhǔn)的 NetBIOS 3.0 命令。NCBRESET 重置網(wǎng)卡。網(wǎng)卡在接受新的NCB命令之前必須重置。NC

14、BASTAT 接受本地或遠(yuǎn)程接口卡的狀態(tài)。使用此命令后,ncb_buffer成員指向由ADAPTER_STATUS結(jié)構(gòu)填充的緩沖區(qū),隨后是NAME_BUFFER結(jié)構(gòu)的數(shù)組。下面就是取得您系統(tǒng)MAC地址的步驟:1列舉所有的接口卡。2重置每塊卡以取得它的正確信息。3查詢接口卡,取得MAC地址并生成標(biāo)準(zhǔn)的冒號(hào)分隔格式。下面就是實(shí)例源程序。netbios.cpp#include <windows.h>#include <stdlib.h>#include <stdio.h>#include <iostream>#include <string>

15、;using namespace std;#define bzero(thing,sz) memset(thing,0,sz)bool GetAdapterInfo(int adapter_num, string &mac_addr) / 重置網(wǎng)卡,以便我們可以查詢 NCB Ncb; memset(&Ncb, 0, sizeof(Ncb); Ncb.ncb_command = NCBRESET; Ncb.ncb_lana_num = adapter_num; if (Netbios(&Ncb) != NRC_GOODRET) mac_addr = "bad (

16、NCBRESET): " mac_addr += string(Ncb.ncb_retcode); return false; / 準(zhǔn)備取得接口卡的狀態(tài)塊 bzero(&Ncb,sizeof(Ncb); Ncb.ncb_command = NCBASTAT; Ncb.ncb_lana_num = adapter_num; strcpy(char *) Ncb.ncb_callname, "*"); struct ASTAT ADAPTER_STATUS adapt; NAME_BUFFER NameBuff30; Adapter; bzero(&A

17、dapter,sizeof(Adapter); Ncb.ncb_buffer = (unsigned char *)&Adapter; Ncb.ncb_length = sizeof(Adapter);/ 取得網(wǎng)卡的信息,并且如果網(wǎng)卡正常工作的話,返回標(biāo)準(zhǔn)的冒號(hào)分隔格式。 if (Netbios(&Ncb) = 0) char acMAC18; sprintf(acMAC, "%02X:%02X:%02X:%02X:%02X:%02X", int (Adapter.adapt.adapter_address0), int (Adapter.adapt.ada

18、pter_address1), int (Adapter.adapt.adapter_address2), int (Adapter.adapt.adapter_address3), int (Adapter.adapt.adapter_address4), int (Adapter.adapt.adapter_address5); mac_addr = acMAC; return true; else mac_addr = "bad (NCBASTAT): " mac_addr += string(Ncb.ncb_retcode); return false; int m

19、ain() / 取得網(wǎng)卡列表 LANA_ENUM AdapterList; NCB Ncb; memset(&Ncb, 0, sizeof(NCB); Ncb.ncb_command = NCBENUM; Ncb.ncb_buffer = (unsigned char *)&AdapterList; Ncb.ncb_length = sizeof(AdapterList); Netbios(&Ncb);/ 取得本地以太網(wǎng)卡的地址 string mac_addr; for (int i = 0; i < AdapterList.length - 1; +i) if

20、(GetAdapterInfo(AdapterList.lanai, mac_addr) cout << "Adapter " << int (AdapterList.lanai) << "'s MAC is " << mac_addr << endl; else cerr << "Failed to get MAC address! Do you" << endl; cerr << "have the NetBIOS p

21、rotocol installed?" << endl; break; return 0;file:/-第二種方法使用COM GUID API這種方法使用COM API創(chuàng)建一個(gè)GUID(全局唯一標(biāo)識(shí)符)并從那里繼承MAC地址。GUID通常用來(lái)標(biāo)識(shí)COM組件以及系統(tǒng)中的其他對(duì)象。它們是由MAC地址(結(jié)合其他東西)計(jì)算得來(lái)的,表面上MAC地址就包含在其中。我說(shuō)表面上是因?yàn)槭聦?shí)上并沒(méi)有包含。我提供這種方法更多的是為了作為反面教材。您也許用這種方法能夠得到MAC地址,但有時(shí)候您只會(huì)得到隨機(jī)的十六進(jìn)制數(shù)值。下面的例子十分簡(jiǎn)單,無(wú)需多講。我們使用CoCreateGuid創(chuàng)建GUID,

22、并將最后六個(gè)字節(jié)放入字符串中。它們可能是MAC地址,但并不是必然的。uuid.cpp#include <windows.h>#include <iostream>#include <conio.h>using namespace std;int main() cout << "MAC address is: "/ 向COM要求一個(gè)UUID。如果機(jī)器中有以太網(wǎng)卡, / UUID最后的六個(gè)字節(jié)(Data4的27字節(jié))應(yīng)該是本地以太網(wǎng)卡的MAC地址。 GUID uuid; CoCreateGuid(&uuid); / Spi

23、t the address out char mac_addr18; sprintf(mac_addr,"%02X:%02X:%02X:%02X:%02X:%02X", uuid.Data42,uuid.Data43,uuid.Data44, uuid.Data45,uuid.Data46,uuid.Data47); cout << mac_addr << endl; getch(); return 0;第三種方法 使用SNMP擴(kuò)展API我要討論的第三種方法是使用Windows的SNMP(簡(jiǎn)單網(wǎng)絡(luò)管理協(xié)議)擴(kuò)展來(lái)取得MAC地址。在我的經(jīng)驗(yàn)里,這個(gè)協(xié)議

24、很簡(jiǎn)單。代碼也是直勾勾的向前的。基本步驟和Netbios相同:1取得網(wǎng)卡列表2查詢每塊卡的類型和MAC地址3保存當(dāng)前網(wǎng)卡我個(gè)人對(duì)SNMP了解不多,但如我剛剛所言,代碼十分清楚。snmp.cpp#include <snmp.h>#include <conio.h>#include <stdio.h>typedef bool(WINAPI * pSnmpExtensionInit) ( IN DWORD dwTimeZeroReference, OUT HANDLE * hPollForTrapEvent, OUT AsnObjectIdentifier * s

25、upportedView);typedef bool(WINAPI * pSnmpExtensionTrap) ( OUT AsnObjectIdentifier * enterprise, OUT AsnInteger * genericTrap, OUT AsnInteger * specificTrap, OUT AsnTimeticks * timeStamp, OUT RFC1157VarBindList * variableBindings);typedef bool(WINAPI * pSnmpExtensionQuery) ( IN BYTE requestType, IN O

26、UT RFC1157VarBindList * variableBindings, OUT AsnInteger * errorStatus, OUT AsnInteger * errorIndex);typedef bool(WINAPI * pSnmpExtensionInitEx) ( OUT AsnObjectIdentifier * supportedView);void main() HINSTANCE m_hInst; pSnmpExtensionInit m_Init; pSnmpExtensionInitEx m_InitEx; pSnmpExtensionQuery m_Q

27、uery; pSnmpExtensionTrap m_Trap; HANDLE PollForTrapEvent; AsnObjectIdentifier SupportedView; UINT OID_ifEntryType = 1, 3, 6, 1, 2, 1, 2, 2, 1, 3; UINT OID_ifEntryNum = 1, 3, 6, 1, 2, 1, 2, 1; UINT OID_ipMACEntAddr = 1, 3, 6, 1, 2, 1, 2, 2, 1, 6; AsnObjectIdentifier MIB_ifMACEntAddr = sizeof(OID_ipMA

28、CEntAddr) sizeof(UINT), OID_ipMACEntAddr ; AsnObjectIdentifier MIB_ifEntryType = sizeof(OID_ifEntryType) sizeof(UINT), OID_ifEntryType; AsnObjectIdentifier MIB_ifEntryNum = sizeof(OID_ifEntryNum) sizeof(UINT), OID_ifEntryNum; RFC1157VarBindList varBindList; RFC1157VarBind varBind2; AsnInteger errorS

29、tatus; AsnInteger errorIndex; AsnObjectIdentifier MIB_NULL = 0, 0; int ret; int dtmp; int i = 0, j = 0; bool found = false; char TempEthernet13; m_Init = NULL; m_InitEx = NULL; m_Query = NULL; m_Trap = NULL;/* 載入SNMP DLL并取得實(shí)例句柄 */ m_hInst = LoadLibrary("inetmib1.dll"); if (m_hInst < (HI

30、NSTANCE) HINSTANCE_ERROR) m_hInst = NULL; return; m_Init = (pSnmpExtensionInit) GetProcAddress(m_hInst, "SnmpExtensionInit"); m_InitEx = (pSnmpExtensionInitEx) GetProcAddress(m_hInst, "SnmpExtensionInitEx"); m_Query = (pSnmpExtensionQuery) GetProcAddress(m_hInst, "SnmpExtens

31、ionQuery"); m_Trap = (pSnmpExtensionTrap) GetProcAddress(m_hInst, "SnmpExtensionTrap"); m_Init(GetTickCount(), &PollForTrapEvent, &SupportedView);/* 初始化用來(lái)接收m_Query查詢結(jié)果的變量列表 */ varBindList.list = varBind; varB = MIB_NULL; varB = MIB_NULL;/* 在OID中拷貝并查找接口表中的入口數(shù)量

32、 */ varBindList.len = 1; /* Only retrieving one item */ SNMP_oidcpy(&varB, &MIB_ifEntryNum); ret = m_Query(ASN_RFC1157_GETNEXTREQUEST, &varBindList, &errorStatus, &errorIndex); printf("# of adapters in this system : %in", varBind0.value.asnValue.number); varBin

33、dList.len = 2;/* 拷貝OID的ifType接口類型 */ SNMP_oidcpy(&varB, &MIB_ifEntryType);/* 拷貝OID的ifPhysAddress物理地址 */ SNMP_oidcpy(&varB, &MIB_ifMACEntAddr);do /* 提交查詢,結(jié)果將載入 varBindList。 可以預(yù)料這個(gè)循環(huán)調(diào)用的次數(shù)和系統(tǒng)中的接口卡數(shù)量相等 */ ret = m_Query(ASN_RFC1157_GETNEXTREQUEST, &varBindList, &

34、errorStatus, &errorIndex); if (!ret) ret = 1; else /* 確認(rèn)正確的返回類型 */ ret = SNMP_oidncmp(&varB, &MIB_ifEntryType, MIB_ifEntryType.idLength); if (!ret) j+; dtmp = varBind0.value.asnValue.number; printf("Interface #%i type : %in", j, dtmp);/* Type 6 describes ethernet inter

35、faces */ if (dtmp = 6) /* 確認(rèn)我們已經(jīng)在此取得地址 */ ret = SNMP_oidncmp(&varB, &MIB_ifMACEntAddr, MIB_ifMACEntAddr.idLength); if (!ret) && (varBind1.value.asnValue.address.stream != NULL) if(varBind1.value.asnValue.address.stream0 = 0x44) && (varBind1.value.asnValue.address.str

36、eam1 = 0x45) && (varBind1.value.asnValue.address.stream2 = 0x53) && (varBind1.value.asnValue.address.stream3 = 0x54) && (varBind1.value.asnValue.address.stream4 = 0x00) /* 忽略所有的撥號(hào)網(wǎng)絡(luò)接口卡 */ printf("Interface #%i is a DUN adaptern", j); continue; if (varBind1.value.asnValue.address.stream0 = 0x00) && (varBind1.value.asnValue.address.stream1 = 0x00) && (varBind1.value.asnValue.address.stream2 = 0x00) && (varBind1.value.asnValue.ad

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論