Skip to content

fix(internet): a whole IPv6 extension header rebuilt from its info gains next-layer keys and loses Shim6's protocol #2768

Closed

Description

@JarryShaw

Describe the bug
An IPv6 extension header parsed whole with extension=True rebuilds from from_data(info) with next-layer keys (__next_type__, __next_name__, nopayload) that its parse never had. HOPOPT, IPv6-Opts, IPv6-Frag, AH, MH, HIP and IPv6_Ext all do this, standalone and as the __exthdr__ infos of IPv6. IPv6_Ext (Shim6) also loses protocol. The octets are exact, and a whole IPv6 rebuild is unaffected.

Reproduction

from pcapkit.protocols.internet.ipv6_ext.protocol import IPv6_Ext
p = IPv6_Ext(bytes([59, 0, 0x80, 0, 0, 0, 0, 0]), extension=True, alias=140)
IPv6_Ext.from_data(p.info).info == p.info                    # False: + __next_name__, __next_type__, nopayload
IPv6_Ext.from_data(p.info, extension=True).info.protocol     # None (parse: 140, Shim6)

Expected behavior
from_data(info).info == info (test-coverage.rst, Round-Trip Invariants).

Additional context
from_data doesn't replay the parse's extension mode, as it already replays __short_read__. IPv6_Ext.read takes protocol only from the parse-only alias. The capture round-trip test compares .data only, which is why this went unnoticed. It is the uncut counterpart of #2761.

Activity

  1. added
    bugIssues reporting a defect (set by the bug report template; a default, not an assessment)
    wipWork in flight - a covering PR is open or an agent is actively on it
    on Nov 4, 2026
  2. added this to the PyPCAPKit v1.6 milestone on Nov 4, 2026
  3. JarryShaw commented on Nov 4, 2026

    @JarryShaw
    OwnerAuthor

    #2774 fixes the extension-mode keys for every header. Shim6's protocol needs a decision.

    The gap: IPv6_Ext.read takes protocol from the parse-only alias keyword. The data model already holds the value (Data_IPv6_Ext.protocol), so _make_data can return 'alias': data.protocol. The construction-keyword check would then warn, because no signature declares alias.

    • (a) Add __keywords__ = frozenset({'alias'}) to IPv6_Ext. Measured in a scratch edit: the Shim6 rebuild is exact, with no warnings. Downside: subclasses inherit it, so HOPOPT(alias=3) is accepted and silently dropped.
    • (b) Add 'alias' to OUT_OF_BAND_KEYWORDS. This adds no new member, but every protocol would then accept alias at construction, and test_construction_keyword_check_unit pins that set.
    • (c) Declare alias on IPv6_Ext.__post_init__. This changes the signature and is inherited the same way as (a).

    Recommendation: (a). It is scoped to the extension-header family, and the new member goes where protocol-member-order.rst places it. The Shim6 alias and in-IPv6 test cases are added once this is ruled.

  4. added
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Nov 4, 2026
  5. moved this from WIP to Needs decision in PyPCAPKiton Nov 4, 2026
  6. JarryShaw commented on Nov 4, 2026

    @JarryShaw
    OwnerAuthor

    take (a)

  7. JarryShaw commented on Nov 4, 2026

    @JarryShaw
    OwnerAuthor

    Option (a), reconciled. IPv6_Ext declares __keywords__ = frozenset({'alias'}), and _make_data returns 'alias': data.protocol. A rebuilt Shim6 header then keeps its protocol, both standalone and inside IPv6, without a keyword warning. Subclasses inherit the keyword, so HOPOPT(alias=3) is accepted and has no effect. That was the accepted downside of (a).

    The change goes into #2774 as a follow-up commit. The new member goes where protocol-member-order.rst places it. The Shim6 alias=140 and in-IPv6 cases join the #2768 test. #2774 will then close this issue.

  8. removed
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Nov 4, 2026
  9. moved this from Needs decision to WIP in PyPCAPKiton Nov 4, 2026
  10. removed
    wipWork in flight - a covering PR is open or an agent is actively on it
    on Nov 4, 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

    bugIssues reporting a defect (set by the bug report template; a default, not an assessment)

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions