S7comm协议解析

记录一下通过wireshark对S7comm协议的解析过程

S7协议介绍

S7comm(S7 通信)是西门子专有协议,可在西门子 S7-300/400 系列的可编程逻辑控制器 (PLC) 之间运行。

它用于 PLC 编程、PLC 之间的数据交换、从 SCADA(监控和数据采集)系统访问 PLC 数据以及诊断目的。

S7comm 数据作为 COTP 数据包的有效载荷出现。第一个字节总是 0x32 作为协议标识符。

要建立与 S7 PLC 的连接,有 3 个步骤:

1.通过 TCP 端口 102 连接到 PLC
2.在 ISO 层连接(COTP 连接请求)
3.在 S7comm 层连接(s7comm.param.func = 0xf0,Setup 通信)

步骤 1) 使用 PLC/CP 的 IP 地址。

步骤 2) 用作两个字节长度的目标 TSAP。目标 TSAP 的第一个字节编码通信类型(1=PG,2=OP)。目标 TSAP 的第二个字节编码机架和插槽号:这是 PLC CPU 的位置。插槽编号在位 0-4 中编码,机架编号在位 5-7 中编码。

步骤 3) 用于协商 S7comm 的具体细节(如 PDU 大小)。

S7抓包分析

TPKT协议

TPKT协议是一个传输服务协议,它为上层的COPT和下层TCP进行了过渡。我们常用的RDP协议(remote desktop protocol,windows的远程桌面协议)也是基于TPKT的,TPKT的默认TCP端口为102(RDP为3389),其实它本身为payload增加的数据并不多,主要就是以下几个:

  • version,1byte,表明版本信息
  • reserved,1byte,保留
  • length,2byte,包括payload和这三部分在内的总长度

COTP

COTP协议的全称是Connection-Oriented Transport Protocol,即面向连接的传输协议,从这个名字就可以看出,它的传输必然是依赖于连接的,所以在传输数据前必然有类似TCP握手建立链接的操作。
这里wireshark为我们标注出了CR和CC,后面的COTP包都是DT,这里的CR和CC其实分别是connect request和connet confirm的,也就是建立连接的过程,之后连接建立成功后,发送DT包,也就是data,是在发送数据。

接下来我们看一下COTP的连接包:

第一部分:

包含:length、PDU type、DST reference、SRC reference
length :标识长度(但是length这个标识位不计入长度)
PDU type:标识类型,常见的值有:

  • 0x01: ED Expedited Data,加急数据
  • 0x02: EA Expedited Data Acknowledgement,加急数据确认
  • 0x04: UD,用户数据
  • 0x05: RJ Reject,拒绝
  • 0x06: AK Data Acknowledgement,数据确认
  • 0x07: ER TPDU Error,TPDU错误
  • 0x08: DR Disconnect Request,断开请求
  • 0x0C: DC Disconnect Confirm,断开确认
  • 0x0D: CC Connect Confirm,连接确认
  • 0x0E: CR Connect Request,连接请求
  • 0x0F: DT Data,数据传输

DST reference: 目标标识
SRC reference:源标识

第二部分(option)

可以看到在wireshark中将这部分(1个byte拆成了前四位和后两位),其中:

  • 前四位标识class,也就是标识类别
  • 倒数第二位对应Extended formats,是否使用拓展样式
  • 倒数第一位对应No explicit flow control,是否有明确的指定流控制

第三部分(parameter)

分为三部分:parameter code、parameter length、data,
parameter code:标识类型,主要有:

  • 0xc0,tpdu的size,tpdu即传送协议数据单元,也就是传输的数据的大小
  • 0xc1,src-tsap (源设备号)
  • 0xc2,dst-tsap (同上)
    parameter length:长度
    data:对应数据

COPT功能包

可以看到COTP功能包的PDU type为0X0f,只有三部分:length,type,opt

以上便是TPKT和COTP协议的解析过程。

S7COMM

S7Comm数据作为COTP数据包的有效载荷,第一个字节总是0x32作为协议标识符。
S7Comm协议包含三部分:

  • Header
  • Parameter
  • Data
    根据实现的功能不同,S7comm协议的结构会有所不同

Header部分:



在Header中最重要的字段就是ROSCTR,它决定了后续参数的结构。ROSCTR的类型常见有以下值:

  • 0x01 - JOB(Request: job with acknowledgement):作业请求。由主设备发送的请求(例如,读/写存储器,读/写块,启动/停止设备,设置通信);
  • 0x02 - ACK(acknowledgement without additional field):确认响应,没有数据的简单确认(未遇到过由S7 300/400设备发送得);
  • 0x03 - ACK_DATA(Response: acknowledgement with additional field):确认数据响应,这个一般都是响应JOB的请求;
  • 0x07 - USERDATA:原始协议的扩展,参数字段包含请求/响应ID(用于编程/调试,读取SZL,安全功能,时间设置,循环读取...)

Parameter部分:

Parameter的第一个字段为function,根据Header中ROSCTR的类别和Parameter中function的不同,parameter的结构,目的也会有所不同。
下面根据不同的功能码(function的值)讲解parameter的字段的构成:

0XF0(建立通信)

建立通信在每个会话开始时被发送,然后可以交换任何其他消息。它用于协商ACK队列的大小和最大PDU长度,双方声明它们的支持值。ACK队列的长度决定了可以同时启动而不需要确认的并行作业的数量。PDU和队列长度字段都是大端。
当PDU类型为Job(ROSCTR的值为0x01),function为0xf0时,Paramter的结构为:

具体的Parameter结构,如下:

  • 1 (Unsigned integer, 1 byte): Parameter part: Reserved byte in communication setup pdu,保留字节;
  • 2 (Unsigned integer, 2 bytes): Max AmQ (parallel jobs with ack) calling;
  • 3 (Unsigned integer, 2 bytes): Max AmQ (parallel jobs with ack) called;
  • 4 (Unsigned integer, 2 bytes): Parameter part: Negotiate PDU length。协商PDU长度。


从响应包可以看出ack队列为1,PDU最大长度为240
(不同的function的值,parameter的结构不一样,以下只列出结构信息,不一一详述)

0x04(读取值)

当PDU类型为Job,function为0x04时,Parameter的结构为:

(今天暂时先写到这里吧)

posted @   仰望飞鸟的鱼  阅读(3220)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示