1use core::cmp::Ordering;
4
5use crate::data_buffer::traits::{
6 BufferAccess, BufferAccessMut, HeaderManipulation, HeaderMetadata, Layer,
7};
8use crate::ipv6::UpdateIpv6Length;
9use crate::ipv6_extensions::metadata_trait::{Ipv6ExtMetaData, Ipv6ExtMetaDataMut};
10use crate::ipv6_extensions::{
11 Ipv6ExtFieldError, Ipv6ExtSetFieldError, Ipv6ExtTypedHeaderError,
12 Ipv6ExtensionIndexOutOfBoundsError, Ipv6ExtensionType,
13};
14use crate::typed_protocol_headers::InternetProtocolNumber;
15use crate::typed_protocol_headers::RoutingType;
16
17pub(crate) static NEXT_HEADER: usize = 0;
18pub(crate) static EXTENSION_MIN_LEN: usize = 8;
19
20mod shared_dest_opt_hop_by_hop_routing {
21 pub(crate) static LENGTH: usize = 1;
22}
23
24mod dest_opt_and_hop_by_hop {
25 pub(crate) static DATA_START: usize = 2;
26}
27
28mod routing {
29 pub(crate) static ROUTING_TYPE: usize = 2;
30 pub(crate) static SEGMENTS_LEFT: usize = 3;
31 pub(crate) static DATA_START: usize = 4;
32}
33
34mod fragment {
35 use core::ops::Range;
36
37 pub(crate) static FRAGMENT_OFFSET: Range<usize> = 2..4;
38 pub(crate) static FRAGMENT_OFFSET_SHIFT: usize = 3;
39 pub(crate) static MORE_FRAGMENTS_BYTE: usize = 3;
40 pub(crate) static MORE_FRAGMENTS_MASK: u8 = 0b0000_0001;
41 pub(crate) static IDENTIFICATION: Range<usize> = 4..8;
42}
43
44pub(crate) static LAYER: Layer = Layer::Ipv6Ext;
45
46#[allow(private_bounds)]
54pub trait Ipv6ExtMethods<const MAX_EXTENSIONS: usize>:
55 HeaderMetadata + BufferAccess + Ipv6ExtMetaData<MAX_EXTENSIONS>
56{
57 #[inline]
59 fn ipv6_ext_amount(&self) -> usize {
60 self.extensions_amount()
61 }
62
63 #[inline]
68 fn ipv6_extensions(&self) -> [Option<Ipv6ExtensionType>; MAX_EXTENSIONS] {
69 let mut result = [None; MAX_EXTENSIONS];
70 self.extensions_array()[..self.extensions_amount()]
71 .iter()
72 .enumerate()
73 .for_each(|(i, ext)| result[i] = Some(ext.ext_type));
74 result
75 }
76
77 #[inline]
82 fn ipv6_ext_next_header(&self) -> Result<u8, Ipv6ExtensionIndexOutOfBoundsError> {
83 let extension_metadata = self.extension(self.extensions_amount().saturating_sub(1))?;
84 Ok(self.read_value(LAYER, extension_metadata.offset + NEXT_HEADER))
85 }
86
87 #[inline]
94 fn ipv6_ext_typed_next_header(
95 &self,
96 ) -> Result<InternetProtocolNumber, Ipv6ExtTypedHeaderError> {
97 Ok(self.ipv6_ext_next_header()?.try_into()?)
98 }
99
100 #[inline]
109 fn ipv6_ext_per_extension_next_header(
110 &self,
111 extension_index: usize,
112 ) -> Result<u8, Ipv6ExtensionIndexOutOfBoundsError> {
113 let extension_metadata = self.extension(extension_index)?;
114 Ok(self.read_value(LAYER, extension_metadata.offset + NEXT_HEADER))
115 }
116
117 #[inline]
128 fn ipv6_ext_per_extension_typed_next_header(
129 &self,
130 extension_index: usize,
131 ) -> Result<InternetProtocolNumber, Ipv6ExtTypedHeaderError> {
132 Ok(self
133 .ipv6_ext_per_extension_next_header(extension_index)?
134 .try_into()?)
135 }
136
137 #[inline]
148 fn ipv6_ext_length(&self, extension_index: usize) -> Result<u8, Ipv6ExtFieldError> {
149 let extension_metadata = self.extension(extension_index)?;
150 match extension_metadata.ext_type {
151 Ipv6ExtensionType::Fragment => Err(Ipv6ExtFieldError::HeaderFieldDoesNotExist),
152 Ipv6ExtensionType::DestinationOptions
153 | Ipv6ExtensionType::HopByHop
154 | Ipv6ExtensionType::Routing => Ok(self.read_value(
155 LAYER,
156 extension_metadata.offset + shared_dest_opt_hop_by_hop_routing::LENGTH,
157 )),
158 }
159 }
160
161 #[inline]
170 fn ipv6_ext_length_in_bytes(
171 &self,
172 extension_index: usize,
173 ) -> Result<usize, Ipv6ExtensionIndexOutOfBoundsError> {
174 let extension_metadata = self.extension(extension_index)?;
175 match extension_metadata.ext_type {
176 Ipv6ExtensionType::Fragment => Ok(8),
177 Ipv6ExtensionType::DestinationOptions
178 | Ipv6ExtensionType::HopByHop
179 | Ipv6ExtensionType::Routing => Ok((usize::from(self.read_value(
180 LAYER,
181 extension_metadata.offset + shared_dest_opt_hop_by_hop_routing::LENGTH,
182 )) + 1)
183 * 8),
184 }
185 }
186
187 #[inline]
198 fn ipv6_ext_data(&self, extension_index: usize) -> Result<&[u8], Ipv6ExtFieldError> {
199 let extension_metadata = self.extension(extension_index)?;
200 let data_range = match extension_metadata.ext_type {
201 Ipv6ExtensionType::Fragment => return Err(Ipv6ExtFieldError::HeaderFieldDoesNotExist),
202 Ipv6ExtensionType::Routing => {
203 let data_end = self.ipv6_ext_length_in_bytes(extension_index)?;
204 extension_metadata.offset + routing::DATA_START
205 ..extension_metadata.offset + data_end
206 }
207 Ipv6ExtensionType::DestinationOptions | Ipv6ExtensionType::HopByHop => {
208 let data_end = self.ipv6_ext_length_in_bytes(extension_index)?;
209 extension_metadata.offset + dest_opt_and_hop_by_hop::DATA_START
210 ..extension_metadata.offset + data_end
211 }
212 };
213 Ok(self.read_slice(LAYER, data_range))
214 }
215
216 #[inline]
227 fn ipv6_ext_routing_type(&self, extension_index: usize) -> Result<u8, Ipv6ExtFieldError> {
228 let extension_metadata = self.extension(extension_index)?;
229 match extension_metadata.ext_type {
230 Ipv6ExtensionType::Routing => {
231 Ok(self.read_value(LAYER, extension_metadata.offset + routing::ROUTING_TYPE))
232 }
233 Ipv6ExtensionType::DestinationOptions
234 | Ipv6ExtensionType::HopByHop
235 | Ipv6ExtensionType::Fragment => Err(Ipv6ExtFieldError::HeaderFieldDoesNotExist),
236 }
237 }
238
239 #[inline]
250 fn ipv6_ext_segments_left(&self, extension_index: usize) -> Result<u8, Ipv6ExtFieldError> {
251 let extension_metadata = self.extension(extension_index)?;
252 match extension_metadata.ext_type {
253 Ipv6ExtensionType::Routing => {
254 Ok(self.read_value(LAYER, extension_metadata.offset + routing::SEGMENTS_LEFT))
255 }
256 Ipv6ExtensionType::DestinationOptions
257 | Ipv6ExtensionType::HopByHop
258 | Ipv6ExtensionType::Fragment => Err(Ipv6ExtFieldError::HeaderFieldDoesNotExist),
259 }
260 }
261
262 #[inline]
273 fn ipv6_ext_fragment_offset(&self, extension_index: usize) -> Result<u16, Ipv6ExtFieldError> {
274 let extension_metadata = self.extension(extension_index)?;
275 match extension_metadata.ext_type {
276 Ipv6ExtensionType::Fragment => Ok(u16::from_be_bytes(self.read_array(
277 LAYER,
278 extension_metadata.offset + fragment::FRAGMENT_OFFSET.start
279 ..extension_metadata.offset + fragment::FRAGMENT_OFFSET.end,
280 )) >> fragment::FRAGMENT_OFFSET_SHIFT),
281 Ipv6ExtensionType::DestinationOptions
282 | Ipv6ExtensionType::HopByHop
283 | Ipv6ExtensionType::Routing => Err(Ipv6ExtFieldError::HeaderFieldDoesNotExist),
284 }
285 }
286
287 #[inline]
298 fn ipv6_ext_more_fragments(&self, extension_index: usize) -> Result<bool, Ipv6ExtFieldError> {
299 let extension_metadata = self.extension(extension_index)?;
300 match extension_metadata.ext_type {
301 Ipv6ExtensionType::Fragment => Ok((self.read_value(
302 LAYER,
303 extension_metadata.offset + fragment::MORE_FRAGMENTS_BYTE,
304 ) & fragment::MORE_FRAGMENTS_MASK)
305 != 0),
306 Ipv6ExtensionType::DestinationOptions
307 | Ipv6ExtensionType::HopByHop
308 | Ipv6ExtensionType::Routing => Err(Ipv6ExtFieldError::HeaderFieldDoesNotExist),
309 }
310 }
311
312 #[inline]
323 fn ipv6_ext_fragment_identification(
324 &self,
325 extension_index: usize,
326 ) -> Result<u32, Ipv6ExtFieldError> {
327 let extension_metadata = self.extension(extension_index)?;
328 match extension_metadata.ext_type {
329 Ipv6ExtensionType::Fragment => Ok(u32::from_be_bytes(self.read_array(
330 LAYER,
331 extension_metadata.offset + fragment::IDENTIFICATION.start
332 ..extension_metadata.offset + fragment::IDENTIFICATION.end,
333 ))),
334 Ipv6ExtensionType::DestinationOptions
335 | Ipv6ExtensionType::HopByHop
336 | Ipv6ExtensionType::Routing => Err(Ipv6ExtFieldError::HeaderFieldDoesNotExist),
337 }
338 }
339}
340
341#[allow(private_bounds)]
344pub trait Ipv6ExtMethodsMut<const MAX_EXTENSIONS: usize>:
345 HeaderMetadata
346 + HeaderManipulation
347 + BufferAccessMut
348 + Ipv6ExtMethods<MAX_EXTENSIONS>
349 + Ipv6ExtMetaData<MAX_EXTENSIONS>
350 + Ipv6ExtMetaDataMut<MAX_EXTENSIONS>
351 + UpdateIpv6Length
352 + Sized
353{
354 #[inline]
359 fn set_ipv6_ext_next_header(
360 &mut self,
361 next_header: InternetProtocolNumber,
362 ) -> Result<(), Ipv6ExtensionIndexOutOfBoundsError> {
363 let extension_metadata = self.extension(self.extensions_amount().saturating_sub(1))?;
364 self.write_value(
365 LAYER,
366 extension_metadata.offset + NEXT_HEADER,
367 next_header as u8,
368 );
369 Ok(())
370 }
371
372 #[inline]
388 fn set_ipv6_ext_length(
389 &mut self,
390 new_length: u8,
391 extension_index: usize,
392 ) -> Result<(), Ipv6ExtSetFieldError> {
393 let extension_metadata = self.extension(extension_index)?;
394
395 match extension_metadata.ext_type {
396 Ipv6ExtensionType::Fragment => Err(Ipv6ExtSetFieldError::HeaderFieldDoesNotExist),
397 Ipv6ExtensionType::DestinationOptions
398 | Ipv6ExtensionType::HopByHop
399 | Ipv6ExtensionType::Routing => {
400 let new_length_in_bytes = (usize::from(new_length) + 1) * 8;
401 let old_length_in_bytes = self.ipv6_ext_length_in_bytes(extension_index)?;
402
403 match old_length_in_bytes.cmp(&new_length_in_bytes) {
404 Ordering::Less => {
405 let difference = new_length_in_bytes - old_length_in_bytes;
406 self.grow_header(
407 extension_metadata.offset + old_length_in_bytes,
408 difference,
409 LAYER,
410 )?;
411 let extensions_amount = self.extensions_amount();
412 self.extensions_array_mut()[extension_index + 1..extensions_amount]
413 .iter_mut()
414 .for_each(|extension_metadata| {
415 extension_metadata.offset += difference;
416 });
417 }
418 Ordering::Equal => return Ok(()),
419 Ordering::Greater => {
420 let difference = old_length_in_bytes - new_length_in_bytes;
421 self.shrink_header(
422 extension_metadata.offset + new_length_in_bytes,
423 difference,
424 LAYER,
425 );
426 let extensions_amount = self.extensions_amount();
427 self.extensions_array_mut()[extension_index + 1..extensions_amount]
428 .iter_mut()
429 .for_each(|extension_metadata| {
430 extension_metadata.offset -= difference;
431 });
432 }
433 }
434
435 self.update_ipv6_length();
436 self.write_value(
437 LAYER,
438 extension_metadata.offset + shared_dest_opt_hop_by_hop_routing::LENGTH,
439 new_length,
440 );
441 Ok(())
442 }
443 }
444 }
445
446 #[inline]
457 fn ipv6_ext_data_mut(
458 &mut self,
459 extension_index: usize,
460 ) -> Result<&mut [u8], Ipv6ExtFieldError> {
461 let extension_metadata = self.extension(extension_index)?;
462 let data_range = match extension_metadata.ext_type {
463 Ipv6ExtensionType::Fragment => return Err(Ipv6ExtFieldError::HeaderFieldDoesNotExist),
464 Ipv6ExtensionType::Routing => {
465 let data_end = self.ipv6_ext_length_in_bytes(extension_index)?;
466 extension_metadata.offset + routing::DATA_START
467 ..extension_metadata.offset + data_end
468 }
469 Ipv6ExtensionType::DestinationOptions | Ipv6ExtensionType::HopByHop => {
470 let data_end = self.ipv6_ext_length_in_bytes(extension_index)?;
471 extension_metadata.offset + dest_opt_and_hop_by_hop::DATA_START
472 ..extension_metadata.offset + data_end
473 }
474 };
475 Ok(self.get_slice_mut(LAYER, data_range))
476 }
477
478 #[inline]
489 fn set_ipv6_ext_routing_type(
490 &mut self,
491 routing_type: RoutingType,
492 extension_index: usize,
493 ) -> Result<(), Ipv6ExtFieldError> {
494 let extension_metadata = self.extension(extension_index)?;
495 match extension_metadata.ext_type {
496 Ipv6ExtensionType::Routing => {
497 self.write_value(
498 LAYER,
499 extension_metadata.offset + routing::ROUTING_TYPE,
500 routing_type as u8,
501 );
502 Ok(())
503 }
504 Ipv6ExtensionType::DestinationOptions
505 | Ipv6ExtensionType::HopByHop
506 | Ipv6ExtensionType::Fragment => Err(Ipv6ExtFieldError::HeaderFieldDoesNotExist),
507 }
508 }
509
510 #[inline]
521 fn set_ipv6_ext_segments_left(
522 &mut self,
523 segments_left: u8,
524 extension_index: usize,
525 ) -> Result<(), Ipv6ExtFieldError> {
526 let extension_metadata = self.extension(extension_index)?;
527 match extension_metadata.ext_type {
528 Ipv6ExtensionType::Routing => {
529 self.write_value(
530 LAYER,
531 extension_metadata.offset + routing::SEGMENTS_LEFT,
532 segments_left,
533 );
534 Ok(())
535 }
536 Ipv6ExtensionType::DestinationOptions
537 | Ipv6ExtensionType::HopByHop
538 | Ipv6ExtensionType::Fragment => Err(Ipv6ExtFieldError::HeaderFieldDoesNotExist),
539 }
540 }
541
542 #[inline]
553 fn set_ipv6_ext_fragment_offset(
554 &mut self,
555 mut fragment_offset: u16,
556 extension_index: usize,
557 ) -> Result<(), Ipv6ExtFieldError> {
558 let extension_metadata = self.extension(extension_index)?;
559 match extension_metadata.ext_type {
560 Ipv6ExtensionType::Fragment => {
561 fragment_offset <<= fragment::FRAGMENT_OFFSET_SHIFT;
562 fragment_offset |= u16::from(
563 self.read_value(LAYER, fragment::MORE_FRAGMENTS_BYTE)
564 & fragment::MORE_FRAGMENTS_MASK,
565 );
566
567 self.write_slice(
568 LAYER,
569 extension_metadata.offset + fragment::FRAGMENT_OFFSET.start
570 ..extension_metadata.offset + fragment::FRAGMENT_OFFSET.end,
571 &fragment_offset.to_be_bytes(),
572 );
573
574 Ok(())
575 }
576 Ipv6ExtensionType::DestinationOptions
577 | Ipv6ExtensionType::HopByHop
578 | Ipv6ExtensionType::Routing => Err(Ipv6ExtFieldError::HeaderFieldDoesNotExist),
579 }
580 }
581
582 #[inline]
593 fn set_ipv6_ext_more_fragments(
594 &mut self,
595 more_fragments: bool,
596 extension_index: usize,
597 ) -> Result<(), Ipv6ExtFieldError> {
598 let extension_metadata = self.extension(extension_index)?;
599 match extension_metadata.ext_type {
600 Ipv6ExtensionType::Fragment => {
601 let byte_to_set = (self.read_value(LAYER, fragment::MORE_FRAGMENTS_BYTE)
602 & !fragment::MORE_FRAGMENTS_MASK)
603 | u8::from(more_fragments);
604 self.write_value(
605 LAYER,
606 extension_metadata.offset + fragment::MORE_FRAGMENTS_BYTE,
607 byte_to_set,
608 );
609
610 Ok(())
611 }
612 Ipv6ExtensionType::DestinationOptions
613 | Ipv6ExtensionType::HopByHop
614 | Ipv6ExtensionType::Routing => Err(Ipv6ExtFieldError::HeaderFieldDoesNotExist),
615 }
616 }
617
618 #[inline]
629 fn set_ipv6_ext_fragment_identification(
630 &mut self,
631 identification: u32,
632 extension_index: usize,
633 ) -> Result<(), Ipv6ExtFieldError> {
634 let extension_metadata = self.extension(extension_index)?;
635 match extension_metadata.ext_type {
636 Ipv6ExtensionType::Fragment => {
637 self.write_slice(
638 LAYER,
639 extension_metadata.offset + fragment::IDENTIFICATION.start
640 ..extension_metadata.offset + fragment::IDENTIFICATION.end,
641 &identification.to_be_bytes(),
642 );
643 Ok(())
644 }
645 Ipv6ExtensionType::DestinationOptions
646 | Ipv6ExtensionType::HopByHop
647 | Ipv6ExtensionType::Routing => Err(Ipv6ExtFieldError::HeaderFieldDoesNotExist),
648 }
649 }
650}