zero_packet/network/
ipv6.rs1use super::extensions::headers::ExtensionHeaders;
2use crate::misc::bytes_to_ipv6;
3use core::{fmt, str::from_utf8};
4
5pub const IPV6_HEADER_LEN: usize = 40;
7
8pub struct IPv6Writer<'a> {
10 pub bytes: &'a mut [u8],
11}
12
13impl<'a> IPv6Writer<'a> {
14 #[inline]
16 pub fn new(bytes: &'a mut [u8]) -> Result<Self, &'static str> {
17 if bytes.len() < IPV6_HEADER_LEN {
18 return Err("Slice is too short to contain an IPv6 header.");
19 }
20
21 Ok(Self { bytes })
22 }
23
24 #[inline]
26 pub fn header_len(&self) -> usize {
27 IPV6_HEADER_LEN
28 }
29
30 #[inline]
34 pub fn set_version(&mut self, version: u8) {
35 self.bytes[0] = (self.bytes[0] & 0x0F) | (version << 4);
36 }
37
38 #[inline]
42 pub fn set_traffic_class(&mut self, traffic_class: u8) {
43 self.bytes[0] = (self.bytes[0] & 0xF0) | (traffic_class >> 4);
44 self.bytes[1] = (self.bytes[1] & 0x0F) | (traffic_class << 4);
45 }
46
47 #[inline]
51 pub fn set_flow_label(&mut self, flow_label: u32) {
52 self.bytes[1] = (self.bytes[1] & 0xF0) | ((flow_label >> 16) as u8);
53 self.bytes[2] = (flow_label >> 8) as u8;
54 self.bytes[3] = flow_label as u8;
55 }
56
57 #[inline]
61 pub fn set_payload_length(&mut self, payload_length: u16) {
62 self.bytes[4] = (payload_length >> 8) as u8;
63 self.bytes[5] = payload_length as u8;
64 }
65
66 #[inline]
72 pub fn set_next_header(&mut self, next_header: u8) {
73 self.bytes[6] = next_header;
74 }
75
76 #[inline]
84 pub fn set_hop_limit(&mut self, hop_limit: u8) {
85 self.bytes[7] = hop_limit;
86 }
87
88 #[inline]
92 pub fn set_src_addr(&mut self, src_addr: &[u8; 16]) {
93 self.bytes[8] = src_addr[0];
94 self.bytes[9] = src_addr[1];
95 self.bytes[10] = src_addr[2];
96 self.bytes[11] = src_addr[3];
97 self.bytes[12] = src_addr[4];
98 self.bytes[13] = src_addr[5];
99 self.bytes[14] = src_addr[6];
100 self.bytes[15] = src_addr[7];
101 self.bytes[16] = src_addr[8];
102 self.bytes[17] = src_addr[9];
103 self.bytes[18] = src_addr[10];
104 self.bytes[19] = src_addr[11];
105 self.bytes[20] = src_addr[12];
106 self.bytes[21] = src_addr[13];
107 self.bytes[22] = src_addr[14];
108 self.bytes[23] = src_addr[15];
109 }
110
111 #[inline]
115 pub fn set_dest_addr(&mut self, dest_addr: &[u8; 16]) {
116 self.bytes[24] = dest_addr[0];
117 self.bytes[25] = dest_addr[1];
118 self.bytes[26] = dest_addr[2];
119 self.bytes[27] = dest_addr[3];
120 self.bytes[28] = dest_addr[4];
121 self.bytes[29] = dest_addr[5];
122 self.bytes[30] = dest_addr[6];
123 self.bytes[31] = dest_addr[7];
124 self.bytes[32] = dest_addr[8];
125 self.bytes[33] = dest_addr[9];
126 self.bytes[34] = dest_addr[10];
127 self.bytes[35] = dest_addr[11];
128 self.bytes[36] = dest_addr[12];
129 self.bytes[37] = dest_addr[13];
130 self.bytes[38] = dest_addr[14];
131 self.bytes[39] = dest_addr[15];
132 }
133}
134
135pub struct IPv6Reader<'a> {
139 pub bytes: &'a [u8],
140 pub extension_headers: Option<ExtensionHeaders<'a>>,
141 pub extension_headers_len: usize,
142}
143
144impl<'a> IPv6Reader<'a> {
145 #[inline]
147 pub fn new(bytes: &'a [u8]) -> Result<Self, &'static str> {
148 if bytes.len() < IPV6_HEADER_LEN {
149 return Err("Slice is too short to contain an IPv6 header.");
150 }
151
152 let mut reader = Self {
153 bytes,
154 extension_headers: None,
155 extension_headers_len: 0,
156 };
157
158 let extension_headers = ExtensionHeaders::parse(reader.payload(), reader.next_header())?;
160
161 if let Some(extension_headers) = extension_headers {
162 reader.extension_headers_len = extension_headers.total_headers_len;
163 reader.extension_headers = Some(extension_headers);
164 }
165
166 Ok(reader)
167 }
168
169 #[inline]
173 pub fn version(&self) -> u8 {
174 self.bytes[0] >> 4
175 }
176
177 #[inline]
181 pub fn traffic_class(&self) -> u8 {
182 ((self.bytes[0] & 0x0F) << 4) | (self.bytes[1] >> 4)
183 }
184
185 #[inline]
189 pub fn flow_label(&self) -> u32 {
190 ((self.bytes[1] as u32 & 0x0F) << 16)
191 | ((self.bytes[2] as u32) << 8)
192 | (self.bytes[3] as u32)
193 }
194
195 #[inline]
199 pub fn payload_length(&self) -> u16 {
200 ((self.bytes[4] as u16) << 8) | (self.bytes[5] as u16)
201 }
202
203 #[inline]
209 pub fn next_header(&self) -> u8 {
210 self.bytes[6]
211 }
212
213 #[inline]
219 pub fn final_next_header(&self) -> u8 {
220 let mut next_header = self.next_header();
221
222 if let Some(extension_headers) = &self.extension_headers {
223 next_header = extension_headers.final_next_header;
224 }
225
226 next_header
227 }
228
229 #[inline]
237 pub fn hop_limit(&self) -> u8 {
238 self.bytes[7]
239 }
240
241 #[inline]
245 pub fn src_addr(&self) -> &[u8] {
246 &self.bytes[8..24]
247 }
248
249 #[inline]
253 pub fn dest_addr(&self) -> &[u8] {
254 &self.bytes[24..40]
255 }
256
257 #[inline]
261 pub fn header_len(&self) -> usize {
262 IPV6_HEADER_LEN
263 }
264
265 #[inline]
267 pub fn header(&self) -> &'a [u8] {
268 &self.bytes[..self.header_len()]
269 }
270
271 #[inline]
275 pub fn payload(&self) -> &'a [u8] {
276 &self.bytes[self.header_len()..]
277 }
278
279 #[inline]
283 pub fn upper_layer_payload(&self) -> &'a [u8] {
284 &self.bytes[self.header_len() + self.extension_headers_len..]
285 }
286}
287
288impl fmt::Debug for IPv6Reader<'_> {
289 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
290 let mut s_buf = [0u8; 39];
291 let s_len = bytes_to_ipv6(self.src_addr(), &mut s_buf);
292 let s_hex = from_utf8(&s_buf[..s_len]).unwrap();
293 let mut d_buf = [0u8; 39];
294 let d_len = bytes_to_ipv6(self.dest_addr(), &mut d_buf);
295 let d_hex = from_utf8(&d_buf[..d_len]).unwrap();
296 f.debug_struct("IPv6Packet")
297 .field("version", &self.version())
298 .field("traffic_class", &self.traffic_class())
299 .field("flow_label", &self.flow_label())
300 .field("payload_length", &self.payload_length())
301 .field("next_header", &self.next_header())
302 .field("hop_limit", &self.hop_limit())
303 .field("src_addr", &s_hex)
304 .field("dest_addr", &d_hex)
305 .field("extension_headers", &self.extension_headers)
306 .field("extension_headers_len", &self.extension_headers_len)
307 .finish()
308 }
309}
310
311#[cfg(test)]
312mod tests {
313 use super::*;
314
315 #[test]
316 fn getters_and_setters() {
317 let mut bytes = [0u8; 40];
319
320 let version = 6;
322 let traffic_class = 5;
323 let flow_label = 4;
324 let payload_length = 3;
325 let next_header = 2;
326 let hop_limit = 1;
327 let src_addr = [
328 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70,
329 0x73, 0x34,
330 ];
331 let dest_addr = [
332 0x20, 0x01, 0x0d, 0xb8, 0x83, 0xa3, 0x00, 0x00, 0x50, 0x00, 0x81, 0x2e, 0x03, 0x70,
333 0x73, 0x32,
334 ];
335
336 let mut writer = IPv6Writer::new(&mut bytes).unwrap();
338
339 writer.set_version(version);
341 writer.set_traffic_class(traffic_class);
342 writer.set_flow_label(flow_label);
343 writer.set_payload_length(payload_length);
344 writer.set_next_header(next_header);
345 writer.set_hop_limit(hop_limit);
346 writer.set_src_addr(&src_addr);
347 writer.set_dest_addr(&dest_addr);
348
349 let reader = IPv6Reader::new(&bytes).unwrap();
351
352 assert_eq!(reader.version(), version);
354 assert_eq!(reader.traffic_class(), traffic_class);
355 assert_eq!(reader.flow_label(), flow_label);
356 assert_eq!(reader.payload_length(), payload_length);
357 assert_eq!(reader.next_header(), next_header);
358 assert_eq!(reader.hop_limit(), hop_limit);
359 assert_eq!(reader.src_addr(), &src_addr);
360 assert_eq!(reader.dest_addr(), &dest_addr);
361 }
362}