ndp

package
v0.331.0 Latest Latest
Warning

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

Go to latest
Published: May 21, 2026 License: AGPL-3.0 Imports: 5 Imported by: 0

Documentation

Overview

Package ndp decodes ICMPv6 NDP (Neighbor Discovery Protocol) messages per RFC 4861 (base NDP) + RFC 4191 (Default Router Preferences + Route Information) + RFC 8106 (RDNSS / DNSSL for SLAAC-only IPv6 hosts). NDP is the **foundational signalling layer** of IPv6 — every IPv6 host speaks NDP for neighbor resolution (the IPv6 equivalent of ARP), router discovery, parameter discovery, redirect handling, and duplicate-address detection.

Operationally, NDP is interesting because it carries every step of how a fresh IPv6 host learns its environment:

  • **Router Solicitation (RS)** — "any routers out there?" A newly-joined host (cold boot, link up, interface re-attach) sends one to FF02::2 (all-routers multicast) to short-circuit the periodic Router Advertisement interval.
  • **Router Advertisement (RA)** — "I'm a router; here are my prefixes + DNS servers + MTU + default-router lifetime." This is the canonical IPv6-pentest target: mitm6 / suddensix / parasite6 / fake_router6 inject malicious RAs to redirect the victim's default route via the attacker's host.
  • **Neighbor Solicitation (NS)** — "who has this IPv6 address?" The IPv6 equivalent of ARP — sent to the solicited-node multicast group derived from the target IPv6 address.
  • **Neighbor Advertisement (NA)** — "I have it; here's my MAC." Carries R (Router) / S (Solicited) / O (Override) flags; unsolicited NAs with O=1 are the IPv6 equivalent of gratuitous ARP and can be abused for ND-cache poisoning.
  • **Redirect** — "you sent traffic for X to me but I'm not the best next-hop; use Y instead." Historically abusable for IPv6 redirect attacks; modern stacks rate- limit + cryptographically validate.

The **NDP Options** TLV stream attached to every NDP message carries the actual interesting data: Source/Target Link-Layer Addresses (the IPv6 → MAC binding), Prefix Information (the SLAAC prefix + on-link bit + autoconfig bit + lifetime), MTU (link MTU override), RDNSS (the DNS servers the host should use for name resolution — leak target for mitm6 + rogue RA attacks), DNSSL (the search-domain list).

Wrap-vs-native judgement

Native. RFC 4861 + 4191 + 8106 are publicly available; NDP
uses a tight 4-byte ICMPv6 header + per-type fixed fields
+ a TLV Options stream where every option is (Type +
Length-in-8-byte-units + Value). No crypto at the parse
layer (the optional SeND extension — RFC 3971 — adds CGA
+ RSA Signature options that this decoder surfaces as raw
hex; key validation is higher-level work).

What this package covers

  • **ICMPv6 header** (RFC 4443 §2, 4 bytes; multi-byte fields are big-endian): byte 0 Type + byte 1 Code (always 0 for NDP) + bytes 2-3 Checksum.

  • **5-entry NDP type name table** (RFC 4861 §4): 133 `Router_Solicitation` / 134 `Router_Advertisement` / 135 `Neighbor_Solicitation` / 136 `Neighbor_Advertisement` / 137 `Redirect`.

  • **Router Advertisement body** (RFC 4861 §4.2, 12 bytes after the ICMPv6 header): byte 4 Cur Hop Limit + byte 5 Flags (bit 7 `M` Managed Address Configuration / bit 6 `O` Other Configuration / bit 5 `H` Home Agent / bits 4-3 `Prf` Default Router Preference per RFC 4191 — 00 Medium, 01 High, 10 Reserved, 11 Low / bit 2 `P` Proxy) + bytes 6-7 Router Lifetime (uint16 BE seconds; 0 = NOT a default router) + bytes 8-11 Reachable Time (uint32 BE milliseconds) + bytes 12-15 Retrans Timer (uint32 BE milliseconds).

  • **Neighbor Solicitation body** (RFC 4861 §4.3, 20 bytes): bytes 4-7 Reserved + bytes 8-23 Target Address (IPv6).

  • **Neighbor Advertisement body** (RFC 4861 §4.4, 20 bytes): byte 4 Flags (bit 7 `R` Router / bit 6 `S` Solicited / bit 5 `O` Override) + bytes 5-7 Reserved + bytes 8-23 Target Address (IPv6).

  • **Router Solicitation body** (RFC 4861 §4.1, 4 bytes): bytes 4-7 Reserved.

  • **Redirect body** (RFC 4861 §4.5, 36 bytes): bytes 4-7 Reserved + bytes 8-23 Target Address (the better next- hop) + bytes 24-39 Destination Address (the original destination).

  • **NDP Options TLV walker** (RFC 4861 §4.6): every option is byte 0 Type + byte 1 Length-in-8-byte-units (so total option bytes = Length × 8) + (Length×8 - 2) bytes of payload. Walker stops at the end of the input or on a Length=0 (illegal — would loop).

  • **9-entry NDP Option type name table**: 1 `Source_Link_Layer_Address` (SLLA) / 2 `Target_Link_Layer_Address` (TLLA) / 3 `Prefix_Information` / 4 `Redirected_Header` / 5 `MTU` / 13 `Nonce` (RFC 3971 SeND) / 24 `Route_Information` (RFC 4191) / 25 `RDNSS` (RFC 8106 Recursive DNS Server) / 31 `DNSSL` (RFC 8106 DNS Search List).

  • **Per-option decoders**:

  • **SLLA / TLLA** (Types 1, 2): 6-byte MAC address (assuming Ethernet — the common case).

  • **Prefix Information** (Type 3, 32 bytes total): byte 2 Prefix Length (bits 0-128) + byte 3 Flags (bit 7 `L` On-Link / bit 6 `A` Autonomous Address Configuration / bit 5 `R` Router Address per RFC 6275 Mobile IPv6) + bytes 4-7 Valid Lifetime (uint32 BE seconds; 0xFFFFFFFF = infinity) + bytes 8-11 Preferred Lifetime + bytes 12-15 Reserved + bytes 16-31 Prefix (IPv6).

  • **MTU** (Type 5, 8 bytes total): bytes 4-7 MTU (uint32 BE; overrides the link-layer MTU for IPv6 transmission).

  • **RDNSS** (Type 25, variable): byte 2-3 Reserved + bytes 4-7 Lifetime (uint32 BE seconds — how long to trust these DNS servers) + bytes 8+ one or more 16-byte IPv6 DNS server addresses.

  • **DNSSL** (Type 31, variable): bytes 4-7 Lifetime

  • bytes 8+ DNS search domains (each a sequence of length-prefixed labels followed by a 0x00 root terminator — RFC 1035 §3.1 encoding).

  • **Route Information** (Type 24, variable per RFC 4191): byte 2 Prefix Length + byte 3 Flags (bits 4-3 Prf Preference) + bytes 4-7 Route Lifetime + bytes 8+ Prefix (truncated to fit per Prefix Length).

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

  • **IPv6 framing** — feed NDP bytes after the IPv6 header strip (NDP messages travel inside ICMPv6 packets with Next Header = 58). Standard L3 destination is FF02::1 (all-nodes), FF02::2 (all-routers), or the solicited- node multicast group FF02::1:FF**xx:xxxx** derived from the target IPv6 address.
  • **ICMPv6 echo + error decoders** — the existing `icmp_packet_decode` Spec covers ICMPv4 echo + DUR + TE. NDP-specific Types 133-137 are the focus here; other ICMPv6 message types (1 Destination Unreachable, 2 Packet Too Big, 3 Time Exceeded, 4 Parameter Problem, 128 Echo Request, 129 Echo Reply, 130 MLD Query, 131 MLD Report, 132 MLD Done, 143 MLDv2 Report) are out of scope.
  • **Checksum verification** — the ICMPv6 checksum is computed over an IPv6 pseudo-header + the ICMPv6 message; this decoder surfaces the on-wire checksum as hex but does not re-compute (out of scope unless we have the L3 pseudo-header).
  • **SeND (Secure Neighbor Discovery)** — RFC 3971 adds CGA
  • RSA Signature + Nonce + Timestamp options to prevent ND spoofing; the Nonce option (Type 13) name surfaces but the CGA + RSA Signature options are not decoded.
  • **DAD (Duplicate Address Detection)** state-machine — the per-address tentative / preferred / deprecated / invalid state machine is a higher-level concern.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Option

type Option struct {
	Type         int    `json:"type"`
	TypeName     string `json:"type_name"`
	LengthOctets int    `json:"length_octets"`
	PayloadHex   string `json:"payload_hex,omitempty"`

	// SLLA / TLLA
	LinkLayerAddress string `json:"link_layer_address,omitempty"`

	// Prefix Information
	PrefixLength       int    `json:"prefix_length,omitempty"`
	PrefixFlagsHex     string `json:"prefix_flags_hex,omitempty"`
	PrefixOnLink       bool   `json:"prefix_on_link,omitempty"`
	PrefixAutoconfig   bool   `json:"prefix_autoconfig,omitempty"`
	PrefixRouter       bool   `json:"prefix_router,omitempty"`
	ValidLifetimeS     uint32 `json:"valid_lifetime_seconds,omitempty"`
	PreferredLifetimeS uint32 `json:"preferred_lifetime_seconds,omitempty"`
	Prefix             string `json:"prefix,omitempty"`

	// MTU
	MTU uint32 `json:"mtu,omitempty"`

	// RDNSS / Route Information
	LifetimeS     uint32   `json:"lifetime_seconds,omitempty"`
	DNSServers    []string `json:"dns_servers,omitempty"`
	SearchDomains []string `json:"search_domains,omitempty"`

	// Route Information
	RoutePreference string `json:"route_preference,omitempty"`
}

Option is one entry in the NDP Options TLV stream.

type Result

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

	// ICMPv6 header
	Type        int    `json:"type"`
	TypeName    string `json:"type_name"`
	Code        int    `json:"code"`
	ChecksumHex string `json:"checksum_hex"`

	// Per-type fixed fields (only the relevant subset is
	// populated; the others stay zero / omitted).
	CurHopLimit        int    `json:"cur_hop_limit,omitempty"`
	RAFlagsHex         string `json:"ra_flags_hex,omitempty"`
	RAManaged          bool   `json:"ra_managed,omitempty"`
	RAOther            bool   `json:"ra_other,omitempty"`
	RAHomeAgent        bool   `json:"ra_home_agent,omitempty"`
	RAPreference       string `json:"ra_preference,omitempty"`
	RAProxy            bool   `json:"ra_proxy,omitempty"`
	RouterLifetimeS    uint16 `json:"router_lifetime_seconds,omitempty"`
	ReachableTimeMs    uint32 `json:"reachable_time_ms,omitempty"`
	RetransTimerMs     uint32 `json:"retrans_timer_ms,omitempty"`
	NAFlagsHex         string `json:"na_flags_hex,omitempty"`
	NARouter           bool   `json:"na_router,omitempty"`
	NASolicited        bool   `json:"na_solicited,omitempty"`
	NAOverride         bool   `json:"na_override,omitempty"`
	TargetAddress      string `json:"target_address,omitempty"`
	DestinationAddress string `json:"destination_address,omitempty"`

	Options []Option `json:"options,omitempty"`
}

Result is the structured decode of an ICMPv6 NDP message.

func Decode

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

Decode parses an ICMPv6 NDP message from a hex string starting at the ICMPv6 Type byte. Separators (':' '-' '_' whitespace) tolerated; '0x' prefix tolerated.

Jump to

Keyboard shortcuts

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