netlink-packet-utils
netlink-packet-utils: Rust macros and traits for parsing and emitting Netlink protocol messages
Repository Health
Technical Analysis
netlink-packet-utils is a small Rust crate shared by the rust-netlink family of crates (netlink-packet-route, netlink-packet-audit, and others) for parsing and serializing Linux Netlink attribute (NLA) and message buffers. It defines the core Emitable, Parseable, and ParseableParametrized traits that give every downstream netlink-packet-* type a consistent encode/decode contract, plus macros (getter!, buffer!) that generate boilerplate accessor methods for fixed-layout wire structures.
As of 2025 the crate is officially deprecated: its README and Cargo.toml version (0.6.1-deprecated) point users to netlink-packet-core, which absorbs the same functionality going forward. It remains useful as a reference for how the rust-netlink ecosystem structures low-level buffer parsing, but new projects should adopt netlink-packet-core instead.
What You Get
EmitableandParseable/ParseableParametrizedtraits defining a uniform serialize/deserialize contract for netlink wire typesNlaBuffer<T>wrapper with checked accessors (kind(),length(),value()) for reading and writing Netlink Attribute (NLA) headersDefaultNlaand theNlatrait for generic attribute handling, including nested and network-byte-order flag bitsgetter!andbuffer!macros that generate typed accessor methods (u8/u16/u32/u64/i8/i16/i32/i64/slice) for fixed-offset buffer fieldsDecodeErrorandEncodeErrorenums (viathiserror) covering malformed buffers, invalid lengths, and UTF-8 failures- Standalone parser helpers (
parse_mac,parse_ip,parse_ipv6) for common Netlink payload types
Common Use Cases
- Implementing a new Netlink protocol family (e.g. a custom generic-netlink subsystem) by hand-rolling
Emitable/Parseabletypes - Parsing raw NLA buffers received from a
AF_NETLINKsocket into typed attribute structs - Generating repetitive fixed-offset buffer accessors via the
getter!/buffer!macros instead of writing byte-offset math by hand - Referencing this crate’s trait design as a template when studying or extending netlink-packet-core, its successor
Under The Hood
Architecture — The crate is organized around three small modules: traits.rs defines the Emitable/Parseable/ParseableParametrized contract every wire type implements; nla.rs builds on those traits with NlaBuffer<T>, a checked wrapper over a byte slice that exposes kind(), length(), value() and mutation counterparts, plus a blanket impl<T: Nla> Emitable for T that derives serialization from a simpler Nla trait; and parsers.rs/errors.rs supply standalone helpers (parse_mac, parse_ip) and thiserror-based DecodeError/EncodeError enums. macros.rs generates typed getters (getter!) for fixed-offset fields so downstream crates avoid hand-written byte-offset math. The design cleanly separates the wire-format contract (traits) from the reusable NLA-specific implementation (nla.rs), which is why it could be lifted wholesale into other rust-netlink crates.
Tech Stack — Pure Rust (edition 2018), zero-async, with three runtime dependencies: byteorder for endian-aware integer reads/writes, pastey (a paste-style token-pasting macro helper) for macro-generated identifiers, and thiserror 2 for ergonomic error enums. No build scripts, no unsafe blocks observed, no feature flags — the crate is deliberately minimal and dependency-light, appropriate for a low-level shared utility consumed by many downstream crates.
Code Quality — Test coverage is thin: only nla.rs carries #[test] functions (byte-order flag handling, alignment macro behavior, and an overflow-panic case), while parsers.rs, macros.rs, and errors.rs have none. Error handling is structured and idiomatic (thiserror-derived enums with #[from] conversions rather than string errors), and naming follows Rust convention consistently (snake_case functions, CamelCase types). Documentation comments exist on public traits and NLA methods but are sparse elsewhere, and the crate carries no #![deny(missing_docs)] or CI badge to enforce doc coverage.
API Design — The public surface is small and consistent: two or three traits to implement, one buffer wrapper to use, and a handful of macros for boilerplate reduction. This low surface area makes it easy to learn once you understand Netlink’s TLV wire format, but the API assumes that background knowledge — there’s no beginner-level example demonstrating an end-to-end parse/emit cycle in the README itself. The crate’s own deprecation notice is the clearest piece of “documentation” a new adopter will encounter, redirecting them to netlink-packet-core instead.