Skip to main content

pktkit/
lib.rs

1//! Zero-copy L2/L3 packet handling toolkit.
2//!
3//! `pktkit` provides primitives for building virtual network topologies:
4//! devices, hubs, adapters, NAT, and tunnels that move Ethernet frames and IP
5//! packets without copying buffers on the hot path.
6//!
7//! See the crate-level [README](https://github.com/KarpelesLab/pktkit-rs) for
8//! a tour of what each Cargo feature adds. The default build ships only the
9//! core types — everything else is opt-in.
10//!
11//! # Core
12//!
13//! - [`Frame`] is an Ethernet frame; [`Packet`] is an IP packet. Both are
14//!   `#[repr(transparent)]` newtypes over `[u8]` so `&Frame` is the same shape
15//!   as `&[u8]` and accessors are free.
16//! - [`L2Device`] and [`L3Device`] are object-safe traits for anything that
17//!   sends/receives frames or packets. Forwarding is a synchronous callback;
18//!   the buffer is only valid for the duration of the call.
19//! - [`L2Hub`] is a MAC-learning switch with 5-minute aging. [`L3Hub`] is a
20//!   prefix-routing hub with a default route fallback.
21//! - [`PipeL2`] and [`PipeL3`] are in-memory devices for tests and for wiring
22//!   subpackages together.
23//! - [`connect_l2`] and [`connect_l3`] wire two devices point-to-point.
24//! - [`serve`] runs an accept loop, joining each incoming L2 device into a
25//!   connector.
26//!
27//! # Reading and writing wire formats
28//!
29//! [`Frame`] covers L2 and [`Packet`] covers L3; the [`l4`] module adds the
30//! transport layer ([`TcpSegment`], [`UdpDatagram`], [`IcmpMessage`]) and the
31//! [`FiveTuple`] that identifies a flow. Get an L4 view straight from a packet
32//! with [`Packet::tcp`], [`Packet::udp`] or [`Packet::icmp`].
33//!
34//! Going the other way, [`build`] constructs well-formed packets with lengths
35//! and checksums filled in, [`icmp`] generates the error messages a forwarder
36//! owes to senders, and [`fragment`] splits a datagram that is too large for
37//! the next hop.
38
39#![cfg_attr(docsrs, feature(doc_cfg))]
40#![warn(missing_debug_implementations)]
41#![warn(rust_2018_idioms)]
42// A low-level networking crate carries inherently rich callback/handler types
43// and a few wide protocol constructors; and several modules mirror the Go
44// upstream's `pkg/pkg.rs` layout. These clippy lints fight that on purpose, so
45// we opt out crate-wide rather than scatter per-item allows.
46#![allow(clippy::type_complexity)]
47#![allow(clippy::too_many_arguments)]
48#![allow(clippy::module_inception)]
49
50// --- Core (always compiled) -------------------------------------------------
51
52mod accept;
53pub mod build;
54mod checksum;
55mod connect;
56mod ethertype;
57pub mod fragment;
58mod frame;
59pub mod icmp;
60mod iface;
61mod ip;
62mod l2hub;
63mod l3hub;
64pub mod l4;
65mod mac;
66mod packet;
67mod pipe;
68mod pool;
69mod protocol;
70mod rand;
71mod stats;
72#[cfg(feature = "wg")]
73mod zeroize;
74
75pub use accept::{
76    Cleanup, Done, DoneSignal, L2Acceptor, L2AcceptorWithDone, L2Connector, L3Connector, serve,
77    serve_with_done,
78};
79pub use checksum::{
80    checksum, combine_checksums, incremental_update, pseudo_header_checksum, transport_checksum,
81};
82pub use connect::{connect_l2, connect_l3};
83pub use ethertype::EtherType;
84pub use frame::{Frame, build_frame};
85pub use iface::{Handler, L2Device, L2Handler, L3Device, L3Handler};
86pub use ip::IpPrefix;
87pub use l2hub::{L2Hub, L2HubHandle, PortMode, VlanSet};
88pub use l3hub::{L3Hub, L3HubHandle};
89pub use l4::{FiveTuple, IcmpMessage, TcpFlags, TcpSegment, UdpDatagram};
90pub use mac::{BROADCAST_MAC, MacAddr};
91pub use packet::Packet;
92pub use pipe::{PipeL2, PipeL3};
93pub use pool::{BufferPool, DEFAULT_MTU};
94pub use protocol::Protocol;
95pub use stats::{DeviceStats, HubCounters, HubStats, Stats};
96
97/// Crate-wide `Result` alias.
98pub type Result<T> = std::io::Result<T>;
99
100// Linux syscall helpers, compiled only for the features that issue them.
101#[cfg(all(target_os = "linux", any(feature = "tuntap", feature = "afpacket")))]
102mod sys;
103
104// Parser entry points collected for fuzzing. Not an API; see `src/fuzz.rs`.
105#[cfg(feature = "fuzzing")]
106#[doc(hidden)]
107pub mod fuzz;
108
109// --- Feature modules --------------------------------------------------------
110
111#[cfg(feature = "l2adapter")]
112#[cfg_attr(docsrs, doc(cfg(feature = "l2adapter")))]
113pub mod arp;
114
115#[cfg(feature = "l2adapter")]
116#[cfg_attr(docsrs, doc(cfg(feature = "l2adapter")))]
117pub mod ndp;
118
119#[cfg(feature = "l2adapter")]
120#[cfg_attr(docsrs, doc(cfg(feature = "l2adapter")))]
121mod l2adapter;
122
123#[cfg(feature = "l2adapter")]
124#[cfg_attr(docsrs, doc(cfg(feature = "l2adapter")))]
125pub use l2adapter::{L2Adapter, L2AdapterConfig};
126
127#[cfg(feature = "dhcp")]
128#[cfg_attr(docsrs, doc(cfg(feature = "dhcp")))]
129pub mod dhcp;
130
131#[cfg(feature = "afpacket")]
132#[cfg_attr(docsrs, doc(cfg(feature = "afpacket")))]
133pub mod afpacket;
134
135#[cfg(feature = "impair")]
136#[cfg_attr(docsrs, doc(cfg(feature = "impair")))]
137pub mod impair;
138
139#[cfg(feature = "pcap")]
140#[cfg_attr(docsrs, doc(cfg(feature = "pcap")))]
141pub mod pcap;
142
143#[cfg(feature = "qemu")]
144#[cfg_attr(docsrs, doc(cfg(feature = "qemu")))]
145pub mod qemu;
146
147#[cfg(feature = "tuntap")]
148#[cfg_attr(docsrs, doc(cfg(feature = "tuntap")))]
149pub mod tuntap;
150
151// XDP and AF_XDP are Linux kernel interfaces with no analogue elsewhere, and
152// unlike `tuntap` or `afpacket` there is no meaningful stub to offer: the API
153// is built around eBPF programs, maps and UMEM rings. The modules are simply
154// absent off Linux, so that enabling `full` -- which includes them -- still
155// builds everywhere.
156#[cfg(all(feature = "xdp", target_os = "linux"))]
157#[cfg_attr(docsrs, doc(cfg(feature = "xdp")))]
158pub mod xdp;
159
160#[cfg(all(feature = "afxdp", target_os = "linux"))]
161#[cfg_attr(docsrs, doc(cfg(feature = "afxdp")))]
162pub mod afxdp;
163
164#[cfg(feature = "vtcp")]
165#[cfg_attr(docsrs, doc(cfg(feature = "vtcp")))]
166pub mod vtcp;
167
168#[cfg(feature = "slirp")]
169#[cfg_attr(docsrs, doc(cfg(feature = "slirp")))]
170pub mod slirp;
171
172#[cfg(feature = "vclient")]
173#[cfg_attr(docsrs, doc(cfg(feature = "vclient")))]
174pub mod vclient;
175
176#[cfg(feature = "nat")]
177#[cfg_attr(docsrs, doc(cfg(feature = "nat")))]
178pub mod nat;
179
180#[cfg(feature = "wg")]
181#[cfg_attr(docsrs, doc(cfg(feature = "wg")))]
182pub mod wg;
183
184#[cfg(feature = "ovpn")]
185#[cfg_attr(docsrs, doc(cfg(feature = "ovpn")))]
186pub mod ovpn;