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