2. GOOSE报文结构解析:以太网帧头、APPID、GOOSE PDU、数据集与控制块

各位好,我是老张。今天咱们来聊聊GOOSE报文的结构。说实话,我刚入行那会儿,看着报文抓包里那一长串十六进制数,头都大了。后来摸清了门道,发现其实就那么几个关键部分。今天我就把这套"拆报文"的功夫教给你。

2.1 从以太网帧头说起

GOOSE报文,说白了就是跑在以太网上的特殊数据包。它首先得是个标准的以太网帧,然后才谈得上"特殊"在哪。

以太网帧头长这样:

| 目的MAC (6字节) | 源MAC (6字节) | 以太网类型 (2字节) |

这里有个关键点——目的MAC地址。GOOSE用的是组播MAC,范围是01-0C-CD-01-00-0001-0C-CD-01-01-FF。我当年在变电站调试时,有次发现某台智能终端死活收不到GOOSE,查了半天,结果是交换机的IGMP Snooping把组播给过滤了。嗯,这种坑踩过一次就记住了。

以太网类型字段固定为0x88B8,这是IEC 61850给GOOSE分配的专属标识。抓包时看到这个值,基本就能确定是GOOSE报文了。

2.2 APPID——报文的"身份证"

紧跟在以太网帧头后面的,是4字节的TPID和2字节的APPID。不过在实际工程中,我们更关注APPID。

APPID的全称是Application Identifier,应用标识。它是个2字节的值,用来唯一标识一个GOOSE控制块。说白了,就是告诉接收方:"嘿,我是谁发出来的,属于哪个应用。"

APPID的取值规则:

  • 范围:0x0000 ~ 0xFFFF
  • 0x0000:保留,表示未配置
  • 0x0001 ~ 0x3FFF:用于GOOSE
  • 0x4000 ~ 0x7FFF:用于SMV(采样值)

我在现场调试时,习惯把APPID和装置编号对应起来。比如保护装置1用0x1001,保护装置2用0x1002,这样看报文就能快速定位来源。你想想看,要是所有装置都用默认的0x0001,那排查问题得多痛苦?

2.3 GOOSE PDU——核心数据区

接下来是重头戏——GOOSE PDU(Protocol Data Unit)。这部分采用ASN.1的BER编码,说白了就是TLV结构:Type-Length-Value。

一个完整的GOOSE PDU包含以下字段:

字段名 标签 说明
gocbRef 0x81 GOOSE控制块引用,格式如"LD1/LLN0$GO$gcb1"
timeAllowedtoLive 0x82 允许生存时间,单位毫秒,接收方用这个判断报文是否超时
datSet 0x83 数据集引用,指向具体的数据定义
goID 0x84 GOOSE标识,可选字段,用于调试
t 0x85 时间戳,报文生成时刻
stNum 0x86 状态序号,每次数据变化+1
sqNum 0x87 序列序号,每次重发+1
simulation 0x88 仿真标志,TRUE表示测试报文
confRev 0x89 配置版本号,配置变化时递增
ndsCom 0x8A 需要后续通信,通常为FALSE
numDatSetEntries 0x8B 数据集中条目数量
allData 0xAB 实际数据,按数据集定义顺序排列

这里我特别想强调stNumsqNum这两个序号。它们配合起来,构成了GOOSE的"心跳+变化"机制:

  • 数据不变时:stNum不变,sqNum递增(重发机制)
  • 数据变化时:stNum+1,sqNum重置为0

我曾经遇到过一个奇怪的问题:某台装置频繁报"GOOSE断链",但抓包看报文明明在发。后来发现是stNum溢出了——从65535跳回0时,接收方认为序号异常,直接丢弃了报文。这种边界情况,厂家文档里很少提,全靠现场踩坑。

2.4 数据集与控制块——报文背后的"剧本"

报文里传输的allData字段,到底包含哪些数据?这就得看数据集(DataSet)的定义了。

数据集就像一份"数据清单",告诉发送方:"你要把这几条数据打包发出去。"比如:

数据集 "dsGOOSE1" 包含:
  1. 位置1:断路器A相位置 (GGIO1.Ind1.stVal)
  2. 位置2:断路器B相位置 (GGIO1.Ind2.stVal)
  3. 位置3:断路器C相位置 (GGIO1.Ind3.stVal)
  4. 位置4:重合闸充电状态 (RBRF1.Ind1.stVal)

控制块(GSEControl)则是"执行者",它指定了:

  • 用哪个数据集(datSet)
  • 发往哪个组播地址(destination MAC)
  • APPID是多少
  • 最小重发间隔、最大重发间隔等参数

说白了,控制块是"怎么发",数据集是"发什么"。两者配合,才构成了一条完整的GOOSE报文。

我的调试小技巧:

拿到SCD文件后,先搜"GSEControl"关键字,找到所有控制块定义。然后对照着看报文里的gocbRef和datSet,就能快速定位这条报文对应哪个IED的哪个功能。这比瞎抓包有效率得多。

2.5 一张图看懂GOOSE报文结构

说了这么多,不如一张图来得直观。下面是我用SVG画的GOOSE报文结构图,你一看就明白:

GOOSE报文结构总览 以太网帧头 (14字节) 目的MAC(6B) | 源MAC(6B) | 以太网类型=0x88B8(2B) VLAN标签 (4字节,可选) TPID=0x8100 | PRI | CFI | VID APPID (2字节) + 保留 (2字节) + 长度 (2字节) APPID唯一标识GOOSE控制块,如0x1001 GOOSE PDU (ASN.1 BER编码) gocbRef (0x81) — 控制块引用 timeAllowedtoLive (0x82) — 生存时间 datSet (0x83) — 数据集引用 goID (0x84) — GOOSE标识 t (0x85) — 时间戳 stNum (0x86) / sqNum (0x87) — 序号 allData (0xAB) — 实际数据值 其他字段:simulation, confRev, ndsCom... 注:allData中的数据顺序由数据集(DataSet)定义决定,与控制块(GSEControl)绑定

⚠️ 重要提醒:

报文解析时,千万别把VLAN标签和APPID搞混了。VLAN标签的TPID是0x8100,而APPID是0x88B8后面的内容。我见过有人把VLAN ID当成APPID来配置,结果两台装置怎么都对不上号。

2.6 实战:手撕一条GOOSE报文

光说不练假把式。咱们拿一条真实的GOOSE报文来拆解:

01 0C CD 01 00 01   // 目的MAC:组播地址
00 50 56 C0 00 08   // 源MAC:VMware虚拟网卡
88 B8               // 以太网类型:GOOSE
81 00 00 64         // VLAN标签:VID=100
00 01               // APPID:0x0001
00 64               // 长度:100字节
// 以下是GOOSE PDU内容(ASN.1编码)
61 82 00 60         // 外部TLV:类型0x61,长度0x60
80 1A               // gocbRef:标签0x80,长度0x1A
  4C 44 31 2F 4C 4C 4E 30 24 47 4F 24 67 63 62 31
  // "LD1/LLN0$GO$gcb1"
81 0A               // timeAllowedtoLive:标签0x81,长度0x0A
  00 00 27 10       // 10000ms = 10s
82 18               // datSet:标签0x82,长度0x18
  4C 44 31 2F 4C 4C 4E 30 24 44 53 24 64 73 47 4F 4F 53 45 31
  // "LD1/LLN0$DS$dsGOOSE1"
85 08               // t(时间戳):标签0x85,长度0x08
  00 00 01 87 5A 3C 00 00  // 2024-01-15 10:30:00
86 01               // stNum:标签0x86,长度0x01
  05                // 状态序号=5
87 01               // sqNum:标签0x87,长度0x01
  03                // 序列序号=3
AB 82 00 10         // allData:标签0xAB,长度0x10
  // 具体数据内容(按数据集定义解析)
  83 01 01          // 第1个数据:布尔值TRUE
  83 01 00          // 第2个数据:布尔值FALSE
  83 01 01          // 第3个数据:布尔值TRUE
  83 01 00          // 第4个数据:布尔值FALSE

看到没?报文里每个字段都清清楚楚。我建议你拿到Wireshark抓包后,对照着这个结构逐字节看一遍。看个三五条,你就能闭着眼认出每个字段了。

💡 个人习惯分享:

我调试时喜欢在Wireshark里加两列:一列显示gocbRef,一列显示stNum/sqNum。这样一眼就能看出报文是"心跳"还是"变位"。具体做法是:右键报文 → Protocol Preferences → IEC 61850 GOOSE → 勾选显示字段。

好了,GOOSE报文的结构就讲到这里。记住核心三要素:以太网帧头决定怎么传,APPID决定是谁发的,GOOSE PDU决定发了什么。下次你看到一条GOOSE报文,按这个思路拆解,保证不会乱。


公众号:蓝海资料掘金营,微信deep3321