netlink_packet_route/address/
message.rs

1// SPDX-License-Identifier: MIT
2
3use crate::AddressFamily;
4use crate::address::{AddressAttribute, AddressError, AddressHeaderFlags, AddressScope};
5use netlink_packet_utils::nla::{NlaBuffer, NlaError, NlasIterator};
6use netlink_packet_utils::traits::{Emitable, Parseable};
7use zerocopy::byteorder::native_endian::U32;
8use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
9
10pub const ADDRESS_HEADER_LEN: usize = 8;
11
12#[derive(FromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)]
13#[repr(C)]
14pub struct AddressMessageBuffer {
15    header: AddressHeader,
16    payload: [u8],
17}
18
19use netlink_packet_utils::DecodeError;
20
21#[derive(
22    FromBytes,
23    IntoBytes,
24    KnownLayout,
25    Immutable,
26    Unaligned,
27    Debug,
28    PartialEq,
29    Eq,
30    Clone,
31    Copy,
32    Default,
33)]
34#[repr(C)]
35pub struct AddressHeader {
36    pub family: u8,
37    pub prefix_len: u8,
38    pub flags: u8,
39    pub scope: u8,
40    pub index: U32,
41}
42
43impl AddressHeader {
44    pub fn family(&self) -> AddressFamily {
45        self.family.into()
46    }
47
48    pub fn flags(&self) -> AddressHeaderFlags {
49        AddressHeaderFlags::from_bits_truncate(self.flags)
50    }
51
52    pub fn scope(&self) -> AddressScope {
53        self.scope.into()
54    }
55}
56
57impl AddressMessageBuffer {
58    pub fn new(bytes: &[u8]) -> Result<&AddressMessageBuffer, DecodeError> {
59        AddressMessageBuffer::ref_from_prefix(bytes).map(|(buffer, _rest)| buffer).map_err(|_e| {
60            DecodeError::InvalidBufferLength {
61                name: "AddressMessageBuffer",
62                len: bytes.len(),
63                buffer_len: ADDRESS_HEADER_LEN,
64            }
65        })
66    }
67
68    pub fn new_mut(bytes: &mut [u8]) -> Result<&mut AddressMessageBuffer, DecodeError> {
69        let len = bytes.len();
70        AddressMessageBuffer::mut_from_prefix(bytes).map(|(buffer, _rest)| buffer).map_err(|_e| {
71            DecodeError::InvalidBufferLength {
72                name: "AddressMessageBuffer",
73                len,
74                buffer_len: ADDRESS_HEADER_LEN,
75            }
76        })
77    }
78
79    pub fn attributes(&self) -> impl Iterator<Item = Result<NlaBuffer<&[u8]>, NlaError>> {
80        NlasIterator::new(&self.payload)
81    }
82}
83
84#[derive(Debug, PartialEq, Eq, Clone, Default)]
85#[non_exhaustive]
86pub struct AddressMessage {
87    pub header: AddressHeader,
88    pub attributes: Vec<AddressAttribute>,
89}
90
91impl Emitable for AddressHeader {
92    fn buffer_len(&self) -> usize {
93        ADDRESS_HEADER_LEN
94    }
95
96    fn emit(&self, buffer: &mut [u8]) {
97        let packet =
98            AddressMessageBuffer::new_mut(buffer).expect("buffer has incorrect size/alignment");
99        packet.header = *self
100    }
101}
102
103impl Emitable for AddressMessage {
104    fn buffer_len(&self) -> usize {
105        self.header.buffer_len() + self.attributes.as_slice().buffer_len()
106    }
107
108    fn emit(&self, buffer: &mut [u8]) {
109        self.header.emit(buffer);
110        self.attributes.as_slice().emit(&mut buffer[self.header.buffer_len()..]);
111    }
112}
113
114impl Parseable<AddressMessageBuffer> for AddressHeader {
115    type Error = ();
116    fn parse(buf: &AddressMessageBuffer) -> Result<Self, ()> {
117        Ok(Self {
118            family: buf.header.family.into(),
119            prefix_len: buf.header.prefix_len,
120            flags: AddressHeaderFlags::from_bits_retain(buf.header.flags).bits(),
121            scope: buf.header.scope.into(),
122            index: buf.header.index.into(),
123        })
124    }
125}
126
127impl<'a> Parseable<AddressMessageBuffer> for AddressMessage {
128    type Error = AddressError;
129    fn parse(buf: &AddressMessageBuffer) -> Result<Self, AddressError> {
130        Ok(AddressMessage {
131            // ok to unwrap, we never fail parsing the header.
132            header: AddressHeader::parse(buf).unwrap(),
133            attributes: Vec::<AddressAttribute>::parse(buf)?,
134        })
135    }
136}
137
138impl<'a> Parseable<AddressMessageBuffer> for Vec<AddressAttribute> {
139    type Error = AddressError;
140    fn parse(buf: &AddressMessageBuffer) -> Result<Self, AddressError> {
141        let mut attributes = vec![];
142        for nla_buf in buf.attributes() {
143            attributes.push(AddressAttribute::parse(&nla_buf?)?);
144        }
145        Ok(attributes)
146    }
147}