Skip to content

IPv6 drops a malformed extension header as NoPayload when preceded by a valid one #2504

Closed

Description

@JarryShaw

Summary

IPv6's extension-header walk (#2480) correctly demotes a malformed extension header to Raw when it's the layer's DIRECT next header -- confirmed: ip.payload is Raw, and the protochain records ('IPv6_Opts', Raw).

But when a VALID extension header precedes the malformed one (e.g. a well-formed Hop-by-Hop Options header, followed by a malformed Destination Options header), the malformed header's bytes are dropped entirely: ip.payload is NoPayload, and the protochain stops at the last successfully-parsed header with no record of what followed. Nothing downstream -- IP_Pseudo (#2471) included -- has any signal that a malformed header was ever there.

Repro

from pcapkit.protocols.internet.ipv6 import IPv6

hop_by_hop = bytes([60, 0]) + bytes(6)          # valid, next=Destination Options (60)
malformed_dest_opts = bytes([17, 2]) + bytes(22) # malformed per #2480's own construction
rest = hop_by_hop + malformed_dest_opts

pkt = bytes.fromhex('60000000') + (8).to_bytes(2, 'big') + bytes([0, 64]) + bytes(16) + bytes(16) + rest
ip = IPv6(pkt)
print(type(ip.payload))        # NoPayload -- expected Raw, per #2480's own precedent
print(list(ip.protochain))     # stops at HOPOPT, no record of the failed header

Scope

Found while fixing #2479 (IP_Pseudo's malformed-header detection, which only works when the malformed header is the layer's direct next header, for exactly this reason). The fix belongs in IPv6's own extension-header walk, not in any downstream consumer.

Activity

  1. added
    enhancementIssues requesting a new capability (set by the feature request template)
    pendingAccepted and unstarted - nobody is on it and nothing blocks it
    on Oct 31, 2026
  2. moved this to Pending in PyPCAPKiton Oct 31, 2026
  3. JarryShaw commented on Oct 31, 2026

    @JarryShaw
    OwnerAuthor

    Correction, my own filing was wrong. A follow-up review (on #2479) checked this and a confirming sweep of my own just now agrees: the repro I used set Payload Length to exactly the Hop-by-Hop header's own size (8), so there are literally no declared bytes left for the 'malformed' Destination Options header to occupy -- NoPayload is correct there, not a dropped header. At Payload Length 16 or 24 (room for the malformed header to actually exist), it correctly demotes to Raw, protochain ('IPv6_Opts', Raw), exactly as #2480 intends. There's no IPv6-layer defect here. Closing as invalid.

  4. moved this from Pending to Done in PyPCAPKiton Oct 31, 2026
  5. removed
    pendingAccepted and unstarted - nobody is on it and nothing blocks it
    on Oct 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementIssues requesting a new capability (set by the feature request template)

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions