netlink_packet_route/neighbour_discovery_user_option/
buffer.rs

1// SPDX-License-Identifier: MIT
2
3use netlink_packet_utils::nla::{NlaBuffer, NlasIterator};
4use netlink_packet_utils::DecodeError;
5
6pub const NEIGHBOUR_DISCOVERY_USER_OPTION_HEADER_LEN: usize = 16;
7
8buffer!(NeighbourDiscoveryUserOptionMessageBuffer {
9    address_family: (u8, 0),
10    padding_1: (u8, 1),
11    options_length: (u16, 2..4),
12    interface_index: (u32, 4..8),
13    icmp_type: (u8, 8),
14    icmp_code: (u8, 9),
15    padding_2: (u16, 10..12),
16    padding_3: (u32, 12..16),
17    payload: (slice, NEIGHBOUR_DISCOVERY_USER_OPTION_HEADER_LEN..),
18});
19
20impl<T: AsRef<[u8]>> NeighbourDiscoveryUserOptionMessageBuffer<T> {
21    pub fn new_checked(buffer: T) -> Result<Self, DecodeError> {
22        let packet = Self::new(buffer);
23        packet.check_buffer_length()?;
24        Ok(packet)
25    }
26
27    fn check_buffer_length(&self) -> Result<(), DecodeError> {
28        let len = self.buffer.as_ref().len();
29        let required_len =
30            NEIGHBOUR_DISCOVERY_USER_OPTION_HEADER_LEN + self.options_length() as usize;
31        if len < required_len {
32            Err(DecodeError::InvalidBufferLength {
33                name: "NeighbourDiscoveryUserOptionMessageBuffer",
34                len,
35                buffer_len: required_len,
36            })
37        } else {
38            Ok(())
39        }
40    }
41}
42
43impl<'a, T: AsRef<[u8]> + ?Sized> NeighbourDiscoveryUserOptionMessageBuffer<&'a T> {
44    pub fn option_body(&self) -> &[u8] {
45        &self.payload()[..self.options_length() as usize]
46    }
47
48    pub fn nlas(&self) -> impl Iterator<Item = Result<NlaBuffer<&'a [u8]>, DecodeError>> {
49        NlasIterator::new(&self.payload()[self.options_length() as usize..])
50            .map(|result| result.map_err(DecodeError::from))
51    }
52}