//可把以下定义UNICODE的宏注释掉
#ifndef UNICODE
#define UNICODE
#endif
#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE
#endif
#endif
#include <WinSock2.h>
#include <IPHlpApi.h>
#include <stdlib.h>
#include <stdio.h>
#include <tchar.h>
#include <strsafe.h>
#pragma comment(lib, "IPHLPAPI.lib")
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))//可以用malloc替代,也可用VirtualAlloc或LocalAlloc
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))//可以用free替代,也可用VirtualFree或LocalFree
struct MyAdapterInfo//自定义的数据结构用于保存获取的网卡信息
{
TCHAR AdapterType[20];
TCHAR AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
TCHAR AdapterDesc[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];
TCHAR IpAddress[16];
TCHAR IpMask[16];
TCHAR GateWay[16];
int AdapterIndex;
TCHAR AdapterMac[18];
};
class AdaptersInfo
{
public:
AdaptersInfo()
{
padapterInfo = (IP_ADAPTER_INFO*)MALLOC(sizeof(IP_ADAPTER_INFO));
bufLen = sizeof(IP_ADAPTER_INFO);
temp = NULL;
}
~AdaptersInfo()
{
if(padapterInfo)
FREE(padapterInfo);
}
int GetAdapterCount()//获取本地计算机中网卡数量
{
PIP_ADAPTER_INFO t = (IP_ADAPTER_INFO*)MALLOC(sizeof(IP_ADAPTER_INFO));
PIP_ADAPTER_INFO temp = NULL;
ULONG tbufLen = 0;
int count = 0;
if(t == NULL)
{
return count;
}
if(GetAdaptersInfo(t, &tbufLen) == ERROR_BUFFER_OVERFLOW)
{
FREE(t);
t = (PIP_ADAPTER_INFO)MALLOC(tbufLen);
}
if(GetAdaptersInfo(t, &tbufLen) == NO_ERROR)
{
temp = t;
while(temp)
{
temp = temp->Next;
count++;
}
}
if(t != NULL)
FREE(t);
return count;
}
DWORD GetAdapterInfo(MyAdapterInfo *m_adp)
{
if(padapterInfo == NULL)
{
return ERROR_INSUFFICIENT_BUFFER;
}
if(GetAdaptersInfo(padapterInfo, &bufLen) == ERROR_BUFFER_OVERFLOW)
{
FREE(padapterInfo);
padapterInfo = (IP_ADAPTER_INFO *)MALLOC(bufLen);
if (padapterInfo == NULL)
{
return ERROR_INSUFFICIENT_BUFFER;
}
}
if((dwError = GetAdaptersInfo(padapterInfo, &bufLen)) == NO_ERROR)
{
int index = 0;
temp = padapterInfo;
while (temp)
{
switch(temp->Type)
{
case MIB_IF_TYPE_OTHER:
StringCchPrintf(m_adp[index].AdapterType, 20, TEXT("Other"));
break;
case MIB_IF_TYPE_ETHERNET:
StringCchPrintf(m_adp[index].AdapterType, 20, TEXT("Ethernet"));
break;
case MIB_IF_TYPE_TOKENRING:
StringCchPrintf(m_adp[index].AdapterType, 20, TEXT("Token Ring"));
break;
case MIB_IF_TYPE_FDDI:
printf("FDDI\n");
StringCchPrintf(m_adp[index].AdapterType, 20, TEXT("FDDI"));
break;
case MIB_IF_TYPE_PPP:
printf("PP\n");
StringCchPrintf(m_adp[index].AdapterType, 20, TEXT("PP"));
break;
case MIB_IF_TYPE_LOOPBACK:
StringCchPrintf(m_adp[index].AdapterType, 20, TEXT("Lookback"));
break;
case MIB_IF_TYPE_SLIP:
StringCchPrintf(m_adp[index].AdapterType, 20, TEXT("Slip"));
break;
default:
StringCchPrintf(m_adp[index].AdapterType, 20, TEXT("Unknown type %ld"), temp->Type);
break;
}
#ifdef UNICODE
MultiByteToWideChar(CP_ACP, 0, temp->Description, -1, m_adp[index].AdapterDesc, 132);
m_adp[index].AdapterIndex = temp->Index;
TCHAR format[] = TEXT("%.2x-%.2x-%.2x-%.2x-%.2x-%.2x");
StringCchPrintf(m_adp[index].AdapterMac, 18, format, temp->Address[0],temp->Address[1],temp->Address[2],temp->Address[3],temp->Address[4],temp->Address[5]);
MultiByteToWideChar(CP_ACP, 0, temp->AdapterName, -1, m_adp[index].AdapterName, 260);
MultiByteToWideChar(CP_ACP, 0, temp->GatewayList.IpAddress.String, -1, m_adp[index].GateWay, 16);
MultiByteToWideChar(CP_ACP, 0, temp->IpAddressList.IpAddress.String, -1, m_adp[index].IpAddress, 16);
MultiByteToWideChar(CP_ACP, 0, temp->IpAddressList.IpMask.String, -1, m_adp[index].IpMask, 16);
#else
strcpy_s(m_adp[index].AdapterDesc, 132, temp->Description);
m_adp[index].AdapterIndex = temp->Index;
char format[] = "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x";
sprintf_s(m_adp[index].AdapterMac, format, temp->Address[0],temp->Address[1],temp->Address[2],temp->Address[3],temp->Address[4],temp->Address[5]);
strcpy_s(m_adp[index].AdapterName, 260, temp->AdapterName);
strcpy_s(m_adp[index].GateWay, 16, temp->GatewayList.IpAddress.String);
strcpy_s(m_adp[index].IpAddress, 16, temp->IpAddressList.IpAddress.String);
strcpy_s(m_adp[index].IpMask, 16, temp->IpAddressList.IpMask.String);
#endif
temp = temp->Next;
index++;
}
}
return dwError;
}
private:
PIP_ADAPTER_INFO padapterInfo, temp;
ULONG bufLen;
DWORD dwError;
};
int _tmain(int argc, TCHAR **argv)
{
MyAdapterInfo *madp;
AdaptersInfo adp;
int count = adp.GetAdapterCount();//动态获取计算机中网卡数量
madp = (MyAdapterInfo*)malloc(sizeof(MyAdapterInfo) * count);
adp.GetAdapterInfo(madp);//我偷懒了,可以打断点察看
.......
free(madp);
return 0;
}
#include "stdafx.h"
#include <iostream>
using namespace std;
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
#include <Nb30.h>
#pragma comment(lib, "Netapi32.lib")
struct ASTAT //copy头文件中定义
{
ADAPTER_STATUS adapt;
NAME_BUFFER NameBuf[30];
};
//NETBIOS(网络基本输入输出系统)
void AboutNetbios()
{
NCB ncb;
UCHAR uRetCode;
int num=0;
LANA_ENUM lana_enum;
memset(&ncb, 0, sizeof(ncb));
ncb.ncb_command = NCBENUM;
ncb.ncb_buffer = (unsigned char*)&lana_enum;
ncb.ncb_length = sizeof(lana_enum);
//向网卡发送NCBENUM命令,以获取当前机器的网卡信息,如有多少个网卡
//每张网卡的编号等
uRetCode = Netbios(&ncb);
if (uRetCode == 0)
{
num = lana_enum.length;
//对每一张网卡,以其网卡编号为输入编号,获取其MAC地址
for (int i = 0; i< num; i++)
{
ASTAT Adapter;
/*if(GetAddressByIndex(lana_enum.lana[i],Adapter) == 0)
{
pMacAddr[i].b1 = Adapter.adapt.adapter_address[0];
pMacAddr[i].b2 = Adapter.adapt.adapter_address[1];
pMacAddr[i].b3 = Adapter.adapt.adapter_address[2];
pMacAddr[i].b4 = Adapter.adapt.adapter_address[3];
pMacAddr[i].b5 = Adapter.adapt.adapter_address[4];
pMacAddr[i].b6 = Adapter.adapt.adapter_address[5];
} */
memset(&ncb,0,sizeof(ncb)); //使用之前要使ncb结构清0
ncb.ncb_command=NCBRESET; //对选定的网卡发送命令,以便进行初始化
ncb.ncb_lana_num=lana_enum.lana[i];
uRetCode=Netbios(&ncb); //
memset(&ncb,0,sizeof(ncb));
ncb.ncb_command=NCBASTAT;
ncb.ncb_lana_num=lana_enum.lana[i];
strcpy((char*)ncb.ncb_callname,"*");
ncb.ncb_buffer=(UCHAR*)&Adapter;
ncb.ncb_length=sizeof(Adapter); //接着发送命令获取网卡信息
uRetCode=Netbios(&ncb);
if(uRetCode==0)
{
char mac[32], * lpmac;
sprintf(mac,"%02X-%02X-%02X-%02X-%02X-%02X", 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]);
lpmac=mac;
cout<<lpmac<<endl;
}
else
{
cout<<"exceptions:"<<(int)uRetCode<<endl;
}
}
}
}
NETBIOS返回值及含义
NETBIOS返回值
00h : 成功地完成,成功返回 或名字已被撤消而不能再使用 | #define NRC_GOODRET 0x00 Good return - also returned when ASYNCH request accepted #define NRC_BUFLEN 0x01 Illegal buffer length #define NRC_ILLCMD 0x03 Illegal command #define NRC_CMDTMO 0x05 Command timed out #define NRC_INCOMP 0x06 Message incomplete, issue another command #define NRC_BADDR 0x07 Illegal buffer address #define NRC_SNUMOUT 0x08 Session number out of range #define NRC_NORES 0x09 No resource available #define NRC_SCLOSED 0x0a Session closed #define NRC_CMDCAN 0x0b Command canceled #define NRC_DUPNAME 0x0d Duplicate name #define NRC_NAMTFUL 0x0e Name table full #define NRC_ACTSES 0x0f No deletions, name has active sessions #define NRC_LOCTFUL 0x11 Local session table full #define NRC_REMTFUL 0x12 Remote session table full #define NRC_ILLNN 0x13 Illegal name number #define NRC_NOCALL 0x14 No callname #define NRC_NOWILD 0x15 Cannot put * in NCB_NAME #define NRC_INUSE 0x16 Name in use on remote adapter #define NRC_NAMERR 0x17 Name deleted #define NRC_SABORT 0x18 Session ended abnormally #define NRC_NAMCONF 0x19 Name conflict detected #define NRC_IFBUSY 0x21 Interface busy, IRET before retrying #define NRC_TOOMANY 0x22 Too many commands outstanding, retry later #define NRC_BRIDGE 0x23 ncb_lana_num field invalid #define NRC_CANOCCR 0x24 Command completed while cancel occurring #define NRC_CANCEL 0x26 Command not valid to cancel #define NRC_DUPENV 0x30 Name defined by anther local process #define NRC_ENVNOTDEF 0x34 Environment undefined. RESET required #define NRC_OSRESNOTAV 0x35 Required OS resources exhausted #define NRC_MAXAPPS 0x36 Max number of applications exceeded #define NRC_NOSAPS 0x37 No saps available for NetBIOS #define NRC_NORESOURCES 0x38 Requested resources are not available #define NRC_INVADDRESS 0x39 Invalid NCB address or length > segment #define NRC_INVDDID 0x3B Invalid NCB DDID #define NRC_LOCKFAIL 0x3C Lock of user area failed #define NRC_OPENERR 0x3f NetBIOS not loaded #define NRC_SYSTEM 0x40 System error #define NRC_PENDING 0xff Asynchronous command is not yet finished |
Reference:关于NetBios的简单应 用点击打开链接
如何获取本机MAC地址 和 IP 点击打开链接