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