Documentation
¶
Overview ¶
Package packet is the IS-IS PDU and TLV wire codec: the protocol's serialization boundary. It parses received frames into PDU views and serializes PDU structs back to bytes.
Layering (umbrella plan/spec-isis-0-umbrella.md): types (leaf) <- packet <- the IS-IS runtime (transport, circuit, adjacency, lsdb, spf). This package imports ONLY the domain types from internal/plugins/isis/types (plus the Go standard library and internal/core/textbuf for display). It contains no runtime, sockets, timers, LSDB, or FSM; those live in later children. It MUST NOT import the runtime, nor BGP-LS.
Decode is lazy and zero-copy (ISO/IEC 10589 clause 7.3.14 unknown-TLV propagation): a PDU view holds the caller's byte slice plus offsets, and TLVs are iterated on demand via TLVIterator yielding (type, value-slice) without copying. Unknown TLVs are retained as opaque spans so the LSDB can re-flood them verbatim. The lifetime contract: a decoded view is valid only while the caller's backing slice is stable; isis-6 copies LSP bytes it retains.
Encode is buffer-first (ai/rules/buffer-first.md): every PDU and TLV writes into a caller-owned buffer via WriteTo(buf []byte, off int) int. The PDU Length field and the LSP Fletcher checksum are written by skip-and-backfill, never a Len()-then-WriteTo() double traversal. Human-readable rendering uses textbuf/AppendTo, never fmt.Sprintf (ai/rules/no-sprintf-alloc.md).
The single highest-risk item is the ISO 8473 Fletcher checksum with its two-step adjustment (checksum.go): it is implemented and vector-tested before any runtime depends on this package.
Index ¶
- Constants
- Variables
- func AuthTLVIndex(tlvs []TLV) int
- func Checksum(data []byte, checkOff int) (high, low byte)
- func ReleaseTLVs(tlvs []TLV)
- func SignPDU(pdu []byte, key Key) ([]byte, error)
- func VerifyChecksum(data []byte) bool
- func VerifyPDU(pdu []byte, keys []Key) error
- func WriteLSPEntriesTLV(buf []byte, off int, t LSPEntriesTLV) int
- func WritePaddingTLV(buf []byte, off, n int) int
- type AdjThreeWayState
- type AreaAddressesTLV
- type AuthAlgorithm
- type AuthTLV
- type CSNP
- type CircuitType
- type ExtIPReachEntry
- type ExtISReachEntry
- type ExtendedIPReachTLV
- type ExtendedISReachTLV
- type Header
- type IPv4InterfaceAddrTLV
- type IPv6InterfaceAddrTLV
- type IPv6ReachEntry
- type IPv6ReachabilityTLV
- type ISNeighborsTLV
- type JSONView
- type Key
- type LANHello
- type LSP
- type LSPEntriesTLV
- type LSPEntry
- type NarrowISReachEntry
- type NarrowISReachTLV
- type P2PHello
- type P2PThreeWayTLV
- type PDU
- type PDUType
- type PSNP
- type ProtocolsSupportedTLV
- type SubTLV
- type TLV
- type TLVIterator
Constants ¶
const ( // CommonHeaderLen is the fixed length of the IS-IS common header in octets. CommonHeaderLen = 8 // ProtocolDiscriminator is the Intra-domain Routeing Protocol Discriminator // (NLPID 0x83 for IS-IS) carried in octet 0 of every PDU. ProtocolDiscriminator = 0x83 // VersionProtocolIDExtension is the "version/protocol ID extension" octet // (octet 2); always 1. VersionProtocolIDExtension = 0x01 // Version is the "version" octet (octet 5); always 1. Version = 0x01 // IDLength is the System ID length advertised in the common header (octet // 3). Ze fixes the System ID at 6 octets; on the wire the value 0 also // means "6 octets" (ISO/IEC 10589 clause 9.5), so both 0 and 6 are accepted // on receive and 6 is sent. IDLength = types.SystemIDLen )
Common-header constants (ISO/IEC 10589 clause 9.5/9.6/9.7/9.8).
const ( LSPFlagPartition = 0x80 // P: partition repair supported LSPFlagOverload = 0x04 // OL: LSP database overload (RFC 3787) LSPFlagISTypeL1 = 0x01 // IS type low bit LSPFlagISTypeL2 = 0x02 // IS type high bit // LSPAttachedMask covers the four ATT bits (default/delay/expense/error // metric attached); set by an L1L2 router in its L1 LSP. LSPAttachedMask = 0x78 )
Type-block bit masks (ISO/IEC 10589 clause 9.8). The high bit P is the partition-repair flag; ATT are the four attached-metric bits; OL is the LSP-database-overload bit; the low two bits are the IS type.
const ( TLVAreaAddresses = 1 // ISO/IEC 10589 clause 9.2 TLVISReachabilityNarrow = 2 // ISO/IEC 10589 clause 9.3 (decode-only) TLVISNeighbors = 6 // ISO/IEC 10589 clause 9.4 (LAN SNPA list) TLVPadding = 8 // ISO/IEC 10589 clause 9.10 TLVLSPEntries = 9 // ISO/IEC 10589 clause 9.14 TLVAuthentication = 10 // ISO/IEC 10589 clause 9.8 / RFC 5304 TLVExtendedISReach = 22 // RFC 5305 sec 3 TLVProtocolsSupported = 129 // RFC 1195 TLVIPInterfaceAddress = 132 // RFC 1195 TLVExtendedIPReach = 135 // RFC 5305 sec 4 TLVDynamicHostname = 137 // RFC 5301 TLVIPv6InterfaceAddress = 232 // RFC 5308 sec 3 TLVIPv6Reachability = 236 // RFC 5308 sec 2 TLVP2PThreeWay = 240 // RFC 5303 sec 3.1 )
TLV type codes handled by this codec (ISO/IEC 10589 clause 9 and the extension RFCs). The umbrella TLV inventory enumerates the full set; this codec encodes/decodes 1, 6, 8, 9, 10, 22, 129, 132, 135, 137, 232, 236, 240 and decode-only TLV 2.
const ( AuthTypeReserved = 0 // ISO/IEC 10589 (reserved) AuthTypeCleartext = 1 // ISO/IEC 10589: cleartext password AuthTypeGenericCrypto = 3 // RFC 5310: generic cryptographic authentication (HMAC-SHA) AuthTypeHMACMD5 = 54 // RFC 5304 sec 2 (0x36) AuthTypeDomainPrivate = 255 // ISO/IEC 10589: routeing domain private method )
IS-IS authentication type codes carried as the first value octet of TLV 10 (RFC 5304 sec 1 / sec 4, RFC 5310). The codec treats everything after this octet as opaque.
const ( NLPIDIPv4 = 0xCC // RFC 1195 NLPIDIPv6 = 0x8E // RFC 5308 sec 4 )
NLPID values carried in TLV 129 (Protocols Supported, RFC 1195 / RFC 5308).
const ( SubTLVLinkLocalRemoteID = 4 // RFC 5305 sec 5.2.1 / RFC 5307: link local/remote identifiers SubTLVIPv4InterfaceAddr = 6 // RFC 5305 sec 3.2: IPv4 interface address SubTLVIPv4NeighborAddr = 8 // RFC 5305 sec 3.3: IPv4 neighbor address )
Sub-TLV type codes for TLV 22 the spec calls out (RFC 5305 sec 3, sec 5.2.1). The codec round-trips ANY sub-TLV as an opaque SubTLV; these constants are provided for callers that build the in-scope set.
const IPv4AddrLen = 4
IPv4AddrLen is the length of one IPv4 address (TLV 132 entry).
const IPv6AddrLen = 16
IPv6AddrLen is the length of one IPv6 address (TLV 232 entry).
const LSPEntryLen = types.LifetimeLen + types.LSPIDLen + types.SequenceNumberLen + 2
LSPEntryLen is the fixed size of one LSP Entries TLV record.
const (
// MaxDISPriority is the largest DIS priority (LAN IIH).
MaxDISPriority = 127
)
PDU-specific fixed-header lengths (the octets after the common header, before the TLVs). All assume the 6-octet System ID (Ze fixes ID length at 6).
const MaxIPv4PrefixLen = 32
MaxIPv4PrefixLen is the largest IPv4 prefix length.
const MaxIPv6PrefixLen = 128
MaxIPv6PrefixLen is the largest IPv6 prefix length.
const MaxTLVValueLen = 255
MaxTLVValueLen is the largest value a single TLV can carry: the length field is one octet (ISO/IEC 10589 clause 9). A value longer than this must be split across multiple TLVs by the caller (e.g. fragmentation in isis-6).
const SNPALen = 6
SNPALen is the length of a Subnetwork Point of Attachment address (a 48-bit IEEE 802 MAC) carried in TLV 6.
const TLVHeaderLen = 2
TLVHeaderLen is the fixed type+length framing of one TLV or sub-TLV.
Variables ¶
var ( // ErrAuthMissing reports that authentication is configured but the received // PDU carries no TLV 10 (downgrade resistance, RFC 5304 sec 2 / spec R-6). ErrAuthMissing = errors.New("isis auth: authentication TLV (10) missing") // ErrAuthNotFirst reports that TLV 10 is present but is not the first TLV // (RFC 5304 sec 1; AC-8). ErrAuthNotFirst = errors.New("isis auth: authentication TLV (10) not first") // ErrAuthTypeMismatch reports that the received auth type byte does not match // any candidate key's algorithm. ErrAuthTypeMismatch = errors.New("isis auth: authentication type mismatch") // ErrAuthMismatch reports that no candidate key produced a matching digest // (the PDU is rejected; the caller increments ze_isis_auth_failures_total). ErrAuthMismatch = errors.New("isis auth: authentication value mismatch") // ErrAuthUnsupported reports an algorithm this build cannot sign/verify. ErrAuthUnsupported = errors.New("isis auth: unsupported authentication algorithm") // ErrAuthMalformed reports a PDU that cannot be decoded for signing/verifying. ErrAuthMalformed = errors.New("isis auth: malformed PDU") // ErrAuthPurgeExtraTLV reports an authenticated purge that carries a TLV other // than the authentication TLV (RFC 5304 sec 2: MUST NOT accept such purges). ErrAuthPurgeExtraTLV = errors.New("isis auth: purge carries non-authentication TLV") )
Errors returned by the auth backend. They are typed sentinels so callers can match without parsing strings; verify failures never echo key material or the received digest (security review: no leakage).
var ( // ErrShortBuffer reports a buffer too short to hold the structure being // decoded or encoded. ErrShortBuffer = errors.New("isis packet: buffer too short") // ErrBadDiscriminator reports a common header whose protocol discriminator // is not 0x83. ErrBadDiscriminator = errors.New("isis packet: bad protocol discriminator") // ErrBadVersion reports a common header whose version octets are not 1. ErrBadVersion = errors.New("isis packet: unsupported version") // ErrBadIDLength reports a common header whose ID length is neither 0 nor 6 // (Ze fixes the System ID at 6 octets). ErrBadIDLength = errors.New("isis packet: unsupported ID length") // ErrUnknownPDUType reports a PDU type code that is not one of the 9 known // types. ErrUnknownPDUType = errors.New("isis packet: unknown PDU type") // ErrTruncated reports a PDU body shorter than its fixed header requires. ErrTruncated = errors.New("isis packet: truncated PDU") // ErrLength reports a length field that is out of range (e.g. a TLV value // longer than 255 octets, or a sub-TLV block that overflows its TLV). ErrLength = errors.New("isis packet: invalid length") )
Errors returned by the codec. They are typed sentinels so callers can match without parsing strings, and they never echo attacker-controlled bytes (security review: error leakage).
Functions ¶
func AuthTLVIndex ¶
AuthTLVIndex returns the index of the first Authentication TLV (type 10) in the slice, or -1 if absent. RFC 5304 sec 1 requires TLV 10 to be the first TLV when present; isis-10 uses this to enforce ordering on receive. (The codec itself does not reject misordered auth TLVs; it only surfaces the position, per the spec's separation of codec from enforcement.)
func Checksum ¶
Checksum computes the two ISO 8473 Fletcher checksum octets for the data region, where the checksum field itself sits at checkOff octets from the start of the region (0-based). The two checksum octets in data[checkOff] and data[checkOff+1] are treated as zero during the computation regardless of their current contents, exactly as required before placing the result.
It returns the (high, low) octets to store at data[checkOff] and data[checkOff+1] so that VerifyChecksum over the same region yields zero.
ISO/IEC 10589 clause 7.3.11: the checksum is computed "commencing with the Source ID field" (the octet after Remaining Lifetime) to the end of the PDU; for an LSP the checksum field is at the start+offset of the checksummed region. The classic adjustment (ISO 8473 annex C.3.4.2) is reproduced below.
func ReleaseTLVs ¶
func ReleaseTLVs(tlvs []TLV)
ReleaseTLVs returns a TLV slice obtained from DecodeTLVs to the pool. Callers must not use the slice after this call. Nil and non-pool-sized slices (e.g. from a PDU with >64 TLVs that outgrew the pool array) are silently ignored.
func SignPDU ¶
SignPDU signs a fully-constructed PDU with key and returns the final on-wire bytes. The input pdu MUST be the complete PDU (common header + body + TLVs), already padded for an IIH (RFC 5304 sec 2 signs padded Hellos) and WITHOUT a TLV 10. SignPDU:
- inserts TLV 10 as the FIRST TLV (RFC 5304 sec 1), sized to the algorithm, with a zero (placeholder) Authentication Value;
- computes the digest over the PDU with the Authentication Value zeroed, and for LSPs with the Checksum and Remaining Lifetime fields also zeroed (RFC 5304 sec 2);
- writes the digest into the TLV 10 value (and the Key ID for the generic- crypto family, RFC 5310 sec 3.1);
- for an LSP, recomputes the Fletcher checksum LAST so the signing order is build -> sign -> checksum (spec AC-9, R-3); the Remaining Lifetime is restored to its original value before the checksum runs.
Cleartext (auth type 1) carries the password as the value and computes no digest (sanity only, not security; spec AC-5).
func VerifyChecksum ¶
VerifyChecksum re-runs the Fletcher sums over the data region (with the checksum octets in place) and reports true iff both sums are zero, which is the ISO 8473 condition for a correct checksum (ISO/IEC 10589 clause 7.3.11). A region whose stored checksum field is all zero is treated as "checksum not present" and is NOT considered valid here (callers that allow disabled checksums check that separately); this function reports strict correctness.
func VerifyPDU ¶
VerifyPDU verifies a received PDU against the candidate keys. It enforces the downgrade and ordering rules and, on a match, returns nil; on any failure it returns a typed error and the caller drops the PDU and increments ze_isis_auth_failures_total (spec AC-1, AC-2). The candidate keys are every currently-valid key in the relevant chain (the active signing key plus all accepted-on-receive keys, for hitless rotation -- spec AC-4).
Behavior:
- No candidate keys: authentication is not configured for this PDU class; VerifyPDU returns nil (unauthenticated operation, the default).
- TLV 10 absent under configured auth: ErrAuthMissing (R-6 downgrade).
- TLV 10 present but not first: ErrAuthNotFirst (RFC 5304 sec 1, AC-8).
- For each candidate key whose algorithm matches the received auth type, recompute the digest with the proper field zeroing and constant-time compare (AC-12); any match accepts.
- For an LSP that is a purge (Remaining Lifetime 0), additionally enforce RFC 5304 sec 2: the purge MUST be authenticated (handled by the digest check) and MUST NOT carry any TLV other than TLV 10 (ErrAuthPurgeExtraTLV).
func WriteLSPEntriesTLV ¶
func WriteLSPEntriesTLV(buf []byte, off int, t LSPEntriesTLV) int
WriteLSPEntriesTLV emits TLV 9 (type+length+value) into buf at off and returns the new offset. It is the exported entry point the flooding spec (isis-7) uses to build CSNP/PSNP bodies via the canonical isis-2 codec rather than re-encoding the entry layout. The caller ensures the entry count fits one TLV (255/16 = 15 entries); isis-7 splits larger lists across multiple TLV 9s.
func WritePaddingTLV ¶
WritePaddingTLV emits one TLV 8 with n zero value octets (0 <= n <= 255) into buf at off and returns the new offset. The padding owner (isis-5) computes how many padding TLVs are needed to reach the interface MTU before authentication (ISO/IEC 10589 clause 8.2.3) and calls this per TLV; buffer-first, assumes room. Exported because the originator lives in a sibling package (isis-5), not this codec child.
Types ¶
type AdjThreeWayState ¶
type AdjThreeWayState uint8
AdjThreeWayState is the RFC 5303 three-way adjacency state (sec 2.1, 3.1).
const ( AdjThreeWayUp AdjThreeWayState = 0 AdjThreeWayInitializing AdjThreeWayState = 1 AdjThreeWayDown AdjThreeWayState = 2 )
Three-way adjacency state values (RFC 5303 sec 3.1: 0 = Up, 1 = Initializing, 2 = Down).
type AreaAddressesTLV ¶
AreaAddressesTLV is the decoded TLV 1: the list of area addresses an IS belongs to. Originated in IIHs (isis-5) and LSPs (isis-6).
func DecodeAreaAddressesTLV ¶
func DecodeAreaAddressesTLV(value []byte) (AreaAddressesTLV, error)
DecodeAreaAddressesTLV parses a TLV 1 value. Each entry is a 1-octet length followed by that many octets. Bound-checked (security review): a length that overruns the value terminates with ErrTruncated and no partial area leaks.
type AuthAlgorithm ¶
type AuthAlgorithm uint8
AuthAlgorithm selects the digest algorithm carried in TLV 10. The values are internal identifiers; the on-wire authentication TYPE byte (1/3/54) is derived from the algorithm by authTypeFor, and for the generic-crypto family (type 3) the algorithm is NEVER sent on the wire (RFC 5310 sec 2: the algorithm is selected per-SA via the Key ID).
const ( AuthAlgoNone AuthAlgorithm = iota // no authentication configured AuthAlgoCleartext // ISO/IEC 10589 cleartext password (auth type 1) AuthAlgoHMACMD5 // RFC 5304 HMAC-MD5 (auth type 54) AuthAlgoHMACSHA1 // RFC 5310 HMAC-SHA-1 (auth type 3) AuthAlgoHMACSHA224 // RFC 5310 HMAC-SHA-224 (auth type 3) AuthAlgoHMACSHA256 // RFC 5310 HMAC-SHA-256 (auth type 3) AuthAlgoHMACSHA384 // RFC 5310 HMAC-SHA-384 (auth type 3) AuthAlgoHMACSHA512 // RFC 5310 HMAC-SHA-512 (auth type 3) )
Authentication algorithms (spec-isis-10). Cleartext is sanity-only; HMAC-MD5 (RFC 5304) and the HMAC-SHA family (RFC 5310) provide integrity.
type AuthTLV ¶
AuthTLV is the decoded TLV 10: the 1-octet authentication type followed by an opaque authentication value. The codec does not interpret the value (the digest / password / key-id structure is isis-10's concern); it only carries it so the TLV round-trips and isis-10 can verify/sign over the full PDU.
func DecodeAuthTLV ¶
DecodeAuthTLV parses a TLV 10 value: the first octet is the authentication type, the remainder the opaque authentication value. A zero-length value is rejected (ErrLength): TLV 10 must carry at least the type octet (RFC 5304 sec 1). The codec does not reject unknown auth types or malformed digest lengths -- that is enforcement (isis-10) -- but it does require the structural minimum so a truncated TLV is not silently accepted as valid (security review: "must not silently accept malformed auth TLV structure").
type CSNP ¶
type CSNP struct {
PDUType PDUType // PDUTypeL1CSNP or PDUTypeL2CSNP
SourceID types.SourceID
StartLSPID types.LSPID
EndLSPID types.LSPID
MaxAreaAddresses uint8 // common-header field; 0 = the default 3
TLVs []TLV
}
CSNP is a decoded Level 1 or Level 2 Complete Sequence Numbers PDU (ISO/IEC 10589 clause 9.10). It summarizes the sender's LSDB over the LSP-ID range [Start, End] via TLV 9 (LSP Entries). The PDU type distinguishes L1 (0x18) from L2 (0x19).
func DecodeCSNP ¶
DecodeCSNP parses a CSNP body following the common header.
func (*CSNP) EncodedLen ¶
EncodedLen returns the total on-wire size of the CSNP.
type CircuitType ¶
type CircuitType uint8
CircuitType is the 1-octet circuit type field in an IIH (ISO/IEC 10589 clause 9.5): the low two bits select the level(s) the sender uses on this circuit.
const ( CircuitL1 CircuitType = 1 // Level 1 only CircuitL2 CircuitType = 2 // Level 2 only CircuitL1L2 CircuitType = 3 // Level 1 and Level 2 )
Circuit type values (ISO/IEC 10589 clause 9.5: only the low two bits are defined; the rest are reserved and ignored on receipt).
type ExtIPReachEntry ¶
type ExtIPReachEntry struct {
Metric types.PrefixMetric
UpDown bool // up/down bit from the control octet (set = leaked down a level)
Prefix netip.Prefix
SubTLVs []SubTLV // present only when the S bit was set; retained verbatim
}
ExtIPReachEntry is one decoded TLV 135 prefix entry.
type ExtISReachEntry ¶
ExtISReachEntry is one decoded TLV 22 neighbor entry. The 24-bit metric is carried in types.Metric (which range-checks the 24-bit bound). SubTLVs are retained opaquely so the entry round-trips verbatim regardless of which sub-TLV types Ze understands.
type ExtendedIPReachTLV ¶
type ExtendedIPReachTLV struct {
Entries []ExtIPReachEntry
}
ExtendedIPReachTLV is the decoded TLV 135: a list of prefix entries.
func DecodeExtendedIPReachTLV ¶
func DecodeExtendedIPReachTLV(value []byte) (ExtendedIPReachTLV, error)
DecodeExtendedIPReachTLV parses a TLV 135 value. Every length is bound-checked before slicing (security review, R-5): a prefix length > 32, a packed prefix or sub-TLV block that overruns the value, is rejected without reading out of bounds. The 32-bit metric is preserved as-is (never capped at 24-bit). The sub-TLV-length octet and sub-TLVs are read ONLY when the S bit is set.
func (ExtendedIPReachTLV) EncodedLen ¶
func (t ExtendedIPReachTLV) EncodedLen() int
EncodedLen returns the full on-wire size of TLV 135 (type + length + value).
func (ExtendedIPReachTLV) WriteTo ¶
func (t ExtendedIPReachTLV) WriteTo(buf []byte, off int) int
WriteTo emits TLV 135 into buf at off and returns the new offset. The S (sub-TLV-present) bit and the sub-TLV-length octet are written ONLY when the entry has sub-TLVs, exactly mirroring the decode (RFC 5305 sec 4.2). The up/down bit is placed in the control octet. Buffer-first; the originator (isis-6/9/11) lives in a sibling package.
type ExtendedISReachTLV ¶
type ExtendedISReachTLV struct {
Entries []ExtISReachEntry
}
ExtendedISReachTLV is the decoded TLV 22: a list of neighbor entries.
func DecodeExtendedISReachTLV ¶
func DecodeExtendedISReachTLV(value []byte) (ExtendedISReachTLV, error)
DecodeExtendedISReachTLV parses a TLV 22 value. Every field is bound-checked before slicing (security review): an entry whose declared sub-TLV length overruns the value is rejected with ErrTruncated, and the 24-bit metric cannot overflow by construction (3 octets). It does NOT cap the metric at MAX_PATH_METRIC; that SPF clamp is isis-9's concern (the codec preserves the wire value).
type Header ¶
type Header struct {
// LengthIndicator is the length of this PDU's fixed header (common header
// plus the PDU-specific fixed fields), as carried in octet 1.
LengthIndicator uint8
// IDLength is the System ID length octet as received (0 or 6).
IDLength uint8
// PDUType is the 5-bit PDU type code.
PDUType PDUType
// MaxAreaAddresses is the maximum number of area addresses (octet 7); 0
// means the default of 3 (ISO/IEC 10589 clause 9.5).
MaxAreaAddresses uint8
}
Header is the parsed common 8-octet IS-IS header (ISO/IEC 10589 clause 9.5). It is a small value copied out of the wire bytes; the body parsers take the remaining slice.
func DecodeHeader ¶
DecodeHeader parses and validates the common 8-octet header at the start of buf. It is bound-checked before every read (security review: input validation) and rejects a bad discriminator, version, ID length, or unknown PDU type. On success it returns the parsed header and the offset at which the PDU-specific body begins (always CommonHeaderLen).
ISO/IEC 10589 clause 9.5: "Intradomain Routeing Protocol Discriminator" = 0x83, "Version/Protocol ID Extension" = 1, "Version" = 1.
type IPv4InterfaceAddrTLV ¶
IPv4InterfaceAddrTLV is the decoded TLV 132.
func DecodeIPv4InterfaceAddrTLV ¶
func DecodeIPv4InterfaceAddrTLV(value []byte) (IPv4InterfaceAddrTLV, error)
DecodeIPv4InterfaceAddrTLV parses a TLV 132 value (one 4-octet address per entry). A value length that is not a multiple of 4 is rejected (ErrLength).
type IPv6InterfaceAddrTLV ¶
IPv6InterfaceAddrTLV is the decoded TLV 232.
func DecodeIPv6InterfaceAddrTLV ¶
func DecodeIPv6InterfaceAddrTLV(value []byte) (IPv6InterfaceAddrTLV, error)
DecodeIPv6InterfaceAddrTLV parses a TLV 232 value (one 16-octet address per entry). A value length that is not a multiple of 16 is rejected (ErrLength).
type IPv6ReachEntry ¶
type IPv6ReachEntry struct {
Metric types.PrefixMetric
UpDown bool // U flag (set = leaked down a level)
External bool // X flag (set = redistributed from another protocol)
Prefix netip.Prefix
SubTLVs []SubTLV // present only when the S flag was set; retained verbatim
}
IPv6ReachEntry is one decoded TLV 236 prefix entry.
type IPv6ReachabilityTLV ¶
type IPv6ReachabilityTLV struct {
Entries []IPv6ReachEntry
}
IPv6ReachabilityTLV is the decoded TLV 236: a list of IPv6 prefix entries.
func DecodeIPv6ReachabilityTLV ¶
func DecodeIPv6ReachabilityTLV(value []byte) (IPv6ReachabilityTLV, error)
DecodeIPv6ReachabilityTLV parses a TLV 236 value. Every length is bound-checked before slicing (security review, R-5): a prefix length > 128, a packed prefix or sub-TLV block that overruns the value, is rejected without reading out of bounds. The 32-bit metric is preserved as-is. The sub-TLV-length octet and sub-TLVs are read ONLY when the S flag is set.
func (IPv6ReachabilityTLV) EncodedLen ¶
func (t IPv6ReachabilityTLV) EncodedLen() int
EncodedLen returns the full on-wire size of TLV 236 (type + length + value).
func (IPv6ReachabilityTLV) WriteTo ¶
func (t IPv6ReachabilityTLV) WriteTo(buf []byte, off int) int
WriteTo emits TLV 236 into buf at off and returns the new offset. The S flag and the sub-TLV-length octet are written ONLY when the entry has sub-TLVs, mirroring the decode (RFC 5308 sec 2). The U and X bits go in the flags octet, the prefix length in its own octet. Buffer-first; the originator (isis-12) lives in a sibling package.
type ISNeighborsTLV ¶
ISNeighborsTLV is the decoded TLV 6: the list of neighbor SNPAs (MACs).
func DecodeISNeighborsTLV ¶
func DecodeISNeighborsTLV(value []byte) (ISNeighborsTLV, error)
DecodeISNeighborsTLV parses a TLV 6 value (one 6-octet SNPA per entry). A value length that is not a multiple of SNPALen is rejected (ErrLength) so a crafted partial address cannot be read past its bounds.
type JSONView ¶
type JSONView struct {
Type string `json:"type"` // PDU type token, e.g. "l2-lsp"
MaxAreaAddresses uint8 `json:"max-area-addresses"` // common-header field
LANHello *lanHelloJSON `json:"lan-hello,omitempty"`
P2PHello *p2pHelloJSON `json:"p2p-hello,omitempty"`
LSP *lspJSON `json:"lsp,omitempty"`
CSNP *csnpJSON `json:"csnp,omitempty"`
PSNP *psnpJSON `json:"psnp,omitempty"`
}
JSONView is a JSON-serializable rendering of a decoded PDU. Exactly one body field is non-nil, matching the header's PDU type. Field names are stable kebab/lower tokens for diagnostics and test assertions.
type Key ¶
type Key struct {
Algorithm AuthAlgorithm
Secret []byte //nolint:gosec // G117: field name describes key material, not a literal secret; never logged.
KeyID uint16
}
Key is one authentication key used to sign or verify. Secret is the raw key material (the $9$-decoded plaintext supplied by the component key store, held only in memory); the auth backend never logs it. KeyID is carried on the wire only for the generic-crypto family (type 3, RFC 5310); it is ignored for cleartext and HMAC-MD5.
type LANHello ¶
type LANHello struct {
PDUType PDUType // PDUTypeL1LANHello or PDUTypeL2LANHello
CircuitType CircuitType
SystemID types.SystemID
HoldingTime types.HoldingTime
Priority uint8 // 0..127 (DIS election)
LANID types.SourceID
MaxAreaAddresses uint8 // common-header field; 0 = the default 3
TLVs []TLV
}
LANHello is a decoded Level 1 or Level 2 LAN IS-IS Hello (ISO/IEC 10589 clause 9.5). The PDU type (set by the caller on encode, read on decode) distinguishes L1 (0x0f) from L2 (0x10). LANID is the System ID + pseudonode of the current DIS (zero when none elected). TLVs are retained in order.
func DecodeLANHello ¶
DecodeLANHello parses a LAN IIH body following the common header. body is the slice after the 8-octet common header. pt is the PDU type from the header (L1/L2). Every field is bound-checked before slicing (security review). The returned TLVs alias body; the caller copies any it retains.
func (*LANHello) EncodedLen ¶
EncodedLen returns the total on-wire size of the LAN IIH.
func (*LANHello) WriteTo ¶
WriteTo serializes the LAN IIH into buf at off and returns the new offset. The PDU Length field is filled by skip-and-backfill (ai/rules/buffer-first.md) rather than a Len()-then-WriteTo() double pass. Buffer-first: the caller guarantees room (>= EncodedLen()).
ISO/IEC 10589 clause 9.5: priority is a 7-bit field; the high bit is reserved and sent zero, so the priority is masked to 0..127.
type LSP ¶
type LSP struct {
PDUType PDUType // PDUTypeL1LSP or PDUTypeL2LSP
RemainingLifetime types.RemainingLifetime
LSPID types.LSPID
SequenceNumber types.SequenceNumber
Checksum uint16 // as decoded; recomputed and backfilled on WriteTo
TypeBlock uint8
MaxAreaAddresses uint8 // common-header field; 0 = the default 3
TLVs []TLV
// RawBytes is the verbatim PDU as decoded (nil when the struct was built
// for encoding). The LSDB retains this for re-flood.
RawBytes []byte
}
LSP is a decoded Level 1 or Level 2 Link State PDU (ISO/IEC 10589 clause 9.8). The PDU type distinguishes L1 (0x12) from L2 (0x14). RawBytes, when set on a decode, is the full PDU slice (for the LSDB to store and re-flood verbatim); it is nil on a struct built for encoding. TLVs are retained in order so an unknown TLV re-floods verbatim (ISO/IEC 10589 clause 7.3.14).
func DecodeLSP ¶
DecodeLSP parses an LSP body following the common header. body is the slice after the common header; full is the entire PDU slice (common header + body) so RawBytes can be retained for verbatim re-flood. Every field is bound-checked before slicing (security review).
func StripPurgeBody ¶
StripPurgeBody returns the canonical authenticated-purge form of an LSP: the LSP with its body removed (RFC 5304 sec 2: "ISes that ... initiate LSP purges MUST remove the body of the LSP and add the authentication TLV"). The returned PDU has Remaining Lifetime 0, no TLVs (the caller signs it, which adds TLV 10 as the only TLV), and a recomputed length. The caller then SignPDUs it. seq is the purge sequence number the originator assigns.
func (*LSP) EncodedLen ¶
EncodedLen returns the total on-wire size of the LSP.
func (*LSP) IsOverloaded ¶
IsOverloaded reports whether the LSP-database-overload (OL) bit is set in the type block (RFC 3787); SPF (isis-9) treats an overloaded node as transit-only.
func (*LSP) VerifyChecksum ¶
VerifyChecksum recomputes the Fletcher checksum over this LSP's raw bytes and reports whether it is valid (ISO/IEC 10589 clause 7.3.11). It requires RawBytes to be set (a decoded LSP); for an LSP built in memory the checksum is computed by WriteTo, so verify the encoded output instead. Returns false if RawBytes is too short to contain the checksum region.
func (*LSP) WriteTo ¶
WriteTo serializes the LSP into buf at off and returns the new offset. The PDU Length is written via skip-and-backfill, and the ISO 8473 Fletcher checksum is computed over the region from the octet after Remaining Lifetime to the end and backfilled LAST (ISO/IEC 10589 clause 7.3.11). The Checksum field of the struct is ignored on encode; the computed value is authoritative and is also stored back into l.Checksum for the caller. Buffer-first.
Note (RFC 5304 sec 2 / isis-10): when authentication is enabled, isis-10 signs the PDU with the Checksum and Remaining Lifetime fields zeroed, AFTER padding, and BEFORE this checksum is computed. This codec computes the checksum over whatever auth TLV bytes are present; the engine's send order (build -> sign TLV 10 -> Fletcher checksum) guarantees the auth value is in place when the checksum runs.
type LSPEntriesTLV ¶
type LSPEntriesTLV struct {
Entries []LSPEntry
}
LSPEntriesTLV is the decoded TLV 9: a list of LSP summaries.
func DecodeLSPEntriesTLV ¶
func DecodeLSPEntriesTLV(value []byte) (LSPEntriesTLV, error)
DecodeLSPEntriesTLV parses a TLV 9 value into fixed-size entries. A value length that is not a multiple of LSPEntryLen is rejected (ErrLength) so a crafted partial entry cannot be read past its bounds.
func (LSPEntriesTLV) EncodedLen ¶
func (t LSPEntriesTLV) EncodedLen() int
EncodedLen returns the on-wire size of TLV 9 (type+length+value) for this entry list: the 2-octet TLV header plus 16 octets per entry. The caller (the flooding spec, isis-7) sizes its build buffer with this. The entry count must fit one TLV (<= 15 entries); isis-7 chunks larger lists.
type LSPEntry ¶
type LSPEntry struct {
RemainingLifetime types.RemainingLifetime
LSPID types.LSPID
SequenceNumber types.SequenceNumber
Checksum uint16
}
LSPEntry summarizes one LSP for CSNP/PSNP synchronization. The checksum is the LSP's stored Fletcher checksum (opaque to a CSNP/PSNP, compared as a value). isis-7 builds these from the LSDB.
type NarrowISReachEntry ¶
type NarrowISReachEntry struct {
DefaultMetricValue uint8 // low 6 bits of the default metric octet
DefaultMetricExternal bool // I/E bit of the default metric octet (set = external)
DelayMetric uint8
ExpenseMetric uint8
ErrorMetric uint8
Neighbor types.SourceID
}
NarrowISReachEntry is one decoded TLV 2 entry. Only the fields a wide-metric IS needs for interop are surfaced; the delay/expense/error metrics are kept raw. DefaultMetricValue is the 6-bit metric; DefaultMetricInternal reports the I/E bit (0 = internal, 1 = external) of the default metric octet.
type NarrowISReachTLV ¶
type NarrowISReachTLV struct {
VirtualFlag uint8
Entries []NarrowISReachEntry
}
NarrowISReachTLV is the decoded TLV 2 (decode-only). VirtualFlag is the leading octet preceding the entries (ISO/IEC 10589 clause 9.3).
func DecodeNarrowISReachTLV ¶
func DecodeNarrowISReachTLV(value []byte) (NarrowISReachTLV, error)
DecodeNarrowISReachTLV parses a TLV 2 value (decode-only, AC-14). The value must be at least 1 octet (the virtual flag) and the remainder a whole number of 11-octet entries; anything else is rejected with ErrLength rather than reading past the buffer. This never panics on arbitrary input (R-3).
type P2PHello ¶
type P2PHello struct {
CircuitType CircuitType
SystemID types.SystemID
HoldingTime types.HoldingTime
LocalCircuitID uint8
MaxAreaAddresses uint8 // common-header field; 0 = the default 3
TLVs []TLV
}
P2PHello is a decoded Point-to-Point IS-IS Hello (ISO/IEC 10589 clause 9.6). It is level-agnostic (its circuit type carries the level). LocalCircuitID is the 1-octet circuit ID on the sender's side. TLVs are retained in order (notably TLV 240 for the RFC 5303 three-way handshake).
func DecodeP2PHello ¶
DecodeP2PHello parses a P2P IIH body following the common header.
func (*P2PHello) EncodedLen ¶
EncodedLen returns the total on-wire size of the P2P IIH.
type P2PThreeWayTLV ¶
type P2PThreeWayTLV struct {
State AdjThreeWayState
HasCircuitID bool
LocalCircuitID uint32
HasNeighbor bool
NeighborID types.SystemID
NeighborCircuit uint32
}
P2PThreeWayTLV is the decoded TLV 240. HasNeighbor reports whether the neighbor fields are present (the 15-octet form); HasCircuitID whether the extended local circuit ID is present (the 5- or 15-octet form).
func DecodeP2PThreeWayTLV ¶
func DecodeP2PThreeWayTLV(value []byte) (P2PThreeWayTLV, error)
DecodeP2PThreeWayTLV parses a TLV 240 value (length 1, 5, or 15). Any other length is rejected (ErrLength) per RFC 5303 sec 3.1; the codec does not validate the state value here (isis-5 discards an invalid state).
type PDU ¶
type PDU struct {
Header Header
LANHello *LANHello
P2PHello *P2PHello
LSP *LSP
CSNP *CSNP
PSNP *PSNP
}
PDU is the decoded union returned by DecodePDU. Exactly one of the typed pointers is non-nil, selected by Header.PDUType. The runtime dispatcher (isis-4 server.go) keys off Header.PDUType; this struct lets a single decode call return both the parsed header and the typed body without the caller re-switching on the type. The IIH/LSP/SNP body parsers can also be called directly when the PDU type is already known.
func DecodePDU ¶
DecodePDU parses a complete IS-IS PDU: the common header followed by the type-specific body. It validates the common header (discriminator, version, ID length, known PDU type), dispatches by the 5-bit PDU type to the matching body decoder, and threads the common-header Max Area Addresses field into the typed body. It never panics on arbitrary input (AC-11, R-3): a bad header or a truncated body returns a typed error.
buf is one whole PDU (the 802.3 + LLC framing already stripped by isis-3, or supplied directly by the offline decode CLI). Decoded TLV value slices alias buf; the caller copies any it retains.
type PDUType ¶
type PDUType uint8
PDUType is the 1-octet PDU type field of the IS-IS common header. Only the low 5 bits are the type code (ISO/IEC 10589 clause 9.5); the high 3 bits are reserved and MUST be zero on transmit.
const ( PDUTypeL1LANHello PDUType = 0x0f // 15: Level 1 LAN IS-IS Hello PDUTypeL2LANHello PDUType = 0x10 // 16: Level 2 LAN IS-IS Hello PDUTypeP2PHello PDUType = 0x11 // 17: Point-to-Point IS-IS Hello PDUTypeL1LSP PDUType = 0x12 // 18: Level 1 Link State PDU PDUTypeL2LSP PDUType = 0x14 // 20: Level 2 Link State PDU PDUTypeL1CSNP PDUType = 0x18 // 24: Level 1 Complete Sequence Numbers PDU PDUTypeL2CSNP PDUType = 0x19 // 25: Level 2 Complete Sequence Numbers PDU PDUTypeL1PSNP PDUType = 0x1a // 26: Level 1 Partial Sequence Numbers PDU PDUTypeL2PSNP PDUType = 0x1b // 27: Level 2 Partial Sequence Numbers PDU )
PDU type code octets (ISO/IEC 10589 clause 9).
These are the AUTHORITATIVE values from ISO/IEC 10589 clause 9 and the umbrella contract. The research guide (docs/research/isis-implementation-guide.md sec 2) transcribes the L1 codes incorrectly (it lists L1 LSP 0x18, L1 CSNP 0x24, L1 PSNP 0x26); those are typos. TestISISPDUConstants pins these exact values so a regression cannot silently break interop (spec A-5).
type PSNP ¶
type PSNP struct {
PDUType PDUType // PDUTypeL1PSNP or PDUTypeL2PSNP
SourceID types.SourceID
MaxAreaAddresses uint8 // common-header field; 0 = the default 3
TLVs []TLV
}
PSNP is a decoded Level 1 or Level 2 Partial Sequence Numbers PDU (ISO/IEC 10589 clause 9.11). It carries TLV 9 (LSP Entries) to acknowledge or request individual LSPs. The PDU type distinguishes L1 (0x1a) from L2 (0x1b).
func DecodePSNP ¶
DecodePSNP parses a PSNP body following the common header.
func (*PSNP) EncodedLen ¶
EncodedLen returns the total on-wire size of the PSNP.
type ProtocolsSupportedTLV ¶
type ProtocolsSupportedTLV struct {
NLPIDs []uint8
}
ProtocolsSupportedTLV is the decoded TLV 129.
func DecodeProtocolsSupportedTLV ¶
func DecodeProtocolsSupportedTLV(value []byte) ProtocolsSupportedTLV
DecodeProtocolsSupportedTLV parses a TLV 129 value (one NLPID per octet).
type SubTLV ¶
SubTLV is one sub-TLV (RFC 5305 sec 2): the same Type(1)+Length(1)+Value framing as a TLV, nested inside a TLV 22/135/236 entry. Value aliases the source buffer on decode. Unknown sub-TLVs are retained and re-emitted verbatim, matching the unknown-TLV passthrough contract one level down (RFC 5305 sec 2: "Unknown sub-TLVs are to be ignored and skipped upon receipt" -- the codec keeps them so the entry round-trips, and leaves the ignore policy to the consumer).
func (SubTLV) EncodedLen ¶
EncodedLen returns the on-wire size of this sub-TLV.
type TLV ¶
TLV is one decoded TLV retained as a type plus its raw value bytes. It is the opaque carrier used both for unknown TLVs (re-flooded verbatim per ISO/IEC 10589 clause 7.3.14) and as a uniform encode unit for TLVs the caller has already serialized. Value aliases the source buffer on decode; callers that retain it past the buffer's lifetime must copy (see CopyValue).
func DecodeTLVs ¶
DecodeTLVs walks the entire TLV region and returns every TLV in order, retaining each value as an opaque span (zero-copy: the values alias buf). Unknown types are kept identically to known ones, so re-encoding the slice reproduces the region byte-for-byte (AC-5, R-6). A truncated final TLV stops the walk and is reported via the error; the TLVs decoded before the truncation are still returned.
Allocation uses a fixed capacity so all TLV slices are the same size, enabling future pool reuse. The cap is the maximum TLV count that fits in a single MTU-bounded PDU; each TLV consumes at least TLVHeaderLen octets (security review: resource exhaustion).
func (TLV) CopyValue ¶
CopyValue returns a TLV whose Value is an independent copy, safe to retain after the source buffer is recycled (isis-6 LSDB retention).
func (TLV) EncodedLen ¶
EncodedLen returns the number of octets this TLV occupies on the wire.
func (TLV) WriteTo ¶
WriteTo serializes the TLV (type + length + value) into buf at off and returns the new offset. Buffer-first; the caller guarantees room. The value length is assumed valid (<= MaxTLVValueLen); DecodeTLVs cannot produce a longer value because the wire length field is a single octet.
type TLVIterator ¶
type TLVIterator struct {
// contains filtered or unexported fields
}
TLVIterator walks a TLV region lazily, yielding (type, value-slice) pairs without copying. Decode is zero-copy per ai/rules/buffer-first.md: the value slices alias the caller's buffer and are valid only while it is stable.
The iterator never panics on malformed input (spec R-3, AC-11): a TLV whose declared length runs past the end of the region terminates iteration and is reported via Err. The same type is used for sub-TLV regions (RFC 5305 sec 2).
func NewTLVIterator ¶
func NewTLVIterator(buf []byte) TLVIterator
NewTLVIterator returns an iterator over the TLV region buf. The region is the raw TLV bytes only (no PDU header); callers slice it out of the PDU first.
func (*TLVIterator) Err ¶
func (it *TLVIterator) Err() error
Err returns the first error encountered (nil on a clean walk to the region boundary). It is set when a TLV's declared length overruns the region.
func (*TLVIterator) Next ¶
func (it *TLVIterator) Next() (typ uint8, value []byte, ok bool)
Next returns the next (type, value) pair and ok=true, or ok=false at the end of the region or on a truncated TLV. Every read is bound-checked before slicing (security review: input validation). When a TLV's declared length exceeds the remaining bytes, Next stops and records ErrTruncated; the partial bytes are not yielded.