• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::err::{ip_auth, ipv4, LenError};
2 
3 /// Errors that can occur when slicing the IPv4 part of a packet.
4 #[derive(Clone, Debug, Eq, PartialEq, Hash)]
5 pub enum SliceError {
6     /// Length related errors (e.g. not enough data in slice).
7     Len(LenError),
8 
9     /// Error while slicing the header.
10     Header(ipv4::HeaderError),
11 
12     /// Error while slicing an ipv4 extension header.
13     Exts(ip_auth::HeaderError),
14 }
15 
16 impl core::fmt::Display for SliceError {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result17     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
18         use SliceError::*;
19         match self {
20             Len(value) => value.fmt(f),
21             Header(err) => err.fmt(f),
22             Exts(value) => value.fmt(f),
23         }
24     }
25 }
26 
27 #[cfg(feature = "std")]
28 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
29 impl std::error::Error for SliceError {
source(&self) -> Option<&(dyn std::error::Error + 'static)>30     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
31         use SliceError::*;
32         match self {
33             Len(err) => Some(err),
34             Header(err) => Some(err),
35             Exts(err) => Some(err),
36         }
37     }
38 }
39 
40 #[cfg(test)]
41 mod tests {
42     use super::{super::HeaderError, SliceError::*, *};
43     use crate::{err::Layer, LenSource};
44     use alloc::format;
45     use std::{
46         collections::hash_map::DefaultHasher,
47         error::Error,
48         hash::{Hash, Hasher},
49     };
50 
51     #[test]
debug()52     fn debug() {
53         let err = HeaderError::UnexpectedVersion { version_number: 6 };
54         assert_eq!(
55             format!("Header({:?})", err.clone()),
56             format!("{:?}", Header(err))
57         );
58     }
59 
60     #[test]
clone_eq_hash()61     fn clone_eq_hash() {
62         let err = Header(HeaderError::UnexpectedVersion { version_number: 6 });
63         assert_eq!(err, err.clone());
64         let hash_a = {
65             let mut hasher = DefaultHasher::new();
66             err.hash(&mut hasher);
67             hasher.finish()
68         };
69         let hash_b = {
70             let mut hasher = DefaultHasher::new();
71             err.clone().hash(&mut hasher);
72             hasher.finish()
73         };
74         assert_eq!(hash_a, hash_b);
75     }
76 
77     #[test]
fmt()78     fn fmt() {
79         // len
80         {
81             let err = LenError {
82                 required_len: 1,
83                 layer: Layer::Ipv4Packet,
84                 len: 2,
85                 len_source: LenSource::Slice,
86                 layer_start_offset: 3,
87             };
88             assert_eq!(format!("{}", &err), format!("{}", Len(err)));
89         }
90         // header
91         {
92             let err = HeaderError::UnexpectedVersion { version_number: 6 };
93             assert_eq!(format!("{}", &err), format!("{}", Header(err.clone())));
94         }
95         // extensions
96         {
97             let err = ip_auth::HeaderError::ZeroPayloadLen;
98             assert_eq!(format!("{}", &err), format!("{}", Exts(err.clone())));
99         }
100     }
101 
102     #[cfg(feature = "std")]
103     #[test]
source()104     fn source() {
105         assert!(Len(LenError {
106             required_len: 1,
107             layer: Layer::Ipv4Packet,
108             len: 2,
109             len_source: LenSource::Slice,
110             layer_start_offset: 3
111         })
112         .source()
113         .is_some());
114         assert!(Header(HeaderError::UnexpectedVersion { version_number: 6 })
115             .source()
116             .is_some());
117         assert!(Exts(ip_auth::HeaderError::ZeroPayloadLen)
118             .source()
119             .is_some());
120     }
121 }
122