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
fix(toolkit): scapy reads link types the default engine leaves raw, and IPv6 at the wrong BSD loopback families #1650
With engine='scapy', the first layer of a frame is whatever scapy dissects for the capture's link type, and nothing checks whether the default engine dissects that layer too. _tcp_carrier (pcapkit/toolkit/scapy.py:429), _first_ipv4 (:365) and ipv6_reassembly (:608) take whatever IP layers they find.
The default engine dissects only NULL, ETHERNET, LOOP, IPV4, IPV6 and RAW (pcapkit/protocols/misc/pcap/frame.py:101-105, RAW at :658) and keeps every other link type Raw. So scapy hands TCP and IP fragments to reassembly and tracing from frames the default engine leaves undissected. In NULL and LOOP frames, the two engines also disagree on which address families mean IPv6.
Repro on main (b375656e1), Linux, dpkt 1.9.8. Python 3.14.8 with scapy 2.7.0 and Python 3.11.15 with scapy 2.8.0 give the same cells.
Each frame is a link header followed by an IPv4 or IPv6 packet. NULL is little-endian, LOOP big-endian. Each cell has four parts, separated by ·:
TCP reassembly/trace inputs for IPv4 TCP
the same for IPv6 TCP
IPv4,IPv6 reassembly inputs for two IPv4 fragments
the same for two IPv6 fragments
Link type
default
dpkt
scapy
ETHERNET (1), control
1/1 · 1/1 · 2,0 · 0,2
same
same
LINUX_SLL (113), LINUX_SLL2 (276), 12 (DLT_RAW), PPP (9) with or without ff 03, PPP_HDLC (50)
0/0 · 0/0 · 0,0 · 0,0
same
1/1 · 1/1 · 2,0 · 0,2
NULL (0) or LOOP (108), IPv6 at family 10
1/1 · 0/0 · 2,0 · 0,0
same
1/1 · 1/1 · 2,0 · 0,2
NULL (0) or LOOP (108), IPv6 at family 24, 28 or 30
1/1 · 1/1 · 2,0 · 0,2
same
1/1 · 0/0 · 2,0 · 0,0
NULL (0) or LOOP (108), family 0 for IPv4 and IPv6
0/0 · 0/0 · 0,0 · 0,0
same
1/1 · 0/0 · 2,0 · 0,0
The default engine's Loopback maps family 2 to IPv4, and 24, 28 and 30 to IPv6 (pcapkit/protocols/link/loopback.py:130-132, #1574). Scapy binds Loopback to IPv6 at socket.AF_INET6 (scapy/layers/inet6.py), which is 10 on this host; it uses 24 only on Windows. It binds IPv4 at socket.AF_INET and, bottom-up, at family 0 (scapy/layers/inet.py). So the NULL and LOOP rows depend on the host that runs pcapkit.
Expected: scapy reads no TCP, IPv4 or IPv6 in a frame whose link type the default engine leaves raw. In NULL and LOOP frames, on every host, it reads IPv4 only at family 2 and IPv6 only at 24, 28 and 30. dpkt already matches. #1636 covers encapsulations inside IP and Ethernet (GRE, VXLAN, PPPoE); this applies the same rule at the first layer. The #1636 fix (#1635/#1636 PR, being raised) leaves this open.
Activity
JarryShaw commentedon Oct 13, 2026
Blocked until the #1635/#1636 scapy PR merges, because both edit
pcapkit/toolkit/scapy.py's first-layer walk.JarryShaw commentedon Oct 13, 2026
Unblocked: #1652 has merged. A worker has this, in a single scapy PR that also covers the scapy parts of #1609 and #1626.
fix(toolkit): scapy walks link types, layer bounds and IPv6 extension…
fix(toolkit): scapy walks link types, layer bounds and IPv6 extension…