Skip to content

fix(ipv6): keep the extension-header chain in from_data rebuilds (#1177) - #1182

Merged
JarryShaw merged 1 commit into
mainfrom
fix/1177-ipv6-from-data-ext
Oct 7, 2026
Merged

JarryShaw merged 1 commit into
mainfrom
fix/1177-ipv6-from-data-ext

Conversation

@JarryShaw

Copy link
Copy Markdown
Owner
  • Searched for similar pull requests
  • Followed the coding style — ran pylint/mypy/isort on the two source files: no new findings (the 4 mypy, isort and pylint hits are on untouched lines and also on main); make targets not run
  • make test passes, and a test case covers the change — per-module only, listed below
  • Added a changelog entry — N/A, added centrally

What is the purpose of your pull request?

  • fix — corrects a defect

Closes #1177. _decode_next_layer now records the chain in wire order as a hidden __exthdr__ key ((parser class, info) pairs, excluded like __next_type__); _make_data re-emits it ahead of the upper layer. The per-header keys (route, opts, ...) can't carry it, because a repeated header overwrites its key.

Probe: Routing (3b00000000000000): 48 → 40 before, 48 → 48 after; with 4 trailing octets 52 → 44 before, 52 → 52 after.
Capture sweep (1609 frames, non-exact): 183 → 51. IPv6>MH 99 → 0, IPv6_Route 3 → 0, IPv6_Frag 4 → 0, HOPOPT 14 → 1, IPv6_Opts 14 → 1, HIP 49 → 49; no frame regressed. The 51 now raise in the extension classes' own from_data (also on main standalone): HIP.alias reads _info before it is set (49), and _make_opt_mpl calls bit_length() on an IPv6Address in hopopt.py/ipv6_opts.py (2). Out of scope here.

Tests: new test_ipv6_from_data_ext_unit.py (HOPOPT, Routing, Dest Opts, MH, a 4-header chain with a repeated Dest Opts): 7 failed without the fix, 3 passed / 6 subtests with it. test_ipv6_unit, test_ipv6_extension_unit/_runtime, test_ipv6_ext_unit, test_mh_unit, test_hip_unit, test_option_roundtrip_unit all pass; tests/project 389 passed, 1 skipped; run_unittest_leg.py protocols/internet 475 tests, 0 failures.

IPv6._make_data rebuilt the payload from the upper layer alone, so every
extension header between the IPv6 header and that layer was dropped: a
48-octet packet with an 8-octet Routing header rebuilt as 40 octets.

_decode_next_layer now records the chain in wire order as a hidden
__exthdr__ info key (parser class, info), excluded from to_dict and
iteration like __next_type__. The per-header keys cannot carry it, since
a repeated header overwrites its predecessor's key. _make_data re-emits
each header ahead of the upper-layer payload.

Adds tests/protocols/internet/test_ipv6_from_data_ext_unit.py.
@JarryShaw JarryShaw added fix Pull requests that fix a defect (fix: subject prefix) review: running A cross-review is in flight against the current head - no verdict yet labels Oct 7, 2026
@JarryShaw

JarryShaw commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner Author

Cross-review verdict on 55c8ed67e: GOOD TO GO (ran on Sonnet; author Opus). Labelled review: good-to-go.

  • Sweep, per frame against main, 1602 frames: 1422 were exact on both; 130 went from wrong bytes to exact (MH 99, HOPOPT 12, IPv6_Opts 12, Frag 4, Route 3); 50 went from wrong bytes to AttributeError; 0 regressed from exact.
  • The 50 raising frames: a loud failure now replaces a silent wrong answer. from_data is a user-facing rebuild API that extract, the engines and dumpkit never call. The causes are two pre-existing defects, now filed as fix(hip): from_data raises AttributeError, alias reads _info before it is set #1184 (HIP, hip.py:475) and fix(ipv6-opts): _make_opt_mpl calls bit_length() on an IPv6Address seed #1185 (MPL seed, hopopt.py:1878 / ipv6_opts.py:1867). I checked both sites on main myself.
  • The __exthdr__ key stays hidden: it is absent from to_dict, iteration and repr, and from extract json/tree/plist output. It survives pickle and deepcopy.
  • Repeated headers: two Destination Options headers rebuild 64/64.
  • Tests: the new test fails without the fix (7 failures). The protocols/internet ordering leg ran 475 tests, 0F/0E.
  • Nit: test_chain_is_hidden_from_info_views passes on main too. It guards against a leak but does not prove the fix.

@JarryShaw JarryShaw added review: good-to-go Cross-review at the current head says ready; CI state is separate and removed review: running A cross-review is in flight against the current head - no verdict yet labels Oct 7, 2026
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Coverage: 88.89% (unit tier, Python 3.14, 55c8ed67e, Unit Tests run success)

Package Statements Missed Branches Partial Cover
pcapkit (top level) 104 4 20 4 93.55%
pcapkit/const 18757 1034 2342 845 90.24%
pcapkit/corekit 1878 91 580 22 94.34%
pcapkit/dumpkit 142 0 42 0 100.00%
pcapkit/foundation 2442 102 852 39 94.38%
pcapkit/interface 112 7 40 5 92.11%
pcapkit/protocols 15715 188 3976 163 98.19%
pcapkit/toolkit 487 65 144 1 85.42%
pcapkit/utilities 429 4 122 4 98.55%
pcapkit/vendor 4409 2359 1006 158 42.84%

Per-file detail: the coverage-html artifact of this run.

@JarryShaw

Copy link
Copy Markdown
Owner Author

Merge note: merge this together with #1188. On its own, this PR makes IPv6.from_data raise AttributeError on all 49 IPv6>HIP frames of options-internet.pcap (re-measured at 55c8ed67e). With #1188 merged in, all of them rebuild byte-exactly.

@JarryShaw
JarryShaw merged commit ad26767 into main Oct 7, 2026
41 checks passed
@JarryShaw
JarryShaw deleted the fix/1177-ipv6-from-data-ext branch October 7, 2026 13:58
@JarryShaw JarryShaw removed the review: good-to-go Cross-review at the current head says ready; CI state is separate label Oct 7, 2026
@JarryShaw JarryShaw added this to the PyPCAPKit v1.5 milestone Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix Pull requests that fix a defect (fix: subject prefix)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

fix(ipv6): from_data drops the extension-header chain from the rebuild

1 participant