You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
scapy toolkit adapter passes raw 13-bit fragment offset unscaled to IP reassembly #483
Found while fixing #477. pcapkit/toolkit/scapy.py:160:
```python
data = IP_Packet(
...
fo=ipv4.frag, # fragment offset
...
)
```
`ipv4.frag` is scapy's raw IPv4 fragment-offset field — a 13-bit value counted in 8-octet units, per the wire format — not a byte offset. Every other pcapkit toolkit adapter either multiplies by 8 explicitly or uses a value the underlying engine has already scaled:
`pcapkit/toolkit/pcap.py:67` / `pcapkit/toolkit/pcapng.py:70`: `fo=ipv4_info.offset` (pcapkit's own `ipv4.py` sets `offset=int(schema.flags['offset']) * 8` at `pcapkit/protocols/internet/ipv4.py:307`, i.e. already in octets)
`pcapkit/toolkit/scapy.py:225` (IPv6 fragment header, same file): `fo=ipv6_frag.offset * 8` — scapy's IPv6 fragment path does scale it; only the IPv4 path at line 160 does not
Reproduction (not yet executed against the reassembler, confirmed only at the field level)
```python
import scapy.all as sc
p = sc.IP(frag=5, flags='MF')
bytes(p)[6:8].hex()
'2005'
```
`0x2005` decodes as flags=`001` (MF set) + a 13-bit offset of `5` — i.e. scapy stored the raw unit count `5`, not a byte offset of `40`. `pcapkit.toolkit.scapy.ipv4_reassembly` would hand this packet to `IP.reassembly()` as `fo=5`, when every other engine reading the same bytes would report `fo=40`.
Expected impact
Any capture read through the scapy engine (`pcapkit.foundation.engines.scapy`) containing IPv4 fragments would compute fragment placement 8x too small, corrupting reassembly for that engine specifically — silently, since nothing validates `fo` against the fragment's own length. IPv6 fragments read through the same engine are unaffected (the Fragment-header path already multiplies by 8).
Scope
Not fixing here — this is a single-line, single-adapter fix (`fo=ipv4.frag * 8`) but wants its own verification against an actual reassembly run through the scapy engine (e.g. a scapy-crafted fragmented IPv4 packet fed through `pcapkit.foundation.engines.scapy`) and its own test, rather than being folded into #477/#482, which own `pcapkit/foundation/reassembly/ip.py` and its data model, not `pcapkit/toolkit/scapy.py`.
Activity
tests: assert the scapy fragment-offset regression leaves no overlap …
docs: add a fifth sweep strand for duplicated logic wanting a shared …
release: bump to 1.5.0b1, the wave-1 beta (#488)