Skip to content

fix(protocols): reject an IPv6 header whose Version is not 6 (#1680) - #1723

Merged
JarryShaw merged 1 commit into
mainfrom
fix/1680-ipv6-version-check
Oct 14, 2026
Merged

JarryShaw merged 1 commit into
mainfrom
fix/1680-ipv6-version-check

Conversation

@JarryShaw

Copy link
Copy Markdown
Owner

Please follow the guide below

What is the purpose of your pull request?

Tick the commit type your subject line carries.

  • fix — corrects a defect
  • feat — adds a feature
  • perf — changes performance, not behaviour
  • refactor — changes neither behaviour nor performance
  • test — tests only
  • docs — documentation only
  • ci — workflows or build tooling
  • release — bumps the version or rolls up a distribution
  • chore — anything else

Description of your pull request and other information

Closes #1680.

  • Fix: IPv6.read raises ProtocolError("[IPv6] invalid version: N") for any Version but 6, as IPv4.read does for 4 (owner ruling). The default engine only; the adapters are unchanged, per the best-effort ruling on fix(protocols): the default engine accepts an IPv6 Jumbo Payload option of 65535 octets or less, against RFC 2675 #1687.
  • Effect: a frame whose IPv6 header has the wrong Version now stops at its link layer, or at a tunnel's inner header, and rebuilds byte for byte. On main, rebuilding such a frame wrote Version 6 (60... for 40...).
  • Captures: none of the 23 generated captures change: 1616 frames, 247 IPv6 layers on both trees.
  • Make: IPv6.make already hard-codes Version 6, so make->parse is unaffected.
  • Tests:
    • New: test_ipv6_version_1680_unit.py, plus an ipv6/version-4 edge round-trip case. With the check removed, the three changed modules show 78 failures.
    • Updated: test_pcap_tcp_segment_ipv6_version_1666_unit.py pinned the old accept-anything reading. It now checks that the default engine reads only the controls, and checks dpkt and scapy against fixed values.
    • Narrow runs on 3.14: tests/protocols and tests/toolkit pass, as do tests/foundation, tests/integration, tests/interface and tests/cli.

- IPv6.read raises ProtocolError("[IPv6] invalid version: N") for any
  Version but 6, as IPv4.read does for any but 4; behind Ethernet or a
  tunnel the frame stops there, kept raw and rebuilt as captured, where
  from_data used to rewrite the first octet to 6
- default engine only; the third-party adapters are unchanged (#1687)
- IPv6.make cannot write another Version, so make->parse is unaffected
- the #1666 module now pins that the default engine hands the Version 4
  frames nothing, and checks dpkt and scapy against constants
- add test_ipv6_version_1680_unit and an ipv6/version-4 REJECTED case to
  the internet edge round trip; drop toolkit/pcap.py's stale note

No frame of the 23 generated captures changes (1616 frames, 247 IPv6
layers). tests/protocols/internet, tests/toolkit and the project guards
pass on 3.14; the changed modules pass on 3.11.

Closes #1680
@JarryShaw JarryShaw added fix Pull requests that fix a defect (fix: subject prefix) review: good-to-go Cross-review at the current head says ready; CI state is separate labels Oct 14, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

Verdict: GOOD TO GO at db9193d25. A Sonnet cross-review checked it; the author was Opus.

  • Matches IPv4: the check is the first statement after the schema read, as in IPv4.read. The message is the same apart from the protocol name, and both raise ProtocolError.
  • Mutation: turning the check off gives 78 failed, 12 passed. Restoring it gives 12 passed.
  • Captures: an independent script compared the default engine before and after the fix over all 23 captures: 0 of 1616 frames differ.
  • Hand-built frames: Versions 0, 4, 5, 7 and 15 behind Ethernet behave like the IPv4 sibling. So do linktype 229, 6in4 and 6in6.
  • Make path: ipv6.py:319 hard-codes Version 6, so make->parse cannot produce another Version.
  • Scope: no adapter or engine file is touched.
  • Non-blocking: the rewritten dpkt/scapy test pins TCP inputs, trace inputs and flows, but no longer the IPv4, IPv6 and datagram aspects. That follows refactor(toolkit): revert the cross-engine agreement tests and the adapter code that only mirrors the default engine #1708.

@JarryShaw JarryShaw moved this to In review in PyPCAPKit Oct 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Coverage: 89.42% (unit tier, Python 3.15, db9193d25, Unit Tests run success)

Package Statements Missed Branches Partial Cover
pcapkit (top level) 104 3 20 3 95.16%
pcapkit/const 18860 954 2368 868 91.06%
pcapkit/corekit 2372 67 762 35 96.49%
pcapkit/dumpkit 275 3 100 3 98.40%
pcapkit/foundation 2887 144 1012 34 94.20%
pcapkit/interface 138 7 52 5 93.68%
pcapkit/protocols 17183 226 4592 190 98.07%
pcapkit/toolkit 1313 280 532 5 75.88%
pcapkit/utilities 500 4 150 4 98.77%
pcapkit/vendor 4417 2342 1010 157 43.38%

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

@JarryShaw
JarryShaw merged commit b627a08 into main Oct 14, 2026
52 checks passed
@JarryShaw
JarryShaw deleted the fix/1680-ipv6-version-check branch October 14, 2026 15:47
@github-project-automation github-project-automation Bot moved this from In review to Done in PyPCAPKit Oct 14, 2026
@JarryShaw JarryShaw removed the review: good-to-go Cross-review at the current head says ready; CI state is separate label Oct 14, 2026
@JarryShaw JarryShaw added this to the PyPCAPKit v1.5 milestone Oct 26, 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(protocols): IPv6.read accepts a header whose Version is not 6

1 participant