proc-connector
Linux Process Event Connector (NETLINK_CONNECTOR + CN_IDX_PROC) — safe,
zero-overhead, full-coverage parser for all 10+ PROC_EVENT_* types.
Installation
Minimum supported Rust version: 1.85 (edition 2024).
Requirements
- Linux kernel with
CONFIG_CONNECTORandCONFIG_PROC_EVENTSenabled CAP_NET_ADMINcapability (run as root or withcap_net_admin+ep)
The crate compiles on any platform, but all runtime operations require a Linux
kernel with proc connector support. Non-Linux platforms will fail at runtime
with Error::Os(ENOSYS).
Testing
Unit tests (no privileges needed)
67 unit tests covering all protocol parsing (every event variant, truncation edge cases, malformed headers, kernel boundary conditions, multi-message iteration), error formatting, alignment helpers, and alignment math.
Integration tests (require root)
2 additional tests verify end-to-end behavior against a real Linux kernel.
Build as normal user, run under sudo:
| Test | What it checks |
|---|---|
test_receive_exec_event |
Create connector → spawn /bin/true → receive Exec event within 5s |
test_subscribe_unsubscribe |
Subscribe → unsubscribe → re-subscribe, no errors |
About this crate
The Linux kernel exposes process lifecycle events (exec, fork, exit, uid/gid
change, ptrace, etc.) through the Proc Connector — a netlink protocol
multiplexed over NETLINK_CONNECTOR with CN_IDX_PROC.
Event coverage
| Event | Kernel constant | Fields |
|---|---|---|
Exec |
PROC_EVENT_EXEC |
pid, tgid |
Fork |
PROC_EVENT_FORK |
parent_pid, parent_tgid, child_pid, child_tgid |
Exit |
PROC_EVENT_EXIT |
pid, tgid, exit_code, exit_signal |
Uid |
PROC_EVENT_UID |
pid, tgid, ruid, euid |
Gid |
PROC_EVENT_GID |
pid, tgid, rgid, egid |
Sid |
PROC_EVENT_SID |
pid, tgid |
Ptrace |
PROC_EVENT_PTRACE |
pid, tgid, tracer_pid, tracer_tgid |
Comm |
PROC_EVENT_COMM |
pid, tgid, comm: [u8; 16] |
Coredump |
PROC_EVENT_COREDUMP |
pid, tgid |
Quick example
use ProcConnector;
use Duration;
// Requires CAP_NET_ADMIN
let conn = new.expect;
let mut buf = ;
loop
Async integration
use ProcConnector;
let conn = new.unwrap;
let raw_fd = conn.as_raw_fd;
// With tokio:
// let async_fd = tokio::io::unix::AsyncFd::new(conn).unwrap();
Modules
src/
├── consts.rs # All kernel constants (PROC_EVENT_*, CN_IDX_PROC, NLMSG_*, layout offsets)
├── error.rs # Error enum (Os, Truncated, BufferTooSmall, Interrupted, ConnectionClosed, Overrun)
├── socket.rs # ProcConnector (new, subscribe, unsubscribe, recv_raw, as_raw_fd)
├── event.rs # ProcEvent enum + netlink/cn_msg/proc_event three-layer parser
└── lib.rs # Re-exports, prelude
Error handling
All fallible operations return Result<T, Error>. The Error enum covers both
system-level and protocol-level failures:
| Variant | Meaning |
|---|---|
Os(io::Error) |
System call failed (socket, bind, sendmsg, recv) |
Truncated |
Message shorter than minimum protocol header |
BufferTooSmall { needed } |
Provided buffer too small |
Interrupted |
recv interrupted by signal (retry) |
ConnectionClosed |
recv returned 0 |
Overrun |
Kernel reporting dropped events (increase buffer / consume faster) |
use Error;