Crate netlink_packet

source ·
Expand description

This package contains types that represent netlink messages. See the libnl library documentation for an introduction to the Netlink protocols.

This crate provides widely different types based on the features that are enabled. There are currently two features available, which are mutually exclusive rtnetlink and audit. With the rtnetlink feature, this crates provides types for the NETLINK_ROUTE protocol family (see man 7 rtnetlink). With the audit feature, this crate provides types for the NETLINK_AUDIT protocol family.

Generating the documentation for the desired feature

At the moment, rustdoc does not support features very well. If you plan on using this crate, you should probably generate the appropriate documentation yourself by getting the source, and running cargo doc:

cargo doc --open --features audit     # for the audit messages
cargo doc --open --features rtnetlink # for the rtnetlink messages

Overview

Independently of the feature that is enabled, this crate provides two representations of most netlink packets:

  • Buffer types like NetlinkBuffer for instance. These types wrappers around actual byte buffers, and provide safe accessors to the various fields of the packet they represent. These types are useful if you manipulate byte streams, but everytime data is accessed, it must be parsed or encoded.

  • Higher level representation of netlink packets, like NetlinkMessage, which are the prefered way to build packets.

Using buffer types to parse messages

It is possible to go from on representation to another. Actually, the buffer types are used to parse byte buffers into messages types, using the Parseable trait. In the list of implementors, we can see for instance:

impl<'buffer, T: AsRef<[u8]> + 'buffer> Parseable<NetlinkMessage> for NetlinkBuffer<&'buffer T>

That means a NetlinkBuffer is parseable into a NetlinkMessage (note that the following snippets assumes the crate is being used with the rtnetlink feature):

extern crate netlink_packet;
use netlink_packet::{NetlinkBuffer, NetlinkMessage, Parseable};
use netlink_packet::constants::{RTM_GETLINK, NLM_F_ROOT, NLM_F_REQUEST, NLM_F_MATCH};

// a packet captured with tcpdump that was sent when running `ip link show`
static PKT: [u8; 40] = [
    0x28, 0x00, 0x00, 0x00, // length
    0x12, 0x00, // message type
    0x01, 0x03, // flags
    0x34, 0x0e, 0xf9, 0x5a, // sequence number
    0x00, 0x00, 0x00, 0x00, // port id
    // payload
    0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x08, 0x00, 0x1d, 0x00, 0x01, 0x00, 0x00, 0x00];

fn main() {
    let pkt: NetlinkMessage =
        // Create a buffer. Notice the double &&. That is because Parseable<NetlinkMessage> is
        // implemented for NetlinkBuffer<&T> not NetlinkBuffer<T>. The reason behing this is
        // that we want the storage T to be able to outlive our NetlinkBuffer, if necessary. It
        // feels a bit weird here but can be useful in other circumstances.
        NetlinkBuffer::new_checked(&&PKT[..])
            .unwrap()
            // Convert the buffer into an actual message. This is when the parsing occurs.
            .parse()
            .unwrap();

    println!("{:#?}", pkt);
}

This prints:

NetlinkMessage {
    header: NetlinkHeader {
        length: 40,
        message_type: 18,
        flags: NetlinkFlags(769),
        sequence_number: 1526271540,
        port_number: 0
    },
    message: GetLink(
        LinkMessage {
            header: LinkHeader {
                address_family: 17,
                index: 0,
                link_layer_type: Netrom,
                flags: LinkFlags(0),
                change_mask: LinkFlags(0)
            },
            nlas: [ExtMask(1)]
        }
    ),
}

Emitting messages

TODO

Modules

Structs

A raw Netlink buffer that provides getters and setter for the various header fields, and to retrieve the payloads.
Represent the flags field in a netlink packet header.
A Netlink header representation.
Represent a netlink message.

Enums

Constants

Length of a Netlink packet header

Traits

A type that implements Emitable can be serialized.
A Parseable type can be used to deserialize data into the target type T for which it is implemented.

Type Definitions