获取网卡地址

本文介绍了NETBIOS的返回值及其含义,并提供了获取本机MAC和IP地址的方法,包括相关参考资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//可把以下定义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 : 成功地完成,成功返回
01h : 无效的缓冲区
03h : 无效的命令
05h : 命令超时
06h : 不完整地接收消息
07h : 本地No-Ack命令失败
08h : 无效的本地会话
09h : 没有可使用的资源
0Ah : 会话已关闭
0Bh : 命令已撤消
0Dh : 本地NetBIOS命名表中名字重复
0Eh : NetBIOS命名表满
0Fh : 名字具有活动会话,现被撤消登记
11h : NetBIOS 本地会话表满了
12h : 没有挂起的Listen 命令,所有拒绝断开会话
13h : 非法名字编号
14h : 不能找到被调用名字或无回答
15h : 找不到命令,或不能把*号或00h指定ncb_name的首字节,

或名字已被撤消而不能再使用
17h : 名字已被删除18h : 会话非正常结束
19h : 检测到名字冲突
1Ah : 不兼容的远程设备
21h : 接口忙
22h : 挂起的命令太多
23h : 在ncb_lana_num域中无效的编号
24h : 产生取消时,命令已完成
25h : 字节组名命令指定了保留名字
26h : 命令不能被撤消
30h : 被另一个进程定义了名字
34h : NetBIOS环境未被定义
35h : 所用的操作系统资源用尽
36h : 超出最大应用个数
37h : NetBIOS无可以使用的SAP
38h : 无可以使用的请求资源
40h : 系统错误
41h : 检测到远程适配器的热载波
42h : 检测到本地适配器的热载波
43h : 未检测到载波
4Eh : 状态位12、14、或15被置位的时间超过 1 min
4Fh : 状态位8--11中的一个或多个被置位
50h-F6h: 适配器发生故障
F7h : 隐式DIR-INITIALIZE错误
F8h : 隐式DIR-OPEN-ADAPTER 错误
F9h : IBM LAN支持程序内部错误
Fah : 适配器检查
FBh : NetBIOS 程序未被装入PC
FCh : DIR-OPEN-ADAPTER 或 DIR-OPEN-SAP失败
FDh : 不期望关闭适配器
FFh : 命令挂起状态

#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   点击打开链接

一分钟学会获取本机网卡物理地址(MAC)

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShineSpark

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值