netlink_packet_route/neighbour/
message.rs

1// SPDX-License-Identifier: MIT
2
3use anyhow::Context;
4use netlink_packet_utils::{
5    traits::{Emitable, Parseable, ParseableParametrized},
6    DecodeError,
7};
8
9use super::{
10    super::AddressFamily, NeighbourAttribute, NeighbourHeader,
11    NeighbourMessageBuffer,
12};
13
14#[derive(Debug, PartialEq, Eq, Clone, Default)]
15#[non_exhaustive]
16pub struct NeighbourMessage {
17    pub header: NeighbourHeader,
18    pub attributes: Vec<NeighbourAttribute>,
19}
20
21impl Emitable for NeighbourMessage {
22    fn buffer_len(&self) -> usize {
23        self.header.buffer_len() + self.attributes.as_slice().buffer_len()
24    }
25
26    fn emit(&self, buffer: &mut [u8]) {
27        self.header.emit(buffer);
28        self.attributes
29            .as_slice()
30            .emit(&mut buffer[self.header.buffer_len()..]);
31    }
32}
33
34impl<'a, T: AsRef<[u8]> + 'a> Parseable<NeighbourMessageBuffer<&'a T>>
35    for NeighbourMessage
36{
37    fn parse(buf: &NeighbourMessageBuffer<&'a T>) -> Result<Self, DecodeError> {
38        let header = NeighbourHeader::parse(buf)
39            .context("failed to parse neighbour message header")?;
40        let address_family = header.family;
41        Ok(NeighbourMessage {
42            header,
43            attributes: Vec::<NeighbourAttribute>::parse_with_param(
44                buf,
45                address_family,
46            )
47            .context("failed to parse neighbour message NLAs")?,
48        })
49    }
50}
51
52impl<'a, T: AsRef<[u8]> + 'a>
53    ParseableParametrized<NeighbourMessageBuffer<&'a T>, AddressFamily>
54    for Vec<NeighbourAttribute>
55{
56    fn parse_with_param(
57        buf: &NeighbourMessageBuffer<&'a T>,
58        address_family: AddressFamily,
59    ) -> Result<Self, DecodeError> {
60        let mut attributes = vec![];
61        for nla_buf in buf.attributes() {
62            attributes.push(NeighbourAttribute::parse_with_param(
63                &nla_buf?,
64                address_family,
65            )?);
66        }
67        Ok(attributes)
68    }
69}