VC编程获取网卡物理地址MAC的几种方法

2012-03-04 17:52:57|?次阅读|上传:wustguangh【已有?条评论】发表评论

关键词:C/C++, 操作系统, 网络通信|来源:唯设编程网

进行网络底层编程时经常需要获取网卡的MAC地址,这是一个大家都无法回避的问题,也是一个比较棘手的问题。就我所知道的方法有如下几种:

1 使用NetBois命令。

  在网上搜索,可以发现这是最常见的方法。不过有点复杂,使用起来也有限制,如果机器禁用了NetBois,那么这种方法就行不通了。
 

2 使用Winpcap Packet.dll中的PacketGetNetType函数。

  熟悉Winpcap的人都知道,Winpcap常规及推荐使用的是wpcap.dll,winpcap并没有提供对Packet.dll的API支持,在 开发文档中没有关于Packet.dll的文档。因此使用这种方法不规范也比较麻烦(需要安装winpcap驱动)。

3 使用ipconfig /all命令获取,并写入管道,我们的程序再从管道中读取 "Physical Address. . . . . . . . . :"

  这是我在CSDN上看到的一种方法。很巧妙,不过也比较麻烦,特别是有多个网卡时就更不实用了。
 

4 使用GetAdaptersAddresses/GetAdaptersInfo函数。

  最简单的方法。但是在MSDN6.0中查询不到该函数。该函数是在Windows 2000以上的系统中才有的函数,VC++6.0默认所带的SDK是win98的,所以要使用这个函数,就需要安装相应的SDK,我的系统是"XP",因此就要安装“XPSP2 PSDK”。系统相关的SDK可以到微软官方下载。

下面是使用GetAdaptersAddresses获取网卡MAC的示例,该程序在VS2005+win7旗舰版测试通过,但是只能够获取网卡MAC地址,无法获取IP,NetMask,NetGate等信息:

// 获取网卡地址
CStringArray& CSysInfo::getMAC(void)
{
    macAddrArray.RemoveAll();
    //////////////////////////////////////////////////////
    PIP_ADAPTER_ADDRESSES pAddresses;
    pAddresses=(IP_ADAPTER_ADDRESSES*)GlobalAlloc(GMEM_ZEROINIT,sizeof(IP_ADAPTER_ADDRESSES));
    ULONG outBufLen=0;
    DWORD dwRetVal=0;  
    //Make an initial call to GetAdapters Addresses to get the
    //size needed into the outBufLen variable
    if(GetAdaptersAddresses(AF_INET,
        0,
        NULL,
        pAddresses,
        &outBufLen)==ERROR_BUFFER_OVERFLOW){
            GlobalFree(pAddresses);
            pAddresses=(IP_ADAPTER_ADDRESSES*)GlobalAlloc(GMEM_ZEROINIT,outBufLen);
    }
    //Make a second call to GetAdapters Addresses to get the
    //actual data we want
    if((dwRetVal=GetAdaptersAddresses(AF_INET,
        0,
        NULL,
        pAddresses,
        &outBufLen))==NO_ERROR){
            //if successful,output some information from the data we received
            while(pAddresses){  //获取所有网卡地址
                CString macAddr;    //网卡地址
                CString strTmp;     //临时内容
                for(DWORD i=0;i<pAddresses->PhysicalAddressLength;i++){
                    strTmp.Format(_T("%02x"),pAddresses->PhysicalAddress[i]);
                    macAddr+=strTmp;
                    if(i<pAddresses->PhysicalAddressLength-1)
                        macAddr+=_T("-");                    
                }
                //加入链表中
                macAddrArray.Add(macAddr);
                //下一个
                pAddresses=pAddresses->Next;
            }
    }else{
        ::MessageBox(NULL,
            _T("Call to GetAdaptersAddresses failed."),
            _T("ERROR"),
            MB_OK);
        LPVOID lpMsgBuf;
        if(FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER|
            FORMAT_MESSAGE_FROM_SYSTEM|
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            dwRetVal,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),  //Default language
            (LPTSTR)&lpMsgBuf,
            0,
            NULL)){
                CString strTmp;
                strTmp.Format(_T("Error:%s"),lpMsgBuf);
                ::MessageBox(NULL,strTmp,_T("ERROR"),MB_OK);
        }
        LocalFree(lpMsgBuf);
        macAddrArray.RemoveAll();
    }
    GlobalFree(pAddresses);
    return macAddrArray;
}
<123>
发表评论0条 】
网友评论(共?条评论)..
VC编程获取网卡物理地址MAC的几种方法