1. 项目概述:从枯燥手册到实战抓包
如果你是一名电力自动化、工业控制或者嵌入式通信领域的工程师,提到IEC 101规约,脑海里是不是立刻浮现出厚厚一摞的协议标准文档,里面充斥着抽象的帧格式定义、复杂的链路层状态机、以及一堆需要死记硬背的ASDU类型和传送原因?传统的学习路径,往往是从阅读这些“天书”开始,过程枯燥且收效甚微,常常是看完了也不知道一个真实的遥控命令在网络上到底长什么样。今天,我们就换一种方式,告别对着手册空想,直接上手Wireshark这个“网络显微镜”,通过实战抓包,亲眼看看IEC 101规约的遥控、遥信报文究竟是如何在线上“奔跑”的。
这个方法的核心价值在于直观和高效。协议手册告诉你理论,而抓包展示给你现实。通过分析真实的数据流,你能瞬间理解帧结构、掌握报文交互时序、定位通信故障,甚至逆向解析未知设备的数据。无论是为了调试新接入的设备、排查现场通信中断问题,还是单纯想深入理解规约本质,这都是一条捷径。本文假设你已有基础的网络概念(知道IP、端口),并且对IEC 101有初步了解(知道它是用于变电站、配电自动化等场景的通信规约)。我们将从环境搭建开始,一步步带你捕获、过滤、解码并深度分析IEC 101的遥控与遥信报文,过程中会穿插大量只有实际踩过坑才知道的注意事项和技巧。
2. 实战环境搭建与Wireshark配置要点
工欲善其事,必先利其器。在开始抓包之前,我们需要一个合适的战场和得心应手的工具。
2.1 网络拓扑与抓包点选择
IEC 101规约通常运行在串行链路(如RS-485)或网络传输(基于TCP/IP,即IEC 101-104的传输层)上。对于现代系统,基于TCP/IP的101规约(常被称为101 over TCP)更为常见,这也是我们抓包分析的主要场景。
一个典型的网络拓扑是:站控层主机(主站)通过以太网交换机,与多个间隔层设备(子站/RTU)通信。你的抓包点选择至关重要,它决定了你能看到什么。
- 最佳抓包点:镜像端口。如果你的交换机支持端口镜像(Port Mirroring 或 SPAN),将主站和子站连接的端口流量镜像到一个单独的端口,然后在这个端口上接入你的装有Wireshark的电脑。这是最理想的情况,你可以看到所有双向、原始的通信报文。
- 次选方案:主站或子站本机。如果无法操作交换机,可以在主站服务器或某一台子站设备上直接安装Wireshark进行抓包。这时,你只能看到该设备发出和收到的报文。对于分析单点通信问题也足够,但无法全局观察广播或组播流量。
- 串行链路抓包:如果仍然是传统的串行RS-485,则需要硬件串口监听设备(如USB转串口监听线),或者使用支持串口数据流转换并注入虚拟网卡的软件工具(如
com0com配合hub4com),过程更复杂一些。本文聚焦于更主流的网络抓包。
注意:在生产环境抓包务必获得授权,避免影响实时控制系统运行。建议在调试环境或实验室仿真系统中进行。
2.2 Wireshark关键配置与插件准备
安装好Wireshark后,默认设置可能无法最优地展示IEC 101报文,需要进行几项关键配置。
1. 捕获过滤器(Capture Filter)设置:开始捕获前,如果网络背景流量很大,可以设置捕获过滤器以减少干扰。对于IEC 101 over TCP,通常使用固定端口号(如2404)。你可以设置过滤器为:tcp port 2404。这样Wireshark只会捕获涉及2404端口的TCP流量,非常干净。但如果你不确定端口号,或者想捕获更多相关流量(如ARP、ICMP用于排查网络连通性),可以先不设过滤器,捕获后再用显示过滤器分析。
2. 显示过滤器(Display Filter)精通:显示过滤器是Wireshark分析的核心技能。对于IEC 101,我们需要用到其协议解码器。Wireshark内置了iec60870和iec60870_asdu等协议解析。常用的显示过滤器包括:
iec60870:显示所有被识别为IEC 60870-5-101/104的报文。iec60870_asdu.type == 45:筛选ASDU类型为45(单点遥控)的报文。tcp.port == 2404:按端口筛选。- 结合使用:
iec60870 and tcp.port==2404 and iec60870_asdu.cot==6(筛选端口2404上、传送原因为6(激活)的IEC 101报文)。
3. 解码器(Dissector)验证与自定义:有时,设备厂商可能使用了私有的地址映射或略微非标准的实现,导致Wireshark内置解码器解析出的信息名称不对。你可以通过“视图” -> “内部” -> “协议表”查看iec60870解码器的细节。对于高级用户,甚至可以编写Lua脚本自定义解码规则,但这需要深厚的协议知识。一个更实用的技巧是:如果发现某个信息对象地址(IOA)对应的含义不明,可以结合设备说明书,在Wireshark的“编辑” -> “首选项” -> “协议” ->IEC 60870-5-101/104中,尝试修改或添加信息对象地址的映射表(如果支持的话),或者简单地使用备注功能,在抓包文件中为特定报文添加注释。
4. 着色规则(Coloring Rules)定制:为不同类型的报文设置不同的颜色,可以极大提升分析效率。例如,你可以设置:
- 遥控选择报文:绿色背景
- 遥控执行报文:红色背景
- 遥信变位报文:黄色背景
- TCP重传、乱序报文:醒目的紫红色(使用内置规则
TCP Analysis相关规则即可) 这样,在复杂的报文流中,关键操作一眼就能被识别。
3. IEC 101规约核心帧结构快速回顾
在深入抓包分析前,我们有必要快速回顾一下IEC 101规约(基于TCP时)的核心帧结构,这样在看Wireshark解码时才能心中有数。IEC 101报文是嵌套结构的,可以理解为“俄罗斯套娃”。
1. 应用协议数据单元(APDU):这是最外层的结构。在TCP传输中,APDU由一个启动字符(68H)、一个长度字段(L)、以及后续的链路规约数据单元(LPDU)组成。长度L定义了从LPDU开始到结束的字节数。Wireshark会清晰地解析出APDU的起始和长度。
2. 链路规约数据单元(LPDU):位于APDU内部。它包含链路控制域和链路用户数据。链路控制域用于区分帧类型,比如:
- I格式帧(信息传输格式):用于传输数据,包含发送序列号N(S)和接收序列号N(R),用于确认机制。
- S格式帧(监视功能格式):仅包含接收序列号N(R),用于确认接收到的I帧。
- U格式帧(无编号控制功能格式):用于链路启停、测试等控制,例如
STARTDT(启动数据传输)、STOPDT(停止数据传输)、TESTFR(测试帧)。
3. 应用服务数据单元(ASDU):这是承载具体“业务内容”的核心,位于I格式帧的“链路用户数据”部分。ASDU的结构是分析遥控遥信的关键,它包含:
- 类型标识(Type ID):1字节,定义ASDU的类型。例如:
1:单点信息(遥信,不带时标)45:单命令(遥控)46:双命令100:召唤命令(总召)
- 可变结构限定词(VSQ):1字节,最高位指示地址是顺序的还是独立的,低7位表示信息对象数目。
- 传送原因(COT):1-2字节,说明数据发送的原因。例如:
3:突发/自发6:激活7:激活确认10:激活终止
- 公共地址(Common Address):通常2字节,代表子站(RTU)的站地址。
- 信息对象地址(IOA):2或3字节,唯一标识一个具体的遥信点或遥控点。
- 信息元素:具体的数值或状态,如单点遥信的值(1=合,0=分),遥控命令的值(0=分,1=合)及选择/执行标识(S/E)。
- 时标(可选):7字节,包含毫秒、分钟、小时等信息。
Wireshark的强大之处在于,它会自动将这个复杂的嵌套结构层层展开,以树状视图清晰地展示出来,我们无需手动计算偏移量。
4. 实战抓包分析:遥信(通信)报文解析
遥信,即状态量信息,是子站向主站上报开关、刀闸等设备位置状态的信息。我们首先从最常见的单点遥信变位(类型标识1)开始分析。
4.1 捕获与筛选遥信报文
启动Wireshark,在正确的网卡上开始捕获。在子站设备发生状态变化(比如一个开关分闸)时,你应该能捕获到相应的报文。停止捕获后,在显示过滤器栏输入:iec60870_asdu.type == 1并应用。
你会看到若干条报文被筛选出来。点击其中一条,在Wireshark窗口中部,展开协议详情树,找到IEC 60870-5-104 ASDU或类似的节点。逐层展开:
- APDU层:你会看到启动字符
68,以及长度L。 - LPDU层(I格式帧):看到
I-frame标识,以及N(S)和N(R)序列号。这体现了101规约的链路层确认机制。 - ASDU层:这是重点。
TypeID: 1 (M_SP_NA_1):这明确告诉我们这是一个“不带时标的单点信息”。VSQ: 0x81:二进制1000 0001。最高位1表示信息对象地址是顺序的(即后续信息对象地址是连续的),低7位000 0001(即1)表示包含1个信息对象。如果VSQ是0x01,则表示地址是独立的且只有一个对象。COT: 3 (SPONTANEOUS):传送原因是“突发/自发”,这正是变位上传的典型原因。Common Address: 1 (0x0001):公共地址为1,表示这个报文来自站地址为1的子站。IOA: 2049 (0x0801):信息对象地址。这是关键!2049对应着实际物理设备中的某个具体的开关或信号。你需要查阅子站的点表(Point List)来确认IOA 2049代表的是“10kV进线101开关位置”还是其他什么信号。SIQ: 0x01:单点信息品质。将其转换为二进制:0000 0001。通常最低位(bit 0)表示状态值:1代表“合”(ON),0代表“分”(OFF)。其他位可能代表品质,如是否被封锁、是否无效等。这里0x01通常表示“合闸,有效”。
4.2 遥信分析中的关键技巧与常见问题
- 技巧:关联点表。单独看
IOA: 2049毫无意义。你必须有一份设备厂商提供的点表文档,其中列出了每个IOA对应的实际信号描述。将Wireshark解析出的IOA与点表对照,是分析工作的第一步,也是必不可少的一步。我习惯在分析时,打开一个Excel点表,使用Ctrl+F快速查找。 - 技巧:观察品质位。不要只关注状态值。SIQ或DIQ(双点信息品质)中的其他位可能指示数据是否有效、是否被取代、是否被封锁。如果状态值异常,首先检查品质位。例如,如果“无效(IV)”位被置1,即使状态值是0或1,这个数据也是不可信的。
- 常见问题:遥信抖动(Flickering)。在抓包文件中,你可能会看到在极短时间内(几十到几百毫秒),同一个IOA的遥信状态连续快速变化多次。这通常不是真实的设备抖动,可能是接线松动、继电器触点抖动或通信干扰导致的。在Wireshark中,你可以使用
io.analysis相关过滤器或统计功能,找出短时间内重复变位的IOA,为现场检修提供精准线索。 - 常见问题:遥信不上送。如果某个开关实际变位了,但主站没收到报文。首先,检查抓包文件中是否有对应的ASDU类型1的报文。如果没有,问题可能出在子站配置(是否将该点配置为“自发上传”)、子站程序或硬件采集回路。如果有报文,则检查主站侧的接收逻辑和点表配置是否正确。
5. 实战抓包分析:遥控(控制)报文交互全过程
遥控是主站向子站发送命令,控制开关分合的过程。这是一个典型的“选择-执行”或“直接执行”的二次确认过程。我们以最常见的“选择-执行”模式分析双命令(类型标识46,C_DC_NA_1)为例。
5.1 遥控选择阶段报文分析
在主站操作员下发一个“合闸”命令后,Wireshark会捕获到一个交互序列。首先过滤遥控相关的报文:iec60870_asdu.type == 46。
主站 -> 子站:遥控选择命令(激活)
- 找到第一条类型为46的报文。查看其ASDU详情:
TypeID: 46 (C_DC_NA_1):双命令。COT: 6 (ACTIVATION):传送原因为“激活”,这正对应“选择”阶段。Common Address: 1:目标子站地址。IOA: 2050:要遥控的开关对象地址(假设)。DCO: 0x81:双命令对象。分析其值:0x81二进制1000 0001。这里需要看规约定义。通常,bit 1-0表示命令状态:01可能代表“合”,10代表“分”。bit 7(最高位)是S/E(选择/执行)位,这里为1,表示这是一个**选择(SELECT)**命令。bit 6是QU(瞬时/持续)位。所以0x81很可能表示“选择合闸”。
- 同时,注意这条报文的链路层是I格式帧,它会被赋予一个发送序列号N(S)。
- 找到第一条类型为46的报文。查看其ASDU详情:
子站 -> 主站:遥控选择确认(激活确认)
- 紧接着,你应该能找到子站回应的另一条类型46的报文。
- 查看其
COT: 7 (ACTIVATION CONFIRMATION):传送原因为“激活确认”。 - 查看其
DCO字段。在确认报文中,子站会回显接收到的命令状态。其DCO值应与主站下发的选择命令完全相同(例如0x81)。这表示子站已正确接收并准备好执行该命令。 - 注意这条确认报文的链路层,它是一个S格式帧或一个新的I帧(其N(R)确认了主站的I帧)。S格式帧的N(R)等于主站发送的I帧的N(S)+1,表示“我已收到你的N(S)帧,期待下一帧是N(S)+1”。
5.2 遥控执行阶段报文分析
操作员在主站界面点击“执行”后。
主站 -> 子站:遥控执行命令(激活)
- 捕获到新的类型46报文。
- 其
COT仍然是6 (ACTIVATION),因为这也是一个激活过程。 - 关键变化在
DCO字段。此时,DCO的值可能变为0x83(假设)。对比0x81,低位的命令状态位(01)可能没变(还是合闸),但S/E位(bit 7)可能被置为0?这里需要根据具体规约实现。更常见的是,执行命令的DCO中,S/E位会是一个不同的值来标识“执行”,或者通过一个单独的“执行”位(bit 6)来标识。你必须结合设备厂商的规约说明书来解读。无论如何,这个DCO值会明确指示这是一个“执行”动作。 - 同样,这是一个I格式帧。
子站 -> 主站:遥控执行确认(激活确认)
- 子站再次回应一条类型46,
COT为7的报文。 - 其
DCO回显主站发送的执行命令的DCO值(例如0x83)。 - 同时,子站会开始操作实际的继电器出口。
- 子站再次回应一条类型46,
子站 -> 主站:遥控最终命令状态(激活终止)
- 在操作执行完成后(继电器已动作,且子站检测到相应的位置信号),子站会主动上送一条新的ASDU,通常是单点遥信(类型1)或双点遥信(类型3),来报告开关的新位置状态。
- 这条报文的
COT通常是3 (SPONTANEOUS)或20 (ACTIVATION TERMINATION)。 - 其
IOA就是被遥控的开关地址(2050),其状态值应与命令要求一致(合闸)。 - 这是遥控闭环完成的标志。主站收到此变位信号,才会在界面上将开关图标更新为合闸状态,并提示遥控成功。
5.3 遥控分析中的核心陷阱与心得
- 陷阱:混淆选择与执行的DCO编码。这是最容易出错的地方。不同厂商、不同版本的规约对DCO中S/E位、QU位的定义可能有细微差别。绝对不要想当然。一定要找到对应设备型号的《IEC 101通信规约说明书》,里面会有详细的DCO位定义表。没有这个表,分析遥控报文就像猜谜。
- 心得:使用“追踪TCP流”功能辅助分析。对于一次完整的遥控过程,右键点击遥控选择阶段的报文,选择“追踪流” -> “TCP流”。Wireshark会弹出一个新窗口,只显示这次TCP连接中的所有报文,并按时间顺序排列。这能让你非常清晰地看到“选择-确认-执行-确认-变位上报”的完整交互序列,比在密密麻麻的列表里找方便得多。
- 常见问题:遥控超时失败。如果在抓包中看到主站发了选择命令,但没有收到子站的激活确认,或者发了执行命令后没有收到确认和变位,问题可能出在:1) 网络中断或延迟;2) 子站程序处理超时;3) 子站校验(如对象地址不可控、就地/远方切换把手在就地位置等)失败。通过分析交互序列中缺失的环节,可以快速定位责任方。
- 技巧:关注链路层序列号。在分析遥控这种关键操作时,务必同时关注链路层I帧和S帧的序列号N(S)/N(R)。如果出现序列号不连续、大量重传([TCP Out-Of-Order]或[TCP Retransmission]警告),说明网络存在丢包或拥塞,这可能是导致遥控偶发失败的根源,即使应用层报文看起来是完整的。
6. 高级分析与故障排查实战案例
掌握了基础报文解析后,我们可以利用Wireshark更强大的功能来解决复杂问题。
6.1 利用统计和图表功能进行宏观分析
Wireshark的“统计”(Statistics)菜单功能强大。
- “对话”(Conversations):查看TCP对话,可以清晰看到主站和各个子站IP之间的数据流量大小、报文数量。如果某个子站的流量异常低(可能断线)或异常高(可能数据风暴),这里一目了然。
- “协议分级”(Protocol Hierarchy):看看整个抓包文件中,IEC 60870协议占比多少,TCP/IP开销占比多少,有没有其他无关协议占用大量带宽。
- “IO图表”(IO Graph):这是定位遥信雪崩或网络风暴的利器。你可以创建一个图表,Y轴为“报文数/秒”或“字节数/秒”,X轴为时间。然后为IEC 101遥信报文(
iec60870_asdu.type == 1)添加一条曲线。如果图上出现一个尖锐的峰值,对应时间点可能就是大量遥信同时变位(例如站内事故导致多个保护动作),这可能会冲击主站处理能力。你也可以为TCP重传报文添加一条曲线,观察网络质量。
6.2 典型通信故障排查流程
当现场报告“通信中断”或“数据不刷新”时,可以遵循以下步骤用Wireshark排查:
- 物理连通性检查:首先看抓包文件最前面,有没有主站和子站IP之间的ARP广播和应答?如果没有ARP应答,说明链路层就不通,问题在物理网线、交换机或IP配置。
- TCP连接建立检查:过滤
tcp.port == 2404,查看是否有完整的TCP三次握手(SYN, SYN-ACK, ACK)?如果没有,可能是子站服务未启动、防火墙拦截、或IP/端口错误。 - IEC 101链路层状态检查:过滤
iec60870,查看报文交互。- 没有U格式帧(STARTDT):如果TCP连接建立了,但长时间没有IEC 101的应用层报文,可能是主站或子站的应用层连接管理逻辑有问题,没有发送
STARTDT激活链路。 - 只有TESTFR(测试帧)往返:如果只有
TESTFR和TESTFR CONFIRM在来回传递,没有数据帧,说明链路是激活的,但可能没有配置数据召唤或子站没有自发上传权限。 - 序列号停滞:观察I帧的N(S)和N(R)。如果主站发送的I帧的N(S)一直不增长,或者子站的N(R)一直不更新,说明有一方的报文没有被对方确认,链路可能已“卡死”。这通常是因为缓冲区满、处理超时或程序bug。
- 没有U格式帧(STARTDT):如果TCP连接建立了,但长时间没有IEC 101的应用层报文,可能是主站或子站的应用层连接管理逻辑有问题,没有发送
- 应用层数据分析:如果链路正常,但某个信号不对。就按照前面章节的方法,针对该信号的IOA进行过滤(如
iec60870_asdu.ioa == 2050),查看其所有历史报文,检查数值、品质、时标是否正确。
6.3 解码异常与自定义解析
有时你会遇到Wireshark无法正确解析的报文,状态栏显示“Malformed Packet”或解码信息混乱。可能的原因和应对措施:
- 原因一:TCP粘包/拆包。IEC 101 over TCP的APDU理论上应该是完整的报文。但有些设备实现不佳,可能将一个APDU拆成多个TCP包发送,或者将多个APDU合并成一个TCP包。Wireshark的
iec60870解码器期望每个TCP段开始都是0x68。如果发生粘包拆包,解码会错位。你可以尝试在“编辑”->“首选项”->“协议”->IEC 60870-5-101/104中,调整“尝试将流重组为ASDU”等选项。 - 原因二:非标准端口或私有扩展。如果设备使用了非标准端口,Wireshark可能不会自动将其识别为IEC 101流量。你需要右键点击一个TCP包,选择“解码为...”(Decode As...),然后强制指定该TCP端口使用
IEC 60870-5-104解码器。 - 原因三:厂商私有数据域。有些厂商在标准ASDU后面添加了自定义的数据域,导致Wireshark解析剩余字节时出错。这时,你可以看到解码树中有一部分显示为“剩余数据”或解析错误。对于这部分,就需要结合厂商的私有协议文档,使用Wireshark的“自定义字节”功能或编写Lua脚本来解析了。一个更简单的办法是,只要标准部分解析正确,私有部分可以先忽略,或者直接以十六进制形式对照文档查看。
7. 将分析技能固化为工作流程
经过几次实战,你应该能将这套方法固化为标准工作流程:
- 准备阶段:获取网络拓扑图、设备IP地址表、通信端口表、子站点表(IOA映射表)、设备规约说明书。这是你的“地图”和“词典”。
- 捕获阶段:根据问题现象,在关键节点(镜像端口、主站、问题子站)部署Wireshark,设置合适的捕获过滤器,开始捕获。重现问题(例如,进行一次遥控操作,或等待一次通信中断)。
- 初步筛选:使用显示过滤器(如
iec60870、特定IP、特定端口)缩小范围,聚焦问题相关流量。 - 分层解析:
- 物理/网络层:检查ARP、TCP握手、重传、丢包。
- 链路层:检查STARTDT/STOPDT、TESTFR、I/S/U帧序列是否正常,序列号是否连续。
- 应用层:针对具体功能(遥控、遥信、遥测、总召),分析ASDU的类型、原因、地址、数据、品质。
- 关联分析:将报文中的抽象地址(IOA)和值,与点表中的实际设备名称和状态关联起来。将报文交互时序与操作员的操作时间线关联起来。
- 定位与验证:根据分析结果,提出假设(例如“子站未响应激活确认,可能是配置中该点被封锁”),然后通过修改配置、重启服务、检查硬件等方式验证假设。
- 报告与归档:将关键的抓包文件(
.pcapng格式)保存,并在Wireshark中标记出问题报文,添加注释。生成一份简明的分析报告,附上截图和过滤条件,便于团队交流和知识沉淀。
我个人在实际工作中发现,养成随手抓包、存包的习惯非常有用。很多偶发性问题,当时可能没时间深究,但只要保存了抓包文件,日后就可以反复分析,或者在新遇到类似问题时进行对比。Wireshark不仅仅是一个故障排查工具,更是一个深度理解通信协议、验证系统行为、甚至进行协议一致性测试的利器。告别枯燥的手册,让网络上的真实数据成为你最好的老师。