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