• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::*;
2 
3 /// Error when slicing an packet from downwards (both
4 /// starting from ethernet or ip layer downwards).
5 #[derive(Clone, Debug, Eq, PartialEq, Hash)]
6 pub enum SliceError {
7     /// Length related errors (e.g. not enough data in slice).
8     Len(err::LenError),
9     /// Error when decoding an Linux SLL header.
10     LinuxSll(err::linux_sll::HeaderError),
11     /// Error when decoding starting at an IP header (v4 or v6).
12     Ip(err::ip::HeaderError),
13     /// Error when decoding an IPv4 header.
14     Ipv4(err::ipv4::HeaderError),
15     /// Error when decoding an IPv6 header.
16     Ipv6(err::ipv6::HeaderError),
17     /// Error when decoding an IPv4 extension header.
18     Ipv4Exts(err::ip_auth::HeaderError),
19     /// Error when decoding an IPv6 extension header.
20     Ipv6Exts(err::ipv6_exts::HeaderError),
21     /// Error when decoding a TCP header.
22     Tcp(err::tcp::HeaderError),
23 }
24 
25 impl core::fmt::Display for SliceError {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result26     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
27         use SliceError::*;
28 
29         match self {
30             Len(err) => err.fmt(f),
31             LinuxSll(err) => err.fmt(f),
32             Ip(err) => err.fmt(f),
33             Ipv4(err) => err.fmt(f),
34             Ipv6(err) => err.fmt(f),
35             Ipv4Exts(err) => err.fmt(f),
36             Ipv6Exts(err) => err.fmt(f),
37             Tcp(err) => err.fmt(f),
38         }
39     }
40 }
41 
42 #[cfg(feature = "std")]
43 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
44 impl std::error::Error for SliceError {
source(&self) -> Option<&(dyn std::error::Error + 'static)>45     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
46         use SliceError::*;
47         match self {
48             Len(err) => Some(err),
49             LinuxSll(err) => Some(err),
50             Ip(err) => Some(err),
51             Ipv4(err) => Some(err),
52             Ipv6(err) => Some(err),
53             Ipv4Exts(err) => Some(err),
54             Ipv6Exts(err) => Some(err),
55             Tcp(err) => Some(err),
56         }
57     }
58 }
59 
60 #[cfg(test)]
61 mod tests {
62     use super::{SliceError::*, *};
63     use crate::err::Layer;
64     use alloc::format;
65     use std::{
66         collections::hash_map::DefaultHasher,
67         error::Error,
68         hash::{Hash, Hasher},
69     };
70 
71     #[test]
debug()72     fn debug() {
73         let err = err::ipv4::HeaderError::UnexpectedVersion { version_number: 1 };
74         assert_eq!(
75             format!("Ipv4({:?})", err.clone()),
76             format!("{:?}", Ipv4(err))
77         );
78     }
79 
80     #[test]
clone_eq_hash()81     fn clone_eq_hash() {
82         let err = Ipv4(err::ipv4::HeaderError::UnexpectedVersion { version_number: 1 });
83         assert_eq!(err, err.clone());
84         let hash_a = {
85             let mut hasher = DefaultHasher::new();
86             err.hash(&mut hasher);
87             hasher.finish()
88         };
89         let hash_b = {
90             let mut hasher = DefaultHasher::new();
91             err.clone().hash(&mut hasher);
92             hasher.finish()
93         };
94         assert_eq!(hash_a, hash_b);
95     }
96 
97     #[test]
fmt()98     fn fmt() {
99         // Len
100         {
101             let err = err::LenError {
102                 required_len: 2,
103                 len: 1,
104                 len_source: LenSource::Slice,
105                 layer: Layer::TcpHeader,
106                 layer_start_offset: 3,
107             };
108             assert_eq!(format!("{}", err), format!("{}", Len(err)));
109         }
110 
111         // Linux SLL Header
112         {
113             let err = err::linux_sll::HeaderError::UnsupportedArpHardwareId {
114                 arp_hardware_type: ArpHardwareId::ADAPT,
115             };
116             assert_eq!(
117                 format!("{}", err),
118                 format!("{}", err::packet::SliceError::LinuxSll(err))
119             );
120         }
121 
122         // IpHeader
123         {
124             let err = err::ip::HeaderError::UnsupportedIpVersion { version_number: 1 };
125             assert_eq!(
126                 format!("{}", err),
127                 format!("{}", err::packet::SliceError::Ip(err))
128             );
129         }
130 
131         // Ipv4Header
132         {
133             let err = err::ipv4::HeaderError::UnexpectedVersion { version_number: 1 };
134             assert_eq!(format!("{}", err), format!("{}", Ipv4(err)));
135         }
136 
137         // Ipv6Header
138         {
139             let err = err::ipv6::HeaderError::UnexpectedVersion { version_number: 1 };
140             assert_eq!(format!("{}", err), format!("{}", Ipv6(err)));
141         }
142 
143         // Ipv4ExtHeader
144         {
145             let err = err::ip_auth::HeaderError::ZeroPayloadLen;
146             assert_eq!(format!("{}", err), format!("{}", Ipv4Exts(err)));
147         }
148 
149         // Ipv6ExtHeader
150         {
151             let err = err::ipv6_exts::HeaderError::HopByHopNotAtStart;
152             assert_eq!(format!("{}", err), format!("{}", Ipv6Exts(err)));
153         };
154 
155         // TcpHeader
156         {
157             let err = err::tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 };
158             assert_eq!(format!("{}", err), format!("{}", Tcp(err)));
159         }
160     }
161 
162     #[cfg(feature = "std")]
163     #[test]
source()164     fn source() {
165         // Len
166         {
167             let err = err::LenError {
168                 required_len: 2,
169                 len: 1,
170                 len_source: LenSource::Slice,
171                 layer: Layer::TcpHeader,
172                 layer_start_offset: 3,
173             };
174             assert!(Len(err).source().is_some());
175         }
176 
177         // IpHeaders
178         {
179             let err = err::linux_sll::HeaderError::UnsupportedArpHardwareId {
180                 arp_hardware_type: ArpHardwareId::ETHERNET,
181             };
182             assert!(LinuxSll(err).source().is_some());
183         }
184 
185         // IpHeaders
186         {
187             let err = err::ip::HeaderError::UnsupportedIpVersion { version_number: 1 };
188             assert!(Ip(err).source().is_some());
189         }
190 
191         // Ipv4Header
192         {
193             let err = err::ipv4::HeaderError::UnexpectedVersion { version_number: 1 };
194             assert!(Ipv4(err).source().is_some());
195         }
196 
197         // Ipv6Header
198         {
199             let err = err::ipv6::HeaderError::UnexpectedVersion { version_number: 1 };
200             assert!(Ipv6(err).source().is_some());
201         }
202 
203         // Ipv4ExtHeader
204         {
205             let err = err::ip_auth::HeaderError::ZeroPayloadLen;
206             assert!(Ipv4Exts(err).source().is_some());
207         }
208 
209         // Ipv6ExtHeader
210         {
211             let err = err::ipv6_exts::HeaderError::HopByHopNotAtStart;
212             assert!(Ipv6Exts(err).source().is_some());
213         };
214 
215         // TcpHeader
216         {
217             let err = err::tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 };
218             assert!(Tcp(err).source().is_some());
219         }
220     }
221 }
222