etherparse/net/
ipv6_routing_exts.rs

1use crate::*;
2
3/// In case a route header is present it is also possible
4/// to attach a "final destination" header.
5#[derive(Clone, Debug, Eq, PartialEq)]
6pub struct Ipv6RoutingExtensions {
7    pub routing: Ipv6RawExtHeader,
8    pub final_destination_options: Option<Ipv6RawExtHeader>,
9}
10
11impl Ipv6RoutingExtensions {
12    /// Minimum length required for routing extension headers in bytes/octets.
13    pub const MIN_LEN: usize = Ipv6RawExtHeader::MAX_LEN;
14
15    /// Maximum summed up length of all extension headers in bytes/octets.
16    pub const MAX_LEN: usize = Ipv6RawExtHeader::MAX_LEN * 2;
17
18    /// Return the length of the headers in bytes.
19    pub fn header_len(&self) -> usize {
20        self.routing.header_len()
21            + self
22                .final_destination_options
23                .as_ref()
24                .map(|h| h.header_len())
25                .unwrap_or(0)
26    }
27}
28
29#[cfg(test)]
30mod tests {
31    use super::*;
32    use crate::test_gens::ipv6_raw_ext_any;
33    use proptest::prelude::*;
34
35    #[test]
36    fn debug() {
37        use alloc::format;
38
39        let a: Ipv6RoutingExtensions = Ipv6RoutingExtensions {
40            routing: Ipv6RawExtHeader::new_raw(0.into(), &[0; 6]).unwrap(),
41            final_destination_options: None,
42        };
43        assert_eq!(
44            &format!(
45                "Ipv6RoutingExtensions {{ routing: {:?}, final_destination_options: {:?} }}",
46                a.routing, a.final_destination_options,
47            ),
48            &format!("{:?}", a)
49        );
50    }
51
52    #[test]
53    fn clone_eq() {
54        let a: Ipv6RoutingExtensions = Ipv6RoutingExtensions {
55            routing: Ipv6RawExtHeader::new_raw(0.into(), &[0; 6]).unwrap(),
56            final_destination_options: None,
57        };
58        assert_eq!(a, a.clone());
59    }
60
61    proptest! {
62        #[test]
63        fn header_len(
64            routing in ipv6_raw_ext_any(),
65            final_destination_options in ipv6_raw_ext_any()
66        ) {
67            // without final dest options
68            assert_eq!(
69                Ipv6RoutingExtensions{
70                    routing: routing.clone(),
71                    final_destination_options: None,
72                }.header_len(),
73                routing.header_len()
74            );
75
76            // with final dest options
77            assert_eq!(
78                Ipv6RoutingExtensions{
79                    routing: routing.clone(),
80                    final_destination_options: Some(final_destination_options.clone()),
81                }.header_len(),
82                routing.header_len() + final_destination_options.header_len()
83            );
84        }
85    }
86}