1 use crate::*;
2 
3 /// Deprecated use [`crate::NetSlice`] or [`crate::IpSlice`] instead.
4 #[cfg(feature = "std")]
5 #[deprecated(
6     since = "0.14.0",
7     note = "Deprecated use crate::NetSlice or crate::IpSlice instead"
8 )]
9 pub use NetSlice as InternetSlice;
10 
11 /// Slice containing the network headers & payloads (e.g. IPv4, IPv6, ARP).
12 #[derive(Clone, Debug, Eq, PartialEq)]
13 pub enum NetSlice<'a> {
14     /// The ipv4 header & the decoded extension headers.
15     Ipv4(Ipv4Slice<'a>),
16     /// The ipv6 header & the decoded extension headers.
17     Ipv6(Ipv6Slice<'a>),
18 }
19 
20 impl<'a> NetSlice<'a> {
21     /// Returns a reference to ip payload if the net slice contains
22     /// an ipv4 or ipv6 slice.
23     #[inline]
ip_payload_ref(&self) -> Option<&IpPayloadSlice<'a>>24     pub fn ip_payload_ref(&self) -> Option<&IpPayloadSlice<'a>> {
25         match self {
26             NetSlice::Ipv4(s) => Some(&s.payload),
27             NetSlice::Ipv6(s) => Some(&s.payload),
28         }
29     }
30 }
31 
32 impl<'a> From<IpSlice<'a>> for NetSlice<'a> {
33     #[inline]
from(value: IpSlice<'a>) -> NetSlice<'a>34     fn from(value: IpSlice<'a>) -> NetSlice<'a> {
35         match value {
36             IpSlice::Ipv4(ipv4) => NetSlice::Ipv4(ipv4),
37             IpSlice::Ipv6(ipv6) => NetSlice::Ipv6(ipv6),
38         }
39     }
40 }
41 
42 impl<'a> From<Ipv4Slice<'a>> for NetSlice<'a> {
43     #[inline]
from(value: Ipv4Slice<'a>) -> NetSlice<'a>44     fn from(value: Ipv4Slice<'a>) -> NetSlice<'a> {
45         NetSlice::Ipv4(value)
46     }
47 }
48 
49 impl<'a> From<Ipv6Slice<'a>> for NetSlice<'a> {
50     #[inline]
from(value: Ipv6Slice<'a>) -> NetSlice<'a>51     fn from(value: Ipv6Slice<'a>) -> NetSlice<'a> {
52         NetSlice::Ipv6(value)
53     }
54 }
55 
56 #[cfg(test)]
57 mod tests {
58     use crate::*;
59     use alloc::{format, vec::Vec};
60 
61     #[test]
debug()62     fn debug() {
63         let bytes = Ipv6Header {
64             next_header: IpNumber::UDP,
65             ..Default::default()
66         }
67         .to_bytes();
68         let s = Ipv6Slice::from_slice(&bytes).unwrap();
69         let n = NetSlice::Ipv6(s.clone());
70         assert_eq!(format!("{n:?}"), format!("Ipv6({s:?})"));
71     }
72 
73     #[test]
clone_eq()74     fn clone_eq() {
75         let bytes = Ipv6Header {
76             next_header: IpNumber::UDP,
77             ..Default::default()
78         }
79         .to_bytes();
80         let s = NetSlice::Ipv6(Ipv6Slice::from_slice(&bytes).unwrap());
81         assert_eq!(s, s.clone())
82     }
83 
84     #[test]
ip_payload_ref()85     fn ip_payload_ref() {
86         // ipv4
87         {
88             let payload = [1, 2, 3, 4];
89             let bytes = {
90                 let mut bytes = Vec::with_capacity(Ipv4Header::MIN_LEN + 4);
91                 bytes.extend_from_slice(
92                     &(Ipv4Header {
93                         total_len: Ipv4Header::MIN_LEN_U16 + 4,
94                         protocol: IpNumber::UDP,
95                         ..Default::default()
96                     })
97                     .to_bytes(),
98                 );
99                 bytes.extend_from_slice(&payload);
100                 bytes
101             };
102             let s = NetSlice::Ipv4(Ipv4Slice::from_slice(&bytes).unwrap());
103             assert_eq!(
104                 s.ip_payload_ref(),
105                 Some(&IpPayloadSlice {
106                     ip_number: IpNumber::UDP,
107                     fragmented: false,
108                     len_source: LenSource::Ipv4HeaderTotalLen,
109                     payload: &payload
110                 })
111             );
112         }
113         // ipv6
114         {
115             let payload = [1, 2, 3, 4];
116             let bytes = {
117                 let mut bytes = Vec::with_capacity(Ipv6Header::LEN + 4);
118                 bytes.extend_from_slice(
119                     &(Ipv6Header {
120                         next_header: IpNumber::UDP,
121                         payload_length: 4,
122                         ..Default::default()
123                     })
124                     .to_bytes(),
125                 );
126                 bytes.extend_from_slice(&payload);
127                 bytes
128             };
129             let s = NetSlice::Ipv6(Ipv6Slice::from_slice(&bytes).unwrap());
130             assert_eq!(
131                 s.ip_payload_ref(),
132                 Some(&IpPayloadSlice {
133                     ip_number: IpNumber::UDP,
134                     fragmented: false,
135                     len_source: LenSource::Ipv6HeaderPayloadLen,
136                     payload: &payload
137                 })
138             );
139         }
140     }
141 
142     #[test]
from()143     fn from() {
144         // IpSlice::Ipv4
145         {
146             let payload = [1, 2, 3, 4];
147             let bytes = {
148                 let mut bytes = Vec::with_capacity(Ipv4Header::MIN_LEN + 4);
149                 bytes.extend_from_slice(
150                     &(Ipv4Header {
151                         total_len: Ipv4Header::MIN_LEN_U16 + 4,
152                         protocol: IpNumber::UDP,
153                         ..Default::default()
154                     })
155                     .to_bytes(),
156                 );
157                 bytes.extend_from_slice(&payload);
158                 bytes
159             };
160             let i = Ipv4Slice::from_slice(&bytes).unwrap();
161             let actual: NetSlice = IpSlice::Ipv4(i.clone()).into();
162             assert_eq!(NetSlice::Ipv4(i.clone()), actual);
163         }
164         // Ipv4Slice
165         {
166             let payload = [1, 2, 3, 4];
167             let bytes = {
168                 let mut bytes = Vec::with_capacity(Ipv4Header::MIN_LEN + 4);
169                 bytes.extend_from_slice(
170                     &(Ipv4Header {
171                         total_len: Ipv4Header::MIN_LEN_U16 + 4,
172                         protocol: IpNumber::UDP,
173                         ..Default::default()
174                     })
175                     .to_bytes(),
176                 );
177                 bytes.extend_from_slice(&payload);
178                 bytes
179             };
180             let i = Ipv4Slice::from_slice(&bytes).unwrap();
181             let actual: NetSlice = i.clone().into();
182             assert_eq!(NetSlice::Ipv4(i.clone()), actual);
183         }
184         // IpSlice::Ipv6
185         {
186             let payload = [1, 2, 3, 4];
187             let bytes = {
188                 let mut bytes = Vec::with_capacity(Ipv6Header::LEN + 4);
189                 bytes.extend_from_slice(
190                     &(Ipv6Header {
191                         next_header: IpNumber::UDP,
192                         payload_length: 4,
193                         ..Default::default()
194                     })
195                     .to_bytes(),
196                 );
197                 bytes.extend_from_slice(&payload);
198                 bytes
199             };
200             let i = Ipv6Slice::from_slice(&bytes).unwrap();
201             let actual: NetSlice = i.clone().into();
202             assert_eq!(NetSlice::Ipv6(i.clone()), actual);
203         }
204     }
205 }
206