netlink_packet/lib.rs
1//! This package contains types that represent netlink messages. See the [`libnl` library
2//! documentation][libnl] for an introduction to the Netlink protocols.
3//!
4//! This crate provides widely different types based on the features that are enabled. There are
5//! currently two features available, which are mutually exclusive `rtnetlink` and `audit`. With
6//! the `rtnetlink` feature, this crates provides types for the `NETLINK_ROUTE` protocol family
7//! (see `man 7 rtnetlink`). With the `audit` feature, this crate provides types for the
8//! `NETLINK_AUDIT` protocol family.
9//!
10//! [libnl]: https://www.infradead.org/~tgr/libnl/doc/core.html#core_netlink_fundamentals
11//!
12//! # Generating the documentation for the desired feature
13//!
14//! At the moment, rustdoc does not support features very well. If you plan on using this crate,
15//! you should probably generate the appropriate documentation yourself by getting the source, and
16//! running `cargo doc`:
17//!
18//! ```no_rust
19//! cargo doc --open --features audit # for the audit messages
20//! cargo doc --open --features rtnetlink # for the rtnetlink messages
21//! ```
22//!
23//! # Overview
24//!
25//! Independently of the feature that is enabled, this crate provides two representations of most
26//! netlink packets:
27//!
28//! - **Buffer** types like [`NetlinkBuffer`](struct.NetlinkBuffer.html) for instance. These types
29//! wrappers around actual byte buffers, and provide safe accessors to the various fields of the
30//! packet they represent. These types are useful if you manipulate byte streams, but everytime
31//! data is accessed, it must be parsed or encoded.
32//!
33//! - Higher level representation of netlink packets, like
34//! [`NetlinkMessage`](struct.NetlinkMessage.html), which are the prefered way to build packets.
35//!
36//! ## Using buffer types to parse messages
37//!
38//! It is possible to go from on representation to another. Actually, the buffer types are used to
39//! parse byte buffers into messages types, using the [`Parseable`](trait.Parseable.html) trait. In
40//! the list of implementors, we can see for instance:
41//!
42//! ```no_rust
43//! impl<'buffer, T: AsRef<[u8]> + 'buffer> Parseable<NetlinkMessage> for NetlinkBuffer<&'buffer T>
44//! ```
45//!
46//! That means a `NetlinkBuffer` is parseable into a `NetlinkMessage` (note that the following
47//! snippets assumes the crate is being used with the `rtnetlink` feature):
48//!
49//! ```rust,no_run
50//! # // FIXME: this snippet is `no_run` because it breaks cargo test, when the rtnetlink feature
51//! # // is not enabled. If rustc supports that better in the future, somehow, we should run this
52//! # // example.
53//! extern crate netlink_packet;
54//! use netlink_packet::{NetlinkBuffer, NetlinkMessage, Parseable};
55//! use netlink_packet::constants::{RTM_GETLINK, NLM_F_ROOT, NLM_F_REQUEST, NLM_F_MATCH};
56//!
57//! // a packet captured with tcpdump that was sent when running `ip link show`
58//! static PKT: [u8; 40] = [
59//! 0x28, 0x00, 0x00, 0x00, // length
60//! 0x12, 0x00, // message type
61//! 0x01, 0x03, // flags
62//! 0x34, 0x0e, 0xf9, 0x5a, // sequence number
63//! 0x00, 0x00, 0x00, 0x00, // port id
64//! // payload
65//! 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66//! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67//! 0x08, 0x00, 0x1d, 0x00, 0x01, 0x00, 0x00, 0x00];
68//!
69//! fn main() {
70//! let pkt: NetlinkMessage =
71//! // Create a buffer. Notice the double &&. That is because Parseable<NetlinkMessage> is
72//! // implemented for NetlinkBuffer<&T> not NetlinkBuffer<T>. The reason behing this is
73//! // that we want the storage T to be able to outlive our NetlinkBuffer, if necessary. It
74//! // feels a bit weird here but can be useful in other circumstances.
75//! NetlinkBuffer::new_checked(&&PKT[..])
76//! .unwrap()
77//! // Convert the buffer into an actual message. This is when the parsing occurs.
78//! .parse()
79//! .unwrap();
80//!
81//! println!("{:#?}", pkt);
82//! }
83//! ```
84//!
85//! This prints:
86//!
87//! ```no_rust
88//! NetlinkMessage {
89//! header: NetlinkHeader {
90//! length: 40,
91//! message_type: 18,
92//! flags: NetlinkFlags(769),
93//! sequence_number: 1526271540,
94//! port_number: 0
95//! },
96//! message: GetLink(
97//! LinkMessage {
98//! header: LinkHeader {
99//! address_family: 17,
100//! index: 0,
101//! link_layer_type: Netrom,
102//! flags: LinkFlags(0),
103//! change_mask: LinkFlags(0)
104//! },
105//! nlas: [ExtMask(1)]
106//! }
107//! ),
108//! }
109//! ```
110//!
111//! ## Emitting messages
112//!
113//! TODO
114
115#![cfg_attr(rustfmt, rustfmt::skip)]
116
117#[macro_use] extern crate log;
118
119pub use netlink_sys::constants;
120
121mod errors;
122pub use self::errors::*;
123
124use core::ops::{Range, RangeFrom};
125/// Represent a multi-bytes field with a fixed size in a packet
126pub(crate) type Field = Range<usize>;
127/// Represent a field that starts at a given index in a packet
128pub(crate) type Rest = RangeFrom<usize>;
129
130#[cfg(feature = "rtnetlink")]
131/// Represent a field of exactly one byte in a packet
132pub(crate) type Index = usize;
133
134#[cfg(feature = "rtnetlink")]
135/// rtnetlink types (see `man 7 rtnetlink`)
136mod rtnl;
137#[cfg(feature = "rtnetlink")]
138pub use self::rtnl::*;
139
140#[cfg(feature = "audit")]
141mod audit;
142#[cfg(feature = "audit")]
143pub use self::audit::*;
144
145mod netlink;
146pub use self::netlink::*;
147
148// FIXME: should we expose these traits or only keep them for internal use?
149mod traits;
150pub use self::traits::*;
151
152#[cfg(test)] #[macro_use] extern crate lazy_static;