Internals
Packet path — kernel bypass, hand-assembled
How a scan gets from a Go struct to a live packet on the wire and back — bytecode assembled by hand, loaded straight into the kernel, and read through a shared memory ring instead of a socket.
Load path — once, at startup
Bytecode, hand-assembled
internal/scan/xdp_asm.go builds eBPF instructions directly with
cilium/ebpf/asm — no C source, no clang -target bpf step.
ebpf.CollectionSpec
The assembled instructions plus a map layout, still just Go values in memory.
cilium/ebpf (Go library)
Loads the program and creates the maps in one bpf() syscall — the only
part of this path clang would normally have done for you.
Data path — per scan
tcpcat process
Crafts SYN / RST / ACK / ICMP frames by hand, parses replies, scores OS fingerprints, paces itself with an RTT/AIMD rate controller — all plain userspace Go.
cmd/tcpcat · internal/scan · internal/osdetectVerifier
Statically proves the program can't crash the kernel or loop forever.
JIT compiler
Turns the verified bytecode into native machine code for the NIC's core.
XDP hook
Runs on every inbound frame, at the driver — before the kernel's own TCP/IP stack ever sees it.
eBPF maps
xsks_map — a tiny lookup the hook uses to decide which socket owns a
given RX queue.
AF_XDP socket
A UMEM region shared with the process: fill, RX, TX and completion rings, mapped once and never copied per packet.
Anything the hook doesn't claim — every other process's traffic — falls through to the normal socket / TCP-IP stack, untouched.
What tcpcat does with those frames
Everything below runs in the userspace process, on results the kernel path above hands it.
Host discovery
ICMP echo + SYN/443 + ACK/80 fired together over the same ring.
Half-open SYN scan
Reads the SYN/ACK, then sends its own crafted RST — never a full connection.
OS fingerprint
TTL, window, MSS and option order scored against a small signature table.
Adaptive rate
RFC 6298 RTT estimate feeds an AIMD limiter that paces the next batch.
Service detect
Open ports get a real TCP connection for a banner — back on ordinary sockets.
Vuln correlate
Banner versions checked against OSV, Vulners, and an offline CVE database.
Report
JSON, SARIF, XML or console — one result set, several writers.
No Linux, no root, or no compatible NIC driver?
tcpcat drops the whole kernel-bypass path above and runs the same pipeline over
SOCK_RAW or a plain TCP connect scan instead — slower, but no eBPF required.