1 use crate::*; 2 3 /// Laxly parsed payload together with an identifier the type of content & the 4 /// information if the payload is incomplete. 5 #[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] 6 pub enum LaxPayloadSlice<'a> { 7 /// Payload with it's type identified by an ether type number 8 /// (e.g. after an ethernet II or vlan header). 9 Ether(EtherPayloadSlice<'a>), 10 /// Payload with is's type identified by an ip number (e.g. 11 /// after an IP header or after an) 12 Ip(LaxIpPayloadSlice<'a>), 13 /// UDP payload. 14 Udp { payload: &'a [u8], incomplete: bool }, 15 /// TCP payload. 16 Tcp { 17 payload: &'a [u8], 18 /// True if the payload has been cut off. 19 incomplete: bool, 20 }, 21 /// Payload part of an ICMP V4 message. Check [`crate::Icmpv4Type`] 22 /// for a description what will be part of the payload. 23 Icmpv4 { 24 payload: &'a [u8], 25 /// True if the payload has been cut off. 26 incomplete: bool, 27 }, 28 /// Payload part of an ICMP V4 message. Check [`crate::Icmpv6Type`] 29 /// for a description what will be part of the payload. 30 Icmpv6 { 31 payload: &'a [u8], 32 /// True if the payload has been cut off. 33 incomplete: bool, 34 }, 35 } 36 37 impl<'a> LaxPayloadSlice<'a> { slice(&self) -> &'a [u8]38 pub fn slice(&self) -> &'a [u8] { 39 match self { 40 LaxPayloadSlice::Ether(e) => e.payload, 41 LaxPayloadSlice::Ip(i) => i.payload, 42 LaxPayloadSlice::Udp { 43 payload, 44 incomplete: _, 45 } => payload, 46 LaxPayloadSlice::Tcp { 47 payload, 48 incomplete: _, 49 } => payload, 50 LaxPayloadSlice::Icmpv4 { 51 payload, 52 incomplete: _, 53 } => payload, 54 LaxPayloadSlice::Icmpv6 { 55 payload, 56 incomplete: _, 57 } => payload, 58 } 59 } 60 } 61 62 #[cfg(test)] 63 mod test { 64 use super::*; 65 use alloc::format; 66 67 #[test] debug()68 fn debug() { 69 assert_eq!( 70 format!("Udp {{ payload: {:?}, incomplete: {} }}", &[0u8; 0], false), 71 format!( 72 "{:?}", 73 LaxPayloadSlice::Udp { 74 payload: &[], 75 incomplete: false 76 } 77 ) 78 ); 79 } 80 81 #[test] clone_eq_hash_ord()82 fn clone_eq_hash_ord() { 83 let s = LaxPayloadSlice::Udp { 84 payload: &[], 85 incomplete: false, 86 }; 87 assert_eq!(s.clone(), s); 88 89 use std::collections::hash_map::DefaultHasher; 90 use std::hash::{Hash, Hasher}; 91 92 let a_hash = { 93 let mut hasher = DefaultHasher::new(); 94 s.hash(&mut hasher); 95 hasher.finish() 96 }; 97 let b_hash = { 98 let mut hasher = DefaultHasher::new(); 99 s.clone().hash(&mut hasher); 100 hasher.finish() 101 }; 102 assert_eq!(a_hash, b_hash); 103 104 use std::cmp::Ordering; 105 assert_eq!(s.clone().cmp(&s), Ordering::Equal); 106 assert_eq!(s.clone().partial_cmp(&s), Some(Ordering::Equal)); 107 } 108 109 #[test] slice()110 fn slice() { 111 let payload = [1, 2, 3, 4]; 112 113 use LaxPayloadSlice::*; 114 assert_eq!( 115 Ether(EtherPayloadSlice { 116 ether_type: EtherType::IPV4, 117 payload: &payload 118 }) 119 .slice(), 120 &payload 121 ); 122 assert_eq!( 123 Ip(LaxIpPayloadSlice { 124 ip_number: IpNumber::IPV4, 125 fragmented: false, 126 len_source: LenSource::Slice, 127 payload: &payload, 128 incomplete: true, 129 }) 130 .slice(), 131 &payload 132 ); 133 assert_eq!( 134 Udp { 135 payload: &payload, 136 incomplete: false 137 } 138 .slice(), 139 &payload 140 ); 141 assert_eq!( 142 Tcp { 143 payload: &payload, 144 incomplete: false 145 } 146 .slice(), 147 &payload 148 ); 149 assert_eq!( 150 Icmpv4 { 151 payload: &payload, 152 incomplete: false 153 } 154 .slice(), 155 &payload 156 ); 157 assert_eq!( 158 Icmpv6 { 159 payload: &payload, 160 incomplete: false 161 } 162 .slice(), 163 &payload 164 ); 165 } 166 } 167