goose

package
v0.739.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 24, 2026 License: AGPL-3.0 Imports: 4 Imported by: 0

Documentation

Overview

Package goose decodes IEC 61850-8-1 GOOSE (Generic Object Oriented Substation Events) messages — the time-critical multicast Ethernet protocol that carries protective-relay signals between Intelligent Electronic Devices (IEDs) inside modern digital substations.

GOOSE is the latency-bounded sibling of MMS (the IEC 61850 SCADA application layer) and Sampled Values (the instantaneous-current/voltage multicast from merging units). When a protective relay detects a fault and decides to trip a breaker, the trip signal travels as a GOOSE message — and the IEC 61850-5 performance requirements demand it reach the trip coil within **4 ms** end-to-end (Type 1A "Trip" performance class). To make that latency budget realistic, GOOSE rides **directly over Ethernet** (EtherType 0x88B8) — no IP, no UDP, no TCP — and uses **multicast** so a single sender reaches every interested IED on the substation LAN simultaneously.

Operationally, GOOSE carries:

  • **Trip / Block signals** from protection IEDs (line distance, bus differential, transformer differential) to circuit- breaker controllers.
  • **Interlocking** between IEDs supervising adjacent bays (busbar isolators, transfer switches, earthing switches).
  • **Synchronisation status + position indications** from bay-control IEDs to the station HMI.
  • **Test-mode + maintenance signals** during commissioning.

Each GOOSE message carries a **stNum** (state number; increments on every state change) and **sqNum** (sequence number; increments on each retransmission while state is stable). Receivers detect data loss by watching stNum / sqNum and tag messages stale once the **timeAllowedToLive** budget expires.

Wrap-vs-native judgement

Native. IEC 61850-8-1 is publicly available; the GOOSE wire
format is a tight 8-byte fixed header (APPID + Length +
Reserved1 + Reserved2) followed by an ASN.1 BER-encoded
IECGoosePdu. The PDU schema is fully specified — a
deterministic walker with implicit context-class tags 0x80
through 0x8B. No crypto at the parse layer (IEC 62351-6
signs GOOSE with HMAC-SHA256 in a trailing field; that
signature appears AFTER the PDU and is surfaced as raw
`security_trailer_hex` for future per-signature decoders).

What this package covers

  • **GOOSE header** (IEC 61850-8-1 §A.3, 8 bytes, big-endian; transmitted IMMEDIATELY after the 0x88B8 EtherType):

  • bytes 0-1: **APPID** (uint16 BE; identifies the GOOSE control block; convention is 0x0000-0x3FFF for GOOSE, 0x4000-0x7FFF for Sampled Values).

  • bytes 2-3: **Length** (uint16 BE; total bytes from APPID through end of APDU — INCLUDING the 8-byte header itself).

  • bytes 4-5: Reserved1 (= 0x0000).

  • bytes 6-7: Reserved2 (= 0x0000; IEC 62351-6 re-purposes these bytes for a security tag).

  • **IECGoosePdu** (ASN.1 BER-encoded; tag 0x61 = IMPLICIT [APPLICATION 1] CONSTRUCTED — IEC 61850-8-1 §A.2):

  • byte 0: 0x61 outer tag.

  • bytes 1+: BER length (short form for ≤127 bytes; long form for ≥128 bytes).

  • Inside the PDU, a sequence of context-class IMPLICIT fields (uniformly tagged 0x80 + N):

  • [0] `gocbRef` IMPLICIT VISIBLE-STRING (tag 0x80) — "<IED-name>/<LD>$GO$<GoCB-name>" reference.

  • [1] `timeAllowedToLive` IMPLICIT INTEGER (tag 0x81; milliseconds — receivers must mark stale after this elapses without a fresh message).

  • [2] `datSet` IMPLICIT VISIBLE-STRING (tag 0x82) — "<IED-name>/<LD>$<DataSet-name>" reference.

  • [3] `goID` IMPLICIT VISIBLE-STRING (tag 0x83; optional human-readable label).

  • [4] `t` IMPLICIT UtcTime (tag 0x84; 8 bytes — 4-byte secondsSinceEpoch + 3-byte fractionOfSecond

  • 1-byte timeQuality).

  • [5] `stNum` IMPLICIT INTEGER (tag 0x85).

  • [6] `sqNum` IMPLICIT INTEGER (tag 0x86).

  • [7] `test` IMPLICIT BOOLEAN (tag 0x87).

  • [8] `confRev` IMPLICIT INTEGER (tag 0x88; configuration revision counter).

  • [9] `ndsCom` IMPLICIT BOOLEAN (tag 0x89; "Needs Commissioning").

  • [10] `numDatSetEntries` IMPLICIT INTEGER (tag 0x8A).

  • [11] `allData` IMPLICIT SEQUENCE OF Data (tag 0xAB; constructed). The per-entry Data choice is dataset-specific and surfaced as raw `all_data_hex`.

What this package does NOT cover (deliberately out of scope)

  • **L2 framing** — feed GOOSE bytes after the 14-byte Ethernet header (destination MAC, source MAC, EtherType 0x88B8). Standard GOOSE destination is multicast group 01:0C:CD:01:00:00 / range 01:0C:CD:01:00:00 - 01:0C:CD:01:01:FF. VLAN tagging (IEEE 802.1Q PCP=4 priority + VID) is common but is part of the L2 frame and not parsed here.
  • **Per-entry Data decoder** — the `allData` field carries a sequence of Data choices (Boolean, BitString, Integer, UnsignedInteger, FloatingPoint, OctetString, VisibleString, BinaryTime, UtcTime, BCD, BooleanArray, MMSString, Structure). The per-IED dataset schema is loaded from SCL (SubstationConfigurationLanguage) files at engineering time; this decoder surfaces `all_data_hex` for downstream per-DataSet walkers.
  • **IEC 62351-6 security** — the trailing HMAC-SHA256 signature + key-management metadata appear AFTER the IECGoosePdu in the Length-bounded region; surfaced as `security_trailer_hex`. Verification requires the per- IED shared key.
  • **Replay / sequence-number reasoning** — the decoder surfaces stNum / sqNum / timeAllowedToLive but does not itself enforce freshness or detect replay (per-flow state is a higher-level concern).
  • **Sampled Values (SMV)** — IEC 61850-9-2 SMV uses a similar Ethernet header (EtherType 0x88BA) with a different PDU shape; out of scope here.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Result

type Result struct {
	TotalBytes int `json:"total_bytes"`

	// GOOSE header
	APPID     int `json:"appid"`
	Length    int `json:"length"`
	Reserved1 int `json:"reserved1"`
	Reserved2 int `json:"reserved2"`

	// IECGoosePdu fields (in BER tag order)
	GOCBRef             string   `json:"gocb_ref,omitempty"`
	TimeAllowedToLiveMS int64    `json:"time_allowed_to_live_ms,omitempty"`
	DatSet              string   `json:"dat_set,omitempty"`
	GoID                string   `json:"go_id,omitempty"`
	UtcTime             *UtcTime `json:"utc_time,omitempty"`
	StNum               int64    `json:"st_num"`
	SqNum               int64    `json:"sq_num"`
	Test                bool     `json:"test"`
	ConfRev             int64    `json:"conf_rev,omitempty"`
	NdsCom              bool     `json:"nds_com,omitempty"`
	NumDatSetEntries    int64    `json:"num_dat_set_entries,omitempty"`
	AllDataHex          string   `json:"all_data_hex,omitempty"`

	// Trailing IEC 62351-6 security bytes (if any).
	SecurityTrailerHex string `json:"security_trailer_hex,omitempty"`
}

Result is the structured decode of a GOOSE message.

func Decode

func Decode(hexStr string) (*Result, error)

Decode parses an IEC 61850 GOOSE message from a hex string starting at the APPID (i.e. AFTER the 14-byte Ethernet header + 0x88B8 EtherType). Separators (':' '-' '_' whitespace) are tolerated; a leading '0x' prefix is stripped.

type UtcTime

type UtcTime struct {
	SecondsSinceEpoch uint32 `json:"seconds_since_epoch"`
	FractionOfSecond  uint32 `json:"fraction_of_second"`
	TimeQualityHex    string `json:"time_quality_hex"`
}

UtcTime is the 8-byte IEC 61850 UtcTime breakdown.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL