f67802967d
CRITICAL from NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md §3.1: netstack/src/router/mod.rs:528-545 used a fixed 40-byte offset for IPv6 transport-layer payload extraction. Any IPv6 packet with extension headers (Hop-by-Hop, Routing, Fragment, Destination, ESP, AH) caused parse_ports() to read the wrong bytes and return None,None. A firewall rule with a port predicate (--sport/--dport) would silently fail to match on such packets — a firewall bypass. Fix: add ipv6_transport_offset(packet, initial_next_header) that walks the extension header chain (RFC 8200 §4) and returns the byte offset of the transport-layer header. The walker handles: - Hop-by-Hop (0), Routing (43), Destination (60), AH (51): 8-byte aligned headers with length-in-units field - Fragment (44): fixed 8-byte header, no length field - ESP (50): returns None (payload is encrypted, port extraction impossible) - No Next Header (59): chain ends, transport offset unknown - Unknown header types: returns None to avoid unbounded walk The walker is bounded by packet.len() to prevent DoS via a chain that loops on itself. The transport-layer protocols (TCP=6, UDP=17, ICMPv6=58, SCTP=132) terminate the chain and return the current offset.