netlink_packet_route/address/
message.rs1use 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 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}