西门子作为一个老牌工控企业,在中国市场拥有很高的市场占有率。如果要说起西门子的通信协议,相信大家多多少少能说出一些,比如MPI、PPI、USS、Profibus、Profinet、S7等,但是西门子在协议的开放性方面还是相对要封闭一些,所以很多时候我们是没法知道这些协议的底层通信原理的。 在这里,我主要是结合Wireshark抓包工具,跟大家去分享一下,如何是一步一步抓取西门子S7通信协议底层通信报文的,希望通过我一步一步地分析,让大家都能够对西门子S7协议有所了解的同时,也学会基本的抓包操作与报文分析。 环境搭建 1、首先我们要准备要准备一个西门子的PLC,并保证PLC与PC之间的网络连接正常。PS:对于手头没有PLC的童鞋,可以自行查看相关文章:基于TIA搭建西门子PLC仿真环境及通信方案。 2、为了抓取到通信的报文,需要实现PC与PLC之间的通信,这里我采用的方式是通过KepServer V6.4来实现。 3、安装Wireshark抓包软件。 4、认识S7协议的网络模型。 2 操作步骤 1、首先将KepServer与PLC之间的通信连接配置好; PS:对于KepServer软件应用可以参考相关文章:基于KepServer V6.4实现与三菱FX3U PLC之间的通信。 2、将Wireshark软件打开,并处于监控报文状态; 3、将KepServer进行连接PLC,此时Wireshark软件中会出现报文的数据,将KepServer连接停止并关闭软件,同时将Wireshark的监控停止,以便进行后续的报文分析; 3 初步分析 结合自身对TCP通信的了解,可以将抓取到的报文类型进行区分: TCP三次握手过程 S7协议的第一次连接验证 S7协议的第二次连接验证 TCP四次挥手过程 通过分析,我们发现西门子的S7通信并不是简简单单的TCP通信,在TCP执行三次握手之后,还需要发送两次连接验证,在两次连接验证之后,才进行真正的数据交互。 4 抓包分析 (1)第一次握手发送报文 报文说明: TPKT(第五层:会话层) 该层总共占4个字节: 版本号:0x03 预留:0x00 长度:0x0016 COTP(第六层:表示层) 该层总共占用18个字节: 长度:0x11 PDU类型(CRConnect Request 连接请求):0x0E 目标引用:0x0000 源引用:0x0001 扩展格式/流控制:0x00 参数代码TPDU-Size:0xC0 参数长度:0x01 TPDU大小:0x0A 参数代码SRC-TASP:0xC1 参数长度:0x02 SourceTSAP:0x0201 参数代码DST-TASP:0xC2 参数长度:0x02 DestinationTSAP:0x0201 (2)第一次握手回复报文 报文说明: TPKT(第五层:会话层) 该层总共占4个字节: 版本号:0x03 预留:0x00 长度:0x0016 COTP(第六层:表示层) 该层总共占18个字节: 长度:0x11 PDU类型(CCConnect Confirm 连接确认):0x0D 目标引用:0x0001 源引用:0x0006 扩展格式/流控制:0x00 参数代码TPDU-Size:0xC0 参数长度:0x01 TPDU大小:0x0A 参数代码SRC-TASP:0xC1 参数长度:0x02 SourceTSAP:0x0201 参数代码DST-TASP:0xC2 参数长度:0x02 DestinationTSAP:0x0201 (3)第二次握手发送报文 报文说明: TPKT(第五层:会话层) 该层总共占4个字节: 版本号:0x03 预留:0x00 长度:0x0019 COTP(第六层:表示层) 该层总共占3个字节: 长度:0x02 PDU类型(DT Data):0XF0 目标引用:0x80 S7Communication(第七层:应用层) 该层总用占18个字节,并且分两部分: Header: 协议ID(Protocol ID):0x32 ROSCTR:0x01 预留:0x0000 协议数据单元引用:0x037C 参数长度:0x0008 数据长度:0x0000 Parameter: 功能码:0xF0 预留:0x00 最大AmQ(Calling):0x0001 最大AmQ(Called):0x0001 PDU长度:0x03C0 (4)第二次握手返回报文 报文说明: TPKT(第五层:会话层) 该层总共占4个字节: 版本号:0x03 预留:0x00 长度:0x0019 COTP(第六层:表示层) 该层总共占3个字节: 长度:0x02 PDU类型(DT Data):0XF0 目标引用:0x80 S7Communication(第七层:应用层) 该层总用占20个字节,并且分两部分: Header: 协议ID(Protocol ID):0x32 Ack_Data:0x03 预留:0x0000 协议数据单元引用:0x037C 参数长度:0x0008 数据长度:0x0000 错误等级:0x00 错误代码:0x00 Parameter: 功能码:0xF0 预留:0x00 最大AmQ(Calling):0x0001 最大AmQ(Called):0x0001 PDU长度:0x00F0 (5)读取数据发送报文: 由于只配置了VD0,因此读取DB1.DBX0.0 开始的4个字节 ![]() 报文说明: TPKT(第五层:会话层) 该层总共占4个字节: 版本号:0x03 预留:0x00 长度:0x001F COTP(第六层:表示层) 该层总共占3个字节: 长度:0x02 PDU类型(DT Data):0XF0 目标引用:0x80 S7Communication(第七层:应用层) 该层总用占24个字节,并且分两部分: Header: 协议ID(Protocol ID):0x32 Ack_Data:0x01 预留:0x0000 协议数据单元引用:0x037D 参数长度:0x000E 数据长度:0x0000 Parameter: 功能码Read Var:0x04 通信项数:0x01 通信项1: 通信项Header 变量指定:0x12 地址长度:0x0A SyntaxID:0x10 传输数据类型byte:0x02 通信项Param 读取长度:0x04 DB号:0x01 存储区类型DB存储区:0x84 开始字节:0x000000 (6)读取数据返回报文: ![]() 报文说明: TPKT(第五层:会话层) 该层总共占4个字节: 版本号:0x03 预留:0x00 长度:0x001D COTP(第六层:表示层) 该层总共占3个字节: 长度:0x02 PDU类型(DT Data):0XF0 目标引用:0x80 S7Communication(第七层:应用层) 该层总用占22个字节,并且分两部分: Header: 协议ID(Protocol ID):0x32 Ack_Data:0x03 预留:0x0000 协议数据单元引用:0x037D 参数长度:0x0002 数据长度:0x0008 错误等级:0x00 错误代码:0x00 Parameter: 功能码Read Var:0x04 通信项数:0x01 通信项1: 返回结果Success:0xFF 传输数据类型Byte/Word/DWord:0x04 长度:0x0020 数据:0x00000000 该返回报文说明读取的4个字节数值均为0 如果将这里的报文进行整理,结合Socket通信的相关知识,与西门子PLC通信的问题便迎刃而解了。 5 结语 大部分电气工控人员都更偏向于工程实践,本文从通信底层报文的角度跟大家分析了西门子S7通信的整体过程,希望可以对大家有所帮助。 |
|