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協議它的報文結構基本都是一樣的。
剩下的就不在累述了,基本上你能看懂一個報文,其他的也都可以看