• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::err::*;
2 
3 /// "Catch all" error for all `from_slice` or `read` errors (supports automatic conversion from all
4 /// other slice errors).
5 ///
6 /// This type aggregates all errors that can be caused by decoding from a slice or reading
7 /// from an io stream.
8 ///
9 /// This type can be used as a "catch all" type for errors caused by `from_slice` or
10 /// `read` functions as all errors from these functions can be converted into this type.
11 #[derive(Debug)]
12 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
13 pub enum ReadError {
14     /// IO error was encountered while reading header or expected packet contents.
15     Io(std::io::Error),
16 
17     /// Error when parsing had to be aborted because of a length error (usually
18     /// not enough data being available).
19     Len(LenError),
20 
21     /// Error while parsing a double vlan header.
22     DoubleVlan(double_vlan::HeaderError),
23 
24     /// Error while parsing a IP header.
25     Ip(ip::HeaderError),
26 
27     /// Error while parsing a IP authentication header.
28     IpAuth(ip_auth::HeaderError),
29 
30     /// Error while parsing a IPv4 header.
31     Ipv4(ipv4::HeaderError),
32 
33     /// Error while parsing a IPv6 header.
34     Ipv6(ipv6::HeaderError),
35 
36     /// Error while parsing a IPv6 extension header.
37     Ipv6Exts(ipv6_exts::HeaderError),
38 
39     /// Error while parsing a Linux Cooked Capture v1 (SLL)
40     LinuxSll(linux_sll::HeaderError),
41 
42     /// Error while parsing a TCP extension header.
43     Tcp(tcp::HeaderError),
44 }
45 
46 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
47 impl ReadError {
io(&self) -> Option<&std::io::Error>48     pub fn io(&self) -> Option<&std::io::Error> {
49         match self {
50             ReadError::Io(err) => Some(err),
51             _ => None,
52         }
53     }
len(&self) -> Option<&LenError>54     pub fn len(&self) -> Option<&LenError> {
55         match self {
56             ReadError::Len(err) => Some(err),
57             _ => None,
58         }
59     }
double_vlan(&self) -> Option<&double_vlan::HeaderError>60     pub fn double_vlan(&self) -> Option<&double_vlan::HeaderError> {
61         match self {
62             ReadError::DoubleVlan(err) => Some(err),
63             _ => None,
64         }
65     }
ip(&self) -> Option<&ip::HeaderError>66     pub fn ip(&self) -> Option<&ip::HeaderError> {
67         match self {
68             ReadError::Ip(err) => Some(err),
69             _ => None,
70         }
71     }
ip_auth(&self) -> Option<&ip_auth::HeaderError>72     pub fn ip_auth(&self) -> Option<&ip_auth::HeaderError> {
73         match self {
74             ReadError::IpAuth(err) => Some(err),
75             _ => None,
76         }
77     }
ipv4(&self) -> Option<&ipv4::HeaderError>78     pub fn ipv4(&self) -> Option<&ipv4::HeaderError> {
79         match self {
80             ReadError::Ipv4(err) => Some(err),
81             _ => None,
82         }
83     }
ipv6(&self) -> Option<&ipv6::HeaderError>84     pub fn ipv6(&self) -> Option<&ipv6::HeaderError> {
85         match self {
86             ReadError::Ipv6(err) => Some(err),
87             _ => None,
88         }
89     }
ipv6_exts(&self) -> Option<&ipv6_exts::HeaderError>90     pub fn ipv6_exts(&self) -> Option<&ipv6_exts::HeaderError> {
91         match self {
92             ReadError::Ipv6Exts(err) => Some(err),
93             _ => None,
94         }
95     }
linux_sll(&self) -> Option<&linux_sll::HeaderError>96     pub fn linux_sll(&self) -> Option<&linux_sll::HeaderError> {
97         match self {
98             ReadError::LinuxSll(err) => Some(err),
99             _ => None,
100         }
101     }
tcp(&self) -> Option<&tcp::HeaderError>102     pub fn tcp(&self) -> Option<&tcp::HeaderError> {
103         match self {
104             ReadError::Tcp(err) => Some(err),
105             _ => None,
106         }
107     }
108 }
109 
110 impl core::fmt::Display for ReadError {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result111     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
112         use crate::err::ReadError::*;
113         match self {
114             Io(err) => err.fmt(f),
115             Len(err) => err.fmt(f),
116             DoubleVlan(err) => err.fmt(f),
117             Ip(err) => err.fmt(f),
118             IpAuth(err) => err.fmt(f),
119             Ipv4(err) => err.fmt(f),
120             Ipv6(err) => err.fmt(f),
121             Ipv6Exts(err) => err.fmt(f),
122             LinuxSll(err) => err.fmt(f),
123             Tcp(err) => err.fmt(f),
124         }
125     }
126 }
127 
128 #[cfg(feature = "std")]
129 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
130 impl std::error::Error for ReadError {
source(&self) -> Option<&(dyn std::error::Error + 'static)>131     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
132         match self {
133             ReadError::Io(err) => Some(err),
134             ReadError::Len(err) => Some(err),
135             ReadError::DoubleVlan(err) => Some(err),
136             ReadError::Ip(err) => Some(err),
137             ReadError::IpAuth(err) => Some(err),
138             ReadError::Ipv4(err) => Some(err),
139             ReadError::Ipv6(err) => Some(err),
140             ReadError::Ipv6Exts(err) => Some(err),
141             ReadError::LinuxSll(err) => Some(err),
142             ReadError::Tcp(err) => Some(err),
143         }
144     }
145 }
146 
147 // io & len error conversions
148 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
149 impl From<std::io::Error> for ReadError {
from(value: std::io::Error) -> Self150     fn from(value: std::io::Error) -> Self {
151         ReadError::Io(value)
152     }
153 }
154 
155 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
156 impl From<LenError> for ReadError {
from(value: LenError) -> Self157     fn from(value: LenError) -> Self {
158         ReadError::Len(value)
159     }
160 }
161 
162 // double vlan error conversions
163 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
164 impl From<double_vlan::HeaderError> for ReadError {
from(value: double_vlan::HeaderError) -> Self165     fn from(value: double_vlan::HeaderError) -> Self {
166         ReadError::DoubleVlan(value)
167     }
168 }
169 
170 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
171 impl From<double_vlan::HeaderReadError> for ReadError {
from(value: double_vlan::HeaderReadError) -> Self172     fn from(value: double_vlan::HeaderReadError) -> Self {
173         use double_vlan::HeaderReadError::*;
174         match value {
175             Io(err) => ReadError::Io(err),
176             Content(err) => ReadError::DoubleVlan(err),
177         }
178     }
179 }
180 
181 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
182 impl From<double_vlan::HeaderSliceError> for ReadError {
from(value: double_vlan::HeaderSliceError) -> Self183     fn from(value: double_vlan::HeaderSliceError) -> Self {
184         use double_vlan::HeaderSliceError::*;
185         match value {
186             Len(err) => ReadError::Len(err),
187             Content(err) => ReadError::DoubleVlan(err),
188         }
189     }
190 }
191 
192 // ip error conversions
193 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
194 impl From<ip::HeaderError> for ReadError {
from(value: ip::HeaderError) -> Self195     fn from(value: ip::HeaderError) -> Self {
196         ReadError::Ip(value)
197     }
198 }
199 
200 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
201 impl From<ip::HeadersError> for ReadError {
from(value: ip::HeadersError) -> Self202     fn from(value: ip::HeadersError) -> Self {
203         match value {
204             ip::HeadersError::Ip(err) => ReadError::Ip(err),
205             ip::HeadersError::Ipv4Ext(err) => ReadError::IpAuth(err),
206             ip::HeadersError::Ipv6Ext(err) => ReadError::Ipv6Exts(err),
207         }
208     }
209 }
210 
211 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
212 impl From<ip::HeaderReadError> for ReadError {
from(value: ip::HeaderReadError) -> Self213     fn from(value: ip::HeaderReadError) -> Self {
214         use ip::HeaderReadError::*;
215         match value {
216             Io(err) => ReadError::Io(err),
217             Len(err) => ReadError::Len(err),
218             Content(err) => err.into(),
219         }
220     }
221 }
222 
223 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
224 impl From<ip::HeadersSliceError> for ReadError {
from(value: ip::HeadersSliceError) -> Self225     fn from(value: ip::HeadersSliceError) -> Self {
226         use ip::HeadersSliceError::*;
227         match value {
228             Len(err) => ReadError::Len(err),
229             Content(err) => err.into(),
230         }
231     }
232 }
233 
234 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
235 impl From<ip::SliceError> for ReadError {
from(value: ip::SliceError) -> Self236     fn from(value: ip::SliceError) -> Self {
237         use ip::SliceError::*;
238         match value {
239             Len(err) => ReadError::Len(err),
240             IpHeaders(err) => err.into(),
241         }
242     }
243 }
244 
245 // ip auth error conversions
246 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
247 impl From<ip_auth::HeaderError> for ReadError {
from(value: ip_auth::HeaderError) -> Self248     fn from(value: ip_auth::HeaderError) -> Self {
249         ReadError::IpAuth(value)
250     }
251 }
252 
253 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
254 impl From<ip_auth::HeaderReadError> for ReadError {
from(value: ip_auth::HeaderReadError) -> Self255     fn from(value: ip_auth::HeaderReadError) -> Self {
256         use ip_auth::HeaderReadError::*;
257         match value {
258             Io(err) => ReadError::Io(err),
259             Content(err) => ReadError::IpAuth(err),
260         }
261     }
262 }
263 
264 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
265 impl From<ip_auth::HeaderSliceError> for ReadError {
from(value: ip_auth::HeaderSliceError) -> Self266     fn from(value: ip_auth::HeaderSliceError) -> Self {
267         use ip_auth::HeaderSliceError::*;
268         match value {
269             Len(err) => ReadError::Len(err),
270             Content(err) => ReadError::IpAuth(err),
271         }
272     }
273 }
274 
275 // ipv4 error conversions
276 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
277 impl From<ipv4::HeaderError> for ReadError {
from(value: ipv4::HeaderError) -> Self278     fn from(value: ipv4::HeaderError) -> Self {
279         ReadError::Ipv4(value)
280     }
281 }
282 
283 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
284 impl From<ipv4::HeaderReadError> for ReadError {
from(value: ipv4::HeaderReadError) -> Self285     fn from(value: ipv4::HeaderReadError) -> Self {
286         use ipv4::HeaderReadError::*;
287         match value {
288             Io(err) => ReadError::Io(err),
289             Content(err) => ReadError::Ipv4(err),
290         }
291     }
292 }
293 
294 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
295 impl From<ipv4::HeaderSliceError> for ReadError {
from(value: ipv4::HeaderSliceError) -> Self296     fn from(value: ipv4::HeaderSliceError) -> Self {
297         use ipv4::HeaderSliceError::*;
298         match value {
299             Len(err) => ReadError::Len(err),
300             Content(err) => ReadError::Ipv4(err),
301         }
302     }
303 }
304 
305 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
306 impl From<ipv4::SliceError> for ReadError {
from(value: ipv4::SliceError) -> Self307     fn from(value: ipv4::SliceError) -> Self {
308         use ipv4::SliceError::*;
309         match value {
310             Len(err) => ReadError::Len(err),
311             Header(err) => ReadError::Ipv4(err),
312             Exts(err) => ReadError::IpAuth(err),
313         }
314     }
315 }
316 
317 // ipv6 error conversions
318 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
319 impl From<ipv6::HeaderError> for ReadError {
from(value: ipv6::HeaderError) -> Self320     fn from(value: ipv6::HeaderError) -> Self {
321         ReadError::Ipv6(value)
322     }
323 }
324 
325 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
326 impl From<ipv6::HeaderReadError> for ReadError {
from(value: ipv6::HeaderReadError) -> Self327     fn from(value: ipv6::HeaderReadError) -> Self {
328         use ipv6::HeaderReadError::*;
329         match value {
330             Io(err) => ReadError::Io(err),
331             Content(err) => ReadError::Ipv6(err),
332         }
333     }
334 }
335 
336 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
337 impl From<ipv6::HeaderSliceError> for ReadError {
from(value: ipv6::HeaderSliceError) -> Self338     fn from(value: ipv6::HeaderSliceError) -> Self {
339         use ipv6::HeaderSliceError::*;
340         match value {
341             Len(err) => ReadError::Len(err),
342             Content(err) => ReadError::Ipv6(err),
343         }
344     }
345 }
346 
347 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
348 impl From<ipv6::SliceError> for ReadError {
from(value: ipv6::SliceError) -> Self349     fn from(value: ipv6::SliceError) -> Self {
350         use ipv6::SliceError::*;
351         match value {
352             Len(err) => ReadError::Len(err),
353             Header(err) => ReadError::Ipv6(err),
354             Exts(err) => ReadError::Ipv6Exts(err),
355         }
356     }
357 }
358 
359 // ipv6 exts error conversions
360 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
361 impl From<ipv6_exts::HeaderError> for ReadError {
from(value: ipv6_exts::HeaderError) -> Self362     fn from(value: ipv6_exts::HeaderError) -> Self {
363         ReadError::Ipv6Exts(value)
364     }
365 }
366 
367 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
368 impl From<ipv6_exts::HeaderReadError> for ReadError {
from(value: ipv6_exts::HeaderReadError) -> Self369     fn from(value: ipv6_exts::HeaderReadError) -> Self {
370         use ipv6_exts::HeaderReadError::*;
371         match value {
372             Io(err) => ReadError::Io(err),
373             Content(err) => ReadError::Ipv6Exts(err),
374         }
375     }
376 }
377 
378 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
379 impl From<ipv6_exts::HeaderSliceError> for ReadError {
from(value: ipv6_exts::HeaderSliceError) -> Self380     fn from(value: ipv6_exts::HeaderSliceError) -> Self {
381         use ipv6_exts::HeaderSliceError::*;
382         match value {
383             Len(err) => ReadError::Len(err),
384             Content(err) => ReadError::Ipv6Exts(err),
385         }
386     }
387 }
388 
389 // linux sll error conversions
390 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
391 impl From<linux_sll::HeaderError> for ReadError {
from(value: linux_sll::HeaderError) -> Self392     fn from(value: linux_sll::HeaderError) -> Self {
393         ReadError::LinuxSll(value)
394     }
395 }
396 
397 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
398 impl From<linux_sll::HeaderReadError> for ReadError {
from(value: linux_sll::HeaderReadError) -> Self399     fn from(value: linux_sll::HeaderReadError) -> Self {
400         use linux_sll::HeaderReadError::*;
401         match value {
402             Io(err) => ReadError::Io(err),
403             Content(err) => ReadError::LinuxSll(err),
404         }
405     }
406 }
407 
408 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
409 impl From<linux_sll::HeaderSliceError> for ReadError {
from(value: linux_sll::HeaderSliceError) -> Self410     fn from(value: linux_sll::HeaderSliceError) -> Self {
411         use linux_sll::HeaderSliceError::*;
412         match value {
413             Len(err) => ReadError::Len(err),
414             Content(err) => ReadError::LinuxSll(err),
415         }
416     }
417 }
418 
419 // packet error conversions
420 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
421 impl From<packet::SliceError> for ReadError {
from(value: packet::SliceError) -> Self422     fn from(value: packet::SliceError) -> Self {
423         use packet::SliceError::*;
424         match value {
425             Len(err) => ReadError::Len(err),
426             LinuxSll(err) => ReadError::LinuxSll(err),
427             Ip(err) => ReadError::Ip(err),
428             Ipv4(err) => ReadError::Ipv4(err),
429             Ipv6(err) => ReadError::Ipv6(err),
430             Ipv4Exts(err) => ReadError::IpAuth(err),
431             Ipv6Exts(err) => ReadError::Ipv6Exts(err),
432             Tcp(err) => ReadError::Tcp(err),
433         }
434     }
435 }
436 
437 // tcp error conversions
438 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
439 impl From<tcp::HeaderError> for ReadError {
from(value: tcp::HeaderError) -> Self440     fn from(value: tcp::HeaderError) -> Self {
441         ReadError::Tcp(value)
442     }
443 }
444 
445 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
446 impl From<tcp::HeaderReadError> for ReadError {
from(value: tcp::HeaderReadError) -> Self447     fn from(value: tcp::HeaderReadError) -> Self {
448         use tcp::HeaderReadError::*;
449         match value {
450             Io(err) => ReadError::Io(err),
451             Content(err) => ReadError::Tcp(err),
452         }
453     }
454 }
455 
456 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
457 impl From<tcp::HeaderSliceError> for ReadError {
from(value: tcp::HeaderSliceError) -> Self458     fn from(value: tcp::HeaderSliceError) -> Self {
459         use tcp::HeaderSliceError::*;
460         match value {
461             Len(err) => ReadError::Len(err),
462             Content(err) => ReadError::Tcp(err),
463         }
464     }
465 }
466 
467 #[cfg(test)]
468 mod tests {
469     use crate::{
470         err::{ReadError::*, *},
471         LenSource,
472     };
473     use crate::{ArpHardwareId, EtherType};
474     use std::error::Error;
475     use std::format;
476 
477     #[test]
debug_source()478     fn debug_source() {
479         let test_values: [(&str, ReadError); 10] = [
480             (
481                 "Len",
482                 Len(LenError {
483                     required_len: 0,
484                     len: 0,
485                     len_source: LenSource::Slice,
486                     layer: Layer::Icmpv4,
487                     layer_start_offset: 0,
488                 }),
489             ),
490             (
491                 "LinuxSll",
492                 LinuxSll(linux_sll::HeaderError::UnsupportedArpHardwareId {
493                     arp_hardware_type: ArpHardwareId::ETHERNET,
494                 }),
495             ),
496             (
497                 "DoubleVlan",
498                 DoubleVlan(double_vlan::HeaderError::NonVlanEtherType {
499                     unexpected_ether_type: EtherType(123),
500                 }),
501             ),
502             (
503                 "Ip",
504                 Ip(ip::HeaderError::UnsupportedIpVersion {
505                     version_number: 123,
506                 }),
507             ),
508             ("IpAuth", IpAuth(ip_auth::HeaderError::ZeroPayloadLen)),
509             (
510                 "Ipv4",
511                 Ipv4(ipv4::HeaderError::UnexpectedVersion { version_number: 1 }),
512             ),
513             (
514                 "Ipv6",
515                 Ipv6(ipv6::HeaderError::UnexpectedVersion { version_number: 1 }),
516             ),
517             (
518                 "Ipv6Exts",
519                 Ipv6Exts(ipv6_exts::HeaderError::HopByHopNotAtStart),
520             ),
521             (
522                 "LinuxSll",
523                 LinuxSll(linux_sll::HeaderError::UnsupportedPacketTypeField { packet_type: 123 }),
524             ),
525             (
526                 "Tcp",
527                 Tcp(tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 }),
528             ),
529         ];
530         for (prefix, value) in &test_values {
531             // display
532             assert_eq!(
533                 format!("{:?}", value),
534                 format!("{}({:?})", prefix, value.source().unwrap())
535             );
536         }
537         // io handled separately as source points to the underlying type
538         {
539             let io_error = || std::io::Error::new(std::io::ErrorKind::Other, "some error");
540             assert_eq!(
541                 format!("Io({:?})", io_error()),
542                 format!("{:?}", Io(io_error()))
543             );
544         }
545     }
546 
547     #[test]
display_source()548     fn display_source() {
549         let test_values: [ReadError; 10] = [
550             Len(LenError {
551                 required_len: 0,
552                 len: 0,
553                 len_source: LenSource::Slice,
554                 layer: Layer::Icmpv4,
555                 layer_start_offset: 0,
556             }),
557             LinuxSll(linux_sll::HeaderError::UnsupportedArpHardwareId {
558                 arp_hardware_type: ArpHardwareId::ETHERNET,
559             }),
560             DoubleVlan(double_vlan::HeaderError::NonVlanEtherType {
561                 unexpected_ether_type: EtherType(123),
562             }),
563             Ip(ip::HeaderError::UnsupportedIpVersion {
564                 version_number: 123,
565             }),
566             IpAuth(ip_auth::HeaderError::ZeroPayloadLen),
567             Ipv4(ipv4::HeaderError::UnexpectedVersion { version_number: 1 }),
568             Ipv6(ipv6::HeaderError::UnexpectedVersion { version_number: 1 }),
569             Ipv6Exts(ipv6_exts::HeaderError::HopByHopNotAtStart),
570             LinuxSll(linux_sll::HeaderError::UnsupportedPacketTypeField { packet_type: 123 }),
571             Tcp(tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 }),
572         ];
573         for value in &test_values {
574             // display
575             assert_eq!(format!("{}", value), format!("{}", value.source().unwrap()));
576         }
577         // io handled separately as source points to the underlying type
578         {
579             let io_error = || std::io::Error::new(std::io::ErrorKind::Other, "some error");
580             assert_eq!(format!("{}", io_error()), format!("{}", Io(io_error())));
581             assert!(Io(io_error()).source().is_some());
582         }
583     }
584 
585     #[test]
accessors()586     fn accessors() {
587         use ReadError::*;
588         let io_error = || std::io::Error::new(std::io::ErrorKind::Other, "some error");
589         let len_error = || LenError {
590             required_len: 0,
591             len: 0,
592             len_source: LenSource::Slice,
593             layer: Layer::Icmpv4,
594             layer_start_offset: 0,
595         };
596         let double_vlan_error = || double_vlan::HeaderError::NonVlanEtherType {
597             unexpected_ether_type: EtherType(1),
598         };
599         let ip_error = || ip::HeaderError::UnsupportedIpVersion { version_number: 0 };
600         let ipv4_error = || ipv4::HeaderError::UnexpectedVersion { version_number: 1 };
601         let ipv6_error = || ipv6::HeaderError::UnexpectedVersion { version_number: 1 };
602         let ip_auth_error = || ip_auth::HeaderError::ZeroPayloadLen;
603         let ipv6_exts_error = || ipv6_exts::HeaderError::HopByHopNotAtStart;
604         let linux_sll_error =
605             || linux_sll::HeaderError::UnsupportedPacketTypeField { packet_type: 123 };
606         let tcp_error = || tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 };
607 
608         // io
609         assert!(Io(io_error()).io().is_some());
610         assert!(Ipv4(ipv4_error()).io().is_none());
611 
612         // len
613         assert_eq!(Len(len_error()).len(), Some(&len_error()));
614         assert_eq!(Ipv4(ipv4_error()).len(), None);
615 
616         // linux sll
617         assert_eq!(
618             LinuxSll(linux_sll_error()).linux_sll(),
619             Some(&linux_sll_error())
620         );
621         assert_eq!(Ipv4(ipv4_error()).linux_sll(), None);
622 
623         // double_vlan
624         assert_eq!(
625             DoubleVlan(double_vlan_error()).double_vlan(),
626             Some(&double_vlan_error())
627         );
628         assert_eq!(Ipv4(ipv4_error()).double_vlan(), None);
629 
630         // ip
631         assert_eq!(Ip(ip_error()).ip(), Some(&ip_error()));
632         assert_eq!(Ipv4(ipv4_error()).ip(), None);
633 
634         // ip_auth
635         assert_eq!(IpAuth(ip_auth_error()).ip_auth(), Some(&ip_auth_error()));
636         assert_eq!(Ipv4(ipv4_error()).ip_auth(), None);
637 
638         // ipv4
639         assert_eq!(Ipv4(ipv4_error()).ipv4(), Some(&ipv4_error()));
640         assert_eq!(IpAuth(ip_auth_error()).ipv4(), None);
641 
642         // ipv6
643         assert_eq!(Ipv6(ipv6_error()).ipv6(), Some(&ipv6_error()));
644         assert_eq!(IpAuth(ip_auth_error()).ipv6(), None);
645 
646         // ipv6_exts
647         assert_eq!(
648             Ipv6Exts(ipv6_exts_error()).ipv6_exts(),
649             Some(&ipv6_exts_error())
650         );
651         assert_eq!(IpAuth(ip_auth_error()).ipv6_exts(), None);
652 
653         // linux_sll
654         assert_eq!(
655             LinuxSll(linux_sll_error()).linux_sll(),
656             Some(&linux_sll_error())
657         );
658         assert_eq!(IpAuth(ip_auth_error()).linux_sll(), None);
659 
660         // tcp
661         assert_eq!(Tcp(tcp_error()).tcp(), Some(&tcp_error()));
662         assert_eq!(IpAuth(ip_auth_error()).tcp(), None);
663     }
664 
665     #[test]
from()666     fn from() {
667         let io_error =
668             || -> std::io::Error { std::io::Error::new(std::io::ErrorKind::Other, "some error") };
669         let len_error = || -> LenError {
670             LenError {
671                 required_len: 0,
672                 len: 0,
673                 len_source: LenSource::Slice,
674                 layer: Layer::Icmpv4,
675                 layer_start_offset: 0,
676             }
677         };
678 
679         // io & len
680         assert!(ReadError::from(io_error()).io().is_some());
681         assert_eq!(&len_error(), ReadError::from(len_error()).len().unwrap());
682 
683         // linux sll
684         {
685             let header_error = || linux_sll::HeaderError::UnsupportedArpHardwareId {
686                 arp_hardware_type: ArpHardwareId::ETHERNET,
687             };
688             assert_eq!(
689                 &header_error(),
690                 ReadError::from(header_error()).linux_sll().unwrap()
691             );
692             assert_eq!(
693                 &header_error(),
694                 ReadError::from(linux_sll::HeaderReadError::Content(header_error()))
695                     .linux_sll()
696                     .unwrap()
697             );
698             assert!(ReadError::from(linux_sll::HeaderReadError::Io(io_error()))
699                 .io()
700                 .is_some());
701             assert_eq!(
702                 &header_error(),
703                 ReadError::from(linux_sll::HeaderSliceError::Content(header_error()))
704                     .linux_sll()
705                     .unwrap()
706             );
707             assert_eq!(
708                 &len_error(),
709                 ReadError::from(linux_sll::HeaderSliceError::Len(len_error()))
710                     .len()
711                     .unwrap()
712             );
713             assert_eq!(
714                 &header_error(),
715                 ReadError::from(linux_sll::HeaderSliceError::Content(header_error()))
716                     .linux_sll()
717                     .unwrap()
718             );
719         }
720 
721         // double vlan errors
722         {
723             let header_error = || double_vlan::HeaderError::NonVlanEtherType {
724                 unexpected_ether_type: EtherType(123),
725             };
726             assert_eq!(
727                 &header_error(),
728                 ReadError::from(header_error()).double_vlan().unwrap()
729             );
730             assert_eq!(
731                 &header_error(),
732                 ReadError::from(double_vlan::HeaderReadError::Content(header_error()))
733                     .double_vlan()
734                     .unwrap()
735             );
736             assert!(
737                 ReadError::from(double_vlan::HeaderReadError::Io(io_error()))
738                     .io()
739                     .is_some()
740             );
741             assert_eq!(
742                 &header_error(),
743                 ReadError::from(double_vlan::HeaderSliceError::Content(header_error()))
744                     .double_vlan()
745                     .unwrap()
746             );
747             assert_eq!(
748                 &len_error(),
749                 ReadError::from(double_vlan::HeaderSliceError::Len(len_error()))
750                     .len()
751                     .unwrap()
752             );
753             assert_eq!(
754                 &header_error(),
755                 ReadError::from(double_vlan::HeaderSliceError::Content(header_error()))
756                     .double_vlan()
757                     .unwrap()
758             );
759         }
760 
761         // ip errors
762         {
763             let header_error = || ip::HeaderError::UnsupportedIpVersion {
764                 version_number: 123,
765             };
766             assert_eq!(
767                 &header_error(),
768                 ReadError::from(header_error()).ip().unwrap()
769             );
770             assert_eq!(
771                 &header_error(),
772                 ReadError::from(ip::HeaderReadError::Content(ip::HeadersError::Ip(
773                     header_error()
774                 )))
775                 .ip()
776                 .unwrap()
777             );
778             assert_eq!(
779                 &len_error(),
780                 ReadError::from(ip::HeaderReadError::Len(len_error()))
781                     .len()
782                     .unwrap()
783             );
784             assert!(ReadError::from(ip::HeaderReadError::Io(io_error()))
785                 .io()
786                 .is_some());
787             assert_eq!(
788                 &header_error(),
789                 ReadError::from(ip::HeadersSliceError::Content(ip::HeadersError::Ip(
790                     header_error()
791                 )))
792                 .ip()
793                 .unwrap()
794             );
795             assert_eq!(
796                 &len_error(),
797                 ReadError::from(ip::HeadersSliceError::Len(len_error()))
798                     .len()
799                     .unwrap()
800             );
801             assert_eq!(
802                 &header_error(),
803                 ReadError::from(ip::HeadersSliceError::Content(ip::HeadersError::Ip(
804                     header_error()
805                 )))
806                 .ip()
807                 .unwrap()
808             );
809             assert_eq!(
810                 &len_error(),
811                 ReadError::from(ip::SliceError::Len(len_error()))
812                     .len()
813                     .unwrap()
814             );
815             assert_eq!(
816                 &header_error(),
817                 ReadError::from(ip::SliceError::IpHeaders(ip::HeadersError::Ip(
818                     header_error()
819                 )))
820                 .ip()
821                 .unwrap()
822             );
823         }
824 
825         // ip auth errors
826         {
827             let header_error = || ip_auth::HeaderError::ZeroPayloadLen;
828             assert_eq!(
829                 &header_error(),
830                 ReadError::from(header_error()).ip_auth().unwrap()
831             );
832             assert_eq!(
833                 &header_error(),
834                 ReadError::from(ip_auth::HeaderReadError::Content(header_error()))
835                     .ip_auth()
836                     .unwrap()
837             );
838             assert!(ReadError::from(ip_auth::HeaderReadError::Io(io_error()))
839                 .io()
840                 .is_some());
841             assert_eq!(
842                 &header_error(),
843                 ReadError::from(ip_auth::HeaderSliceError::Content(header_error()))
844                     .ip_auth()
845                     .unwrap()
846             );
847             assert_eq!(
848                 &len_error(),
849                 ReadError::from(ip_auth::HeaderSliceError::Len(len_error()))
850                     .len()
851                     .unwrap()
852             );
853             assert_eq!(
854                 &header_error(),
855                 ReadError::from(ip_auth::HeaderSliceError::Content(header_error()))
856                     .ip_auth()
857                     .unwrap()
858             );
859         }
860 
861         // ipv4 errors
862         {
863             let header_error = || ipv4::HeaderError::UnexpectedVersion {
864                 version_number: 123,
865             };
866             let exts_error = || ip_auth::HeaderError::ZeroPayloadLen;
867             assert_eq!(
868                 &header_error(),
869                 ReadError::from(header_error()).ipv4().unwrap()
870             );
871             assert_eq!(
872                 &header_error(),
873                 ReadError::from(ipv4::HeaderReadError::Content(header_error()))
874                     .ipv4()
875                     .unwrap()
876             );
877             assert!(ReadError::from(ipv4::HeaderReadError::Io(io_error()))
878                 .io()
879                 .is_some());
880             assert_eq!(
881                 &header_error(),
882                 ReadError::from(ipv4::HeaderSliceError::Content(header_error()))
883                     .ipv4()
884                     .unwrap()
885             );
886             assert_eq!(
887                 &len_error(),
888                 ReadError::from(ipv4::HeaderSliceError::Len(len_error()))
889                     .len()
890                     .unwrap()
891             );
892             assert_eq!(
893                 &header_error(),
894                 ReadError::from(ipv4::HeaderSliceError::Content(header_error()))
895                     .ipv4()
896                     .unwrap()
897             );
898             assert_eq!(
899                 &len_error(),
900                 ReadError::from(ipv4::SliceError::Len(len_error()))
901                     .len()
902                     .unwrap()
903             );
904             assert_eq!(
905                 &header_error(),
906                 ReadError::from(ipv4::SliceError::Header(header_error()))
907                     .ipv4()
908                     .unwrap()
909             );
910             assert_eq!(
911                 &exts_error(),
912                 ReadError::from(ipv4::SliceError::Exts(exts_error()))
913                     .ip_auth()
914                     .unwrap()
915             );
916         }
917 
918         // ipv6 errors
919         {
920             let header_error = || ipv6::HeaderError::UnexpectedVersion {
921                 version_number: 123,
922             };
923             let exts_error = || ipv6_exts::HeaderError::HopByHopNotAtStart;
924             assert_eq!(
925                 &header_error(),
926                 ReadError::from(header_error()).ipv6().unwrap()
927             );
928             assert_eq!(
929                 &header_error(),
930                 ReadError::from(ipv6::HeaderReadError::Content(header_error()))
931                     .ipv6()
932                     .unwrap()
933             );
934             assert!(ReadError::from(ipv6::HeaderReadError::Io(io_error()))
935                 .io()
936                 .is_some());
937             assert_eq!(
938                 &header_error(),
939                 ReadError::from(ipv6::HeaderSliceError::Content(header_error()))
940                     .ipv6()
941                     .unwrap()
942             );
943             assert_eq!(
944                 &len_error(),
945                 ReadError::from(ipv6::HeaderSliceError::Len(len_error()))
946                     .len()
947                     .unwrap()
948             );
949             assert_eq!(
950                 &header_error(),
951                 ReadError::from(ipv6::HeaderSliceError::Content(header_error()))
952                     .ipv6()
953                     .unwrap()
954             );
955             assert_eq!(
956                 &len_error(),
957                 ReadError::from(ipv6::SliceError::Len(len_error()))
958                     .len()
959                     .unwrap()
960             );
961             assert_eq!(
962                 &header_error(),
963                 ReadError::from(ipv6::SliceError::Header(header_error()))
964                     .ipv6()
965                     .unwrap()
966             );
967             assert_eq!(
968                 &exts_error(),
969                 ReadError::from(ipv6::SliceError::Exts(exts_error()))
970                     .ipv6_exts()
971                     .unwrap()
972             );
973         }
974 
975         // ipv6 exts errors
976         {
977             let header_error = || ipv6_exts::HeaderError::HopByHopNotAtStart;
978             assert_eq!(
979                 &header_error(),
980                 ReadError::from(header_error()).ipv6_exts().unwrap()
981             );
982             assert_eq!(
983                 &header_error(),
984                 ReadError::from(ipv6_exts::HeaderReadError::Content(header_error()))
985                     .ipv6_exts()
986                     .unwrap()
987             );
988             assert!(ReadError::from(ipv6_exts::HeaderReadError::Io(io_error()))
989                 .io()
990                 .is_some());
991             assert_eq!(
992                 &header_error(),
993                 ReadError::from(ipv6_exts::HeaderSliceError::Content(header_error()))
994                     .ipv6_exts()
995                     .unwrap()
996             );
997             assert_eq!(
998                 &len_error(),
999                 ReadError::from(ipv6_exts::HeaderSliceError::Len(len_error()))
1000                     .len()
1001                     .unwrap()
1002             );
1003             assert_eq!(
1004                 &header_error(),
1005                 ReadError::from(ipv6_exts::HeaderSliceError::Content(header_error()))
1006                     .ipv6_exts()
1007                     .unwrap()
1008             );
1009         }
1010 
1011         // linux_sll errors
1012         {
1013             let header_error =
1014                 || linux_sll::HeaderError::UnsupportedPacketTypeField { packet_type: 123 };
1015             assert_eq!(
1016                 &header_error(),
1017                 ReadError::from(header_error()).linux_sll().unwrap()
1018             );
1019             assert_eq!(
1020                 &header_error(),
1021                 ReadError::from(linux_sll::HeaderReadError::Content(header_error()))
1022                     .linux_sll()
1023                     .unwrap()
1024             );
1025             assert!(ReadError::from(linux_sll::HeaderReadError::Io(io_error()))
1026                 .io()
1027                 .is_some());
1028             assert_eq!(
1029                 &header_error(),
1030                 ReadError::from(linux_sll::HeaderSliceError::Content(header_error()))
1031                     .linux_sll()
1032                     .unwrap()
1033             );
1034             assert_eq!(
1035                 &len_error(),
1036                 ReadError::from(linux_sll::HeaderSliceError::Len(len_error()))
1037                     .len()
1038                     .unwrap()
1039             );
1040             assert_eq!(
1041                 &header_error(),
1042                 ReadError::from(linux_sll::HeaderSliceError::Content(header_error()))
1043                     .linux_sll()
1044                     .unwrap()
1045             );
1046         }
1047 
1048         // packet error
1049         {
1050             let ip_error = || ip::HeaderError::UnsupportedIpVersion { version_number: 0 };
1051             let ipv4_error = || ipv4::HeaderError::UnexpectedVersion { version_number: 1 };
1052             let ipv6_error = || ipv6::HeaderError::UnexpectedVersion { version_number: 1 };
1053             let ip_auth_error = || ip_auth::HeaderError::ZeroPayloadLen;
1054             let ipv6_exts_error = || ipv6_exts::HeaderError::HopByHopNotAtStart;
1055             let tcp_error = || tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 };
1056 
1057             // IpSliceError
1058             assert_eq!(
1059                 &len_error(),
1060                 ReadError::from(packet::SliceError::Len(len_error()))
1061                     .len()
1062                     .unwrap()
1063             );
1064             assert_eq!(
1065                 &ip_error(),
1066                 ReadError::from(packet::SliceError::Ip(ip_error()))
1067                     .ip()
1068                     .unwrap()
1069             );
1070             assert_eq!(
1071                 &ipv4_error(),
1072                 ReadError::from(packet::SliceError::Ipv4(ipv4_error()))
1073                     .ipv4()
1074                     .unwrap()
1075             );
1076             assert_eq!(
1077                 &ipv6_error(),
1078                 ReadError::from(packet::SliceError::Ipv6(ipv6_error()))
1079                     .ipv6()
1080                     .unwrap()
1081             );
1082             assert_eq!(
1083                 &ip_auth_error(),
1084                 ReadError::from(packet::SliceError::Ipv4Exts(ip_auth_error()))
1085                     .ip_auth()
1086                     .unwrap()
1087             );
1088             assert_eq!(
1089                 &ipv6_exts_error(),
1090                 ReadError::from(packet::SliceError::Ipv6Exts(ipv6_exts_error()))
1091                     .ipv6_exts()
1092                     .unwrap()
1093             );
1094             assert_eq!(
1095                 &tcp_error(),
1096                 ReadError::from(packet::SliceError::Tcp(tcp_error()))
1097                     .tcp()
1098                     .unwrap()
1099             );
1100         }
1101 
1102         // tcp errors
1103         {
1104             let header_error = || tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 };
1105             assert_eq!(
1106                 &header_error(),
1107                 ReadError::from(header_error()).tcp().unwrap()
1108             );
1109             assert_eq!(
1110                 &header_error(),
1111                 ReadError::from(tcp::HeaderReadError::Content(header_error()))
1112                     .tcp()
1113                     .unwrap()
1114             );
1115             assert!(ReadError::from(tcp::HeaderReadError::Io(io_error()))
1116                 .io()
1117                 .is_some());
1118             assert_eq!(
1119                 &header_error(),
1120                 ReadError::from(tcp::HeaderSliceError::Content(header_error()))
1121                     .tcp()
1122                     .unwrap()
1123             );
1124             assert_eq!(
1125                 &len_error(),
1126                 ReadError::from(tcp::HeaderSliceError::Len(len_error()))
1127                     .len()
1128                     .unwrap()
1129             );
1130             assert_eq!(
1131                 &header_error(),
1132                 ReadError::from(tcp::HeaderSliceError::Content(header_error()))
1133                     .tcp()
1134                     .unwrap()
1135             );
1136         }
1137     }
1138 } // mod tests
1139