侧边栏壁纸
  • 累计撰写 47 篇文章
  • 累计创建 22 个标签
  • 累计收到 27 条评论

目 录CONTENT

文章目录

EtherNet/IP协议分析

vchopin
2023-03-02 / 0 评论 / 4 点赞 / 653 阅读 / 4,512 字

EtherNet/IP协议分析

1. 协议介绍

与 Modbus 相比,EtherNet/IP 是一个更现代化的标准协议。由工作组 ControlNet International 与 ODVA 在 20 世纪 90 年代合作设计。它和DeviceNet和ControlNet一样是基于CIP(Common Industrial Protocol通用工业协议)作为应用层协议基础上开发的,这是一种面向对象的协议,可以提供一系列标准服务。时至今日,随着技术的发展工业以太网已经成功的应用到工业的生产当中,但是也出现了多种现场总线标准,现场总线国际标准IEC 61158承认的现在有10种类型总线的国际标准,其中就有着Modbus-IDA、Ethernet-IP等。

尽管EtherNet/IP比Modbus更现代化,但仍然存在协议层面的安全问题。EtherNet/IP通常通过TCP/UDP端口44818运行。此外,EtherNet/IP还有另一个端口 TCP/UDP端口2222。使用这个端口的原因是 EtherNet/IP实现了隐式和显示两种消息传递方式。

显式消息被称为客户端/服务器消息,而隐式消息通常被称为I/O消息。其区别如下:

  • 显示报文:用于在传输时不追求实时性,对时间要求不严格内容,比如程序的上传下载,设备配置信息等。

  • 隐式报文:传输I/O数据。

2. EtherNet/IP协议数据包结构

Ethernet/IP数据包的组成结构可以分成两部分,EtherNet/IP 为 传输层中的内容。EtherNet/IP 可分为两个部分:封装头部,以及封装数据。CIP指令包含于封装数据中。

202102161128044

2.1 封装数据

如上所示,Ethernet/IP协议中的CIP帧包括了命令、数据点和报文信息。

封装的数据包结构如下图所示:

2021021611302390

翻译一下:

image-20230301171430250

其中:

  1. Command:两字节整数,要求与通用工业协议规范中某条特定指令相关,在CIP协议中,即使设备不认识这个命令是什么也必须接收,而且异常处理时必须确保连接不中断,这种设计很好的保证了协议的稳定性,降低了中断连接的风险。CIP协议本身有着实时性、确定性、可重复性、可靠性等特点。

  2. Length:两字节整数,表示数据部分长度,不存在则为0,比如说请求数据包就不存在数据部分

  3. Session Handle: 由目标设备生成,返回至会话发起方,作为一种凭证,证明你可以和我进行对话,这个凭证在接下来的对话里还会用到。

  4. Status:反应了接收方对设备发送的命令的执行能力,0为成功执行,在请求数据包中永远为0。列出其他几种状态码如下:

    • 0x0001无效或不支持的命令(这种命令异常处理时不中断运行)

    • 0x0002接收方处理命令资源不足(这里我没找到相关资料描述,但根据CIP协议高稳定性原则推测应该会进行不中断运行等待资源足的时候进行执行)

    • 0x0003数据格式不正确或数据不正确

    • 0x0065接收到无效数据长度

  5. Max Delay:由于工业以太网对实时性要求高,这里的内容是这个包经历的最大延迟。

  6. Sender Context:命令发送方会生成六个字节的值,接收方要原封不动的发回去,这个内容可以理解为回复的一种编号,发送方知道接收方收到了对应编号的报文,回复的是对相应报文的回复。

  7. Options:始终为0,不为0的话包会被抛弃。

  8. Command-specific Data:这与接受/发送的命令和自身情况有关了。

2.2 主要指令(Command)

在CIP协议中说到前两位字节表示Command,EtherNet/IP的Command共有以下三种:

  • 设备发现 (List Identity),该指令通过UDP 广播发送给所有网络中的设备,接收到消息并且支持EtherNet/IP的设备会返回自身的身份信息。
  • 注册会话 (RegisterSession/UnRegisterSession),该指令用于注册或注销会话。会话注册之后,设备才能够进行数据交换,两台设备之间同时存在一组会话。发起请求后,服务器会返回一个Session Handle,后续交流需要使用该Session Handle 的值方可交流。
  • 发送数据(SendRRData/SendUnitData),SendRRData 用于发送未建立CIP连接的显性数据,SendUnitData用于发送连接了的显性数据。发送RRdata时需要使用Sender Context,发送UnitData时则不需要。

2.3 指令数据(Command Specific Data)

  1. Interface Handle:ENIP的handle一般是CIP(0x00000000)

  2. Timeout:1

  3. Item:一般由两个Item组成:一个地址项和一个数据项,随后是具体CIP命令。每个项的前2bytes用于申明该项的类型,后2bytes用于申明该项值的长度。

20210216114301122

2.4 信息传输

2.4.1 显性传输(explicit Messaging)

显性传输分为 已连接未连接传输。其区别在于:

  • 建立连接的显性传输,设备会保留管理连接所需要的资源,可以提高设备响应效率,示例如下:

image-20230302101133728

  • 未连接的显性传输通常仅在应用程序要求不规则且不频繁的情况下使用,示例如下:

image-20230302101118397

对于未连接的传输,CIP中包含CIP Connection Manager。此处 CIP 协议由服务请求,请求对象类型,对象实例构成,最后是请求的数据,这里Wireshark自动识别出了数据格式符合CIP connection manager的格式。在其它环境下,数据值可能是厂家自行设定的,Wireshark不一定能识别出来,就会显示一串十六进制值。

2.4.2 隐形信息传输(impliciti/I/O Messageing)

隐性信息传输主要用于发送I/O 信息,该传输基于UDP/IP 发送,强调高实时性,该传输方式不需要封装头部,其格式如下所示:

20210216115415804

Wireshark中展示的流量如下:

20210216115453955

其中CIP Sequence Count,在一般情况不影响设备的交流,该项是用于CIP Safety 使用的。

3. CIP 协议

CIP 连接需要通过 Connection Manager(CM) 对象的ForwardOpen 服务来完成,因此在Wireshark中捕获的报文通常具有CM对象,如下所示。

image-20230302105057569

客户端作为请求的发起方,请求中包含传输类,时间信息,电子密钥以及连接ID。当接收到ForwardClose请求或响应超时,清空连接信息。
对于隐形通信,其数据可以广播或发送给某特定地址。数据的发送必须包含对象的IP(单一IP或广播地址)以及 CIP 连接 ID。

3.1 CIP对象模型

每个CIP节点(node)都是一组对象(object)的集合。每个对象都代表了设备的某个特定组件,所有未被描述的对象,都无法通过CIP访问(没有定义当然没法访问)。CIP对象由 类(class),实例(instance),属性(attribute)构成。每个类可以有多个实例,每个实例可以有多个属性。

类(class)是一组代表相同系统组件的对象。实例(instance)是该类中的某个特定对象。每个实例可以有自己特有的属性。

CIP 网络中的每个节点都有节点地址,在EtherNet/IP 网络中,该地址即为设备的IP地址。CIP中每个类,实例,属性都有其对应的ID (Class ID, Instance ID, Attribute ID)。CIP中使用服务代码来明确操作指令。

  • 类ID分为两个部分,公共对象(范围:0x0000–0x0063, 0x00F0–0x02FF),厂家自定义对象(范围:0x0064–0x00C7, 0X0300-0X04FF)。其它范围为预留部分。
  • 实例ID也分为两个部分,公共实例(范围:0x0001–0x0063,0x00C8-0x02FF),厂家自定义实例(范围:0x0064-0xxC7,0x0300-0x04FF)。其它范围为预留部分。
  • 属性ID,公共属性(范围:0x0000–0x0063,0x0100–0x02FF,0x0500–0x08FF),厂家自定义属性(范围:0x0064–0x00C7,0x0300–0x04FF,0x000–0x0CFF)。

部分类ID如下:

名称 代码
Assembly 0x04
Acknowledge Handler 0x2B
Connection 0x05
Connection Manager 0x06
Identity 0x01
Message Router 0x02
Register 0x07

3.2 CIP 服务

CIP 服务代码用来明确请求的操作指令,上述提到的 Forward Open就是一个服务,其它包括常规的读/写服务,创建实例服务。CIP服务代码同样分为公共服务以及厂家自定义服务。部分公共服务代码如下:

指令 服务
0x01 Get Attribute
0x06 Start
0x0a Multiple Service Packet

如下图所示0x060x01就分别是Satrt Service和Get Attribute Service:

image-20230302105430393

公共服务WireShark基本都能识别,但是对于厂家自定义服务,通常会显示Unknown Service:

image-20230302105918763

3.3 报文组成

  1. Service:CIP服务
  2. Request Path Size:请求的对象数量
  3. Request Path: CIP对象

3.4 完整报文示例

image-20230302104454341

4. 总结

EtherNet/IP 采用了生产者/消费者(Producer/Consumer)的通信模式而不是传统的源/目的(Source/Destination)通信模式来交换对时间要求苛刻的数据。生产者是数据的发起者, 向网络上发送数据包, 数据包携有指示数据内容的“唯一的”标识符。消费者是数据接收者,任何感兴趣的消费者都可通过标识符从网络中获取需要的数据, 这样, 多个消费者可以接收和使用这些数据。

CIP 协议节点之间的通信是基于连接的。 在两个节点的对象实例间进行通信时, 先通过连接对象建立一个连接通道, 获得连接标识号(connection ID), 对象实例间就可通过这个固定的连接通道进行通信。 为了保证同类设备的通用性, CIP 协议族将同类设备定义为一个设备类型(device type), 并对其进行设备描述(device profile)。

在发送 CIP 数据包以前必须对其进行封装, CIP 数据包给定一个报文首部, 该首部的内容取决于所请求的服务属性。通过以太网连接的 CIP 数据包包括一个专用的以太网首部、一个 IP 首部、一个 TCP 首部和一个封装首部。 封装首部包含的字段有控制命令、格式、状态信息和同步数据等, 这允许 CIP 数据能通过 TCP 或 UDP 传送并确保在接收方进行 解码。 EtherNet/IP 封 装层也适合 于其它 支持TCP/IP 的网络。 所有封装好的信息, 是通过 TCP(UDP)端口0XAF12 来传送的。

参考

  1. https://blog.csdn.net/weixin_39716043/article/details/119603742
  2. https://blog.csdn.net/weixin_41357300/article/details/104678379
  3. https://blog.csdn.net/m0_46577050/article/details/120898683
4

评论区