Documentation
¶
Overview ¶
Package pim decodes Protocol Independent Multicast (PIM) version 2 packets per RFC 7761 (PIM-SM v2; the dominant multicast routing protocol). PIM Sparse-Mode is the de-facto multicast routing protocol in every enterprise + ISP + cloud fabric that carries multicast traffic; the Dense-Mode + BIDIR variants share the same packet envelope and the same type space.
Wrap-vs-native judgement
Native. RFC 7761 is fully public; PIM uses a tight 4-byte common header (Version + Type + Reserved + Checksum) followed by a per-type body. Bodies use a small set of well-defined "Encoded Address" formats (Unicast / Group / Source — RFC 7761 §4.9) plus typed TLV options for Hello. No crypto, no compression — operators paste PIM bytes (IP protocol number 103, multicast to 224.0.0.13 for Hello / Bootstrap / Assert / Join-Prune, unicast to RPs for Register) from a `tcpdump -X proto 103` line, a Wireshark Follow-IP-Stream view, or any PIM-speaking router's tcpdump and get the documented header + per-type body breakdown.
What this package covers
**4-byte common header** (RFC 7761 §4.9):
byte 0: Version (4 bits; always 2) + Type (4 bits).
byte 1: Reserved (0; some PIM variants use this byte as a subtype — surfaced as a Note when non-zero).
bytes 2-3: Checksum (uint16 BE, hex-formatted).
**11-entry Type name table** (RFC 7761 §4.9 + the older PIM-DM / BIDIR / PIM-MIB registries): 0 Hello, 1 Register, 2 Register-Stop, 3 Join/Prune, 4 Bootstrap, 5 Assert, 6 Graft (PIM-DM only), 7 Graft-Ack (PIM-DM only), 8 Candidate-RP-Advertisement, 9 State Refresh (PIM-DM only), 10 DF Election (PIM-BIDIR).
**Hello body** (Type 0; RFC 7761 §4.3) — TLV option walker over (Type uint16 BE, Length uint16 BE, Value) records. **5-entry option type table**: 1 Holdtime (uint16 seconds; 0xFFFF = never timeout), 2 LAN Prune Delay (uint16 propagation_delay + uint16 override_interval with T-bit in the high bit of propagation_delay), 19 DR Priority (uint32 — higher wins; absence = treat as priority 0 per RFC 7761 §4.3.2), 20 Generation ID (uint32 — changes on neighbor reset; a change is the canonical detection of a PIM neighbor reboot), 24 Address List (encoded-address list of secondary addresses the router owns on the LAN).
**Register body** (Type 1; RFC 7761 §4.4) — 4-byte flags (B = Border-bit, N = Null-Register-bit) + encapsulated multicast IP datagram (surfaced as raw hex; first nibble heuristic for inner IPv4 vs IPv6).
**Register-Stop body** (Type 2; RFC 7761 §4.4) — Encoded Group Address + Encoded Unicast Source Address.
**Join/Prune body** (Type 3; RFC 7761 §4.5) — Encoded Unicast Upstream Neighbor + Reserved + Num Groups + Hold Time (uint16 seconds) + N × Group records:
Multicast Group Address (Encoded Group)
Number of Joined Sources (uint16)
Number of Pruned Sources (uint16)
Joined Source Addresses (N × Encoded Source)
Pruned Source Addresses (N × Encoded Source)
**Bootstrap body** (Type 4; RFC 5059) — Fragment Tag + Hash Mask Len + BSR Priority + Encoded Unicast BSR Address + per-group RP-Set records (decoded structurally, including the RP records inside each group).
**Assert body** (Type 5; RFC 7761 §4.6) — Encoded Group Address + Encoded Unicast Source Address + 1-bit R (RPT bit, high bit of byte 0) + 31-bit Metric Preference + 32-bit Metric. Used for tie-breaking when multiple PIM routers see the same multicast forwarder candidate on a LAN.
**Encoded Address parsing** (RFC 7761 §4.9.1):
**Encoded Unicast** — Addr Family (1 byte: 1 IPv4 / 2 IPv6) + Encoding Type (1 byte; 0 native) + Address (4 bytes IPv4 / 16 bytes IPv6).
**Encoded Group** — Addr Family + Encoding Type + Flags byte (B-bit + Z-bit) + Mask Length + Group Address.
**Encoded Source** — Addr Family + Encoding Type + Flags byte (S/W/R bits in the low 3 bits of byte 2) + Mask Length + Source Address.
What this package does NOT cover (deliberately out of scope)
IP framing — feed PIM bytes after the IPv4/IPv6 header strip. PIM runs over IP protocol 103.
PIMv1 — the pre-RFC 2117 "DVMRP-like" form is obsolete (no production deployments since the late 1990s); the Version field will be flagged in a Note if it is not 2.
Multicast routing-table reasoning — RPF check, (*,G) and (S,G) tree state — that's higher-level analysis.
PIM checksum verification — surfaced as a hex string but not recomputed (the IPv4 pseudo-header dependency would require the operator to provide the IP src/dst).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AssertBody ¶
type AssertBody struct {
Group EncodedGroup `json:"group"`
Source EncodedUnicast `json:"source"`
RPTBit bool `json:"rpt_bit"`
MetricPreference uint32 `json:"metric_preference"`
Metric uint32 `json:"metric"`
}
AssertBody is a PIM Assert with the (group, source) tuple and the metric.
type BootstrapBody ¶
type BootstrapBody struct {
FragmentTag uint16 `json:"fragment_tag"`
HashMaskLen int `json:"hash_mask_length"`
BSRPriority int `json:"bsr_priority"`
BSRAddress EncodedUnicast `json:"bsr_address"`
RemainderHex string `json:"remainder_hex,omitempty"`
RemainderBytes int `json:"remainder_bytes"`
}
BootstrapBody is a PIM-BSR Bootstrap message.
type EncodedGroup ¶
type EncodedGroup struct {
AddressFamily int `json:"address_family"`
EncodingType int `json:"encoding_type"`
BBit bool `json:"b_bit_bidir"`
ZBit bool `json:"z_bit_admin_scope_zone"`
MaskLength int `json:"mask_length"`
Address string `json:"address"`
}
EncodedGroup is RFC 7761 §4.9.1 Encoded-Group-Address.
type EncodedSource ¶
type EncodedSource struct {
AddressFamily int `json:"address_family"`
EncodingType int `json:"encoding_type"`
SBit bool `json:"s_bit_sparse"`
WBit bool `json:"w_bit_wildcard"`
RBit bool `json:"r_bit_rpt"`
MaskLength int `json:"mask_length"`
Address string `json:"address"`
}
EncodedSource is RFC 7761 §4.9.1 Encoded-Source-Address.
type EncodedUnicast ¶
type EncodedUnicast struct {
AddressFamily int `json:"address_family"`
EncodingType int `json:"encoding_type"`
Address string `json:"address"`
}
EncodedUnicast is RFC 7761 §4.9.1 Encoded-Unicast-Address.
type HelloBody ¶
type HelloBody struct {
Options []HelloOption `json:"options"`
}
HelloBody is the TLV option list from a PIM Hello.
type HelloOption ¶
type HelloOption struct {
Type int `json:"type"`
TypeName string `json:"type_name"`
Length int `json:"length"`
ValueHex string `json:"value_hex,omitempty"`
// Decoded forms (populated for known types).
HoldtimeSeconds *int `json:"holdtime_seconds,omitempty"`
HoldtimeNote string `json:"holdtime_note,omitempty"`
DRPriority *uint32 `json:"dr_priority,omitempty"`
GenerationID *uint32 `json:"generation_id,omitempty"`
LANPropagationDelayMs *uint16 `json:"lan_propagation_delay_ms,omitempty"`
LANOverrideIntervalMs *uint16 `json:"lan_override_interval_ms,omitempty"`
LANTBit *bool `json:"lan_t_bit,omitempty"`
AddressList []string `json:"address_list,omitempty"`
}
HelloOption is one TLV record from a PIM Hello.
type JoinPruneBody ¶
type JoinPruneBody struct {
UpstreamNeighbor EncodedUnicast `json:"upstream_neighbor"`
NumGroups int `json:"num_groups"`
HoldTimeSeconds int `json:"hold_time_seconds"`
Groups []JoinPruneGroup `json:"groups"`
}
JoinPruneBody is the Join/Prune state for one upstream neighbor.
type JoinPruneGroup ¶
type JoinPruneGroup struct {
Group EncodedGroup `json:"group"`
NumJoined int `json:"num_joined_sources"`
NumPruned int `json:"num_pruned_sources"`
JoinedSources []EncodedSource `json:"joined_sources,omitempty"`
PrunedSources []EncodedSource `json:"pruned_sources,omitempty"`
}
JoinPruneGroup is one group record inside a Join/Prune.
type RegisterBody ¶
type RegisterBody struct {
FlagBorder bool `json:"flag_border"`
FlagNull bool `json:"flag_null_register"`
FlagsHex string `json:"flags_hex"`
EncapHex string `json:"encapsulated_datagram_hex,omitempty"`
EncapBytes int `json:"encapsulated_datagram_bytes"`
EncapVersion int `json:"encapsulated_ip_version,omitempty"`
}
RegisterBody is the unicast-tunnelled multicast datagram body.
type RegisterStopBody ¶
type RegisterStopBody struct {
Group EncodedGroup `json:"group"`
Source EncodedUnicast `json:"source"`
}
RegisterStopBody is the stop signal for a Register tunnel.
type Result ¶
type Result struct {
Version int `json:"version"`
Type int `json:"type"`
TypeName string `json:"type_name"`
Reserved int `json:"reserved"`
ChecksumHex string `json:"checksum_hex"`
TotalBytes int `json:"total_bytes"`
Hello *HelloBody `json:"hello,omitempty"`
Register *RegisterBody `json:"register,omitempty"`
RegisterStop *RegisterStopBody `json:"register_stop,omitempty"`
JoinPrune *JoinPruneBody `json:"join_prune,omitempty"`
Assert *AssertBody `json:"assert,omitempty"`
Bootstrap *BootstrapBody `json:"bootstrap,omitempty"`
Notes []string `json:"notes,omitempty"`
}
Result is the top-level decoded view.