NetBIOS规范
Gavin Winston 1998-2007
1. Overview 概述
1.1 Names名称
为了网络站的通讯,每个站都赋予了一个或多个名称。这些名称是仅包含字母和数字的,长度为16字节,并且最后一位为00h(ASCIIZ格式)。名称分为两种:
l Unique names 唯一名称 - 这些名称仅用在整个网络中的一台。如果有人想使用唯一名称,网络首先检查请求的名称是否正被使用。唯一名称的一个好例子如,站点使用用于连接并与服务器通信的名称。通常唯一名称就是站名。
l Group names 组名称– 这些名称可以用于任意多的站点。当你尝试添加一个组名,这个组名不能作为唯一名称正被使用,但是可以作为组名使用任意多次。一个好例子如聊天程序。每个站点使用唯一名称来发送信息,这些信息发送到一个全局组名,这样所有站点都可以看到信息。(Note:目前我正在写一个NetBIOS/IPX聊天程序,接下来的几个月内我就会发布为共享软件,请在Free Software节等候)。
1.2 Communication通信
每个站点使用多个名称与网络内其他站点通信。使用NetBIOS用两种类型的通信方式:无连接(connectionless)和有连接(connection-oriented)的。两种类型的细节如下:
1.2.1 Connectionless无连接
站点请求数据使用数据报(datagram)发送。其他站点不断地检查网络上的数据报以确认是否发给自己。如果是,就接收信息。但是,没有握手(handshaking),或者确认(acknowledge)过程,因此不能保证网络中的所有站点都能像预想的那样收到信息。然而,根据我的经验,信息每数千次中才有一次能被接收,这可能与其他网络有所不同。
数据报有两种方式发送到其他站点:
l Specific特定– 发送数据报到特定名称(名称可能为一个唯一的组名)- 如果那个特定名称上的软件等待信息到来,这样就可以接收。
l Broadcast广播– 信息发送到所有站点– 如果软件等待广播数据报的到来,这样可以被接收。
注意所有的信息仅当你在站点编程来接收数据报的情况下才能被接收。否则就会被忽略。下面的规范允许你请求数据报仅被特定名称接收。网络软件可以在后台检测每个过往的数据报,如果需要就接收。
1.2.2 Connection-Oriented有连接
两个名称间首先建立连接。这个连接被叫做会话(session),且可能不是在两个站点之间。事实上,可以在任意两个名称之间,包括同一个站点上的两个名称。数据通过会话来传递,而不是通过PPP线来拨通ISP。这种方式是可信的,尽管编程有点困难。信息如果没有发送成功,就会返回一个错误给程序,这样要么意识到传输,要么接收错误。
1.3 Interface接口
接口通过中断5Ch来访问– 中断调用时,ES:BX指针就指向一个64字节的数据结构,称作网路控制块(Network Control Block, NCB)。它包含需要的数据,如名称,命令号(command codes),缓冲区指针等。NCB直到命令执行结束才能更改,这样当一个命令正在执行时,NCB就不用用于其他命令。然而,命令执行完毕,NCB就可以被修改,以及被其他命令重用。
共有两种不同的方法使用NetBIOS命令– 异步(asynchronous)和同步(synchronous)。
1.3.1 Snchronouscommands同步命令
此命令的初始化是通过设置NCB,调用终端5Ch,ES:BX指向NCB。控制仅返回到你的程序,当命令执行完毕(或超时)。命令字节位7设为0表明是同步命令。控制返回时,NCB返回码(return_code)域表示初始化或完成状态。这个域的值也返回到AL。使用这中命令的例子如,添加通信名称。程序直到此命令成功或失败时才继续。
1.3.2 Asynchronouscommands异步命令
命令的初始化方式和同步命令相同,只是命令字节位7被设置为1,表明异步命令。控制立即返回到程序,返回码和AL包含初始化状态。因此需要检查命令是否执行完毕。有两种方式来做:
l 查看NCB的command_complete域。如果命令正在执行中,为FFh;命令完成(或错误发生)就被设置为完成码。
l 使用4字节的post_address域(通常设为0000:0000)。这个域可以用来指向POST过程(routine)。POST过程在命令执行完成后调用的用户程序。POST过程由网络软件调用,ES:BX指向已完成的NCB,AL包含command_complete域的值。没有其他寄存器被定义。POST过程应该和中断服务过程的写法方式相同– 即,中断被禁用,而且不能被重新启用,过程应该尽量快,并使用IRET指令终止。
这种命令可以用于聊天程序。特定名称上的NCB设置为接收信息/数据报。POST指向处理接收信息的过程并在屏幕上打印出来。直到信息被接收,否则软件不能等待,因为用户不能输入信息。
异步命令不能用于多任务。异步命令可以一个命令的POST过程中初始化。如,一旦一次交谈的信息被接收,NCB要被初始化以接受下一个信息。但是,同步命令不能,也不应该在POST过程中调用,否则机器会必然崩溃。
2. Network Control Block网络控制块
2.1简介
网络控制块(Network Control Block, NCB)非常重要,每个命令都要用到。一条命令的执行需要准备相应的NCB,调用中断5Ch,ES:BX指向这个NCB。就像先前提到的,NCB在命令没有执行完毕时不能重用或改变。
2.2 Structure结构
NCB总是64字节,结构如下:
字节范围 | 名称 | 描述 |
0 | command 命令 | 列举所需命令号 |
1 | return code 返回码 | 返回同步命令的完成码或异步命令的初始化码 |
2 | local session 本地会话 | 指定命令的会话,每个会话打开后都会返回会话号 |
3 | name number 名称号 | 指定当前使用的唯一名称。每个名称添加后,就会同时返回唯一号。这个域应该设为你想使用的名称号。我发现最简单的方法是,每个名称使用单独发的NCB,添加名称后,这个域就设置,这样这个域就可以被这个名称的其他命令使用而不用更改。 |
4-7 | buffer address 缓冲区地址 | 指定接收/发送命令的缓冲区地址。形式为段(segment):偏移量(offset),字节4为偏移量的LSB,字节7为段的MSB。 |
8-9 | buffer length 缓冲区长度 | 指定缓冲区长度,字节8为LSB。 |
10-25 | call name 调用名称 | 调用名称是发送命令中要通信的本地或远程站点,或者接收的数据的来源名称。 |
26-41 | local name 本地名称 | 本地名称是本地站点的名称 – 仅当添加或删除名称时需要,因为当名称被添加,会产生唯一名称,用于所有随后的命令。 |
42 | receive timeout 接收超时 | 接收命令的超时时间,以500ms为单位。 |
43 | send timeout 发送超时 | 发送命令的超时时间,以500ms为单位。 |
44-47 | POST address POST地址 | 异步命令的POST过程地址。若设为0000:0000,异步命令执行结束不会调用过程。同步命令会忽略这个域。字节序和缓冲区地址域(字节4-7)相同。 |
48 | network number 网络号 | 如果一个站点有多个网络适配器,这个域指定使用哪个网络。我提议你小心点,并且设置这个域为00h,不然你可能得到错误23h – 无效网络号。 |
49 | command complete 命令完成 | 异步命令的完成码。命令执行时为FFh,完成后就会改变。同步命令没有函数,应为控制仅当命令完成才返回,完成码通过return_code域返回(字节1)。 |
50-63 | reserved 保留 |
|