1. 程式人生 > >DNP3協議解析 —— 利用Wireshark對報文逐位元組進行解析詳細解析DNP3所含功能碼

DNP3協議解析 —— 利用Wireshark對報文逐位元組進行解析詳細解析DNP3所含功能碼

現在網上有很多類似的文章、其實這一篇也借鑑了很多其他博主的文章。

寫這篇文章的重點是在於解析功能和報文、對Dnp3這個協議並不會做很多介紹。

那我們就開始吧

 

上圖則為dnp3協議整體的報文模型(點選紅框部分可以直接跳轉至應用層的hex流)

Dnp3協議 一共分為三層 鏈路層、傳輸層、應用層。

Dnp3看似很臃腫、但是他的報文格式倒是很簡潔。

Dnp3 協議並沒有對特定的功能做特定的結構、而它的結構基本都可以共用

Dnp3 真正決定功能的功能碼處於應用層、其他層的功能碼只能算是一個大體的範圍

接下來 還是從Wireshark 解析的報文進行出發

read功能

發包

 

 我分部分介紹吧

下圖為鏈路層 

 

Start Bytes byte[0][1] 05 64 為資料開始的位元組 固定為0x0564就可以

Length byte[2] 14為長度、Dnp3的長度計算有一些獨特、 它包括鏈路報文頭中的5個位元組,超出5個位元組的部分為傳輸層報文的長度,也就是說,鏈路層報文長度計數中不含CRC校驗碼位元組。鏈路層報文長度的最小值為5,最大值為255。一條DNP鏈路層報文的最短長度為鏈路報文頭的長度:10個位元組。一條DNP鏈路層報文的最大長度為10+(250/16)×18+(250+2)=292位元組

Control  byte[3] c4 鏈路控制位元組

  第一位為 表明傳送的方向

  第二位為 表示傳送的裝置是主裝置還是從裝置

  第三位為 如果是請求則為糾錯,如果是迴應則為保留位

  第四位為 這一位是說明第三位是否有效、在圖上為0則為Frame count bit(意譯為計數但實為糾錯)未開啟。

  後四位為 功能碼(這個功能碼則是規定了大體的方向,更像是包的型別)

    對於主裝置來說

    0,鏈路重置

    1,程序重置

    3,請求傳送資料

    4,直接傳送資料

    9,查詢當前鏈路的狀態

    對於從裝置來說

    0,同意

    1,拒絕

    11,迴應當前鏈路狀態

Destination byte[4][5] 00 04 目標的地址

Source    byte[6][7] 01 00 源地址

Checksum byte[8]byte[9] e9 b6 為校驗碼、DNP3用的是Crc演算法

到這裡整個鏈路層已經介紹完畢了、後續的其他功能的鏈路層也都是一致的。

下圖為傳輸層

 

很簡單…只有一個位元組

第一位是final,標識是否為最後一個包

第二位是first,標識是否為最後一個包

後六位為seq,表明當前是第幾個包

Data chunks 與 [1 DNP 3.0 AL Fragment 14(bytes): #17(14)]

這些就不用去研究它、它所包含的位元組是應用層的。只不過是Wireshark把它解析出了一欄(我並不能說是Wireshark解析錯誤還是別有用意但是這些不重要、不用在意這兩塊就對了)

下圖為應用層

 

Control byte[0] c1 這裡一共是八個位

  第一位為 表明是否為第一個

  第二位為 表明是否為最後一個

  第三位為 表明是否需要回復,圖中即表示不需要回復

  第四位為 表明是否為主動提出的

  後四位為 為佇列號,這裡的設計和上面傳輸層的類似

Function Code byte[1] 01 這裡就是控制功能的具體方向、若是讀則01 若是寫則02(也有其他型別的功能碼)

那接下來看Read Request這個結構體內的資料

 

這個結構體內的資料還是共處於應用層結構之內

這一塊的意思也就是為 要去讀取什麼(限制物件讀取什麼)

Object byte[2] (這裡是Wireshark解析有些問題、obj和var解析到一塊了實際是為分開的) 3c 這裡表達的意思為 要讀取的資料的基本型別

Object byte[3] 02 進一步說明資料的型別,比如是模擬的話,那你是32位還是64位 (有一份表格說明類這些資料型別,請搜附錄一 資料型別)

Qualifier field byte[4] 06 為限定詞

  第一位為 保留,wireshark同樣沒有給出解析資訊

  第三位為 限定碼,這個不太好理解,簡單點說是表明一個數據物件的索引的位元組數

  後四位為 也就是指定的範圍的意思,圖中6即為讀取所需型別的全部資料。往後就是最後的物件了,這個包中並沒有。

回包

 

還是分層吧 這一層與發包是一樣的 為鏈路層 所迴應hex位元組型別也都是一樣

 

傳輸層的結構也是一樣

 

 

 

應用層會有一些少許的不同

Control byte[0] c1 這裡一共是八個位

  第一位為 表明是否為第一個

  第二位為 表明是否為最後一個

  第三位為 表明是否需要回復,圖中即表示不需要回復

  第四位為 表明是否為主動提出的

  後四位為 為佇列號,這裡的設計和上面傳輸層的類似與發包是一樣的

Function code byte[1] 81 功能碼 這裡就是代表迴應的意思

Internal byte[2]byte[3] 00 00 可以看到這個很雜亂,其實也只是表明的是從裝置的“狀態”問題,包括像是裝置是否重啟、裝置是否有問題、時間同步等等,這裡就不在一一說明了。

但是細心的就就可以發現、dnp3整體的報文最後是包含了60 e6 這兩個位元組,但是在Wireshark 解析中 並沒有解析到 那麼這兩位是幹什麼的呢。我也查了很多資料也對這最後兩位並沒有確切的解釋、姑且認為他只是dnp3攜帶的資料元素吧。

Write

發包

 

整體來看 鏈路層和傳出層都是一致的還是依舊說應用這一層吧。

 

Control byte[0] c0 這裡一共是八個位

  第一位為 表明是否為第一個

  第二位為 表明是否為最後一個

  第三位為 表明是否需要回復,圖中即表示不需要回復

  第四位為 表明是否為主動提出的

  後四位為 為佇列號,這裡的設計和上面傳輸層的類似

Function code byte[1] 02 功能碼 這裡所代表的意思的就寫了

接下來就是Write Request 這個結構體內的資料

Object byte[2] (這裡是Wireshark解析有些問題、obj和var解析到一塊了實際是為分開的,而且也沒有給他確切的欄位名) 50 這裡表達的意思為 要讀取的資料的基本型別

Object byte[3] 01 進一步說明資料的型別,比如是模擬的話,那你是32位還是64位 

Qualifier field byte[4]  00

  第一位為 保留,wireshark同樣沒有給出解析資訊(而且解析到了一起)

  第三位為 限定碼,這個不太好理解,簡單點說是表明一個數據物件的索引的位元組數

  後四位為 也就是指定的範圍的意思

接著往下 number of items這個結構體內

Start byte[5] 07 如子譯一樣 只是為要寫的專案的開始位置

Stop byte[6] 07 在哪裡停

Proint number 7 這個結構體

這個結構體也很明瞭 7號裝置是否重啟,那麼它的值為00 就是不重啟。。

回包

 

與之前的都一樣= = 其實這個dnp3協議它的報文結構基本都是一樣的。

剩下的就不在累述了,基本上你能看懂一個報文,其他的也都可以看