Skip to main content

netlink_packet_route/neighbour_discovery_user_option/
buffer.rs

1// SPDX-License-Identifier: MIT
2
3use netlink_packet_utils::DecodeError;
4use netlink_packet_utils::nla::{HasNlas, NlaBuffer, NlaError, NlasIterator};
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<'a, T: AsRef<[u8]> + ?Sized> HasNlas for NeighbourDiscoveryUserOptionMessageBuffer<&'a T> {
21    fn attributes(&self) -> impl Iterator<Item = Result<NlaBuffer<&[u8]>, NlaError>> {
22        NlasIterator::new(&self.payload()[self.options_length() as usize..])
23    }
24}
25
26impl<T: AsRef<[u8]>> NeighbourDiscoveryUserOptionMessageBuffer<T> {
27    pub fn new(buffer: T) -> Result<Self, DecodeError> {
28        let packet = Self::new_unchecked(buffer);
29        packet.check_buffer_length()?;
30        Ok(packet)
31    }
32
33    fn check_buffer_length(&self) -> Result<(), DecodeError> {
34        let len = self.buffer.as_ref().len();
35        let required_len =
36            NEIGHBOUR_DISCOVERY_USER_OPTION_HEADER_LEN + self.options_length() as usize;
37        if len < required_len {
38            Err(DecodeError::InvalidBufferLength {
39                name: "NeighbourDiscoveryUserOptionMessageBuffer",
40                len,
41                buffer_len: required_len,
42            })
43        } else {
44            Ok(())
45        }
46    }
47}
48
49impl<'a, T: AsRef<[u8]> + ?Sized> NeighbourDiscoveryUserOptionMessageBuffer<&'a T> {
50    pub fn option_body(&self) -> &[u8] {
51        &self.payload()[..self.options_length() as usize]
52    }
53}