use crate::*; /// Deprecated use [`crate::NetSlice`] or [`crate::IpSlice`] instead. #[cfg(feature = "std")] #[deprecated( since = "0.14.0", note = "Deprecated use crate::NetSlice or crate::IpSlice instead" )] pub use NetSlice as InternetSlice; /// Slice containing the network headers & payloads (e.g. IPv4, IPv6, ARP). #[derive(Clone, Debug, Eq, PartialEq)] pub enum NetSlice<'a> { /// The ipv4 header & the decoded extension headers. Ipv4(Ipv4Slice<'a>), /// The ipv6 header & the decoded extension headers. Ipv6(Ipv6Slice<'a>), } impl<'a> NetSlice<'a> { /// Returns a reference to ip payload if the net slice contains /// an ipv4 or ipv6 slice. #[inline] pub fn ip_payload_ref(&self) -> Option<&IpPayloadSlice<'a>> { match self { NetSlice::Ipv4(s) => Some(&s.payload), NetSlice::Ipv6(s) => Some(&s.payload), } } } impl<'a> From> for NetSlice<'a> { #[inline] fn from(value: IpSlice<'a>) -> NetSlice<'a> { match value { IpSlice::Ipv4(ipv4) => NetSlice::Ipv4(ipv4), IpSlice::Ipv6(ipv6) => NetSlice::Ipv6(ipv6), } } } impl<'a> From> for NetSlice<'a> { #[inline] fn from(value: Ipv4Slice<'a>) -> NetSlice<'a> { NetSlice::Ipv4(value) } } impl<'a> From> for NetSlice<'a> { #[inline] fn from(value: Ipv6Slice<'a>) -> NetSlice<'a> { NetSlice::Ipv6(value) } } #[cfg(test)] mod tests { use crate::*; use alloc::{format, vec::Vec}; #[test] fn debug() { let bytes = Ipv6Header { next_header: IpNumber::UDP, ..Default::default() } .to_bytes(); let s = Ipv6Slice::from_slice(&bytes).unwrap(); let n = NetSlice::Ipv6(s.clone()); assert_eq!(format!("{n:?}"), format!("Ipv6({s:?})")); } #[test] fn clone_eq() { let bytes = Ipv6Header { next_header: IpNumber::UDP, ..Default::default() } .to_bytes(); let s = NetSlice::Ipv6(Ipv6Slice::from_slice(&bytes).unwrap()); assert_eq!(s, s.clone()) } #[test] fn ip_payload_ref() { // ipv4 { let payload = [1, 2, 3, 4]; let bytes = { let mut bytes = Vec::with_capacity(Ipv4Header::MIN_LEN + 4); bytes.extend_from_slice( &(Ipv4Header { total_len: Ipv4Header::MIN_LEN_U16 + 4, protocol: IpNumber::UDP, ..Default::default() }) .to_bytes(), ); bytes.extend_from_slice(&payload); bytes }; let s = NetSlice::Ipv4(Ipv4Slice::from_slice(&bytes).unwrap()); assert_eq!( s.ip_payload_ref(), Some(&IpPayloadSlice { ip_number: IpNumber::UDP, fragmented: false, len_source: LenSource::Ipv4HeaderTotalLen, payload: &payload }) ); } // ipv6 { let payload = [1, 2, 3, 4]; let bytes = { let mut bytes = Vec::with_capacity(Ipv6Header::LEN + 4); bytes.extend_from_slice( &(Ipv6Header { next_header: IpNumber::UDP, payload_length: 4, ..Default::default() }) .to_bytes(), ); bytes.extend_from_slice(&payload); bytes }; let s = NetSlice::Ipv6(Ipv6Slice::from_slice(&bytes).unwrap()); assert_eq!( s.ip_payload_ref(), Some(&IpPayloadSlice { ip_number: IpNumber::UDP, fragmented: false, len_source: LenSource::Ipv6HeaderPayloadLen, payload: &payload }) ); } } #[test] fn from() { // IpSlice::Ipv4 { let payload = [1, 2, 3, 4]; let bytes = { let mut bytes = Vec::with_capacity(Ipv4Header::MIN_LEN + 4); bytes.extend_from_slice( &(Ipv4Header { total_len: Ipv4Header::MIN_LEN_U16 + 4, protocol: IpNumber::UDP, ..Default::default() }) .to_bytes(), ); bytes.extend_from_slice(&payload); bytes }; let i = Ipv4Slice::from_slice(&bytes).unwrap(); let actual: NetSlice = IpSlice::Ipv4(i.clone()).into(); assert_eq!(NetSlice::Ipv4(i.clone()), actual); } // Ipv4Slice { let payload = [1, 2, 3, 4]; let bytes = { let mut bytes = Vec::with_capacity(Ipv4Header::MIN_LEN + 4); bytes.extend_from_slice( &(Ipv4Header { total_len: Ipv4Header::MIN_LEN_U16 + 4, protocol: IpNumber::UDP, ..Default::default() }) .to_bytes(), ); bytes.extend_from_slice(&payload); bytes }; let i = Ipv4Slice::from_slice(&bytes).unwrap(); let actual: NetSlice = i.clone().into(); assert_eq!(NetSlice::Ipv4(i.clone()), actual); } // IpSlice::Ipv6 { let payload = [1, 2, 3, 4]; let bytes = { let mut bytes = Vec::with_capacity(Ipv6Header::LEN + 4); bytes.extend_from_slice( &(Ipv6Header { next_header: IpNumber::UDP, payload_length: 4, ..Default::default() }) .to_bytes(), ); bytes.extend_from_slice(&payload); bytes }; let i = Ipv6Slice::from_slice(&bytes).unwrap(); let actual: NetSlice = i.clone().into(); assert_eq!(NetSlice::Ipv6(i.clone()), actual); } } }