netlink_packet_core/
parsers.rs1use std::{
4 mem::size_of,
5 net::{IpAddr, Ipv4Addr, Ipv6Addr},
6};
7
8use pastey::paste;
9
10use crate::DecodeError;
11
12pub fn parse_mac(payload: &[u8]) -> Result<[u8; 6], DecodeError> {
13 if payload.len() != 6 {
14 return Err(DecodeError::invalid_mac_address(payload.len()));
15 }
16 let mut address: [u8; 6] = [0; 6];
17 for (i, byte) in payload.iter().enumerate() {
18 address[i] = *byte;
19 }
20 Ok(address)
21}
22
23pub fn parse_ipv6(payload: &[u8]) -> Result<[u8; 16], DecodeError> {
24 if payload.len() != 16 {
25 return Err(DecodeError::invalid_ip_address(payload.len()));
26 }
27 let mut address: [u8; 16] = [0; 16];
28 for (i, byte) in payload.iter().enumerate() {
29 address[i] = *byte;
30 }
31 Ok(address)
32}
33
34pub fn parse_ip(payload: &[u8]) -> Result<IpAddr, DecodeError> {
35 match payload.len() {
36 4 => Ok(
37 Ipv4Addr::new(payload[0], payload[1], payload[2], payload[3])
38 .into(),
39 ),
40 16 => Ok(Ipv6Addr::from([
41 payload[0],
42 payload[1],
43 payload[2],
44 payload[3],
45 payload[4],
46 payload[5],
47 payload[6],
48 payload[7],
49 payload[8],
50 payload[9],
51 payload[10],
52 payload[11],
53 payload[12],
54 payload[13],
55 payload[14],
56 payload[15],
57 ])
58 .into()),
59 other => Err(DecodeError::invalid_ip_address(other)),
60 }
61}
62
63pub fn parse_string(payload: &[u8]) -> Result<String, DecodeError> {
64 if payload.is_empty() {
65 return Ok(String::new());
66 }
67 let slice = if payload[payload.len() - 1] == 0 {
69 &payload[..payload.len() - 1]
70 } else {
71 &payload[..payload.len()]
72 };
73 let s = String::from_utf8(slice.to_vec())?;
74 Ok(s)
75}
76
77pub fn parse_u8(payload: &[u8]) -> Result<u8, DecodeError> {
78 if payload.len() != 1 {
79 return Err(DecodeError::invalid_number(1, payload.len()));
80 }
81 Ok(payload[0])
82}
83
84pub fn parse_i8(payload: &[u8]) -> Result<i8, DecodeError> {
85 if payload.len() != 1 {
86 return Err(DecodeError::invalid_number(1, payload.len()));
87 }
88 Ok(payload[0] as i8)
89}
90
91macro_rules! gen_int_parser {
92 ( $($data_type:ty,)+ ) => {
93 $(
94
95 paste! {
96 pub fn [<parse_ $data_type >](
97 payload: &[u8]
98 ) -> Result<$data_type, DecodeError> {
99 if payload.len() != size_of::<$data_type>() {
100 return Err(DecodeError::invalid_number(
101 size_of::<$data_type>(),
102 payload.len(),
103 ));
104 }
105 let mut data = [0u8; size_of::<$data_type>()];
106 data.copy_from_slice(payload);
107 Ok(<$data_type>::from_ne_bytes(data))
108 }
109
110 pub fn [<parse_ $data_type _be>](
111 payload: &[u8]
112 ) -> Result<$data_type, DecodeError> {
113 if payload.len() != size_of::<$data_type>() {
114 return Err(DecodeError::invalid_number(
115 size_of::<$data_type>(),
116 payload.len(),
117 ));
118 }
119 let mut data = [0u8; size_of::<$data_type>()];
120 data.copy_from_slice(payload);
121 Ok(<$data_type>::from_be_bytes(data))
122 }
123
124 pub fn [<parse_ $data_type _le>](
125 payload: &[u8]
126 ) -> Result<$data_type, DecodeError> {
127 if payload.len() != size_of::<$data_type>() {
128 return Err(DecodeError::invalid_number(
129 size_of::<$data_type>(),
130 payload.len(),
131 ));
132 }
133 let mut data = [0u8; size_of::<$data_type>()];
134 data.copy_from_slice(payload);
135 Ok(<$data_type>::from_le_bytes(data))
136 }
137
138 pub fn [<emit_ $data_type >](
139 buf: &mut [u8],
140 value: $data_type,
141 ) -> Result<(), DecodeError> {
142 if buf.len() < size_of::<$data_type>() {
143 return Err(DecodeError::buffer_too_small(
144 buf.len(),
145 size_of::<$data_type>(),
146 ));
147 }
148 buf[..size_of::<$data_type>()].copy_from_slice(
149 &value.to_ne_bytes()
150 );
151 Ok(())
152 }
153
154 pub fn [<emit_ $data_type _le>](
155 buf: &mut [u8],
156 value: $data_type,
157 ) -> Result<(), DecodeError> {
158 if buf.len() < size_of::<$data_type>() {
159 return Err(DecodeError::buffer_too_small(
160 buf.len(),
161 size_of::<$data_type>(),
162 ));
163 }
164 buf[..size_of::<$data_type>()].copy_from_slice(
165 &value.to_le_bytes()
166 );
167 Ok(())
168 }
169
170 pub fn [<emit_ $data_type _be>](
171 buf: &mut [u8],
172 value: $data_type,
173 ) -> Result<(), DecodeError> {
174 if buf.len() < size_of::<$data_type>() {
175 return Err(DecodeError::buffer_too_small(
176 buf.len(),
177 size_of::<$data_type>(),
178 ));
179 }
180 buf[..size_of::<$data_type>()].copy_from_slice(
181 &value.to_be_bytes()
182 );
183 Ok(())
184 }
185 }
186 )+
187 }
188}
189
190gen_int_parser!(u16, u32, u64, u128, i16, i32, i64, i128,);