Skip to content

fix(ipv6-route): rebuild RPL source routes byte for byte (#1456, #1457) - #1463

Merged
JarryShaw merged 1 commit into
mainfrom
fix/1456-1457-rpl-routing
Oct 9, 2026
Merged

JarryShaw merged 1 commit into
mainfrom
fix/1456-1457-rpl-routing

Conversation

@JarryShaw

Copy link
Copy Markdown
Owner

What is the purpose of your pull request?

  • fix — corrects a defect

Description of your pull request and other information

Closes #1456
Closes #1457

  • Rebuild compresses each parsed address again (Addresses[n] by CmprE, the rest by CmprI). fix(ipv6-route): an RPL routing header inside IPv6 loses its address compression on rebuild #1456 repro: 80 → 64 octets.
  • The schema splits the address list by the span Hdr Ext Len declares. An address the capture cut short stays as the raw bytes read. rt[:23]: builtins ValueError → exact. rt[:12]: IPv4Address('1.2.3.4') → exact.
  • from_data passes the parsed Hdr Ext Len through a new optional make(hdr_ext_len=). CmprI=CmprE=8 cut at 12: Hdr Ext Len 1 → 2.
  • make(): CmprI/CmprE are clamped to 15, CmprI is 0 for a single address, and an empty ip raises ProtocolError. Before, a single address with dst raised FieldValueError, and an empty ip with dst raised IndexError.

Sweep over every CmprI/CmprE pair (0–15), 1–3 addresses, two Pad values, alone and inside IPv6: full headers are 3072/3072 exact. A cut inside the address list or Pad is exact only when Pad is 0. Otherwise the unread Pad octets come back zero-filled by PaddingField, which is the corekit short-read in #1458 and is left to it. With that one patched, all 75264 cuts are exact.

New test tests/protocols/internet/test_ipv6_route_rpl_roundtrip_unit.py: all 7 tests fail on main (6480 failures).

- Compress a parsed address again on rebuild: Addresses[n] by CmprE, the
  rest by CmprI, so an RPL header inside IPv6 keeps its width (#1456).
- Split the address list by the span Hdr Ext Len declares, not by the
  octets read; an address the capture cut short stays the raw bytes read
  instead of decoding as IPv4 or raising a builtins ValueError (#1457).
- Pass the parsed Hdr Ext Len through from_data via a new make()
  hdr_ext_len argument, so a truncated header keeps its length (#1457).
- make(): clamp CmprI/CmprE to 15, set CmprI to 0 for one address, and
  raise ProtocolError for an empty address list.

New tests/protocols/internet/test_ipv6_route_rpl_roundtrip_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 9, 2026
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Coverage: 89.51% (unit tier, Python 3.14, c84b59304, Unit Tests run success)

Package Statements Missed Branches Partial Cover
pcapkit (top level) 104 4 20 4 93.55%
pcapkit/const 18795 968 2356 869 90.90%
pcapkit/corekit 2043 89 636 25 94.77%
pcapkit/dumpkit 242 2 88 2 98.79%
pcapkit/foundation 2648 98 930 48 94.80%
pcapkit/interface 112 7 40 5 92.11%
pcapkit/protocols 16887 225 4560 189 98.03%
pcapkit/toolkit 539 74 168 3 84.58%
pcapkit/utilities 429 4 122 4 98.55%
pcapkit/vendor 4409 2342 1006 157 43.25%

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

@JarryShaw

Copy link
Copy Markdown
Owner Author

Verdict: GOOD TO GO at c84b59304 (Sonnet cross-review; the author ran on Opus).

  • RFC 6554, re-read. CmprI covers addresses 1..n-1 and CmprE covers address n. The make() address count follows the RFC's n-from-Hdr-Ext-Len formula. Capping at 15 only applies when an address shares all 16 octets with dst. CmprI=0 for a single address is a defensible choice; the RFC doesn't mandate a value.
  • Sweep, independently re-done. 8192 cases covering CmprI/CmprE 0–15, 1–4 addresses and two Pad values, both standalone and inside IPv6, with no mismatches in info form or dict form.
  • fix(ipv6-route): a truncated RPL address list is split by the octets read, not by Hdr Ext Len #1457 repros. Both cut addresses come back as the raw bytes that were read, and both rebuild exactly.
  • Truncation. Cuts with Pad 0 are exact: 2848 of 2848 for every combination. Every cut with Pad > 0 comes back with the original as a prefix plus trailing octets. That is the generic PaddingField zero-fill tracked in fix(corekit): a header cut inside a fixed-width field is zero-filled on parse and rebuilt at full width #1458, not an RPL defect.
  • No ! needed. Data_RPL.ip was already typed IPv6Address | bytes. hdr_ext_len= mirrors IPv6's payload_length=, and an empty address list raises ProtocolError.
  • Tests, re-run by me. The new module gives 7 passed and 6803 subtests in 10 s. Without the fix it gives 6480 failures. The internet leg runs 608 OK and tests/project passes.

Merge note for #1454. Its #1456/#1457 entries go stale when this merges: 20 flip to OK. Two in-IPv6 cut55 entries flip to PADDED and should be re-homed under #1458.

@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 9, 2026
@JarryShaw
JarryShaw merged commit c7cec9c into main Oct 9, 2026
41 checks passed
@JarryShaw
JarryShaw deleted the fix/1456-1457-rpl-routing branch October 9, 2026 03:37
JarryShaw added a commit that referenced this pull request Oct 9, 2026
…fixed

#1454 merged before the three fixes, so its stale-entry check now fails on
main: #1455 (L2TPv2/OSPF trailer), #1456/#1457 (RPL) and #1459 (HIP fixed
bits) all come back OK. Drop those entries. The HIP fixed-bit cuts and two
RPL in-IPv6 cut55 cases now parse but zero-fill, so they move under the
#1451/#1458 short-read gaps. All four edge modules pass.
@JarryShaw JarryShaw removed the review: good-to-go Cross-review at the current head says ready; CI state is separate label Oct 9, 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

1 participant