Skip to main content

netlink_packet_route/address/
message.rs

1// SPDX-License-Identifier: MIT
2
3use crate::address::{AddressAttribute, AddressError, AddressHeaderFlags, AddressScope};
4use crate::{AddressFamily, RouteNetlinkMessageParseMode};
5use netlink_packet_utils::nla::{HasNlas, NlaBuffer, NlaError, NlaParseMode, 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, ParseableParametrized};
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
80impl HasNlas for AddressMessageBuffer {
81    fn attributes(&self) -> impl Iterator<Item = Result<NlaBuffer<&[u8]>, NlaError>> {
82        NlasIterator::new(&self.payload)
83    }
84}
85
86#[derive(Debug, PartialEq, Eq, Clone, Default)]
87#[non_exhaustive]
88pub struct AddressMessage {
89    pub header: AddressHeader,
90    pub attributes: Vec<AddressAttribute>,
91}
92
93impl Emitable for AddressHeader {
94    fn buffer_len(&self) -> usize {
95        ADDRESS_HEADER_LEN
96    }
97
98    fn emit(&self, buffer: &mut [u8]) {
99        let packet =
100            AddressMessageBuffer::new_mut(buffer).expect("buffer has incorrect size/alignment");
101        packet.header = *self
102    }
103}
104
105impl Emitable for AddressMessage {
106    fn buffer_len(&self) -> usize {
107        self.header.buffer_len() + self.attributes.as_slice().buffer_len()
108    }
109
110    fn emit(&self, buffer: &mut [u8]) {
111        self.header.emit(buffer);
112        self.attributes.as_slice().emit(&mut buffer[self.header.buffer_len()..]);
113    }
114}
115
116impl Parseable<AddressMessageBuffer> for AddressHeader {
117    type Error = ();
118    fn parse(buf: &AddressMessageBuffer) -> Result<Self, ()> {
119        Ok(Self {
120            family: buf.header.family.into(),
121            prefix_len: buf.header.prefix_len,
122            flags: AddressHeaderFlags::from_bits_retain(buf.header.flags).bits(),
123            scope: buf.header.scope.into(),
124            index: buf.header.index.into(),
125        })
126    }
127}
128
129impl<'a> ParseableParametrized<AddressMessageBuffer, RouteNetlinkMessageParseMode>
130    for AddressMessage
131{
132    type Error = AddressError;
133    fn parse_with_param(
134        buf: &AddressMessageBuffer,
135        mode: RouteNetlinkMessageParseMode,
136    ) -> Result<Self, AddressError> {
137        Ok(AddressMessage {
138            // ok to unwrap, we never fail parsing the header.
139            header: AddressHeader::parse(buf).unwrap(),
140            attributes: Vec::<AddressAttribute>::parse_with_param(buf, mode.into())?,
141        })
142    }
143}
144
145impl<'a> ParseableParametrized<AddressMessageBuffer, NlaParseMode> for Vec<AddressAttribute> {
146    type Error = AddressError;
147    fn parse_with_param(
148        buf: &AddressMessageBuffer,
149        mode: NlaParseMode,
150    ) -> Result<Self, AddressError> {
151        buf.parse_attributes(mode, AddressAttribute::parse)
152    }
153}