Repository navigation
fix(toolkit): dpkt reassembly adapters build their data from dpkt's re-serialised bytes and mutate the packet - #1335
Conversation
|
Cross-review verdict on 1. An offset regression on AH and odd-length Routing headers — blocking.
Derive the offset from the buffer rather than from dpkt 2. The hard-coded Confirmed as the author described (each re-derived, not taken on trust): the zero-length fallback matches dpkt ( Also worth doing, not blocking: the four adapters' docstrings should carry the unbuffered-fallback caveat that today sits only on |
…e-serialised bytes and mutate the packet The DPKT engine now attaches each record's octets to the frame beside its timestamp (attach_buffer / packet2bytes). ipv4_reassembly, ipv6_reassembly, tcp_reassembly, tcp_traceflow and packet2dict slice the header and payload out of those octets instead of calling .pack(), which recomputed zeroed checksums and lengths and wrote them back into the packet. A hand-built packet with no buffer attached is serialised from a deep copy, so it is never mutated either. The layer's offset in those octets comes from the advance dpkt's own unpack() made, not from len(): IP6.__len__ sums len() of the extension headers, which overshoots by the rest of the frame for an Authentication header and falls 8 octets short for a Routing header whose Hdr Ext Len is odd. The slice is then checked against the layer's own pack_hdr() and a ProtocolError raised rather than wrong bytes returned. ipv6_hdr_len walks the headers in parsed order for the same reason, so an Authentication header before the Fragment header is counted and one after it is not. Closes #1297
19b78ab to
b0af61f
Compare
|
Round-2 verdict on
Nits: dpkt also crashes on Fragment followed by ESP, not just Dst Options, so the docstring should name both. Two Fragment headers make |
Please follow the guide below
isort -l100 -ppcapkitclean;mypyclean;pylint45 findings before and after, all pre-existing inengines/dpkt.py, none intoolkit/dpkt.pymake testpasses, and a test case covers the change (modules listed below)What is the purpose of your pull request?
fix— corrects a defectDescription of your pull request and other information
Closes #1297
The DPKT engine attaches each record's octets to the frame beside its timestamp (new
attach_buffer/packet2bytes).ipv4_reassembly,ipv6_reassembly,tcp_reassembly,tcp_traceflowandpacket2dictslice the layer out of those octets instead of calling.pack(). A hand-built packet without a buffer is serialised from a deep copy, so it is not mutated, but its bytes are still dpkt's re-serialisation — pinned by a test.The offset comes from the advance dpkt's own
unpack()made, not fromlen():IP6.__len__sumslen()of the extension headers, which overshoots by the rest of the frame for an Authentication header and falls 8 octets short for a Routing header with an odd Hdr Ext Len. The slice is then checked against the layer's ownpack_hdr()— exact, since dpkt recomputes nothing there — and aProtocolErrorraised rather than wrong bytes returned.ipv6_hdr_lenwalks the headers in parsed order for the same reason.Probe. Issue repro: header
45000034…4084f8f2…→450000380000000040840000…(wire),ip.sum63730 → 0. All 23 fixture captures: 0 off-wire records, 0 changed on a second call, noProtocolError. IPv6 + AH + TCP: header''→ the wire's 20 octets. Routing Hdr Ext Len 3: the routing header's tail → the wire's 20 octets.Tests. New
tests/toolkit/test_dpkt_reassembly_rawbytes_unit.py, 12 tests / 70 subtests, every frame written to a PCAP and read back through the engine. Againstorigin/main: 62 failed / 7 passed, every failure in the behaviour class anAssertionError. Restoring only thelen()walk fails exactly the 6 extension-header subtests whoselen()disagrees with the wire. Also green:test_dpkt_unit(20),run_unittest_leg.py toolkit(280, 0 failures),tests/project(389),integration/test_reassembly_engine_parity,integration/test_engine_parity,integration/test_engine_runtime,foundation/engines/test_runtime_engines,foundation/test_extraction,interface/test_misc.Stored frames now hold one extra copy of their record octets.
ipv6_hdr_lenkeeps its signature but counts a different set of headers, andProtocolErroris newly reachable from the four adapters.