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