#[non_exhaustive]
pub struct NetlinkBuffer<T> { pub buffer: T, }
Expand description

A raw Netlink buffer that provides getters and setter for the various header fields, and to retrieve the payloads.

Example: reading a packet

use netlink_packet_core::{NetlinkBuffer, NLM_F_MATCH, NLM_F_REQUEST, NLM_F_ROOT};

const RTM_GETLINK: u16 = 18;

fn main() {
    // Artificially create an array of bytes that represents a netlink packet.
    // Normally, we would read it from a socket.
    let buffer = vec![
        0x28, 0x00, 0x00, 0x00, // length = 40
        0x12, 0x00, // message type = 18 (RTM_GETLINK)
        0x01, 0x03, // flags = Request + Specify Tree Root + Return All Matching
        0x34, 0x0e, 0xf9, 0x5a, // sequence number = 1526271540
        0x00, 0x00, 0x00, 0x00, // port id = 0
        // 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];

    // Wrap the storage into a NetlinkBuffer
    let packet = NetlinkBuffer::new_checked(&buffer[..]).unwrap();

    // Check that the different accessor return the expected values
    assert_eq!(packet.length(), 40);
    assert_eq!(packet.message_type(), RTM_GETLINK);
    assert_eq!(packet.sequence_number(), 1526271540);
    assert_eq!(packet.port_number(), 0);
    assert_eq!(packet.payload_length(), 24);
    assert_eq!(packet.payload(), &buffer[16..]);
    assert_eq!(
        Into::<u16>::into(packet.flags()),
        NLM_F_ROOT | NLM_F_REQUEST | NLM_F_MATCH
    );
}

Example: writing a packet

use netlink_packet_core::{NetlinkBuffer, NLM_F_MATCH, NLM_F_REQUEST, NLM_F_ROOT};

const RTM_GETLINK: u16 = 18;

fn main() {
    // The packet we want to write.
    let expected_buffer = vec![
        0x28, 0x00, 0x00, 0x00, // length = 40
        0x12, 0x00, // message type = 18 (RTM_GETLINK)
        0x01, 0x03, // flags = Request + Specify Tree Root + Return All Matching
        0x34, 0x0e, 0xf9, 0x5a, // sequence number = 1526271540
        0x00, 0x00, 0x00, 0x00, // port id = 0
        // 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];

    // Create a storage that is big enough for our packet
    let mut buf = vec![0; 40];
    // the extra scope is to restrict the scope of the borrow
    {
        // Create a NetlinkBuffer.
        let mut packet = NetlinkBuffer::new(&mut buf);
        // Set the various fields
        packet.set_length(40);
        packet.set_message_type(RTM_GETLINK);
        packet.set_sequence_number(1526271540);
        packet.set_port_number(0);
        packet.set_flags(From::from(NLM_F_ROOT | NLM_F_REQUEST | NLM_F_MATCH));
        // we kind of cheat here to keep the example short
        packet.payload_mut().copy_from_slice(&expected_buffer[16..]);
    }
    // Check that the storage contains the expected values
    assert_eq!(&buf[..], &expected_buffer[..]);
}

Note that in this second example we don’t call new_checked() because the length field is initialized to 0, so new_checked() would return an error.

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§buffer: T

Implementations§

source§

impl<T: AsRef<[u8]>> NetlinkBuffer<T>

source

pub fn new(buffer: T) -> NetlinkBuffer<T>

Create a new NetlinkBuffer that uses the given buffer as storage. Note that when calling this method no check is performed, so trying to access fields may panic. If you’re not sure the given buffer contains a valid netlink packet, use new_checked() instead.

source

pub fn new_checked(buffer: T) -> Result<NetlinkBuffer<T>, DecodeError>

Check the length of the given buffer and make sure it’s big enough so that trying to access packet fields won’t panic. If the buffer is big enough, create a new NewlinkBuffer that uses this buffer as storage.

Example

With a buffer that does not even contain a full header:

use netlink_packet_core::NetlinkBuffer;
static BYTES: [u8; 4] = [0x28, 0x00, 0x00, 0x00];
assert!(NetlinkBuffer::new_checked(&BYTES[..]).is_err());

Here is a slightly more tricky error, where technically, the buffer is big enough to contains a valid packet. Here, accessing the packet header fields would not panic but accessing the payload would, so new_checked also checks the length field in the packet header:

use netlink_packet_core::NetlinkBuffer;
// The buffer is 24 bytes long. It contains a valid header but a truncated payload
static BYTES: [u8; 24] = [
    // The length field says the buffer is 40 bytes long
    0x28, 0x00, 0x00, 0x00,
    0x12, 0x00, // message type
    0x01, 0x03, // flags
    0x34, 0x0e, 0xf9, 0x5a, // sequence number
    0x00, 0x00, 0x00, 0x00, // port id
    // payload
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
assert!(NetlinkBuffer::new_checked(&BYTES[..]).is_err());
source

pub fn payload_length(&self) -> usize

Return the payload length.

Panic

This panic is the underlying storage is too small or if the length field in the header is set to a value that exceeds the storage length (see new_checked())

source

pub fn into_inner(self) -> T

Consume the packet, returning the underlying buffer.

source

pub fn length(&self) -> u32

Return the length field

Panic

This panic is the underlying storage is too small (see new_checked())

source

pub fn message_type(&self) -> u16

Return the type field

Panic

This panic is the underlying storage is too small (see new_checked())

source

pub fn flags(&self) -> u16

Return the flags field

Panic

This panic is the underlying storage is too small (see new_checked())

source

pub fn sequence_number(&self) -> u32

Return the sequence_number field

Panic

This panic is the underlying storage is too small (see new_checked())

source

pub fn port_number(&self) -> u32

Return the port_number field

Panic

This panic is the underlying storage is too small (see new_checked())

source§

impl<T: AsRef<[u8]> + AsMut<[u8]>> NetlinkBuffer<T>

source

pub fn set_length(&mut self, value: u32)

Set the packet header length field

Panic

This panic is the underlying storage is too small (see new_checked())

source

pub fn set_message_type(&mut self, value: u16)

Set the packet header message_type field

Panic

This panic is the underlying storage is too small (see new_checked())

source

pub fn set_flags(&mut self, value: u16)

Set the packet header flags field

Panic

This panic is the underlying storage is too small (see new_checked())

source

pub fn set_sequence_number(&mut self, value: u32)

Set the packet header sequence_number field

Panic

This panic is the underlying storage is too small (see new_checked())

source

pub fn set_port_number(&mut self, value: u32)

Set the packet header port_number field

Panic

This panic is the underlying storage is too small (see new_checked())

source§

impl<'a, T: AsRef<[u8]> + ?Sized> NetlinkBuffer<&'a T>

source

pub fn payload(&self) -> &'a [u8]

Return a pointer to the packet payload.

Panic

This panic is the underlying storage is too small or if the length field in the header is set to a value that exceeds the storage length (see [new_checked()](struct.NetlinkBuffer.html#method. new_checked))

source§

impl<'a, T: AsRef<[u8]> + AsMut<[u8]> + ?Sized> NetlinkBuffer<&'a mut T>

source

pub fn payload_mut(&mut self) -> &mut [u8]

Return a mutable pointer to the payload.

Panic

This panic is the underlying storage is too small or if the length field in the header is set to a value that exceeds the storage length (see [new_checked()](struct.NetlinkBuffer.html#method. new_checked))

Trait Implementations§

source§

impl<T: Clone> Clone for NetlinkBuffer<T>

source§

fn clone(&self) -> NetlinkBuffer<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for NetlinkBuffer<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NetlinkBuffer<&'a T>> for NetlinkHeader

source§

fn parse(buf: &NetlinkBuffer<&'a T>) -> Result<NetlinkHeader, DecodeError>

Deserialize the current type.
source§

impl<'buffer, B, I> Parseable<NetlinkBuffer<&'buffer B>> for NetlinkMessage<I>where B: AsRef<[u8]> + 'buffer, I: NetlinkDeserializable,

source§

fn parse(buf: &NetlinkBuffer<&'buffer B>) -> Result<Self, DecodeError>

Deserialize the current type.
source§

impl<T: PartialEq> PartialEq<NetlinkBuffer<T>> for NetlinkBuffer<T>

source§

fn eq(&self, other: &NetlinkBuffer<T>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<T: Eq> Eq for NetlinkBuffer<T>

source§

impl<T> StructuralEq for NetlinkBuffer<T>

source§

impl<T> StructuralPartialEq for NetlinkBuffer<T>

Auto Trait Implementations§

§

impl<T> RefUnwindSafe for NetlinkBuffer<T>where T: RefUnwindSafe,

§

impl<T> Send for NetlinkBuffer<T>where T: Send,

§

impl<T> Sync for NetlinkBuffer<T>where T: Sync,

§

impl<T> Unpin for NetlinkBuffer<T>where T: Unpin,

§

impl<T> UnwindSafe for NetlinkBuffer<T>where T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.