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