Repository navigation
fix(protocols): bound the IPv6 extension-header chain at 32 headers (#1604) - #1608
Conversation
e6d87c6 to
d130f15
Compare
|
Coverage: 89.72% (unit tier, Python 3.14,
Per-file detail: the |
|
Verdict: GOOD TO GO at All nine claims are confirmed.
I reproduced the 32/33/1,000 counts for default, dpkt and scapy myself. Non-blocking:
|
|
Hold this until #1605 merges: combined with #1605, two of this PR's tests fail. I merged both heads (
Both are test expectations that predate #1605; the code is unaffected. Merge #1605 first. I'll then rebase this PR onto |
…1604) - Inside IPv4, each extension header dissected the next recursively, so a long chain hit the recursion limit and beholder left the rest raw, silently, at a depth that varied by interpreter; IPv6's own walk had no bound at all. EXTENSION_HEADER_LIMIT (32) now caps both: past it the rest stays Raw, with one ProtocolWarning. - pypcapfile's _past_extension_headers and _upper_layer stop at the same depth. - dpkt, scapy and tshark walk the chain in their own parsers; where they disagree is recorded as Gap rows in a new agreement module (#1609, #1606).
d130f15 to
2540340
Compare
|
Verdict: GOOD TO GO at This head is one commit on
I corrected the body's new bullet: #1605 reads TCP through IP-in-IP only when the innermost layer is IPv4. |
…1721) Third-party engines are best effort (#1687), so the pypcapfile code that exists only to match the default engine comes out: - revert #1682, #1600, #1575 and #1535, and the pypcapfile hunks of #1655, #1608 and #1605: reading loopback and raw-IP link types, the frame layer bound, the VLAN and tunnel walks, keying tunnelled TCP by the innermost header, stepping over AH and extension headers, and checking options with the default engine's parsers - keep the helpers the dpkt and scapy adapters import, unchanged, until their own reverts drop them; their docstrings no longer say pypcapfile asks the default engine's parsers too - re-land #1576, #1577, #1590 and #1591 as guards in _network and _transport, #1513's once-per-capture warning for TCP straight over IPv6, and #1667's packet2dict fix: an undecoded frame is reported as its octets, not as hex text twice as long - keep #1569's record reader and #1690's packet2timestamp - delete the three test modules those reverts added, the pypcapfile timestamp agreement class, and #1682's link-type warning test; the re-landed guards' tests assert constants - drop what the reverts removed from the docs, READ_LINKTYPES included, and say that TCP behind a VLAN tag, in a tunnel or behind an extension header (an IPv6 one, or AH in IPv4) is now left out without a warning The pypcapfile modules, test_new_engine_parity_runtime.py, test_engine_runtime.py, the timestamp module and the project guards pass on 3.11 (pypcapfile 0.12.0) and 3.14.
Please follow the guide below
You will be asked some questions, please read them carefully and answer honestly
Put an
xinto all the boxes [ ] relevant to your pull request (like that [x])Use Preview tab to see how your pull request will actually look like
Searched for similar pull requests
Followed the coding style (
make pylint,make mypy,make isort)make testpasses, and a test case covers the changeAdded a changelog entry under
docs/source/changelog/and regeneratedCHANGELOG.md, if the change is user-visible — N/A — centralised in docs(changelog): shared 1.5.0 changelog — long-lived, merges last (#610, #616, #617, #618, #620) #657What is the purpose of your pull request?
Tick the commit type your subject line carries.
fix— corrects a defectfeat— adds a featureperf— changes performance, not behaviourrefactor— changes neither behaviour nor performancetest— tests onlydocs— documentation onlyci— workflows or build toolingrelease— bumps the version or rolls up a distributionchore— anything elseDescription of your pull request and other information
Closes #1604 for the default engine and pypcapfile. The ruling's bound for dpkt, scapy and pyshark follows in #1609.
ipv6_opts.py:324→Internet._import_next_layer→ProtocolBase._parse_next_layer, about 11 frames a header). TheRecursionErrorwas caught bybeholder(decorators.py:128), which only logs it and leaves the restRaw. So TCP was lost after 79 headers on 3.11, and after 85 to 90 on 3.14. IPv6's own walk is a loop with no bound.EXTENSION_HEADER_LIMIT = 32inpcapkit/protocols/internet/internet.py.Internet._next_layer_classhands each header its depth in the chain. Past 32 the rest staysRaw, with oneProtocolWarningthat names the bound. Any other layer between headers starts the count again. IPv6's walk stops at the same depth._past_extension_headersand_upper_layerstop at 32 too.Gaprows citing fix(toolkit): the dpkt, scapy and pyshark engines do not stop an extension-header chain at 32 #1609 in the newtest_ext_chain_limit_agreement_1604_unit.py. One more row cites fix(toolkit): the dpkt and scapy engines drop TCP behind an IPv6 extension header carried in IPv4 #1606: dpkt and scapy dissect no extension header carried in IPv4, at any length.test_pypcapfile_ext_chain_limit_1604_unit.pywere updated for fix(toolkit): key tunnelled TCP by the innermost IP header (#1581) #1605's tunnel walk, which now reads TCP through IP-in-IP when the innermost layer is IPv4; TCP over IPv6 is still left out.frame.data, andfrom_data(info.to_dict())) at 32, 33 and 1,000 headers.