历史上的今天
返回首页

历史上的今天

今天是:2025年03月22日(星期六)

2021年03月22日 | 基于W5500的NetBIOS应用实例

2021-03-22 来源:eefocus

一 实例背景


最近一个做智能家居的朋友面临这样的一个烦恼,他想让用户通过智能手机在家里方便地控制家居设备,又想让用户免除下载安装App的麻烦,通过浏览器直接打开设备内嵌的网页便可实现控制。但是设备的IP地址都是通过家里的路由器自动获得的,设备上又没有屏幕来显示其IP地址。问我有没有办法不输入IP地址来实现浏览器访问该设备网页的办法,就是类似DNS之类,但是无需连外网,只在家庭网络内能访问即可。


这使我想起一个古老的协议,NetBIOS(Network Basic Input/Output System)。这个在上世纪80年代由IBM开发的协议,主要用于数十台左右计算机组成的小型局域网,该协议的主要用途之一就是把计算机名称解析为相应IP地址。如果每个设备有一个固定名字,在实现了NetBIOS的前提下,用户在浏览器里输入该设备的名字,然后通过NetBIOS解析,便可实现访问该设备网页的这个功能了。而且NetBIOS占用系统资源少,在单片机上运行不成问题。于是推荐这个朋友在他的设备上实现了NetBIOS协议,解决了他的烦恼。


除了智能家居,在当下物联网时代,想必还有其他应用也会遇到类似问题,就拿手头的WIZnet-W5500评估板实现了一下NetBIOS,希望能对做网络设备开发的朋友有所帮助。在用W5500实现之前,我们还是先在PC上看一下NetBIOS到底是一个什么东西。


二NetBIOS协议


我们知道在DOS命令下可以通过PING主机名获得另外一台电脑的IP地址,实际上就是通过NETBIOS进行的。在Windows操作系统中,默认情况下在安装TCP/IP协议后会自动安装NetBIOS。查看方法如下:本地连接属性的中“高级TCP/IP设置”窗口中选择“WINS”选项卡,在“NetBIOS设置”区域中就可以设置相应的NetBIOS,如图1:

Ping主机名的第一个数据包就是NBNS(NetBIOS Name Server),协议包,它是TCP/IP上的NetBIOS (NetBT)协议族的一部分,它在基于NetBIOS名称访问的网络上提供主机名和地址映射方法。NBNS是动态DNS的一种,Microsoft的NBNS实现称为WINS。NetBIOS的报文类型较多、结构复杂,不同的网络环境及不同的用途中,会使用不同报文,可用端口进行区分,WINS协议中,NetBIOS名字报文、数据报报文及会话报文分别使用TCP 137、138和139端口。


NetBIOS数据报有很多不同格式,主要取决于服务和信息类型,以及用以传送NetBIOS数据报的传输协议。NetBIOS协议架构可见图2,其中包含三种基本服务:NAME、SESSION和DATAGRAM,其中NAME所用协议就是NBNS协议。



图2:NetBIOS协议架构

下面看一下WINS协议使用的报文NETBIOS的名字报文(NAME)的总体格式如表1:


表1 NetBIOS名字报文格式


事物ID(2bytes) 通用标志(2bytes) 问题记录个数(2bytes) 回答记录个数(2bytes) 权威记录个数(2bytes) 附加记录个数(2bytes) 问题记录(若干字节) 回答记录(若干字节) 权威记录(若干字节) 附加记录(若干字节)


报文的前12字节总称为NETBIOS名字报文的首部,通过首部我们可以判断出是否为名字查询的报文。


NETBIOS名字报文中最常见的是携带问题记录的报文,问题记录的格式如表2:


表2 NetBIOS名字报文中问题记录格式


问题名称(若干字节)


问题类型(2 bytes)


问题类别(2bytes)


通过携带问题记录的报文,我们可以得到要查询的名字字符,如果和本机名相符,就发送报文响应,响应中带有IP地址,发送广播的主机就会得到该IP地址。


三W5500EVB实现NETBIOS名字报文解析


了解了NETBIOS协议之后,下面就让我们通过W5500EVB做一个嵌入NetBIOS的简单实验。


实验目的:通过在DOS下ping该设备名“WIZNRTW5500”,可以得到开发板的IP地址。 硬件环境 单片机:STM32F103RC,256K字节Flash,48K字节SRAM,2K字节EEPROM 以太网控制器:W5500,SPI接口与单片机相连 电源:USB供电 硬件外设:板载LED 开发工具: Keil 测试软件:串口调试助手,网络调试助手看代码之前,我们还是先来了解一下整个的程序流程,如图3所示整个程序采用查询方式,通过DHCP子程序成功获取IP后可执行NBNS服务。同时W5500EVB设置成HTTP Server,可以接收,并处理TCP Client发来的数据

图3:主程序流程图


本文主要讨论如何在单片机上实现NETBIOS名字解析服务,DHCP和TCP Server相关部分子程序在此不再详细介绍,根据NETBIOS名字解析服务子程序流程图(如图4示),我们可以得知当查询到137端口收到网络的UDP数据包时,读取数据包并进行判断是否为NETBIOS名字报文,如果是就将解析出的名字与本机名比较,如果一致就回复报文。


图4:NBNS程序流程图


在此贴出NETBIOS部分代码,要获取完整代码,请到


在此贴出NETBIOS部分代码,要获取完整代码,请到http://pan.baidu.com/s/1nt9MQKh上进行下载。


void do_netbios(void)


{


unsigned char state;


unsigned int len;


1state = getSn_SR(NETBIOS_SOCK);


switch(state)


{


case SOCK_UDP:


2if((len=getSn_RX_RSR(NETBIOS_SOCK))>0)


{


unsigned char rem_ip_addr[4];


uint16 rem_udp_port;


3char netbios_name[NETBIOS_NAME_LEN+1];


4NETBIOS_HDR* netbios_hdr;


5NETBIOS_NAME_HDR* netbios_name_hdr;


6len=recvfrom(NETBIOS_SOCK,(unsignedchar*)&netbios_rx_buf,len,rem_ip_addr,&rem_udp_port);


printf(“rem_ip_addr=%d.%d.%d.%d:%drn”,rem_ip_addr[0],rem_ip_addr[1],rem_ip_addr[2],rem_ip_addr[3],rem_udp_port);


7netbios_hdr = (NETBIOS_HDR*)netbios_rx_buf;


8netbios_name_hdr = (NETBIOS_NAME_HDR*)(netbios_hdr+1);


/* if the packet is a NetBIOS name query question */


9if(((netbios_hdr->flags& ntohs(NETB_HFLAG_OPCODE)) == ntohs(NETB_HFLAG_OPCODE_NAME_QUERY)) &&


((netbios_hdr->flags & ntohs(NETB_HFLAG_RESPONSE)) == 0) &&


(netbios_hdr->questions == ntohs(1)))


{


printf(“netbios name query questionrn”);


/* decode the NetBIOS name */


10netbios_name_decoding( (char*)(netbios_name_hdr->encname), netbios_name, sizeof(netbios_name));


printf(“name is %srn”,netbios_name);


/* if the packet is for us */


11if (strcmp(netbios_name, NETBIOS_W5500_NAME) == 0)


{


uint8 ip_addr[4];


NETBIOS_RESP *resp = (NETBIOS_RESP*)netbios_tx_buf;


/* prepare NetBIOS header response */


12resp->resp_hdr.trans_id= netbios_hdr->trans_id;


resp->resp_hdr.flags= htons(NETB_HFLAG_RESPONSE |NETB_HFLAG_OPCODE_NAME_QUERY |


NETB_HFLAG_AUTHORATIVE |


NETB_HFLAG_RECURS_DESIRED);


resp->resp_hdr.questions= 0;


resp->resp_hdr.answerRRs= htons(1);


resp->resp_hdr.authorityRRs= 0;


resp->resp_hdr.additionalRRs = 0;


/* prepare NetBIOS header datas */


memcpy( resp->resp_name.encname, netbios_name_hdr->encname, sizeof(netbios_name_hdr->encname));


resp->resp_name.nametype= netbios_name_hdr->nametype;


resp->resp_name.type= netbios_name_hdr->type;


resp->resp_name.cls= netbios_name_hdr->cls;


resp->resp_name.ttl= htonl(NETBIOS_NAME_TTL);


resp->resp_name.datalen= htons(sizeof(resp->resp_name.flags)+sizeof(resp->resp_name.addr));


resp->resp_name.flags= htons(NETB_NFLAG_NODETYPE_BNODE);


getSIPR(ip_addr);


memcpy(resp->resp_name.addr,ip_addr,4);


/* send the NetBIOS response */


13sendto(NETBIOS_SOCK, (unsigned char*)resp, sizeof(NETBIOS_RESP), rem_ip_addr, rem_udp_port);


printf(“send responsern”);


}


}


}


break;


14case SOCK_CLOSED:


close(NETBIOS_SOCK);


socket(NETBIOS_SOCK,Sn_MR_UDP,NETBIOS_PORT,0);


break;


default:


break;


}


}


主要代码解释:

第1、2段程序功能为通过SPI接口读取NBNS Socket寄存器状态,如果检测建立了UDP连接,并且收到数据则进行NBNS服务。第3段定义了NetBIOS name缓存区,Netbios name长度为16。第4、5段定义了NetBIOS包头和其name部分结构体变量。第6段为读取137端口的UDP数据)netbios_rx_buf。接下来NBNS核心部分:


第7、8两段将接受缓存区数据对定义的包头进行赋值,第9,10段,判断数据NetBIOS包头是否为名字查询,如果是名字查询则进行名字解析。第11行进行NetBIOS名字进一步比较。比较一致后,第12段程序准备回复NetBIOS包头和内容。第13段,发送NetBIOS回复响应。第14段为检测到NBNS Socket为SOCK_CLOSED,则打开137端口的UDP Socket。


四实验测试

试验中,我们通过W5500EVB对NetBIOS的解析,并用浏览器直接访问设备名称,来实现对设备的远程访问,以达实验目的。下面就来看一下实验测试全过程。

首先,打开串口调试助手,运行DHCP相关程序。可看到图5中所示,W5500EVB成功通过DHCP获得可用IP地址。


2. 在DOS下,ping W5500EVB设备名:WIZNET5500,可看到如图6中,获取设备IP地址为:192.168.1.100。

3. 运行NetBIOS解析程序,在串口调试助手中看到解析过程,如图7所示:

4. 最后,我们在浏览器中输入要访问的设备名称:wiznet5500,可以看到顺利访问到设备中的内置网页,浏览到设备的配置信息。NetBIOS解析成功!如图8所示:

推荐阅读

史海拾趣

BREL International Components公司的发展小趣事

品质是BREL International Components公司发展的基石。公司从原材料采购到生产流程控制,再到产品检测,都严格遵循国际质量标准。BREL还建立了完善的品质管理体系,通过定期的质量检查和持续改进,确保每一件产品都达到客户的要求。正是这种对品质的执着追求,让BREL的产品在市场上赢得了良好的口碑,品牌价值不断提升。

DAQ Electronics LLC公司的发展小趣事

DAQ Electronics LLC公司成立于XX年,由一群热衷于数据采集技术的工程师创立。当时,市场上对于高精度、高效率的数据采集设备需求日益增长,但现有产品往往无法满足。创始人们凭借对技术的深刻理解和敏锐的市场洞察力,决定自主研发数据采集硬件,并成立了DAQ Electronics LLC公司。他们凭借有限的资金和资源,开始了艰苦的创业之旅。

Densitron公司的发展小趣事

为了扩大市场份额,Densitron公司制定了一系列市场拓展策略。公司首先分析了市场需求和竞争态势,确定了目标市场。然后,通过加强品牌宣传、优化销售渠道、提高客户服务质量等手段,不断提升品牌知名度和客户满意度。此外,公司还积极开展国际合作,与全球知名电子企业建立了紧密的合作关系,共同开拓市场。这些策略的实施,使得Densitron公司的市场份额逐年上升,成为行业内的领军企业。

Andon Electronics公司的发展小趣事

为了扩大市场份额,Densitron公司制定了一系列市场拓展策略。公司首先分析了市场需求和竞争态势,确定了目标市场。然后,通过加强品牌宣传、优化销售渠道、提高客户服务质量等手段,不断提升品牌知名度和客户满意度。此外,公司还积极开展国际合作,与全球知名电子企业建立了紧密的合作关系,共同开拓市场。这些策略的实施,使得Densitron公司的市场份额逐年上升,成为行业内的领军企业。

CONEXANT公司的发展小趣事

2017年,电子行业迎来了一场引人瞩目的收购案。新思科技(Synaptics),一家在人机界面交互开发解决方案领域具有领导地位的公司,宣布以3.95亿美元现金和726,666只普通股收购科胜讯系统公司(Conexant Systems)。这一收购行动不仅增强了Synaptics在智能家居领域的语音和音频处理解决方案的能力,也标志着Conexant正式成为Synaptics大家庭的一员。通过此次收购,两家公司实现了技术资源和市场优势的互补,共同开启了新的发展篇章。

台湾肯尼威(CANNYWELL)公司的发展小趣事

台湾肯尼威公司成立于1986年,其创始人李明(化名)是一位对电子技术充满热情的工程师。在当时的台湾,电子制造业正处于蓬勃发展的阶段。李明看到电源滤波器在电子设备中的重要性,于是决定专注于这一领域的研发和生产。他带领一支小团队,经过无数次的试验和改进,终于成功研发出CW系列单相电源滤波器,为公司的发展奠定了坚实的技术基础。

问答坊 | AI 解惑

问下路过的高手哈,DXP中编整合库,原理图和PCB怎么对上的

我想了两天没整,明白就是如果原理图多一张或PCB多一张怎么办…

查看全部问答>

怎么样在这里发帖时添加附件啊

我想上传东西但是不知道怎么添加附件…

查看全部问答>

国家IP核标准符合性评测与认证指南

目录 一、 IP 核评测与认证流程......................................................................................................3 二、 IP 核评测与认证类别....................................................................... ...…

查看全部问答>

gooogleman大侠,求助!

就32分了! 请问大侠当时用9650采集图像时采集到的数据格式是什么(rgb,ycbcr?),当时大侠把它转化成图片了吗?是什么格式的?bmp,jpeg? 是怎么做的?谢谢了!…

查看全部问答>

英文系统下的FAT盘符建立中文文件的问题

默认语言为中文的系统,已添加了中文语言的支持,在FAT盘符中建立相同文件名长度的文件就会报已有相同文件名的文件,并无法创建。 比如:已建立一个文件夹“已有文件”,再建立“新建文件”,同为四个字符,在建立“新建文件”就会报错,无法创建 ...…

查看全部问答>

图形绘制

请依照如下要求设计 1、设计显示图形:自己的中文名字; 2、设计显示程序; 3、调试通过。 …

查看全部问答>

8bit轉32bit的疑問

一個32位的單片機器,是不是說 int32_t c, b, a; c = a + b 和unsigned char c, b, a; c = b + a; 一樣快? 是不是在程序中應該儘量使用32 bit 整數類型。…

查看全部问答>

有关于FPGA方面的吗?分享分享

本帖最后由 paulhyde 于 2014-9-15 09:06 编辑 如题  …

查看全部问答>

嵌入式Linux系统开发模式

嵌入式系统通常为一个资源受限的系统。直接在嵌入式系统的硬件平台上编写软件比较困难,有时甚至是不可能的。下面由卓跃教育为您介绍嵌入式系统开发模式。    第一步,建立嵌入式Linux交叉开发环境。目前,常用的交叉开发环境主要有开放和商业 ...…

查看全部问答>

DK-LM3S9B96开发板是什么操作系统

DK-LM3S9B96开发板的软件是什么操作系统?…

查看全部问答>