今天介绍一个通过NetBIOS获取本机的mac地址。
什么是NetBOIS
NETBIOS协议是由IBM公司开发,主要用于数十台计算机的小型局域网。该协议是一种在局域网上的程序可以使用的应用程序编程接口(API),为程序提供了请求低级服务的统一的命令集,作用是为了给局域网提供网络以及其他特殊功能。系统可以利用WINS服务、广播及Lmhost文件等多种模式将NetBIOS名-——特指基于NETBIOS协议获得计算机名称——解析为相应IP地址,实现信息通讯,所以在局域网内部使用NetBIOS协议可以方便地实现消息通信及资源的共享。因为它占用系统资源少、传输效率高,所以几乎所有的局域网都是在NetBIOS协议的基础上工作的。NetBIOS是Network Basic Input/Output System的简称,一般指用于局域网通信的一套API
NetBIOS is an acronym for Network Basic Input/Output System. It provides services related to the session layer of the OSI model allowing applications on separate computers to communicate over a local area network. As strictly an API, NetBIOS is not a networking protocol. Older operating systems[clarification needed] ran NetBIOS over IEEE 802.2 and IPX/SPX using the NetBIOS Frames (NBF) and NetBIOS over IPX/SPX (NBX) protocols, respectively. In modern networks, NetBIOS normally runs over TCP/IP via the NetBIOS over TCP/IP (NBT) protocol. This results in each computer in the network having both an IP address and a NetBIOS name corresponding to a (possibly different) host name.
NCB结构体
功能:
The NCB structure represents a network control block. It contains information about the command to perform, an optional post routine, an optional event handle, and a pointer to a buffer that is used for messages or other data. A pointer to this structure is passed to the Netbios function.
原型:
“`cpp
typedef struct _NCB {
UCHAR ncb_command;
UCHAR ncb_retcode;
UCHAR ncb_lsn;
UCHAR ncb_num;
PUCHAR ncb_buffer;
WORD ncb_length;
UCHAR ncb_callname[NCBNAMSZ];
UCHAR ncb_name[NCBNAMSZ];
UCHAR ncb_rto;
UCHAR ncb_sto;
void (CALLBACK *ncb_post)( struct *NCB);
UCHAR ncb_lana_num;
UCHAR ncb_cmd_cplt;
UCHAR ncb_reserve[X];
HANDLE ncb_event;
} NCB, *PNCB;
**LANA_ENUM结构体**
功能:
The LANA_ENUM structure contains the numbers for the current LAN adapters.
原型:
```cpp
typedef struct _LANA_ENUM {
UCHAR length;
UCHAR lana[MAX_LANA];
} LANA_ENUM, *PLANA_ENUM;
<div class="se-preview-section-delimiter"></div>
* Netbios函数*
功能:
The Netbios function interprets and executes the specified network control block (NCB).
原型:
“`cpp
UCHAR Netbios(
PNCB pcnb
);
** 注意:** Netbios is not supported on Windows Vista, Windows Server 2008, and subsequent versions of the operating system **别忘了引入lib:** <div class="se-preview-section-delimiter"></div> ```cpp #pragma comment(lib, "netapi32.lib")
最后上代码:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <strstream>
#include <string>
using namespace std;
#pragma comment(lib, "netapi32.lib")
bool GetMacAddressByNetBIOS(int nAdapterNum, string & sMAC)
{
// Reset the LAN adapter so that we can begin querying it
NCB Ncb;
memset(&Ncb, 0, sizeof(Ncb));
Ncb.ncb_command = NCBRESET;
Ncb.ncb_lana_num = nAdapterNum;
if (Netbios(&Ncb) != NRC_GOODRET) {
char acTemp[80];
ostrstream outs(acTemp, sizeof(acTemp));
outs << "error " << Ncb.ncb_retcode << " on reset" << ends;
sMAC = acTemp;
return false;
}
// Prepare to get the adapter status block
memset(&Ncb, 0, sizeof(Ncb));
Ncb.ncb_command = NCBASTAT;
Ncb.ncb_lana_num = nAdapterNum;
strcpy((char *)Ncb.ncb_callname, "*");
struct ASTAT {
ADAPTER_STATUS adapt;
NAME_BUFFER NameBuff[30];
} Adapter;
memset(&Adapter, 0, sizeof(Adapter));
Ncb.ncb_buffer = (unsigned char *)&Adapter;
Ncb.ncb_length = sizeof(Adapter);
// Get the adapter's info and, if this works, return it in standard,
// colon-delimited form.
if (Netbios(&Ncb) == 0) {
char acMAC[18];
sprintf(acMAC, "%02X:%02X:%02X:%02X:%02X:%02X",
int(Adapter.adapt.adapter_address[0]),
int(Adapter.adapt.adapter_address[1]),
int(Adapter.adapt.adapter_address[2]),
int(Adapter.adapt.adapter_address[3]),
int(Adapter.adapt.adapter_address[4]),
int(Adapter.adapt.adapter_address[5]));
sMAC = acMAC;
return true;
}
else {
char acTemp[80];
ostrstream outs(acTemp, sizeof(acTemp));
outs << "error " << Ncb.ncb_retcode << " on ASTAT" << ends;
sMAC = acTemp;
return false;
}
}
int main()
{
// Get adapter list
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);
// Get all of the local ethernet addresses
string sMAC;
for (int i = 0; i < AdapterList.length; ++i) {
if (GetMacAddressByNetBIOS(AdapterList.lana[i], sMAC)) {
cout << "Adapter " << int(AdapterList.lana[i]) <<
"'s MAC is " << sMAC << endl;
}
else {
cerr << "Failed to get MAC address! Do you" << endl;
cerr << "have the NetBIOS protocol installed?" << endl;
break;
}
}
return 0;
}
缺点:
1 必须安装了NetBIOS
2 必须进行额外的工作筛选想要的mac地址