網絡協議詳解1 - NBNS

NetBIOS 簡介

NetBIOS,Network Basic Input/Output System的縮寫,一般指用於局域網通信的一套API,相關RFC文檔包括 RFC 1001, RFC 1002. RFC 1001主要對NetBIOS及相關協議和服務進行解釋說明,RFC 1002給出了相關協議和服務的數據組包格式。

NetBIOS提供三種軟件服務:

Service Name Port Protocol Short Name
NetBIOS Name service 137 UDP/TCP NBNS
NetBIOS Datagram 138 UDP NBND
NetBIOS Session service 139 TCP NBSS

本文主要描述最常見的NBNS.

NBNS 簡介

NBNS是NetBIOS name service的縮寫,是NetBIOS的命名服務,用於將NetBIOS名稱映射到IP地址上,是NetBIOS-over-TCP(NBT)協議族的一份子。NBNS是動態DNS的一種,Microsoft的NBNS實現稱爲WINS。路由器可以通過發送NBNS狀態請求以獲取設備名,windows PC 接收到後通過WINS或將本地緩存發送命名信息給路由器。

NBNS 數據報格式

NBNS的數據報文格式在RFC 1002 Ch4.2中定義,包含以下信息

> 4.2.1 GENERAL FORMAT OF NAME SERVICE PACKETS
>   4.2.1.1 HEADER
>   4.2.1.2 QUESTION SECTION
>   4.2.1.3 RESOURCE RECORD
> 4.2.2 NAME REGISTRATION REQUEST
  4.2.3 NAME OVERWRITE REQUEST & DEMAND
  4.2.4 NAME REFRESH REQUEST
> 4.2.5 POSITIVE NAME REGISTRATION RESPONSE
  4.2.6 NEGATIVE NAME REGISTRATION RESPONSE
  4.2.7 END-NODE CHALLENGE REGISTRATION RESPONSE
  4.2.8 NAME CONFLICT DEMAND
  4.2.9 NAME RELEASE REQUEST & DEMAND
  4.2.10 POSITIVE NAME RELEASE RESPONSE
  4.2.11 NEGATIVE NAME RELEASE RESPONSE
  4.2.12 NAME QUERY REQUEST
  4.2.13 POSITIVE NAME QUERY RESPONSE
  4.2.14 NEGATIVE NAME QUERY RESPONSE
  4.2.15 REDIRECT NAME QUERY RESPONSE
  4.2.16 WAIT FOR ACKNOWLEDGEMENT (WACK) RESPONSE
> 4.2.17 NODE STATUS REQUEST
> 4.2.18 NODE STATUS RESPONSE

本文主要介紹列表中>開頭的部分。

GENERL HEADER

NetBIOS數據包的通用格式如下:

                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+ ------                                                ------- +
|                            HEADER                             |
+ ------                                                ------- +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
/                       QUESTION ENTRIES                        /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
/                   ANSWER RESOURCE RECORDS                     /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
/                  AUTHORITY RESOURCE RECORDS                   /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
/                  ADDITIONAL RESOURCE RECORDS                  /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • HEADER: 頭部信息,包含ID信息等
  • QUESTION ENTRIES: 請求信息
  • ANSWER RESOURCE RECORDS: 應答信息
  • AUTHORITY RESOURCE RECORDS: 授權信息
  • ADDITIONAL RESOURCE RECORDS: 額外添加信息,如註冊信息、刷新信息

HEADER

下面先來看HEADER信息。

                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           NAME_TRN_ID         | OPCODE  |   NM_FLAGS  | RCODE |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|             QDCOUNT           |            ANCOUNT            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|             NSCOUNT           |            ARCOUNT            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • NAME_TRN_ID: Transaction ID, 可以稱爲交易ID,就是針對本次請求或應答對應的ID
  • OPCODE: 包的類型碼,後面詳述
  • NM_FLAGS: 本次操作相關的標誌位,後面詳述
  • RCODE: result code or request, 在應答信息中被填入,具體數值依情況而定
  • QDCOUNT: uint_16 請求信息條例數量
  • ANCOUNT: uint_16 應答信息記錄數量
  • NSCOUNT: uint_16 授權資源記錄數量
  • ARCOUNT: uint_16 額外資源記錄數量

關於OPCODE,如下表所示:

  0   1   2   3   4
+---+---+---+---+---+
| R |    OPCODE     |
+---+---+---+---+---+
  • R: 爲0代表請求包,爲1代表應答包
  • 1-4bit的值標誌不同的操作:
    • 0 = query
    • 5 = registration
    • 6 = release
    • 7 = WACK
    • 8 = refresh

關於NM_FLAGS, 如下表所示:

  0   1   2   3   4   5   6
+---+---+---+---+---+---+---+
|AA |TC |RD |RA | 0 | 0 | B |
+---+---+---+---+---+---+---+
  • AA - Authoritative Answer flag, 當OPCODE中的R爲0時必須爲0,在響應報文中總是被設爲1
  • TC - 截斷標誌,當數據報長度超過576字節後,需要截斷
  • RD - 僅用於請求包,應答包會複製該值;該值爲1代表NBNS會迭代請求、註冊和釋放
  • RA - 爲1代表可以遞歸請求、註冊和釋放,爲0則必須迭代請求
  • B - 爲1代表廣播包或多播包,爲0代表單播包

RARD的原文解釋如下:

RA 3 Recursion Available Flag.
Only valid in responses from a NetBIOS Name Server – must be zero in all other responses.
If one (1) then the NBNS supports recursive query, registration, and release.
If zero (0) then the end-node must iterate for query and challenge for registration.

RD 6 Recursion Desired Flag.
May only be set on a request to a NetBIOS Name Server.
The NBNS will copy its state into the response packet.
If one (1) the NBNS will iterate on the query, registration, or release.

大致意思是,對於請求、註冊和釋放,包含遞歸發送和迭代發送兩種方式。RA爲1說明支持遞歸,爲0說明只能迭代,表徵的是一種能力;RD則是說明具體以什麼方式發送,如果爲1則代表迭代,表徵的是一個具體動作,這個值在響應包中會從請求包中複製得到。

QUESTION SECTION

NBNS的請求數據段格式如下:

                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
/                          QUESTION_NAME                        /
/                                                               /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         QUESTION_TYPE         |          QUESTION_CLASS       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • QUESTION_NAME: 被壓縮的NetBIOS,編碼格式如 NetBIOS-命名編碼
  • QUESTION_TYPE: 請求類型
    • 0x0020 NB: NetBIOS 通用名稱服務資源記錄
    • 0x0021 NBSTAT: NetBIOS NODE STATUS 資源記錄
  • QUESTION_CLASS: 請求類別
    • 0x0001 Internet class

RESOURCE RECORD

NBNS的資源數據段可以存在於請求報文和應答報文中,數據格式如下:

                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
/                            RR_NAME                            /
/                                                               /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            RR_TYPE            |            RR_CLASS           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                              TTL                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            RDLENGTH           |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
/                                                               /
/                             RDATA                             /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • RR_NAME: 與上述的QUESTION_NAME一致
  • RR_TYPE: 記錄類型
    • 0x0001 A: IP地址記錄
    • 0x0002 NS: Name Server資源記錄
    • 0x000A NULL: 空記錄
    • 0x0020 NB: NetBIOS 通用名稱服務資源記錄
    • 0x0021 NBSTAT: NetBIOS NODE STATUS 資源記錄
  • RR_CLASS: 記錄類別
    • 0x0001 Internet class
  • RDLENGTH: uint_16 指定RDATA數據段的數據長度
  • TTL: 某資源記錄名稱的生存時間
  • RDATA: 基於RR_TYPERR_CLASS的數據信息,包含具體的NetBIOS name.

針對RR_TYPE爲NB的情況,RDATA的NB_FLAGS部分的數據格式如下:

                                          1   1   1   1   1   1
  0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| G |  ONT  |                RESERVED                           |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  • G: 爲0代表unique NetBIOS name, 即唯一名稱;爲1代表group NetBIOS name, 即組名稱。
  • ONT: Owner Node Type
    • 00 = B node, 廣播節點(Broadcast)
    • 01 = P node, 單播節點(Point to Point)
    • 10 = M node, 混合節點(Mixed)
    • 11 = Reserved
  • RESERVED

以上便是HEADER, QUESTION SECTION以及RESOURCE RECORD 3個部分的主要內容,所有NBNS相關的請求包和響應包都依循以上格式,具體的信息細節則依情況而定。

NAME REGISTRATION REQUEST

名稱註冊請求格式如下:

                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         NAME_TRN_ID           |0|  0x5  |0|0|1|0|0 0|B|  0x0  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          0x0001               |           0x0000              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          0x0000               |           0x0001              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
/                         QUESTION_NAME                         /
/                                                               /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           NB (0x0020)         |        IN (0x0001)            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
/                            RR_NAME                            /
/                                                               /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           NB (0x0020)         |        IN (0x0001)            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                              TTL                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           0x0006              |        NB_FLAGS               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          NB_ADDRESS                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

可以和上面介紹的進行一一覈對,頭部信息的OPCODE0|0x5, R爲0說明是請求包,0x5說明是registration,即註冊信息請求;NM_FLAGSAA|TC|RD|RA|0|0|B0|0|1|0|0|0|B, 因爲是請求包,所以AA=0;默認支持註冊信息請求包含query和additional兩部分信息,所以QDCOUNTARCOUND均爲1,其餘兩個計數值爲0。

HEADER往後是QUESTION_NAME,NB (0x0020)說明名稱請求類型爲NB, 請求類別通常均爲0x0001, 固定不變。

再往後是TTL,固定的0x0006表徵NB_FLAGS和NB_ADDRESS的總長爲6個字節。其中NB_ADDRESS就是要註冊的地址,而NB_FLAGS標記了這個名稱的唯一性和數據包的類型(廣播還是單播)。

POSTIVE NAME REGISTRATION RESPONSE

                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NAME_TRN_ID |1| 0x5 |1|0|1|1|0 0|0| 0x0 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          0x0000               |           0x0001              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          0x0000               |           0x0000              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
/                            RR_NAME                            /
/                                                               /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           NB (0x0020)         |        IN (0x0001)            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                              TTL                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           0x0006              |        NB_FLAGS               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          NB_ADDRESS                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

在Registration response中,HEADER的RAA都變成了1,代表響應包;B爲0代表單播包形式發送;RARD均爲1,說明終端支持遞歸請求、註冊和釋放,但是會以迭代的方式進行請求、註冊或釋放。後面部分與請求註冊的信息一致。

NODE STATUS REQUEST

Node status request也是路由器獲取PC設備名稱的常用方式,其請求格式如下:

                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| NAME_TRN_ID |0| 0x0 |0|0|0|0|0 0|B| 0x0 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          0x0001               |           0x0000              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          0x0000               |           0x0000              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
/                         QUESTION_NAME                         /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         NBSTAT (0x0021)       |        IN (0x0001)            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

與registration相比,RR_TYPE由NB變味了NBSTAT,少了Additional部分,僅僅包含請求信息。

NODE STATUS RESPONSE

Node status response的數據包格式如下:

                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         NAME_TRN_ID           |1|  0x0  |1|0|0|0|0 0|0|  0x0  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          0x0000               |           0x0001              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          0x0000               |           0x0000              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
/                            RR_NAME                            /
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         NBSTAT (0x0021)       |        IN (0x0001)            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          0x00000000                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            RDLENGTH           |   NUM_NAMES   |               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
|                                                               |
+                                                               +
/                         NODE_NAME ARRAY                       /
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
/                           STATISTICS                          /
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

節點狀態信息很多,其中NUM_NAMES表示後面緊隨的節點名稱數組長度,每個數組元素包含18字節:16字節的名稱和2個字節的NAME_FLAGS. NAME_FLAGS格式如下:

                                          1   1   1   1   1   1
  0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| G |  ONT  |DRG|CNF|ACT|PRM|          RESERVED                 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  • G: 組名標誌,爲1代表組名,爲0代表唯一名稱
  • ONT: Owner Node Type
    • 00 = B node
    • 01 = P node
    • 10 = M node
    • 11 = Reserved
  • DRG: 註銷標誌
  • CNF: 衝突標誌
  • ACT: 有效名稱標誌,均設置爲1
  • PRM: 永久名稱標誌
  • RESERVED

STATISTICS字段的格式如下:

                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               UNIT_ID (Unique unit ID)                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|       UNIT_ID,continued       |    JUMPERS    |  TEST_RESULT  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|       VERSION_NUMBER          |      PERIOD_OF_STATISTICS     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|       NUMBER_OF_CRCs          |     NUMBER_ALIGNMENT_ERRORS   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|       NUMBER_OF_COLLISIONS    |       NUMBER_SEND_ABORTS      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       NUMBER_GOOD_SENDS                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      NUMBER_GOOD_RECEIVES                     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|       NUMBER_RETRANSMITS      | NUMBER_NO_RESOURCE_CONDITIONS |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  NUMBER_FREE_COMMAND_BLOCKS   |  TOTAL_NUMBER_COMMAND_BLOCKS  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|MAX_TOTAL_NUMBER_COMMAND_BLOCKS|    NUMBER_PENDING_SESSIONS    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  MAX_NUMBER_PENDING_SESSIONS  |  MAX_TOTAL_SESSIONS_POSSIBLE  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   SESSION_DATA_PACKET_SIZE    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

NetBIOS 命名編碼

上面所有提及的報文中都包含NetBIOS名稱,這個名稱是被經過編碼處理的。參考以下RFC 1001 Ch14.1可知,最長16Byte的NetBIOS name被要求映射爲32Byte的可逆的、半ASCII偏置編碼。

The 16 byte NetBIOS name is mapped into a 32 byte wide field using a reversible, half-ASCII, biased encoding. Each half-octet of the NetBIOS name is encoded into one byte of the 32 byte field. The first half octet is encoded into the first byte, the second half- octet into the second byte, etc.

Each 4-bit, half-octet of the NetBIOS name is treated as an 8-bit, right-adjusted, zero-filled binary number. This number is added to value of the ASCII character ‘A’ (hexidecimal 41). The resulting 8- bit number is stored in the appropriate byte.

簡單講,就是將每個字符按ASCII拆成兩部分,每部分再加上A,從而由1個字符變成兩個字符。比如字符L,對應ASCII 0x4C,拆成兩部分爲0x40xC,然後每部分都加上字符A對應的ASCII 0x41,得到0x450x4D,對應字符EM,這樣原始字符L就變成了雙字符EM。下面是這個示例的詳細說明圖解。

nbns name

注意原始名稱不足16字節可以補空格0x20或NULL0x00,這裏補的是空格;如果長度超過16則需要截取前16字節。

使用Python可以快速完成編碼↓

>>> orig_name = 'LITREILY'.ljust(16)
>>> encoded_name = ''.join([ chr((ord(c)>>4) + ord('A')) + chr((ord(c)&0x0F) + ord('A')) for c in orig_name ])
>>> encoded_name
'EMEJFEFCEFEJEMFJCACACACACACACACA'

在真實的數據包中,NetBIOS名稱前面是0x20,代表名稱固定長度32字節,名稱後面填補一個0x00\0作爲結束符。那麼上面的LITREILY對應的數據爲:

20 45 4d 45 4a 46 45 46 43 45 46 45 4a 45 4d 46
4a 43 41 43 41 43 41 43 41 43 41 43 41 43 41 43
41 00

注意:

A label length count is actually a 6-bit field in the label length field. The most significant 2 bits of the field, bits 7 and 6, are flags allowing an escape from the above compressed representation. If bits 7 and 6 are both set (11), the following 14 bits are an offset pointer into the full message to the actual label string from another domain name that belongs in this name. This label pointer allows for a further compression of a domain name in a packet.

簡單說,當長度設置不爲0x20,而是將最高兩位置1,即設爲0xc0時,代表當前名稱使用指針,隨後的字節指定名稱所在的位置。

nbtstat

nbtstat.exe是Windows中用於查看NBT status的工具,通過它可以查看當前局域網內的NetBIOS name.

幫助信息

C:\Users\Litre>nbtstat.exe -a
顯示協議統計和當前使用 NBI 的 TCP/IP 連接
(在 TCP/IP 上的 NetBIOS)。

NBTSTAT [ [-a RemoteName] [-A IP address] [-c] [-n]
        [-r] [-R] [-RR] [-s] [-S] [interval] ]

  -a   (適配器狀態)    列出指定名稱的遠程機器的名稱表
  -A   (適配器狀態)    列出指定 IP 地址的遠程機器的名稱表。
  -c   (緩存)          列出遠程[計算機]名稱及其 IP 地址的 NBT 緩存
  -n   (名稱)          列出本地 NetBIOS 名稱。
  -r   (已解析)        列出通過廣播和經由 WINS 解析的名稱
  -R   (重新加載)      清除和重新加載遠程緩存名稱表
  -S   (會話)          列出具有目標 IP 地址的會話表
  -s   (會話)          列出將目標 IP 地址轉換成計算機 NETBIOS 名稱的會話表。
  -RR  (釋放刷新)      將名稱釋放包發送到 WINS,然後啓動刷新

  RemoteName   遠程主機計算機名。
  IP address   用點分隔的十進制表示的 IP 地址。
  interval     重新顯示選定的統計、每次顯示之間暫停的間隔秒數。
               按 Ctrl+C 停止重新顯示統計。

其中RemoteName既可以是ASCII形式的名稱,也可以是IP地址。

使用示例一

第一個例子,在加入域DELTA的辦公電腦上。3個網卡,第1個網卡連接路由器,第2個網卡連接公司網,第3個爲虛擬網卡。

C:\WINDOWS\system32>nbtstat.exe -n

Router:
節點 IP 址址: [192.168.1.10] 範圍 ID: []

                NetBIOS 本地名稱表

       名稱               類型         狀態
    ---------------------------------------------
    CNSHDNI2PC074  <00>  唯一          已註冊
    DELTA          <00>  組           已註冊
    CNSHDNI2PC074  <20>  唯一          已註冊
    DELTA          <1E>  組           已註冊
    DELTA          <1D>  唯一          已註冊
    ..__MSBROWSE__.<01>  組           已註冊

Company:
節點 IP 址址: [172.17.144.33] 範圍 ID: []

                NetBIOS 本地名稱表

       名稱               類型         狀態
    ---------------------------------------------
    CNSHDNI2PC074  <00>  唯一          已註冊
    DELTA          <00>  組           已註冊
    CNSHDNI2PC074  <20>  唯一          已註冊
    DELTA          <1E>  組           已註冊

以太網:
節點 IP 址址: [0.0.0.0] 範圍 ID: []

    緩存中沒有名稱

需要注意的是,名稱表中每個名稱都是16字節,中間空白處是空格符,最後一個字節用<>顯示,裏面使用16進制數表示。如CHSH2DNIPC074__<00>_代表空格,最後一個字節<00>\0. NetBIOS name可以唯一,也可以是多個設備共用一個組,唯一名稱用於指定唯一一臺設備,而組名如此處的DELTA是域名稱,局域網加入域對應的域名就是這種組名稱,也稱之爲工作組

使用示例二

第二個例子,我使用家用臺式PC在局域網內進行了反覆測試。下面是簡要的抓包信息。

nbns packets

nbtstat -a RemoteName用於請求指定名稱所在設備的名稱表。

C:\WINDOWS\system32>nbtstat -a DZ-DN-700

eth0:
節點 IP 址址: [192.168.1.14] 範圍 ID: []

           NetBIOS 遠程計算機名稱表

       名稱               類型         狀態
    ---------------------------------------------
    DZ-DN-700      <20>  唯一          已註冊
    DZ-DN-700      <00>  唯一          已註冊
    DIAS           <00>  組           已註冊
    DIAS           <1E>  組           已註冊

    MAC 地址 = E4-42-A6-18-AB-00


C:\WINDOWS\system32>nbtstat -a 192.168.1.12

eth0:
節點 IP 址址: [192.168.1.14] 範圍 ID: []

           NetBIOS 遠程計算機名稱表

       名稱               類型         狀態
    ---------------------------------------------
    DZ-DN-700      <20>  唯一          已註冊
    DZ-DN-700      <00>  唯一          已註冊
    DIAS           <00>  組           已註冊
    DIAS           <1E>  組           已註冊

    MAC 地址 = E4-42-A6-18-AB-00

nbtstat -A IP_Address用於請求指定IP所在設備的名稱表。

C:\WINDOWS\system32>nbtstat -A 192.168.1.12

eth0:
節點 IP 址址: [192.168.1.14] 範圍 ID: []

           NetBIOS 遠程計算機名稱表

       名稱               類型         狀態
    ---------------------------------------------
    DZ-DN-700      <20>  唯一          已註冊
    DZ-DN-700      <00>  唯一          已註冊
    DIAS           <00>  組           已註冊
    DIAS           <1E>  組           已註冊
    DIAS           <1D>  唯一          已註冊
    ..__MSBROWSE__.<01>  組           已註冊

    MAC 地址 = E4-42-A6-18-AB-00

nbtstat -c用於查看當前設備緩存中的名稱表,注意每個名稱都是可以被修改的,所以需要定時刷新,同時每個名稱都有其壽命,壽命耗盡後需要重新請求。

C:\WINDOWS\system32>nbtstat -c

eth0:
節點 IP 址址: [192.168.1.14] 範圍 ID: []

                  NetBIOS 遠程緩存名稱表

        名稱              類型       主機地址    壽命[]
    ------------------------------------------------------------
    DZ-DN-700      <20>  唯一              192.168.1.12        269
    DZ-DN-700      <00>  唯一              192.168.1.12        269

nbtstat -n用於查看當前設備的本地名稱表,與第一個例子一樣。

C:\WINDOWS\system32>nbtstat -n

eth0:
節點 IP 址址: [192.168.1.14] 範圍 ID: []

                NetBIOS 本地名稱表

       名稱               類型         狀態
    ---------------------------------------------
    DT-LITREILY    <20>  唯一          已註冊
    DT-LITREILY    <00>  唯一          已註冊
    WORKGROUP      <00>  組           已註冊

nbtstat -r用於查看通過廣播和經由 WINS 解析的名稱

C:\WINDOWS\system32>nbtstat -r

    NetBIOS 名稱解析和註冊統計
    ----------------------------------------------------

    通過廣播解析的     = 5
    通過名稱服務器解析   = 0

    通過廣播註冊的   = 3
    通過名稱服務器註冊的 = 0

    通過廣播解析的 NetBIOS 名稱
    ---------------------------------------------
           DZ-DN-700      <00>
           DZ-DN-700      <00>
           DZ-DN-700      <00>
           DIAS           <00>
           DZ-DN-700      <00>

nbtstat -snbtstat -S都用於會話服務信息查詢,因爲沒有連接所以信息爲空。

C:\WINDOWS\system32>nbtstat -s

eth0:
節點 IP 址址: [192.168.1.14] 範圍 ID: []

    無連接

C:\WINDOWS\system32>nbtstat -S

eth0:
節點 IP 址址: [192.168.1.14] 範圍 ID: []

    無連接

nbtstat -R用於清除緩存,清除後再用-c查看就會顯示沒有名稱了。

C:\WINDOWS\system32>nbtstat -R
    NBT 遠程緩存名稱表的成功清除和預加載。

C:\WINDOWS\system32>nbtstat -c

eth0:
節點 IP 址址: [192.168.1.14] 範圍 ID: []

    緩存中沒有名稱

nbtstat -RR用於刷新經本機註冊的NetBIOS名稱,間隔一段時間方能刷新第二次。

C:\WINDOWS\system32>nbtstat -RR
    已經刷新經過此計算機註冊的 NetBIOS 名稱。

Windows 配置NetBIOS

在Windows操作系統中,可以打開某網卡的屬性配置,然後選擇IPv4配置的高級選項,WINS選項卡即可配置NetBIOS。默認情況是啓用的,與下圖所示一致。

Windows上的NetBIOS配置

wireshark 實例分析

最後來分析兩個使用wireshark抓的NBNS數據包,以便更直觀的理解和記憶。

Node Status

使用指令nbtstat -A 192.168.1.12向指定設備發送Node status query,使用wireshark抓包。
在這裏插入圖片描述

請求數據包如下:

在這裏插入圖片描述

從wireshark得到的解析數據如下:

0000   e4 42 a6 18 ab 00 00 e0 4c 5a 0a 78 08 00 45 00   äB¦.«..àLZ.x..E.
0010   00 4e 1e 82 00 00 80 11 98 b2 c0 a8 01 0e c0 a8   .N.......²À¨..À¨
0020   01 0c 00 89 00 89 00 3a 5a 12 e2 b1 00 00 00 01   .......:Z.â±....
0030   00 00 00 00 00 00 20 43 4b 41 41 41 41 41 41 41   ...... CKAAAAAAA
0040   41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41   AAAAAAAAAAAAAAAA
0050   41 41 41 41 41 41 41 00 00 21 00 01               AAAAAAA..!..

NetBIOS Name Service
    Transaction ID: 0xe2b1
    Flags: 0x0000, Opcode: Name query
        0... .... .... .... = Response: Message is a query
        .000 0... .... .... = Opcode: Name query (0)
        .... ..0. .... .... = Truncated: Message is not truncated
        .... ...0 .... .... = Recursion desired: Do not do query recursively
        .... .... ...0 .... = Broadcast: Not a broadcast packet
    Questions: 1
    Answer RRs: 0
    Authority RRs: 0
    Additional RRs: 0
    Queries
        *<00><00><00><00><00><00><00><00><00><00><00><00><00><00><00>: type NBSTAT, class IN
            Name: *<00><00><00><00><00><00><00><00><00><00><00><00><00><00><00> (Workstation/Redirector)
            Type: NBSTAT (33)
            Class: IN (1)

該數據報包含一個請求,所以Questions爲1,其餘爲0;請求包中的編碼名稱爲*的編碼後數據CKAAAAAAAAAAAAAAA…; 由於使用的是指定IP,所以是單播包;因爲是NODE STATUS REQUEST, 所以QUESTION_TYPE是NBSTAT(0x0021).

從指定設備獲取到的響應數據如下:

nbns node status response

從截圖中已經可以清晰的看到數據格式及具體內容了,被摺疊的名稱信息中,DZ-DN-700<20>DIAS<1e>如下:

0000   00 e0 4c 5a 0a 78 e4 42 a6 18 ab 00 08 00 45 00   ..LZ.x........E.
0010   00 cb 53 50 00 00 80 11 63 67 c0 a8 01 0c c0 a8   ..SP....cg......
0020   01 0e 00 89 00 89 00 b7 01 c0                     .........

0020                                 e2 b1 84 00 00 00            .......
0030   00 01 00 00 00 00 20 43 4b 41 41 41 41 41 41 41   ...... CKAAAAAAA
0040   41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41   AAAAAAAAAAAAAAAA
0050   41 41 41 41 41 41 41 00 00 21 00 01 00 00 00 00   AAAAAAA..!......
0060   00 77 04                                          .w.

0060            44 5a 2d 44 4e 2d 37 30 30 20 20 20 20      DZ-DN-700    
0070   20 20 20 04 00                                       ..
Name: DZ-DN-700<20> (Server service)
Name flags: 0x0400, ONT: B-node, Name is active
    0... .... .... .... = Name type: Unique name
    .00. .... .... .... = ONT: B-node (0)
    ...0 .... .... .... = Name is being deregistered: No
    .... 0... .... .... = Name is in conflict: No
    .... .1.. .... .... = Name is active: Yes
    .... ..0. .... .... = Permanent node name: No

0070                  44 5a 2d 44 4e 2d 37 30 30 20 20        DZ-DN-700  
0080   20 20 20 20 00 04 00                                  ...
Name: DZ-DN-700<00> (Workstation/Redirector)
Name flags: 0x0400, ONT: B-node, Name is active
    0... .... .... .... = Name type: Unique name
    .00. .... .... .... = ONT: B-node (0)
    ...0 .... .... .... = Name is being deregistered: No
    .... 0... .... .... = Name is in conflict: No
    .... .1.. .... .... = Name is active: Yes
    .... ..0. .... .... = Permanent node name: No

0080                        44 49 41 53 20 20 20 20 20          DIAS     
0090   20 20 20 20 20 20 00 84 00                              ...
Name: DIAS<00> (Workstation/Redirector)
Name flags: 0x8400, Name type, ONT: B-node, Name is active
    1... .... .... .... = Name type: Group name
    .00. .... .... .... = ONT: B-node (0)
    ...0 .... .... .... = Name is being deregistered: No
    .... 0... .... .... = Name is in conflict: No
    .... .1.. .... .... = Name is active: Yes
    .... ..0. .... .... = Permanent node name: No

0090                              44 49 41 53 20 20 20            DIAS   
00a0   20 20 20 20 20 20 20 20 1e 84 00                          ...
Name: DIAS<1e> (Browser Election Service)
Name flags: 0x8400, Name type, ONT: B-node, Name is active
    1... .... .... .... = Name type: Group name
    .00. .... .... .... = ONT: B-node (0)
    ...0 .... .... .... = Name is being deregistered: No
    .... 0... .... .... = Name is in conflict: No
    .... .1.. .... .... = Name is active: Yes
    .... ..0. .... .... = Permanent node name: No

00a0                                    e4 42 a6 18 ab              .B...
00b0   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00c0   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00d0   00 00 00 00 00 00 00 00 00                        .........

Name Registration

nbns registration

NBNS名稱註冊請求包如下圖所示:

在這裏插入圖片描述

請求包格式與NAME REGISTRATION REQUEST中的一致。使用廣播包方式,OPCODE爲5,包含一條Questions記錄和Additional記錄,註冊地址爲發送方的IP地址192.168.1.12.

在局域網內的其它設備或路由器接收到該廣播包後,即可將其名稱和IP地址記錄到本地緩存當中。

Reference

  1. rfc1001 - protocol standard for a nETbios service on a tcp/udp transport: concepts and methods
  2. rfc1002 - protocol standard for a nETbios service on a tcp/udp transport: detailed specifications
  3. wireshark抓包數據

文章首發於: 網絡協議詳解1 - NBNS

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章