etherparse/err/
read_error.rs

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