一方面本著學習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的手冊和文件了。
我比較喜歡一個看法,對技術要有敬畏之心,每一門技術都是無數聰明的腦子共同呈現的結果,我們站在巨人的肩膀上,我們無時無刻不在追逐前人的步伐。
學無止境。