zero_packet/network/extensions/
authentication.rs1use core::fmt;
2
3pub const AUTHENTICATION_MIN_HEADER_LENGTH: usize = 12;
5
6pub struct AuthenticationHeaderWriter<'a> {
8 pub bytes: &'a mut [u8],
9}
10
11impl<'a> AuthenticationHeaderWriter<'a> {
12 #[inline]
14 pub fn new(bytes: &'a mut [u8]) -> Result<Self, &'static str> {
15 if bytes.len() < AUTHENTICATION_MIN_HEADER_LENGTH {
16 return Err("Slice is too short to contain an Authentication extension header.");
17 }
18
19 Ok(Self { bytes })
20 }
21
22 #[inline]
24 pub fn header_len(&self) -> usize {
25 (self.bytes[1] as usize + 2) * 4
26 }
27
28 #[inline]
32 pub fn set_next_header(&mut self, next_header: u8) {
33 self.bytes[0] = next_header;
34 }
35
36 #[inline]
42 pub fn set_payload_len(&mut self, payload_len: u8) {
43 self.bytes[1] = payload_len;
44 }
45
46 #[inline]
50 pub fn set_reserved(&mut self, reserved: u16) {
51 self.bytes[2] = (reserved >> 8) as u8;
52 self.bytes[3] = reserved as u8;
53 }
54
55 #[inline]
59 pub fn set_spi(&mut self, spi: u32) {
60 self.bytes[4] = (spi >> 24) as u8;
61 self.bytes[5] = (spi >> 16) as u8;
62 self.bytes[6] = (spi >> 8) as u8;
63 self.bytes[7] = spi as u8;
64 }
65
66 #[inline]
70 pub fn set_sequence_number(&mut self, sequence_number: u32) {
71 self.bytes[8] = (sequence_number >> 24) as u8;
72 self.bytes[9] = (sequence_number >> 16) as u8;
73 self.bytes[10] = (sequence_number >> 8) as u8;
74 self.bytes[11] = sequence_number as u8;
75 }
76
77 #[inline]
83 pub fn set_authentication_data(&mut self, data: &[u8]) -> Result<(), &'static str> {
84 let start_offset = 12;
85 let end_offset = start_offset + data.len();
86
87 if end_offset > self.bytes.len() {
88 return Err("Authentication data exceeds the allocated header length.");
89 }
90
91 self.bytes[start_offset..end_offset].copy_from_slice(data);
92
93 Ok(())
94 }
95}
96
97pub struct AuthenticationHeaderReader<'a> {
99 pub bytes: &'a [u8],
100}
101
102impl<'a> AuthenticationHeaderReader<'a> {
103 #[inline]
105 pub fn new(bytes: &'a [u8]) -> Result<Self, &'static str> {
106 if bytes.len() < AUTHENTICATION_MIN_HEADER_LENGTH {
107 return Err("Slice is too short to contain an Authentication extension header.");
108 }
109
110 Ok(Self { bytes })
111 }
112
113 #[inline]
117 pub fn next_header(&self) -> u8 {
118 self.bytes[0]
119 }
120
121 #[inline]
125 pub fn payload_len(&self) -> u8 {
126 self.bytes[1]
127 }
128
129 #[inline]
133 pub fn reserved(&self) -> u16 {
134 ((self.bytes[2] as u16) << 8) | self.bytes[3] as u16
135 }
136
137 #[inline]
141 pub fn spi(&self) -> u32 {
142 ((self.bytes[4] as u32) << 24)
143 | ((self.bytes[5] as u32) << 16)
144 | ((self.bytes[6] as u32) << 8)
145 | self.bytes[7] as u32
146 }
147
148 #[inline]
152 pub fn sequence_number(&self) -> u32 {
153 ((self.bytes[8] as u32) << 24)
154 | ((self.bytes[9] as u32) << 16)
155 | ((self.bytes[10] as u32) << 8)
156 | self.bytes[11] as u32
157 }
158
159 #[inline]
163 pub fn authentication_data(&self) -> Result<&'a [u8], &'static str> {
164 if self.bytes.len() < self.header_len() {
165 return Err("Indicated Authentication header length exceeds the allocated buffer.");
166 }
167
168 Ok(&self.bytes[12..self.header_len()])
169 }
170
171 #[inline]
173 pub fn header_len(&self) -> usize {
174 (self.bytes[1] as usize + 2) * 4
175 }
176
177 #[inline]
179 pub fn header(&self) -> Result<&'a [u8], &'static str> {
180 let end = self.header_len();
181
182 if end > self.bytes.len() {
183 return Err("Indicated Authentication header length exceeds the allocated buffer.");
184 }
185
186 Ok(&self.bytes[..end])
187 }
188
189 #[inline]
191 pub fn payload(&self) -> Result<&'a [u8], &'static str> {
192 let start = self.header_len();
193
194 if start > self.bytes.len() {
195 return Err("Indicated Authentication header length exceeds the allocated buffer.");
196 }
197
198 Ok(&self.bytes[self.header_len()..])
199 }
200}
201
202impl fmt::Debug for AuthenticationHeaderReader<'_> {
203 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
204 f.debug_struct("AuthenticationHeader")
205 .field("next_header", &self.next_header())
206 .field("payload_len", &self.payload_len())
207 .field("reserved", &self.reserved())
208 .field("spi", &self.spi())
209 .field("sequence_number", &self.sequence_number())
210 .field("authentication_data", &self.authentication_data())
211 .finish()
212 }
213}
214
215#[cfg(test)]
216pub mod tests {
217 use super::*;
218
219 #[test]
220 fn getters_and_setters() {
221 let mut bytes = [0; 20];
223
224 let next_header = 17;
226 let payload_len = 2; let reserved = 0;
228 let spi = 305419896;
229 let sequence_number = 2271560481;
230 let auth_data = [1, 2, 3, 4];
231
232 let mut writer = AuthenticationHeaderWriter::new(&mut bytes).unwrap();
234 writer.set_next_header(next_header);
235 writer.set_payload_len(payload_len);
236 writer.set_reserved(reserved);
237 writer.set_spi(spi);
238 writer.set_sequence_number(sequence_number);
239 writer.set_authentication_data(&auth_data).unwrap();
240
241 let reader = AuthenticationHeaderReader::new(&bytes).unwrap();
243
244 assert_eq!(reader.next_header(), next_header);
245 assert_eq!(reader.payload_len(), payload_len);
246 assert_eq!(reader.reserved(), reserved);
247 assert_eq!(reader.spi(), spi);
248 assert_eq!(reader.sequence_number(), sequence_number);
249 assert_eq!(reader.authentication_data().unwrap(), &auth_data);
250 }
251}