透過wireshark簡單瞭解S7協議

不愿透露姓名的小村村發表於2024-04-13

一方面本著學習wireshark的使用,一方面對S7協議想有一個更深入一點的瞭解。

1.建立連線過程:

一邊是IPC,一邊是PLC。
本著學習的態度,這裡簡單說明一下S7通訊協議簇在ISO模型中的一個示意:

OSI layers Protocol
7 APPlication Layer S7 communication
6 Presentation Layer COTP(S7 communication)
5 Session Layer TPKT(S7 communication)
4 Transport Layer ISO-on-TCP
3 Network Layer IP
2 Data Link Layer Ethernet
1 Physical Layer Ethernet

第1-4層是由計算機自己完成的(底層驅動)。
現在從Frame2-Frame4開始逐幀分析:

  • 物理層資料幀:

    這一行給出了物理層資訊,其中沒有中括號的是資料包文字身提取的一些資訊,帶有中括號的是根據報文整體的分析給出的輔助資訊,雖然報文字身並不包含這些欄位資訊。

.Frame 2: 66 bytes on wire (528 bits), 66 bytes captured (528bits) 2號幀,線路66位元組,實際捕獲528bits
.Encapsulation type: Ethernet (1) #封裝型別,表示乙太網的鏈路
.Arrival Time: 捕獲日期和時間(中國標準時間)
.[Time shift for this packet: 0.000000000 seconds]
.Epoch Time: 絕對時間秒數(和前一種是不同的表達方式)
.[Time delta from previous captured frame: xx seconds] 此包與前一包時間間隔
.[Time delta from previous displayed frame: xx seconds]
.[Time since reference or first frame: xx seconds] 此包與第一個幀的時間間隔
.Frame Number: 2 幀序號
.Frame Length: 66 bytes (528 bits) 幀長度,資料的長度,是根據協議這種類格式中length所得到的長度,和後面的Capture Length長度是不同的。
.Capture Length: 66 bytes (528 bits) 在網路卡上實際捕獲的資料幀長度。通常情況下Frame Length和Capture Length 是相同的,但是如果Capture Length所捕獲的資料有缺失,則Capture Length要比Frame Length要小一些。
.[Frame is marked: False] 此幀是否做了標記:否
.[Frame is ignored: False]
.[Protocols in frame: eth:ethertype:ip:tcp] 幀內封裝的協議層次結構
.[Coloring Rule Name: HTTP] 用不同顏色的染色標記的協議名稱:HTTP
.[Coloring Rule String: http || tcp.port == 80 || http2] 染色顯示規則字串

  • Transmisssion control protocol

這一行描述的傳輸控制協議,這裡主要做一下名詞解釋

.Source port:源埠51664
.Destination port:目的埠102
.Flags:0x002(SYN):表示表示建立連線。擴充一下,FIN表示關閉連線,ACK表示響應,PSH表示由DATA資料傳輸,RST表示連線重置。

  • TCP connect

    這三行,注意右邊的info,他們表示經典的了TCP的三次握手過程。

.Seq為序號,等下描述握手的時候會再講到它
.Ack為確認號,也是個重要引數
.Win=64240表示視窗大小,理解為允許對方傳送的最大資料量
.Len=0表示TCP資料部分長度
.MSS=1460表示最大報文長度
.WS=256表示視窗的放大倍數
.SACK_PERM表示通訊雙方均支援SACK機制

TCP採用三次握手來建立一個連線,其過程如下:
第一次握手:主機A傳送標誌位SYN=1,主機B由SYN狀態知道A要求建立連線,當前主機A的Sequence number=0,Acknowledgment number=0
第二次握手:主機B收到請求後,Sequence number=0,Acknowledgment number=1,主機B的SYN=1,ACK=1
第三次握手:主機A檢查Acknowledgment number=1是否正確,以及ACK=1是否正確。主機B收到Seq值和Ack=1時表示連線建立成功
完成三次握手,主機A和主機B開始傳資料

2. COTP協議
COTP協議的全稱是connection-Oriented Transport Protocol,面向連線的傳輸協議。顧名思義,他必然是依賴連線的,所以在傳輸之前必然要先有類似TCP握手建立連線的過程的。
這裡還是直接截圖逐幀分析,概念光說太抽象:

注意看,兩個COTP包裡面,wireshark已經為我們標註出CR和CC,其實這裡的CR就是connect request,CC就是connect confirm。一個表示請求連線,一個表示確認連線。這就是一個建立連線的過程。
其實在建立連線之後,還跟一個DT包,這個就是DA他的意思,表示在傳送資料。
對於COTP而已,它的包有兩種形態,叫做COTP連線包(COTP connection package)和COTP功能包(COTP function package)。
先來看看COTP連線包的幾個關鍵引數:

.Length:資料的長度,不包括length這個欄位本身(和profinet裡面定義欄位長度的風格一樣)
.PDU type:這裡是標誌型別,0x0e就表示連線請求,我會在後面把PDU的常見型別碼例舉出來。
.Destination reference:目標的引用,可以認為是用來唯一標誌目標的
.Source reference:源的引用,可以認為是用來唯一標誌目標的
.Option:佔用1byte,高4位是標誌類別class,倒數第二位是擴充樣式,倒數第一位表示是否有明確的指定流控制。
.Parameter:附加的引數欄位,每個引數又有幾個欄位構成。欄位code=0xC0表示tpdu-size,就是數傳資料的大小;code=0xC1表示src-tsap;code=0xC2表示dst-tsap
.TSAP:一般在西門子裡面,TSAP表示的是連線資源的地址,有兩個,一個是Local tsap,表示採集程式的地址,一個是Remote tsap,大概相當於PLC的地址。所以從這個解釋來看,code的tsap引數可能是表示的源和目標的地址。

對於COTP功能包而已,其實好像沒啥看的,具體也就那麼些東西:

.length:長度
.PDU type:標誌型別
.Option:第一位標誌是否是最後一個包(從這看出來COPT協議當資料較多的時候會拆開來做單元傳輸),後面7個位表示的是TPDU的number.

現在開始分別貼一下COTP連線包和功能包的PDU TYPE吧:

  • COTP連線包
Code info
0x1 ED Expedited data,加急資料
0x2 EA Expedited data acknowledgement,加急資料確認
0x4 UD,使用者資料
0x5 RJ Reject,拒絕
0x6 AK Data acknowledgement,資料確認
0x7 ER TPDU Error,TPDU錯誤
0x8 DR Disconnect Request,斷開請求
0xC DC Disconnect Confirm,斷開確認
0xD CC Connect Confirm,連線確認
0xE CR Connect Request,連線請求
0xF DT data,資料傳輸
  • COTP功能包(其實和上面是一樣的)
Code info
0x1 ED Expedited data,加急資料
0x2 EA Expedited data acknowledgement,加急資料確認
0x4 UD,使用者資料
0x5 RJ Reject,拒絕
0x6 AK Data acknowledgement,資料確認
0x7 ER TPDU Error,TPDU錯誤
0x8 DR Disconnect Request,斷開請求
0xC DC Disconnect Confirm,斷開確認
0xD CC Connect Confirm,連線確認
0xE CR Connect Request,連線請求
0xF DT data,資料傳輸

3. TPKT協議
TPKT叫做transport service ontop of the TCP。顧名思義,就是在TCP之上的傳輸服務,它是為了在TCP和COTP之間建立橋樑的。其實在講COTP之前應該先講TPKT的。
TPKT一般和COTP一起傳送,當作COTP的header段。
下面貼個圖,這個結構很簡單沒什麼好講的:

.version:版本號
.reserved:保留
.length:總長度

4. S7 communication協議
終於講到S7COMN了,這對於我來說是個很神奇的黑科技。因為我就是透過它直接讀到了PLC資料的絕對地址。
S7COMM協議包含3個部分:

  • Header
  • Parameter
  • Data

先講Header,格式如下:

Protocol ID PDU TYPE reserved PDU reference param length data length error class error code

貼圖如下,逐一解釋:

.Protocol ID:協議ID,通常就是0x32
.ROSCTR:常用的幾個:=0x01,表示JOB,作業請求;=0x02,表示ACK,確認響應;=0x03,表示ACK_DATA,確認資料響應;=0x07,表示USERDATA,原始協議的擴充(像啥安全功能,時間設定,迴圈讀取..);
.Redundancy identification(reserved):冗餘資料,通常就是0x0000
.Protocol data unit reference:協議資料單元參考,透過請求時間增加
.param length:引數長度
.data length:資料長度,如果是PLC內部資料就是0x0000,對於其他功能,就是Data部分的長度。

其中最重要的就是ROSCTR,它決定了後續引數的結構。
比如在Job中的結構:

又比如在ACK_Data中的結構:

你看出區別來了嗎?

繼續講Parameter,這個比較複雜多變。在PDU型別是Job和ACK時格式如下:

function code reserved Max AmQ calling Max AmQ called PDU length

job:

ack_data:

當PDU型別是Job時引數為Read Var[0x40]格式如下:

function item count item 1 ... item n

其中item的格式又如下:

specification type length syntax ID transport sizes request data length DB number Area Adderss

還是截圖說吧,看格式有點抽象:

.Variable specification:確定專案結構的主要型別,通常就是0x12
.Length of following address specification,本Item其餘部分的長度
.Syntax Ids of variable specification,確定定址模式和其餘專案結構的格式
.Transport sizes in item data,確定變數的型別和長度
.Request data length,請求的資料長度
. DB number,DB模組的編號,如果訪問的不是DB區域,此處為0x0000
.Area,區域型別

上面說的是當PDU為Job時,S7COMMN的結構,那當PDU為ACK_DATA時結構又是怎麼樣的呢?我們不說虛的,直接截圖:

是的,其Parameter只有function、item count兩個欄位。
繼續,那麼接下來的是Data啦!

.Return code,返回程式碼
.Transport size,資料的傳輸尺寸
. Length,資料的長度

當值寫入Write Var[0x50]的時候,其實情況和Read Var的時候差不多。這裡就不多贅述了,用wireshark一抓就知道了。

5. 小結
對於整個S7協議簇在ISO七層網路架構裡面的分類其實很簡單了,格式如下:

Ethernet Ip TCP TPKT ISO-COTP S7COMM

截圖說明會更直觀:

我的S7協議簡單分析就到這裡就結束了,全當是個人學習和總結記錄。本文講的都是走馬觀花,往深了講的話每一個引數和功能碼型別都有很多的東西,這個時候就需要去看S7的手冊和文件了。
我比較喜歡一個看法,對技術要有敬畏之心,每一門技術都是無數聰明的腦子共同呈現的結果,我們站在巨人的肩膀上,我們無時無刻不在追逐前人的步伐。
學無止境。

相關文章