pktkit
Zero-copy L2/L3 packet handling toolkit for Rust.
pktkit is a feature-gated multi-tool for building virtual network topologies:
devices, hubs, adapters, NAT, and tunnels that move Ethernet frames and IP
packets without copying buffers on the hot path.
It is a Rust port of the Go pktkit library, re-cast into idiomatic Rust:
FrameandPacketare#[repr(transparent)]newtypes around[u8]. You hold them as&Frame/&mut Frame, exactly like Go's[]bytealias, with no per-call allocation.- Forwarding uses synchronous callbacks (
Arc<dyn Fn(&Frame) -> io::Result<()>>), not channels or async — matching the Go API one-for-one and keeping the hot path zero-cost. - Everything beyond the core (
Frame,Packet,L2Hub,L3Hub,Pipe, …) lives behind a Cargo feature so a user pulling only the core types pays nothing for crypto, OS FFI, or protocol stacks they don't use.
Features
Core (always on)
- Zero-copy types:
Frame,Packet,EtherType,Protocol,MacAddr - Traits:
L2Device,L3Device,L2Acceptor,L2Connector,L3Connector - L2Hub: MAC-learning switch with 5-minute aging
- L3Hub: prefix-routing hub with default-route fallback
- PipeL2 / PipeL3: in-memory devices for testing
- connect_l2 / connect_l3: point-to-point wiring
- serve: accept loop, with auto-cleanup on
Done - checksum: RFC 1071 + pseudo-header
Opt-in cargo features
| Feature | What you get |
|---|---|
l2adapter |
ARP, NDP, gateway routing, L2Adapter bridging an L3 device onto an L2 net |
dhcp |
DHCP client codec + DHCPServer (DISCOVER/OFFER/REQUEST/ACK/…) |
qemu |
QEMU userspace network socket protocol (listener + dialer) |
tuntap |
TUN/TAP devices on Linux and macOS |
afxdp |
Linux AF_XDP zero-copy sockets |
vtcp |
Pure-Rust TCP engine (congestion, SACK, timestamps, window scaling, SYN cookies) |
slirp |
Userspace NAT stack routing virtual traffic to real sockets |
vclient |
High-level virtual client: dial, listen, DNS, minimal HTTP |
nat |
Packet-level IPv4 NAT + NAT64 + ALGs (FTP, SIP, H.323, PPTP, TFTP, IRC) |
wg |
WireGuard tunnel (Noise IK + transport) |
ovpn |
OpenVPN server (TLS control + AES-CBC/GCM data) |
full |
All of the above |
Dependency policy
pktkit depends on:
- the Rust standard library
libc(only whentuntaporafxdpis enabled)- RustCrypto primitive crates (
chacha20poly1305,aes-gcm,curve25519-dalek,sha2,hmac,blake2,rsa, …) — only when the relevant tunnel feature is enabled. We do not roll our own crypto. rustlsfor OpenVPN's control-channel TLS (only whenovpnis enabled), configured with a pure-Rust crypto provider (rustls-rustcrypto, backed by the same RustCrypto crates) — noring, noaws-lc-rs, no vendored C/assembly, and no compile-time build script.
Nothing else. No async runtime. No framework. No native code beyond libc.
Everything cross-compiles. The default build pulls in zero dependencies.
Usage
Point-to-point L3
Devices are shared as Arcs (the Arc<T>: L3Device blanket impl makes this
ergonomic), and connect_l3 cross-wires their handlers:
use Ipv4Addr;
use Arc;
use ;
let a = new;
let b = new;
connect_l3;
Virtual LAN with DHCP and NAT
// requires: --features "l2adapter dhcp slirp"
use Ipv4Addr;
use Arc;
use ;
use ;
use Stack;
let hub = new;
// DHCP server handing out 192.168.0.10–100.
let mut dcfg = new;
dcfg.router = Some;
dcfg.dns = vec!;
let _dhcp_handle = hub.connect;
// NAT gateway: a slirp stack routing to the real network, bridged onto L2.
let stack = new;
stack.set_addr.unwrap;
let gw = new_arc;
let _gw_handle = hub.connect_arc;
Virtual client over the tunnel (DNS + TCP + HTTP)
// requires: --features "vclient"
use Ipv4Addr;
use IpPrefix;
use ;
let client = new;
// Wire `client` into an L3 network (slirp, wg, hub) via its L3Device impl,
// then:
let resp = client.http_get?;
println!;
WireGuard server with per-peer isolation
// requires: --features "wg slirp"
use ;
use Arc;
use ;
use ;
use Stack;
let stack = new;
stack.set_addr.unwrap;
let adapter = new?;
adapter.add_peer;
let udp = bind?;
adapter.serve?;
QEMU VM networking
// requires: --features "qemu"
use Arc;
use ;
use qemu;
let listener = bind_unix?;
let hub = new;
serve?; // accept loop: each VM joins the hub
Status
Active development; the API is not yet stable. Most features are functionally
complete and tested; a few have documented // TODO(<feature>) gaps:
- ovpn: tls-crypt/tls-auth, control-packet retransmit timers, and fuller PUSH_REPLY negotiation are not yet implemented.
- afxdp: the datapath needs root + a real NIC; pure logic is unit-tested, hardware paths are marked as needing verification.
- tuntap: macOS
utunis type-checked against the Apple target but not yet exercised on a macOS host. - slirp: inbound virtual TCP accept is IPv4-only (IPv6 accept is a TODO).
- nat: SIP/H.323/PPTP ALGs rewrite payloads; UPnP's live TCP control endpoint awaits wiring through the virtual TCP listener.
License
MIT — see LICENSE.