netlink_packet_route/rtnl/address/
message.rs

1// SPDX-License-Identifier: MIT
2
3use anyhow::Context;
4
5use crate::{
6    nlas::address::Nla,
7    traits::{Emitable, Parseable},
8    AddressMessageBuffer,
9    DecodeError,
10    ADDRESS_HEADER_LEN,
11};
12
13#[derive(Debug, PartialEq, Eq, Clone, Default)]
14pub struct AddressMessage {
15    pub header: AddressHeader,
16    pub nlas: Vec<Nla>,
17}
18
19#[derive(Debug, PartialEq, Eq, Clone, Default)]
20pub struct AddressHeader {
21    pub family: u8,
22    pub prefix_len: u8,
23    pub flags: u8,
24    pub scope: u8,
25    pub index: u32,
26}
27
28impl Emitable for AddressHeader {
29    fn buffer_len(&self) -> usize {
30        ADDRESS_HEADER_LEN
31    }
32
33    fn emit(&self, buffer: &mut [u8]) {
34        let mut packet = AddressMessageBuffer::new(buffer);
35        packet.set_family(self.family);
36        packet.set_prefix_len(self.prefix_len);
37        packet.set_flags(self.flags);
38        packet.set_scope(self.scope);
39        packet.set_index(self.index);
40    }
41}
42
43impl Emitable for AddressMessage {
44    fn buffer_len(&self) -> usize {
45        self.header.buffer_len() + self.nlas.as_slice().buffer_len()
46    }
47
48    fn emit(&self, buffer: &mut [u8]) {
49        self.header.emit(buffer);
50        self.nlas
51            .as_slice()
52            .emit(&mut buffer[self.header.buffer_len()..]);
53    }
54}
55
56impl<T: AsRef<[u8]>> Parseable<AddressMessageBuffer<T>> for AddressHeader {
57    fn parse(buf: &AddressMessageBuffer<T>) -> Result<Self, DecodeError> {
58        Ok(Self {
59            family: buf.family(),
60            prefix_len: buf.prefix_len(),
61            flags: buf.flags(),
62            scope: buf.scope(),
63            index: buf.index(),
64        })
65    }
66}
67
68impl<'a, T: AsRef<[u8]> + 'a> Parseable<AddressMessageBuffer<&'a T>> for AddressMessage {
69    fn parse(buf: &AddressMessageBuffer<&'a T>) -> Result<Self, DecodeError> {
70        Ok(AddressMessage {
71            header: AddressHeader::parse(buf).context("failed to parse address message header")?,
72            nlas: Vec::<Nla>::parse(buf).context("failed to parse address message NLAs")?,
73        })
74    }
75}
76
77impl<'a, T: AsRef<[u8]> + 'a> Parseable<AddressMessageBuffer<&'a T>> for Vec<Nla> {
78    fn parse(buf: &AddressMessageBuffer<&'a T>) -> Result<Self, DecodeError> {
79        let mut nlas = vec![];
80        for nla_buf in buf.nlas() {
81            nlas.push(Nla::parse(&nla_buf?)?);
82        }
83        Ok(nlas)
84    }
85}