• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::*;
2 
3 #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
4 pub enum IpDefragError {
5     /// Error if a payload lenght of a IP Fragment packet is not a multiple of 16
6     /// and the "more fragments" flag is set.
7     UnalignedFragmentPayloadLen {
8         offset: IpFragOffset,
9         payload_len: usize,
10     },
11 
12     /// Error if a segment is bigger then the maximum allowed size.
13     SegmentTooBig {
14         offset: IpFragOffset,
15         payload_len: usize,
16         max: u16,
17     },
18 
19     /// Error if multiple TP segments were received with the "more segment"
20     /// unset and differing end points.
21     ConflictingEnd {
22         /// Offset + tp_payload.len() of the previous package with "more segment" unset.
23         previous_end: u16,
24 
25         /// Offset + tp_payload.len() of the current package.
26         conflicting_end: u16,
27     },
28 
29     /// Error if not enough memory could be allocated to store the TP payload.
30     AllocationFailure { len: usize },
31 }
32 
33 impl core::fmt::Display for IpDefragError {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result34     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35         use IpDefragError::*;
36         match self {
37             UnalignedFragmentPayloadLen{ offset, payload_len } => write!(f, "Payload length {payload_len} of IP fragment (offset {offset}) is not a multiple of 8. This is only allowed for the last fragment packet."),
38             SegmentTooBig{ offset, payload_len, max } => write!(f, "Overall length of IP fragment (offset {offset}, payload len: {payload_len}) bigger then the maximum allowed size of {max}."),
39             ConflictingEnd { previous_end, conflicting_end } => write!(f, "Received a IP fragment (offset + len: {conflicting_end}) which conflicts a package that previously set the end to {previous_end}."),
40             AllocationFailure { len } => write!(f, "Failed to allocate {len} bytes of memory to reconstruct the fragmented IP packets."),
41         }
42     }
43 }
44 
45 impl std::error::Error for IpDefragError {}
46 
47 #[cfg(test)]
48 mod tests {
49     use super::IpDefragError::*;
50     use super::*;
51     use std::format;
52 
53     #[test]
debug()54     fn debug() {
55         let err = UnalignedFragmentPayloadLen {
56             offset: IpFragOffset::try_new(0).unwrap(),
57             payload_len: 16,
58         };
59         let _ = format!("{err:?}");
60     }
61 
62     #[test]
clone_eq_hash_ord()63     fn clone_eq_hash_ord() {
64         use core::cmp::Ordering;
65         use std::collections::hash_map::DefaultHasher;
66         use std::hash::{Hash, Hasher};
67 
68         let err = UnalignedFragmentPayloadLen {
69             offset: IpFragOffset::try_new(0).unwrap(),
70             payload_len: 16,
71         };
72         assert_eq!(err, err.clone());
73         let hash_a = {
74             let mut hasher = DefaultHasher::new();
75             err.hash(&mut hasher);
76             hasher.finish()
77         };
78         let hash_b = {
79             let mut hasher = DefaultHasher::new();
80             err.clone().hash(&mut hasher);
81             hasher.finish()
82         };
83         assert_eq!(hash_a, hash_b);
84         assert_eq!(Ordering::Equal, err.cmp(&err));
85         assert_eq!(Some(Ordering::Equal), err.partial_cmp(&err));
86     }
87 
88     #[test]
fmt()89     fn fmt() {
90         let tests = [
91             (UnalignedFragmentPayloadLen { offset: IpFragOffset::try_new(0).unwrap(), payload_len: 2 }, "Payload length 2 of IP fragment (offset 0) is not a multiple of 8. This is only allowed for the last fragment packet."),
92             (SegmentTooBig { offset: IpFragOffset::try_new(0).unwrap(), payload_len: 2, max: 3, }, "Overall length of IP fragment (offset 0, payload len: 2) bigger then the maximum allowed size of 3."),
93             (ConflictingEnd { previous_end: 2, conflicting_end: 1 }, "Received a IP fragment (offset + len: 1) which conflicts a package that previously set the end to 2."),
94             (AllocationFailure { len: 0 }, "Failed to allocate 0 bytes of memory to reconstruct the fragmented IP packets."),
95         ];
96         for test in tests {
97             assert_eq!(format!("{}", test.0), test.1);
98         }
99     }
100 
101     #[test]
source()102     fn source() {
103         use std::error::Error;
104         assert!(UnalignedFragmentPayloadLen {
105             offset: IpFragOffset::try_new(0).unwrap(),
106             payload_len: 16
107         }
108         .source()
109         .is_none());
110     }
111 }
112