208 lines
14 KiB
Markdown
208 lines
14 KiB
Markdown
# Stack Research
|
|
|
|
**Domain:** Rust eBPF-based network monitoring TUI tool (cross-platform: Linux + macOS)
|
|
**Researched:** 2026-03-21
|
|
**Confidence:** MEDIUM-HIGH (eBPF/Linux stack is well-established; macOS backend strategy has more uncertainty)
|
|
|
|
## Recommended Stack
|
|
|
|
### Core Technologies
|
|
|
|
| Technology | Version | Purpose | Why Recommended |
|
|
|------------|---------|---------|-----------------|
|
|
| Rust (nightly) | nightly-2026-xx | Language + eBPF compilation | Nightly required for eBPF target (`bpfel-unknown-none`, `-Z build-std=core`). Pin a specific nightly via `rust-toolchain.toml` for reproducibility. |
|
|
| Aya | 0.13.x | eBPF library (userspace loader + kernel program SDK) | Pure Rust eBPF, no libbpf/bcc dependency. BTF support for kernel portability. Async tokio integration via `AsyncPerfEventArray` and `RingBufAsync`. The standard choice for Rust eBPF -- no real competitor in the Rust ecosystem. |
|
|
| aya-ebpf | 0.1.x | eBPF kernel-side program macros | Companion to aya. Provides `#[kprobe]`, `#[tracepoint]`, `#[cgroup_skb]` macros for writing eBPF programs in Rust. |
|
|
| Ratatui | 0.30.x | Terminal UI framework | Undisputed standard for Rust TUIs. Immediate-mode rendering, sub-millisecond performance, huge widget library. Table, sparklines, and layout primitives are exactly what a `top`-like tool needs. |
|
|
| Crossterm | 0.28.x+ | Terminal backend for Ratatui | Default backend for ratatui. Cross-platform (Linux, macOS). Pure Rust, no ncurses dependency. |
|
|
| Tokio | 1.43+ (LTS) | Async runtime | Required by Aya's async features (`AsyncPerfEventArray`, `RingBufAsync`). Handles concurrent event processing from eBPF maps and TUI rendering loop. Use the LTS release for stability. |
|
|
| clap | 4.6.x | CLI argument parsing | De facto standard. Derive macros for zero-boilerplate argument definitions. Supports `--port`, `--log`, `--pid` flags naturally. |
|
|
|
|
### Platform-Specific Backend (Data Collection)
|
|
|
|
This is the most architecturally significant decision. eBPF only works on Linux. macOS needs a different backend behind a shared trait interface.
|
|
|
|
| Technology | Platform | Purpose | Why Recommended |
|
|
|------------|----------|---------|-----------------|
|
|
| Aya (eBPF kprobes/tracepoints) | Linux | Kernel-level connection tracing | Lowest overhead. Attach to `tcp_connect`, `tcp_close`, `tcp_sendmsg`, `udp_sendmsg` etc. Data flows via `RingBuf` or `PerfEventArray` to userspace. |
|
|
| pcap (libpcap bindings) | macOS (primary) | Packet capture with PKTAP | macOS PKTAP embeds PID and process name directly in packet headers. The pcap crate (v2.3.x) wraps libpcap which is pre-installed on macOS. PKTAP is the closest macOS equivalent to eBPF for network monitoring. |
|
|
| sysinfo | Both | Process name/metadata enrichment | Cross-platform process information (PID to name mapping, etc.). Supplements both backends. |
|
|
| procfs | Linux only | /proc/net/* parsing (fallback) | Fallback for connection state when eBPF data is incomplete. Parse `/proc/net/tcp`, `/proc/net/udp` for socket-to-PID mapping. |
|
|
|
|
### Supporting Libraries
|
|
|
|
| Library | Version | Purpose | When to Use |
|
|
|---------|---------|---------|-------------|
|
|
| csv | 1.4.x | CSV log file writing | `--log output.csv` mode. BurntSushi's csv crate is the only sensible choice -- fast, serde-integrated, battle-tested (129M+ downloads). |
|
|
| serde + serde_json | 1.x | Serialization framework | Derive `Serialize` for connection records. Used by csv crate for struct-to-row mapping. |
|
|
| anyhow | 1.x | Error handling (application) | Ergonomic error handling in the binary crate. Use `thiserror` in library code if you extract one. |
|
|
| thiserror | 2.x | Error handling (library) | Typed errors for the platform abstraction layer and data collection backends. |
|
|
| nix | 0.29.x | Unix system calls | Low-level syscall access (socket options, process info, privilege checking). Cross-platform Unix support. |
|
|
| libc | 0.2.x | FFI type definitions | Required by aya and nix. Transitive dependency but worth pinning. |
|
|
| log + env_logger | 0.4.x / 0.11.x | Logging | Debug logging during development. Not for the TUI output -- for internal diagnostics. |
|
|
| signal-hook | 0.3.x | Signal handling | Graceful shutdown on SIGINT/SIGTERM. Important for root-privilege tools that manipulate kernel state. |
|
|
|
|
### Build and Development Tools
|
|
|
|
| Tool | Purpose | Notes |
|
|
|------|---------|-------|
|
|
| bpf-linker | Links eBPF object files | `cargo install bpf-linker`. On macOS, install with `--no-default-features` and ensure LLVM 21+ is available. |
|
|
| cargo-generate | Project scaffolding | Use `aya-template` for initial project structure. Optional after initial setup. |
|
|
| rust-toolchain.toml | Pin nightly version | Critical for reproducible eBPF builds. Pin both `nightly` channel and `bpfel-unknown-none` target. |
|
|
| cargo xtask | Build orchestration | Aya projects use an `xtask` pattern: a workspace member that builds the eBPF program and embeds it in the userspace binary. Standard pattern -- follow it. |
|
|
| cross | Cross-compilation | For building Linux binaries from macOS (CI/CD). Not needed for local dev if targeting native platform. |
|
|
|
|
## Project Structure (Aya Convention)
|
|
|
|
```
|
|
tcptop/
|
|
Cargo.toml # Workspace root
|
|
xtask/ # Build tool (compiles eBPF, embeds in binary)
|
|
Cargo.toml
|
|
src/main.rs
|
|
tcptop-ebpf/ # eBPF kernel programs (no_std, nightly)
|
|
Cargo.toml
|
|
src/main.rs # kprobes, tracepoints
|
|
tcptop/ # Userspace binary
|
|
Cargo.toml
|
|
src/
|
|
main.rs # CLI parsing, TUI loop
|
|
collector/ # Platform abstraction trait
|
|
mod.rs # trait NetworkCollector
|
|
linux.rs # Aya eBPF implementation
|
|
macos.rs # PKTAP/libpcap implementation
|
|
tui/ # Ratatui rendering
|
|
model/ # Connection state, aggregation
|
|
```
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
# Prerequisites (Linux)
|
|
rustup toolchain install nightly
|
|
rustup target add bpfel-unknown-none --toolchain nightly
|
|
cargo install bpf-linker
|
|
|
|
# Prerequisites (macOS -- for cross-compiling eBPF or developing userspace)
|
|
brew install llvm
|
|
cargo install bpf-linker --no-default-features
|
|
|
|
# Project dependencies (in workspace Cargo.toml for userspace crate)
|
|
cargo add aya tokio --features tokio/full
|
|
cargo add ratatui crossterm
|
|
cargo add clap --features derive
|
|
cargo add csv serde --features serde/derive
|
|
cargo add anyhow thiserror
|
|
cargo add sysinfo nix --features nix/net,nix/process
|
|
cargo add pcap # macOS backend
|
|
cargo add signal-hook
|
|
cargo add log env_logger
|
|
|
|
# eBPF crate dependencies (tcptop-ebpf/Cargo.toml)
|
|
# aya-ebpf = "0.1"
|
|
# aya-log-ebpf = "0.1"
|
|
```
|
|
|
|
## Alternatives Considered
|
|
|
|
| Recommended | Alternative | When to Use Alternative |
|
|
|-------------|-------------|-------------------------|
|
|
| Aya | libbpf-rs (Rust bindings for libbpf) | If you need C-based eBPF programs or have existing .bpf.c code to integrate. Aya is better for pure-Rust projects. |
|
|
| Aya | RedBPF | Never -- RedBPF is largely unmaintained and has been superseded by Aya in the Rust ecosystem. |
|
|
| Ratatui | cursive | If you want a callback-based (retained mode) TUI instead of immediate mode. Ratatui is better for data-heavy dashboards that redraw frequently. |
|
|
| Crossterm | termion | If you want a simpler API and only target Unix. Crossterm is better because it already works on both platforms and is ratatui's default. |
|
|
| Tokio | async-std | Aya supports both, but tokio has far more ecosystem support and is the standard async runtime. No reason to choose async-std. |
|
|
| clap | argh (Google) | Only if you need minimal binary size and don't need rich help text. clap is better for user-facing CLI tools. |
|
|
| pcap (macOS) | DTrace via FFI | DTrace is powerful but the Rust FFI story is poor, scripting interface is awkward from Rust, and PKTAP via libpcap is simpler and provides process attribution natively. |
|
|
| pcap (macOS) | Network Extension Framework | Requires app sandbox, provisioning profiles, and Apple Developer account. Massive overkill for a CLI tool. |
|
|
|
|
## What NOT to Use
|
|
|
|
| Avoid | Why | Use Instead |
|
|
|-------|-----|-------------|
|
|
| RedBPF | Largely abandoned, last meaningful update 2022. Aya has won the Rust eBPF space. | Aya |
|
|
| tui-rs (original) | Deprecated. Ratatui is the maintained fork that the community migrated to in 2023. | Ratatui |
|
|
| termion | Doesn't support Windows (not relevant here), but more importantly crossterm is ratatui's default and better maintained. | Crossterm |
|
|
| ncurses / pancurses | C dependency, complex linking, less Rust-idiomatic. | Ratatui + Crossterm (pure Rust) |
|
|
| raw /proc parsing for all data | Fragile, slow (polling), and misses short-lived connections. | eBPF (event-driven, kernel-level) with /proc as fallback only |
|
|
| npcap / WinPcap | Windows only. Out of scope. | pcap (libpcap) for macOS |
|
|
| pnet (Rust networking) | Lower-level than needed, doesn't provide PKTAP integration, would require reimplementing what libpcap gives you. | pcap crate |
|
|
|
|
## Stack Patterns by Variant
|
|
|
|
**If Linux-only (no macOS support needed):**
|
|
- Skip the pcap dependency entirely
|
|
- Skip the platform abstraction trait (simplifies architecture)
|
|
- Use Aya directly in the main collector module
|
|
- This significantly reduces complexity
|
|
|
|
**If macOS is a first-class target:**
|
|
- Must implement the `NetworkCollector` trait with two backends
|
|
- macOS backend uses pcap with PKTAP for packet capture + process attribution
|
|
- Connection state tracking (TCP states, byte counts) must be done in userspace on macOS since PKTAP gives raw packets, not connection events
|
|
- Consider shipping macOS as "monitoring mode" (less kernel integration) vs Linux as "full mode"
|
|
|
|
**If you want to develop eBPF programs from macOS:**
|
|
- bpf-linker compiles eBPF bytecode on macOS (cross-compilation works)
|
|
- But you cannot load/test eBPF programs on macOS -- need a Linux VM or remote machine
|
|
- Use Lima or OrbStack for local Linux VM testing on Apple Silicon
|
|
|
|
## Version Compatibility
|
|
|
|
| Package | Compatible With | Notes |
|
|
|---------|-----------------|-------|
|
|
| aya 0.13.x | tokio 1.x | Use `features = ["async_tokio"]` on aya |
|
|
| aya-ebpf 0.1.x | Rust nightly | Must use nightly toolchain with `bpfel-unknown-none` target |
|
|
| ratatui 0.30.x | crossterm 0.28.x+ | Ratatui re-exports crossterm types; check ratatui's Cargo.toml for exact pin |
|
|
| bpf-linker | LLVM 21+ | On macOS, `brew install llvm` and set `LLVM_SYS_210_PREFIX` |
|
|
| pcap 2.3.x | libpcap (system) | Pre-installed on macOS. On Linux, `apt install libpcap-dev`. |
|
|
| clap 4.6.x | serde 1.x | Optional serde integration for config file parsing |
|
|
| Rust nightly | aya-ebpf, bpf-linker | Only the eBPF crate needs nightly. Userspace crate can use stable Rust via workspace toolchain override. |
|
|
|
|
## Key Architecture Decisions Driven by Stack
|
|
|
|
1. **Workspace with xtask pattern**: Aya projects conventionally split into workspace members (ebpf crate, userspace crate, xtask build tool). Follow this convention -- it is well-documented and the community expects it.
|
|
|
|
2. **Nightly only for eBPF crate**: Use `rust-toolchain.toml` at workspace root with nightly, but the userspace code should be written to compile on stable (future-proofing for when aya-ebpf stabilizes).
|
|
|
|
3. **Platform abstraction is mandatory**: The `NetworkCollector` trait is the most important architectural boundary. Define it early. Linux backend (Aya) produces connection events; macOS backend (pcap/PKTAP) produces raw packets that must be assembled into connection events.
|
|
|
|
4. **Async everywhere in userspace**: Tokio runtime drives both the eBPF event loop (RingBuf/PerfEventArray polling) and the TUI tick loop. Use `tokio::select!` to multiplex between data events and TUI input events.
|
|
|
|
5. **Root privilege handling**: Both eBPF loading and libpcap capture require elevated privileges. Check at startup, provide clear error message, fail fast.
|
|
|
|
## Confidence Assessment
|
|
|
|
| Component | Confidence | Rationale |
|
|
|-----------|------------|-----------|
|
|
| Aya for eBPF | HIGH | Undisputed leader in Rust eBPF. Active development (0.13.x released recently). No viable alternative. |
|
|
| Ratatui for TUI | HIGH | Community standard since tui-rs deprecation. 0.30.x is mature. |
|
|
| clap for CLI | HIGH | De facto standard, v4.6 actively maintained. |
|
|
| Tokio async runtime | HIGH | Standard async runtime, LTS releases, Aya integration proven. |
|
|
| csv crate | HIGH | BurntSushi's csv is the only real option. Mature and stable. |
|
|
| pcap + PKTAP for macOS | MEDIUM | PKTAP approach is proven (RustNet uses it), but the pcap crate's PKTAP-specific support is less documented. May need raw header parsing. Needs validation during implementation. |
|
|
| bpf-linker on macOS | MEDIUM | Cross-compilation works per docs, but LLVM version pinning can be fragile. CI may need Linux runners for eBPF compilation. |
|
|
| Overall macOS parity | MEDIUM-LOW | macOS backend will inherently provide less data than eBPF (no kernel-level TCP state machine hooks). Feature parity is not fully achievable -- must design the abstraction to handle this gracefully. |
|
|
|
|
## Sources
|
|
|
|
- [Aya GitHub repository](https://github.com/aya-rs/aya) -- versions, feature set, project structure
|
|
- [Aya crates.io](https://crates.io/crates/aya) -- v0.13.x latest release
|
|
- [Aya documentation](https://docs.rs/aya/latest/aya/) -- async features, map types
|
|
- [Aya book](https://aya-rs.dev/book/) -- development environment setup, bpf-linker installation
|
|
- [Ratatui official site](https://ratatui.rs/) -- v0.30.x features, no_std support
|
|
- [Ratatui GitHub](https://github.com/ratatui/ratatui) -- latest release info
|
|
- [clap crates.io](https://crates.io/crates/clap) -- v4.6.0 latest
|
|
- [Tokio](https://tokio.rs/) -- LTS release schedule (1.43 until March 2026, 1.47 until Sept 2026)
|
|
- [csv crate](https://crates.io/crates/csv) -- v1.4.0 latest
|
|
- [pcap crate GitHub](https://github.com/rust-pcap/pcap) -- v2.3.x, libpcap bindings
|
|
- [PKTAP vs eBPF article](https://domcyrus.github.io/systems-programming/networking/ebpf/macos/linux/2025/01/18/pktap-vs-ebpf-network-process-identification.html) -- macOS PKTAP approach, process attribution
|
|
- [RustNet GitHub](https://github.com/domcyrus/rustnet) -- cross-platform network monitoring reference implementation
|
|
- [Bandix GitHub](https://github.com/beijixi/bandix) -- Rust eBPF network monitoring reference
|
|
- [eBPF with Rust using Aya (blog)](https://www.galiglobal.com/blog/2025/20251119-ebpf-rust-aya.html) -- macOS cross-compilation workflow
|
|
- [How to Write eBPF Programs in Rust with Aya](https://oneuptime.com/blog/post/2026-01-07-ebpf-rust-aya/view) -- build pipeline details
|
|
|
|
---
|
|
*Stack research for: tcptop -- Rust eBPF network monitoring TUI*
|
|
*Researched: 2026-03-21*
|