1 use crate::{err::Layer, *};
2 
3 /// Packet slice split into multiple slices containing
4 /// the different headers & payload.
5 #[derive(Clone, Debug, Eq, PartialEq)]
6 pub struct LaxSlicedPacket<'a> {
7     /// Ethernet II header if present.
8     pub link: Option<LinkSlice<'a>>,
9 
10     /// Single or double vlan headers if present.
11     pub vlan: Option<VlanSlice<'a>>,
12 
13     /// IPv4 or IPv6 header, IP extension headers & payload if present.
14     pub net: Option<LaxNetSlice<'a>>,
15 
16     /// TCP or UDP header & payload if present.
17     pub transport: Option<TransportSlice<'a>>,
18 
19     /// Error that stopped the parsing and the layer on which the stop occurred.
20     pub stop_err: Option<(err::packet::SliceError, Layer)>,
21 }
22 
23 impl<'a> LaxSlicedPacket<'a> {
24     /// Separates a network packet slice into different slices containing the
25     /// headers from the ethernet header downwards with lax length checks and
26     /// non-terminating errors.
27     ///
28     /// # Example
29     ///
30     /// Basic usage:
31     ///
32     ///```
33     /// # use etherparse::{Ethernet2Header, PacketBuilder};
34     /// # let builder = PacketBuilder::
35     /// #    ethernet2([1,2,3,4,5,6],     //source mac
36     /// #               [7,8,9,10,11,12]) //destionation mac
37     /// #    .ipv4([192,168,1,1], //source ip
38     /// #          [192,168,1,2], //destination ip
39     /// #          20)            //time to life
40     /// #    .udp(21,    //source port
41     /// #         1234); //desitnation port
42     /// # // payload of the udp packet
43     /// # let payload = [1,2,3,4,5,6,7,8];
44     /// # // get some memory to store the serialized data
45     /// # let mut packet = Vec::<u8>::with_capacity(
46     /// #     builder.size(payload.len())
47     /// # );
48     /// # builder.write(&mut packet, &payload).unwrap();
49     /// #
50     /// use etherparse::{ether_type, LaxSlicedPacket, LenSource};
51     ///
52     /// match LaxSlicedPacket::from_ethernet(&packet) {
53     ///     Err(value) => {
54     ///         // An error is returned in case the ethernet II header could
55     ///         // not be parsed (other errors are stored in the "stop_err" field)
56     ///         println!("Err {:?}", value)
57     ///     },
58     ///     Ok(value) => {
59     ///         if let Some((stop_err, error_layer)) = value.stop_err.as_ref() {
60     ///             // error was encountered after parsing the ethernet 2 header
61     ///             println!("Error on layer {}: {:?}", error_layer, stop_err);
62     ///         }
63     ///
64     ///         // parts that could be parsed without error
65     ///         println!("link: {:?}", value.link);
66     ///         println!("vlan: {:?}", value.vlan);
67     ///         println!("net: {:?}", value.net);
68     ///         println!("transport: {:?}", value.transport);
69     ///
70     ///         // net (ip) & transport (udp or tcp)
71     ///         println!("net: {:?}", value.net);
72     ///         if let Some(ip_payload) = value.net.as_ref().map(|net| net.ip_payload_ref()).flatten() {
73     ///             // the ip payload len_source field can be used to check
74     ///             // if the slice length was used as a fallback value
75     ///             if ip_payload.len_source == LenSource::Slice {
76     ///                 println!("  Used slice length as fallback to identify the IP payload");
77     ///             } else {
78     ///                 println!("  IP payload could correctly be identfied via the length field in the header");
79     ///             }
80     ///         }
81     ///         println!("transport: {:?}", value.transport);
82     ///     }
83     /// }
84     ///
85     /// ```
from_ethernet(slice: &'a [u8]) -> Result<LaxSlicedPacket<'a>, err::LenError>86     pub fn from_ethernet(slice: &'a [u8]) -> Result<LaxSlicedPacket<'a>, err::LenError> {
87         LaxSlicedPacketCursor::parse_from_ethernet2(slice)
88     }
89 
90     /// Separates a network packet slice into different slices containing the headers using
91     /// the given `ether_type` number to identify the first header with lax length
92     /// checks and non-terminating errors.
93     ///
94     /// The result is returned as a [`LaxSlicedPacket`] struct. Currently supported
95     /// ether type numbers are:
96     ///
97     /// * `ether_type::IPV4`
98     /// * `ether_type::IPV6`
99     /// * `ether_type::VLAN_TAGGED_FRAME`
100     /// * `ether_type::PROVIDER_BRIDGING`
101     /// * `ether_type::VLAN_DOUBLE_TAGGED_FRAME`
102     ///
103     /// If an unsupported ether type is given the given slice will be set as payload
104     /// and all other fields will be set to `None`.
105     ///
106     /// # Example
107     ///
108     /// Basic usage:
109     ///
110     ///```
111     /// # use etherparse::{Ethernet2Header, PacketBuilder};
112     /// # let builder = PacketBuilder::
113     /// #    ethernet2([1,2,3,4,5,6],     //source mac
114     /// #               [7,8,9,10,11,12]) //destionation mac
115     /// #    .ipv4([192,168,1,1], //source ip
116     /// #          [192,168,1,2], //destination ip
117     /// #          20)            //time to life
118     /// #    .udp(21,    //source port
119     /// #         1234); //desitnation port
120     /// # // payload of the udp packet
121     /// # let payload = [1,2,3,4,5,6,7,8];
122     /// # // get some memory to store the serialized data
123     /// # let mut complete_packet = Vec::<u8>::with_capacity(
124     /// #     builder.size(payload.len())
125     /// # );
126     /// # builder.write(&mut complete_packet, &payload).unwrap();
127     /// #
128     /// # // skip ethernet 2 header so we can parse from there downwards
129     /// # let packet = &complete_packet[Ethernet2Header::LEN..];
130     /// #
131     /// use etherparse::{ether_type, LaxSlicedPacket};
132     ///
133     /// let packet = LaxSlicedPacket::from_ether_type(ether_type::IPV4, packet);
134     /// if let Some((stop_err, error_layer)) = packet.stop_err.as_ref() {
135     ///     // in case an error is encountered parsing is stopped
136     ///     println!("Error on layer {}: {:?}", error_layer, stop_err);
137     /// }
138     ///
139     /// // parts that could be parsed without error
140     /// println!("link: {:?}", packet.link);
141     /// println!("vlan: {:?}", packet.vlan);
142     /// println!("net: {:?}", packet.net);
143     /// println!("transport: {:?}", packet.transport);
144     ///
145     /// ```
from_ether_type(ether_type: EtherType, slice: &'a [u8]) -> LaxSlicedPacket<'a>146     pub fn from_ether_type(ether_type: EtherType, slice: &'a [u8]) -> LaxSlicedPacket<'a> {
147         LaxSlicedPacketCursor::parse_from_ether_type(ether_type, slice)
148     }
149 
150     /// Separates a network packet slice into different slices containing
151     /// the headers from the ip header downwards with lax length checks
152     /// and will still return a result even if an error is encountered in
153     /// a layer (except IP).
154     ///
155     /// This function has two main differences to `SlicedPacket::from_ip`:
156     ///
157     /// * Errors encountered bellow the IpHeader will only stop the parsing and
158     ///   return an `Ok` with the successfully parsed parts and the error as optional.
159     ///   Only if an unrecoverable error is encountered in the IP header itself an
160     ///   `Err` is returned.
161     /// * Length in the IP header & UDP headers are allowed to be inconsistent with the
162     ///   given slice length (e.g. data is missing from the slice). In this case it falls
163     ///   back to the length of slice. See [`LaxIpSlice::from_slice`] for a detailed
164     ///   description of when the slice length is used as a fallback.
165     ///
166     /// The result is returned as a [`SlicedPacket`] struct. This function
167     /// assumes the given data starts with an IPv4 or IPv6 header.
168     ///
169     /// # Examples
170     ///
171     /// Basic usage:
172     ///
173     ///```
174     /// # use etherparse::{PacketBuilder, IpSlice, LenSource};
175     /// # let builder = PacketBuilder::
176     /// #    ipv4([192,168,1,1], //source ip
177     /// #         [192,168,1,2], //destination ip
178     /// #         20)            //time to life
179     /// #    .udp(21,    //source port
180     /// #         1234); //desitnation port
181     /// #    //payload of the udp packet
182     /// #    let payload = [1,2,3,4,5,6,7,8];
183     /// #    //get some memory to store the serialized data
184     /// #    let mut packet = Vec::<u8>::with_capacity(
185     /// #                            builder.size(payload.len()));
186     /// #    builder.write(&mut packet, &payload).unwrap();
187     /// use etherparse::LaxSlicedPacket;
188     ///
189     /// match LaxSlicedPacket::from_ip(&packet) {
190     ///     Err(value) => {
191     ///         // An error is returned in case the ip header could
192     ///         // not parsed (other errors are stored in the "stop_err" field)
193     ///         println!("Err {:?}", value)
194     ///     },
195     ///     Ok(value) => {
196     ///         if let Some((stop_err, error_layer)) = value.stop_err.as_ref() {
197     ///             // error is encountered after the ip header (stops parsing)
198     ///             println!("Error on layer {}: {:?}", error_layer, stop_err);
199     ///         }
200     ///
201     ///         // link & vlan fields are empty when parsing from ip downwards
202     ///         assert_eq!(None, value.link);
203     ///         assert_eq!(None, value.vlan);
204     ///
205     ///         // net (ip) & transport (udp or tcp)
206     ///         println!("net: {:?}", value.net);
207     ///         if let Some(ip_payload) = value.net.as_ref().map(|net| net.ip_payload_ref()).flatten() {
208     ///             // the ip payload len_source field can be used to check
209     ///             // if the slice length was used as a fallback value
210     ///             if ip_payload.len_source == LenSource::Slice {
211     ///                 println!("  Used slice length as fallback to identify the IP payload");
212     ///             } else {
213     ///                 println!("  IP payload could correctly be identfied via the length field in the header");
214     ///             }
215     ///         }
216     ///         println!("transport: {:?}", value.transport);
217     ///     }
218     /// }
219     /// ```
from_ip(slice: &'a [u8]) -> Result<LaxSlicedPacket<'a>, err::ip::LaxHeaderSliceError>220     pub fn from_ip(slice: &'a [u8]) -> Result<LaxSlicedPacket<'a>, err::ip::LaxHeaderSliceError> {
221         LaxSlicedPacketCursor::parse_from_ip(slice)
222     }
223 
224     /// Returns the last ether payload of the packet (if one is present).
225     ///
226     /// If VLAN header is present the payload after the most inner VLAN
227     /// header is returned and if there is no VLAN header is present in the
228     /// link field is returned.
ether_payload(&self) -> Option<EtherPayloadSlice<'a>>229     pub fn ether_payload(&self) -> Option<EtherPayloadSlice<'a>> {
230         if let Some(vlan) = self.vlan.as_ref() {
231             match vlan {
232                 VlanSlice::SingleVlan(s) => Some(s.payload()),
233                 VlanSlice::DoubleVlan(s) => Some(s.payload()),
234             }
235         } else if let Some(link) = self.link.as_ref() {
236             match link {
237                 LinkSlice::Ethernet2(e) => Some(e.payload()),
238                 LinkSlice::LinuxSll(e) => match e.protocol_type() {
239                     LinuxSllProtocolType::EtherType(_)
240                     | LinuxSllProtocolType::LinuxNonstandardEtherType(_) => {
241                         Some(EtherPayloadSlice::try_from(e.payload()).ok()?)
242                     }
243                     _ => None,
244                 },
245                 LinkSlice::EtherPayload(e) => Some(e.clone()),
246                 LinkSlice::LinuxSllPayload(e) => match e.protocol_type {
247                     LinuxSllProtocolType::EtherType(_)
248                     | LinuxSllProtocolType::LinuxNonstandardEtherType(_) => {
249                         Some(EtherPayloadSlice::try_from(e.clone()).ok()?)
250                     }
251                     _ => None,
252                 },
253             }
254         } else {
255             None
256         }
257     }
258 
259     /// Return the IP payload after the the IP header and the IP extension
260     /// headers (if one is present).
ip_payload(&self) -> Option<&LaxIpPayloadSlice<'a>>261     pub fn ip_payload(&self) -> Option<&LaxIpPayloadSlice<'a>> {
262         if let Some(net) = self.net.as_ref() {
263             use LaxNetSlice::*;
264             match net {
265                 Ipv4(v) => Some(v.payload()),
266                 Ipv6(v) => Some(v.payload()),
267             }
268         } else {
269             None
270         }
271     }
272 }
273 
274 #[cfg(test)]
275 mod test {
276     use super::*;
277     use crate::err::{packet::SliceError, LenError};
278     use crate::test_packet::TestPacket;
279 
280     const VLAN_ETHER_TYPES: [EtherType; 3] = [
281         ether_type::VLAN_TAGGED_FRAME,
282         ether_type::PROVIDER_BRIDGING,
283         ether_type::VLAN_DOUBLE_TAGGED_FRAME,
284     ];
285 
286     #[test]
clone_eq()287     fn clone_eq() {
288         let header = LaxSlicedPacket {
289             link: None,
290             vlan: None,
291             net: None,
292             transport: None,
293             stop_err: None,
294         };
295         assert_eq!(header.clone(), header);
296     }
297 
298     #[test]
debug()299     fn debug() {
300         use alloc::format;
301         let header = LaxSlicedPacket {
302             link: None,
303             vlan: None,
304             net: None,
305             transport: None,
306             stop_err: None,
307         };
308         assert_eq!(
309             format!("{:?}", header),
310             format!(
311                 "LaxSlicedPacket {{ link: {:?}, vlan: {:?}, net: {:?}, transport: {:?}, stop_err: {:?} }}",
312                 header.link, header.vlan, header.net, header.transport, header.stop_err
313             )
314         );
315     }
316 
317     #[test]
ether_payload()318     fn ether_payload() {
319         use alloc::vec::*;
320 
321         // no content
322         assert_eq!(
323             LaxSlicedPacket {
324                 link: None,
325                 vlan: None,
326                 net: None,
327                 transport: None,
328                 stop_err: None
329             }
330             .ether_payload(),
331             None
332         );
333 
334         // only ethernet header II
335         {
336             let payload = [1, 2, 3, 4];
337             let mut buf = Vec::with_capacity(Ethernet2Header::LEN + 4);
338             buf.extend_from_slice(
339                 &Ethernet2Header {
340                     ether_type: EtherType::WAKE_ON_LAN,
341                     ..Default::default()
342                 }
343                 .to_bytes(),
344             );
345             buf.extend_from_slice(&payload);
346             assert_eq!(
347                 LaxSlicedPacket::from_ethernet(&buf)
348                     .unwrap()
349                     .ether_payload(),
350                 Some(EtherPayloadSlice {
351                     ether_type: EtherType::WAKE_ON_LAN,
352                     payload: &payload
353                 })
354             );
355         }
356 
357         // ether type payload
358         {
359             let payload = [1, 2, 3, 4];
360             assert_eq!(
361                 LaxSlicedPacket {
362                     link: Some(LinkSlice::EtherPayload(EtherPayloadSlice {
363                         ether_type: EtherType::WAKE_ON_LAN,
364                         payload: &payload
365                     })),
366                     vlan: None,
367                     net: None,
368                     transport: None,
369                     stop_err: None,
370                 }
371                 .ether_payload(),
372                 Some(EtherPayloadSlice {
373                     ether_type: EtherType::WAKE_ON_LAN,
374                     payload: &payload
375                 })
376             );
377         }
378 
379         // single vlan header
380         {
381             let payload = [1, 2, 3, 4];
382             let mut buf = Vec::with_capacity(Ethernet2Header::LEN + SingleVlanHeader::LEN + 4);
383             buf.extend_from_slice(
384                 &Ethernet2Header {
385                     ether_type: EtherType::VLAN_TAGGED_FRAME,
386                     ..Default::default()
387                 }
388                 .to_bytes(),
389             );
390             buf.extend_from_slice(
391                 &SingleVlanHeader {
392                     ether_type: EtherType::WAKE_ON_LAN,
393                     ..Default::default()
394                 }
395                 .to_bytes(),
396             );
397             buf.extend_from_slice(&payload);
398             assert_eq!(
399                 LaxSlicedPacket::from_ethernet(&buf)
400                     .unwrap()
401                     .ether_payload(),
402                 Some(EtherPayloadSlice {
403                     ether_type: EtherType::WAKE_ON_LAN,
404                     payload: &payload
405                 })
406             );
407         }
408 
409         // double vlan header
410         {
411             let payload = [1, 2, 3, 4];
412             let mut buf = Vec::with_capacity(Ethernet2Header::LEN + SingleVlanHeader::LEN * 2 + 4);
413             buf.extend_from_slice(
414                 &Ethernet2Header {
415                     ether_type: EtherType::VLAN_DOUBLE_TAGGED_FRAME,
416                     ..Default::default()
417                 }
418                 .to_bytes(),
419             );
420             buf.extend_from_slice(
421                 &SingleVlanHeader {
422                     ether_type: EtherType::VLAN_TAGGED_FRAME,
423                     ..Default::default()
424                 }
425                 .to_bytes(),
426             );
427             buf.extend_from_slice(
428                 &SingleVlanHeader {
429                     ether_type: EtherType::WAKE_ON_LAN,
430                     ..Default::default()
431                 }
432                 .to_bytes(),
433             );
434             buf.extend_from_slice(&payload);
435             assert_eq!(
436                 LaxSlicedPacket::from_ethernet(&buf)
437                     .unwrap()
438                     .ether_payload(),
439                 Some(EtherPayloadSlice {
440                     ether_type: EtherType::WAKE_ON_LAN,
441                     payload: &payload
442                 })
443             );
444         }
445     }
446 
447     #[test]
ip_payload()448     fn ip_payload() {
449         use alloc::vec::*;
450 
451         // no content
452         assert_eq!(
453             LaxSlicedPacket {
454                 link: None,
455                 vlan: None,
456                 net: None,
457                 transport: None,
458                 stop_err: None,
459             }
460             .ip_payload(),
461             None
462         );
463 
464         // ipv4
465         {
466             let payload = [1, 2, 3, 4];
467             let mut buf = Vec::with_capacity(Ipv4Header::MIN_LEN + 4);
468             buf.extend_from_slice(
469                 &Ipv4Header {
470                     protocol: IpNumber::ARIS,
471                     total_len: Ipv4Header::MIN_LEN_U16 + 4,
472                     ..Default::default()
473                 }
474                 .to_bytes(),
475             );
476             buf.extend_from_slice(&payload);
477             assert_eq!(
478                 LaxSlicedPacket::from_ip(&buf).unwrap().ip_payload(),
479                 Some(&LaxIpPayloadSlice {
480                     payload: &payload,
481                     ip_number: IpNumber::ARIS,
482                     fragmented: false,
483                     len_source: LenSource::Ipv4HeaderTotalLen,
484                     incomplete: false,
485                 })
486             );
487         }
488 
489         // ipv6
490         {
491             let payload = [1, 2, 3, 4];
492             let mut buf = Vec::with_capacity(Ipv6Header::LEN + 4);
493             buf.extend_from_slice(
494                 &Ipv6Header {
495                     payload_length: 4,
496                     next_header: IpNumber::ARGUS,
497                     ..Default::default()
498                 }
499                 .to_bytes(),
500             );
501             buf.extend_from_slice(&payload);
502             assert_eq!(
503                 LaxSlicedPacket::from_ip(&buf).unwrap().ip_payload(),
504                 Some(&LaxIpPayloadSlice {
505                     payload: &payload,
506                     ip_number: IpNumber::ARGUS,
507                     fragmented: false,
508                     len_source: LenSource::Ipv6HeaderPayloadLen,
509                     incomplete: false,
510                 })
511             );
512         }
513     }
514 
515     #[test]
from_x_slice()516     fn from_x_slice() {
517         // no eth
518         from_x_slice_vlan_variants(&TestPacket {
519             link: None,
520             vlan: None,
521             net: None,
522             transport: None,
523         });
524 
525         // eth
526         {
527             let eth = Ethernet2Header {
528                 source: [1, 2, 3, 4, 5, 6],
529                 destination: [1, 2, 3, 4, 5, 6],
530                 ether_type: 0.into(),
531             };
532             let test = TestPacket {
533                 link: Some(LinkHeader::Ethernet2(eth.clone())),
534                 vlan: None,
535                 net: None,
536                 transport: None,
537             };
538 
539             // ok ethernet header (with unknown next)
540             from_x_slice_vlan_variants(&test);
541 
542             // eth len error
543             {
544                 let data = test.to_vec(&[]);
545                 for len in 0..data.len() {
546                     assert_test_result(&test, &[], &data[..len], None, None);
547                 }
548             }
549         }
550 
551         // unknown ether_type
552         {
553             let payload = [1, 2, 3, 4];
554             let actual = LaxSlicedPacket::from_ether_type(0.into(), &payload);
555             assert_eq!(
556                 actual.link,
557                 Some(LinkSlice::EtherPayload(EtherPayloadSlice {
558                     ether_type: 0.into(),
559                     payload: &payload
560                 }))
561             );
562             assert_eq!(None, actual.vlan);
563             assert_eq!(None, actual.net);
564             assert_eq!(None, actual.transport);
565             assert_eq!(None, actual.stop_err);
566         }
567     }
568 
from_x_slice_vlan_variants(base: &TestPacket)569     fn from_x_slice_vlan_variants(base: &TestPacket) {
570         // none
571         from_x_slice_ip_variants(base);
572 
573         // single vlan header
574         {
575             let single = SingleVlanHeader {
576                 pcp: 1.try_into().unwrap(),
577                 drop_eligible_indicator: false,
578                 vlan_id: 2.try_into().unwrap(),
579                 ether_type: 3.into(),
580             };
581 
582             for vlan_ether_type in VLAN_ETHER_TYPES {
583                 let mut test = base.clone();
584                 test.set_ether_type(vlan_ether_type);
585                 test.vlan = Some(VlanHeader::Single(single.clone()));
586 
587                 // ok vlan header
588                 from_x_slice_ip_variants(&test);
589 
590                 // len error
591                 {
592                     let data = test.to_vec(&[]);
593                     for len in 0..single.header_len() {
594                         let base_len = test.len(&[]) - single.header_len();
595 
596                         let err = LenError {
597                             required_len: single.header_len(),
598                             len,
599                             len_source: LenSource::Slice,
600                             layer: Layer::VlanHeader,
601                             layer_start_offset: base_len,
602                         };
603                         assert_test_result(
604                             &test,
605                             &[],
606                             &data[..base_len + len],
607                             None,
608                             Some((SliceError::Len(err.clone()), Layer::VlanHeader)),
609                         );
610                     }
611                 }
612             }
613         }
614 
615         // double vlan header
616         for outer_vlan_ether_type in VLAN_ETHER_TYPES {
617             for inner_vlan_ether_type in VLAN_ETHER_TYPES {
618                 let double = DoubleVlanHeader {
619                     outer: SingleVlanHeader {
620                         pcp: 1.try_into().unwrap(),
621                         drop_eligible_indicator: false,
622                         vlan_id: 2.try_into().unwrap(),
623                         ether_type: inner_vlan_ether_type,
624                     },
625                     inner: SingleVlanHeader {
626                         pcp: 1.try_into().unwrap(),
627                         drop_eligible_indicator: false,
628                         vlan_id: 2.try_into().unwrap(),
629                         ether_type: 3.into(),
630                     },
631                 };
632                 let mut test = base.clone();
633                 test.set_ether_type(outer_vlan_ether_type);
634                 test.vlan = Some(VlanHeader::Double(double.clone()));
635 
636                 // ok double vlan header
637                 from_x_slice_ip_variants(&test);
638 
639                 // len error
640                 {
641                     let data = test.to_vec(&[]);
642                     for len in 0..SingleVlanHeader::LEN {
643                         let base_len = test.len(&[]) - SingleVlanHeader::LEN;
644 
645                         let err = LenError {
646                             required_len: SingleVlanHeader::LEN,
647                             len,
648                             len_source: LenSource::Slice,
649                             layer: Layer::VlanHeader,
650                             layer_start_offset: base_len,
651                         };
652                         assert_test_result(
653                             &test,
654                             &[],
655                             &data[..base_len + len],
656                             None,
657                             Some((SliceError::Len(err.clone()), Layer::VlanHeader)),
658                         );
659                     }
660                 }
661             }
662         }
663     }
664 
from_x_slice_ip_variants(base: &TestPacket)665     fn from_x_slice_ip_variants(base: &TestPacket) {
666         // none
667         from_x_slice_transport_variants(base);
668 
669         // ipv4
670         for fragmented in [false, true] {
671             let ipv4 = {
672                 let mut ipv4 =
673                     Ipv4Header::new(0, 1, 2.into(), [3, 4, 5, 6], [7, 8, 9, 10]).unwrap();
674                 ipv4.more_fragments = fragmented;
675                 ipv4
676             };
677 
678             {
679                 let mut test = base.clone();
680                 test.set_ether_type(ether_type::IPV4);
681                 test.net = Some(NetHeaders::Ipv4(ipv4.clone(), Default::default()));
682                 test.set_payload_len(0);
683 
684                 // ok ipv4
685                 from_x_slice_transport_variants(&test);
686 
687                 // ipv4 len error
688                 {
689                     let data = test.to_vec(&[]);
690                     for len in 0..ipv4.header_len() {
691                         let base_len = test.len(&[]) - ipv4.header_len();
692 
693                         let err = LenError {
694                             required_len: if len < 1 { 1 } else { ipv4.header_len() },
695                             len,
696                             len_source: LenSource::Slice,
697                             layer: if len < 1 {
698                                 Layer::IpHeader
699                             } else {
700                                 Layer::Ipv4Header
701                             },
702                             layer_start_offset: base_len,
703                         };
704 
705                         assert_test_result(
706                             &test,
707                             &[],
708                             &data[..base_len + len],
709                             Some(err::ip::LaxHeaderSliceError::Len(err.clone())),
710                             Some((SliceError::Len(err.clone()), Layer::IpHeader)),
711                         );
712                     }
713                 }
714 
715                 // ipv4 content error (ihl length too small)
716                 {
717                     use err::ip::HeaderError::*;
718 
719                     let mut data = test.to_vec(&[]);
720                     let ipv4_offset = data.len() - ipv4.header_len();
721 
722                     // set the ihl to 0 to trigger a content error
723                     data[ipv4_offset] = 0b1111_0000 & data[ipv4_offset];
724 
725                     assert_test_result(
726                         &test,
727                         &[],
728                         &data,
729                         Some(err::ip::LaxHeaderSliceError::Content(
730                             Ipv4HeaderLengthSmallerThanHeader { ihl: 0 },
731                         )),
732                         Some((
733                             SliceError::Ip(Ipv4HeaderLengthSmallerThanHeader { ihl: 0 }),
734                             Layer::IpHeader,
735                         )),
736                     );
737                 }
738 
739                 // ipv 4total length too small (does not change the output)
740                 {
741                     let mut data = test.to_vec(&[]);
742                     let ipv4_offset = data.len() - ipv4.header_len();
743 
744                     // set the total length to 0 to trigger a content error
745                     data[ipv4_offset + 2] = 0;
746                     data[ipv4_offset + 3] = 0;
747 
748                     let mut mod_test = test.clone();
749                     mod_test.net = Some({
750                         let (h, e) = test.net.as_ref().map(|v| v.ipv4_ref()).flatten().unwrap();
751                         let mut ipv4 = h.clone();
752                         ipv4.total_len = 0;
753                         NetHeaders::Ipv4(ipv4, e.clone())
754                     });
755 
756                     assert_test_result(&mod_test, &[], &data, None, None);
757                 }
758             }
759 
760             // ipv4 extension content error
761             {
762                 let auth = IpAuthHeader::new(0.into(), 1, 2, &[]).unwrap();
763 
764                 let mut test = base.clone();
765                 test.set_ether_type(ether_type::IPV4);
766                 test.net = Some(NetHeaders::Ipv4(
767                     {
768                         let mut ipv4 = ipv4.clone();
769                         ipv4.protocol = ip_number::AUTH;
770                         ipv4
771                     },
772                     Ipv4Extensions {
773                         auth: Some(auth.clone()),
774                     },
775                 ));
776                 test.set_payload_len(0);
777 
778                 // ok ipv4 & extension
779                 from_x_slice_transport_variants(&test);
780 
781                 // ipv4 extension len error
782                 for len in 0..auth.header_len() {
783                     // set payload length
784                     let mut test = test.clone();
785                     test.set_payload_le_from_ip_on(
786                         -1 * (auth.header_len() as isize) + (len as isize),
787                     );
788 
789                     let data = test.to_vec(&[]);
790                     let base_len = test.len(&[]) - auth.header_len();
791 
792                     let err = LenError {
793                         required_len: auth.header_len(),
794                         len,
795                         len_source: LenSource::Ipv4HeaderTotalLen,
796                         layer: Layer::IpAuthHeader,
797                         layer_start_offset: base_len,
798                     };
799 
800                     assert_test_result(
801                         &test,
802                         &[],
803                         &data,
804                         None,
805                         Some((SliceError::Len(err.clone()), Layer::IpAuthHeader)),
806                     );
807                 }
808 
809                 // ipv4 extension content error
810                 {
811                     let mut data = test.to_vec(&[]);
812                     let auth_offset = data.len() - auth.header_len();
813 
814                     // set the icv len too smaller then allowed
815                     data[auth_offset + 1] = 0;
816 
817                     // expect an error
818                     assert_test_result(
819                         &test,
820                         &[],
821                         &data,
822                         None,
823                         Some((
824                             SliceError::Ipv4Exts(err::ip_auth::HeaderError::ZeroPayloadLen),
825                             Layer::IpAuthHeader,
826                         )),
827                     );
828                 }
829             }
830         }
831 
832         // ipv6
833         {
834             let ipv6 = Ipv6Header {
835                 traffic_class: 0,
836                 flow_label: 1.try_into().unwrap(),
837                 payload_length: 2,
838                 next_header: 3.into(),
839                 hop_limit: 4,
840                 source: [0; 16],
841                 destination: [0; 16],
842             };
843 
844             // ipv6 header only
845             {
846                 let mut test = base.clone();
847                 test.set_ether_type(ether_type::IPV6);
848                 test.net = Some(NetHeaders::Ipv6(ipv6.clone(), Default::default()));
849                 test.set_payload_len(0);
850 
851                 // ok ipv6
852                 from_x_slice_transport_variants(&test);
853 
854                 // header len ipv6
855                 {
856                     let data = test.to_vec(&[]);
857                     for len in 0..ipv6.header_len() {
858                         let base_len = test.len(&[]) - ipv6.header_len();
859 
860                         let err = err::LenError {
861                             required_len: if len < 1 { 1 } else { ipv6.header_len() },
862                             len,
863                             len_source: LenSource::Slice,
864                             layer: if len < 1 {
865                                 Layer::IpHeader
866                             } else {
867                                 Layer::Ipv6Header
868                             },
869                             layer_start_offset: base_len,
870                         };
871 
872                         assert_test_result(
873                             &test,
874                             &[],
875                             &data[..base_len + len],
876                             Some(err::ip::LaxHeaderSliceError::Len(err.clone())),
877                             Some((
878                                 SliceError::Len({
879                                     if len < 1 {
880                                         let mut err = err.clone();
881                                         err.required_len = 1;
882                                         err.layer = Layer::IpHeader;
883                                         err
884                                     } else {
885                                         err.clone()
886                                     }
887                                 }),
888                                 Layer::IpHeader,
889                             )),
890                         );
891                     }
892                 }
893 
894                 // content error ipv6
895                 {
896                     use err::ip::{HeaderError::*, LaxHeaderSliceError::Content};
897 
898                     let mut data = test.to_vec(&[]);
899 
900                     // inject an invalid ip version
901                     let base_len = data.len() - ipv6.header_len();
902                     data[base_len] = data[base_len] & 0b0000_1111;
903 
904                     assert_test_result(
905                         &test,
906                         &[],
907                         &data,
908                         Some(Content(UnsupportedIpVersion { version_number: 0 })),
909                         Some((
910                             SliceError::Ip(UnsupportedIpVersion { version_number: 0 }),
911                             Layer::IpHeader,
912                         )),
913                     );
914                 }
915             }
916 
917             // ipv6 + extension
918             for fragment in [false, true] {
919                 let auth = IpAuthHeader::new(ip_number::GGP, 1, 2, &[]).unwrap();
920                 let frag = Ipv6FragmentHeader {
921                     next_header: ip_number::AUTH,
922                     fragment_offset: 0.try_into().unwrap(),
923                     more_fragments: fragment,
924                     identification: 3,
925                 };
926 
927                 let mut test = base.clone();
928                 test.set_ether_type(ether_type::IPV6);
929                 test.net = Some(NetHeaders::Ipv6(
930                     {
931                         let mut ipv6 = ipv6.clone();
932                         ipv6.next_header = ip_number::IPV6_FRAG;
933                         ipv6
934                     },
935                     {
936                         let mut exts: Ipv6Extensions = Default::default();
937                         exts.fragment = Some(frag.clone());
938                         exts.auth = Some(auth.clone());
939                         exts
940                     },
941                 ));
942                 test.set_payload_len(0);
943 
944                 // ok ipv6 & extensions
945                 from_x_slice_transport_variants(&test);
946 
947                 // ipv6 extension len error
948                 for len in 0..auth.header_len() {
949                     // set payload length
950                     let mut test = test.clone();
951                     test.set_payload_le_from_ip_on(
952                         -1 * (auth.header_len() as isize) + (len as isize),
953                     );
954 
955                     let data = test.to_vec(&[]);
956                     let base_len = test.len(&[]) - auth.header_len();
957 
958                     let err = LenError {
959                         required_len: auth.header_len(),
960                         len,
961                         len_source: LenSource::Ipv6HeaderPayloadLen,
962                         layer: Layer::IpAuthHeader,
963                         layer_start_offset: base_len,
964                     };
965                     assert_test_result(
966                         &test,
967                         &[],
968                         &data[..base_len + len],
969                         None,
970                         Some((SliceError::Len(err.clone()), Layer::IpAuthHeader)),
971                     );
972                 }
973 
974                 // ipv6 extension content error (auth)
975                 {
976                     let mut data = test.to_vec(&[]);
977                     let auth_offset = data.len() - auth.header_len();
978                     // set the icv len too smaller then allowed
979                     data[auth_offset + 1] = 0;
980 
981                     assert_test_result(
982                         &test,
983                         &[],
984                         &data,
985                         None,
986                         Some((
987                             SliceError::Ipv6Exts(err::ipv6_exts::HeaderError::IpAuth(
988                                 err::ip_auth::HeaderError::ZeroPayloadLen,
989                             )),
990                             Layer::IpAuthHeader,
991                         )),
992                     );
993                 }
994 
995                 // ipv6 extension content error (hop by hop not at start)
996                 {
997                     let mut data = test.to_vec(&[]);
998                     let auth_offset = data.len() - auth.header_len();
999 
1000                     // set the next header to be a hop-by-hop header to trigger a "not at start error"
1001                     data[auth_offset] = 0;
1002 
1003                     assert_test_result(
1004                         &test,
1005                         &[],
1006                         &data,
1007                         None,
1008                         Some((
1009                             SliceError::Ipv6Exts(err::ipv6_exts::HeaderError::HopByHopNotAtStart),
1010                             Layer::Ipv6HopByHopHeader,
1011                         )),
1012                     );
1013                 }
1014             }
1015         }
1016     }
1017 
from_x_slice_transport_variants(base: &TestPacket)1018     fn from_x_slice_transport_variants(base: &TestPacket) {
1019         // none
1020         from_x_slice_assert_ok(base);
1021 
1022         // transport can only be set if ip is present
1023         if let Some(ip) = &base.net {
1024             // udp
1025             {
1026                 let udp = UdpHeader {
1027                     source_port: 1,
1028                     destination_port: 2,
1029                     length: 3,
1030                     checksum: 4,
1031                 };
1032                 let mut test = base.clone();
1033                 test.net = Some({
1034                     let mut ip = match ip {
1035                         NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()),
1036                         NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()),
1037                     };
1038                     ip.set_next_headers(ip_number::UDP);
1039                     ip.into()
1040                 });
1041                 test.transport = Some(TransportHeader::Udp(udp.clone()));
1042                 test.set_payload_len(0);
1043 
1044                 // ok decode
1045                 from_x_slice_assert_ok(&test);
1046 
1047                 // length error
1048                 if false == test.is_ip_payload_fragmented() {
1049                     for len in 0..udp.header_len() {
1050                         // build new test packet
1051                         let mut test = test.clone();
1052 
1053                         // set payload length
1054                         test.set_payload_le_from_ip_on(len as isize);
1055 
1056                         // generate data
1057                         let data = test.to_vec(&[]);
1058 
1059                         let base_len = test.len(&[]) - udp.header_len();
1060                         let err = LenError {
1061                             required_len: udp.header_len(),
1062                             len,
1063                             len_source: match test.net.as_ref().unwrap() {
1064                                 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen,
1065                                 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen,
1066                             },
1067                             layer: Layer::UdpHeader,
1068                             layer_start_offset: base_len,
1069                         };
1070                         assert_test_result(
1071                             &test,
1072                             &[],
1073                             &data[..base_len + len],
1074                             None,
1075                             Some((SliceError::Len(err.clone()), Layer::UdpHeader)),
1076                         );
1077                     }
1078                 }
1079             }
1080 
1081             // tcp
1082             {
1083                 let tcp = TcpHeader::new(1, 2, 3, 4);
1084                 let mut test = base.clone();
1085                 test.net = Some({
1086                     let mut ip = match ip {
1087                         NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()),
1088                         NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()),
1089                     };
1090                     ip.set_next_headers(ip_number::TCP);
1091                     ip.into()
1092                 });
1093                 test.transport = Some(TransportHeader::Tcp(tcp.clone()));
1094                 test.set_payload_len(0);
1095 
1096                 // ok decode
1097                 from_x_slice_assert_ok(&test);
1098 
1099                 // error can only occur if ip does not fragment the packet
1100                 if false == test.is_ip_payload_fragmented() {
1101                     // length error
1102                     {
1103                         for len in 0..(tcp.header_len() as usize) {
1104                             // set payload length
1105                             let mut test = test.clone();
1106                             test.set_payload_le_from_ip_on(len as isize);
1107 
1108                             let data = test.to_vec(&[]);
1109                             let base_len = test.len(&[]) - (tcp.header_len() as usize);
1110 
1111                             let err = LenError {
1112                                 required_len: tcp.header_len() as usize,
1113                                 len,
1114                                 len_source: match test.net.as_ref().unwrap() {
1115                                     NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen,
1116                                     NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen,
1117                                 },
1118                                 layer: Layer::TcpHeader,
1119                                 layer_start_offset: base_len,
1120                             };
1121                             assert_test_result(
1122                                 &test,
1123                                 &[],
1124                                 &data[..base_len + len],
1125                                 None,
1126                                 Some((SliceError::Len(err.clone()), Layer::TcpHeader)),
1127                             );
1128                         }
1129                     }
1130 
1131                     // content error
1132                     {
1133                         let mut data = test.to_vec(&[]);
1134                         let base_len = test.len(&[]) - (tcp.header_len() as usize);
1135 
1136                         // set data offset to 0 to trigger an error
1137                         data[base_len + 12] = data[base_len + 12] & 0b0000_1111;
1138 
1139                         let err = err::tcp::HeaderError::DataOffsetTooSmall { data_offset: 0 };
1140                         assert_test_result(
1141                             &test,
1142                             &[],
1143                             &data,
1144                             None,
1145                             Some((SliceError::Tcp(err.clone()), Layer::TcpHeader)),
1146                         );
1147                     }
1148                 }
1149             }
1150 
1151             // icmpv4
1152             {
1153                 let icmpv4 =
1154                     Icmpv4Header::new(Icmpv4Type::EchoReply(IcmpEchoHeader { id: 1, seq: 2 }));
1155                 let mut test = base.clone();
1156                 test.net = Some({
1157                     let mut ip = match ip {
1158                         NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()),
1159                         NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()),
1160                     };
1161                     ip.set_next_headers(ip_number::ICMP);
1162                     ip.into()
1163                 });
1164                 test.transport = Some(TransportHeader::Icmpv4(icmpv4.clone()));
1165                 test.set_payload_len(0);
1166 
1167                 // ok decode
1168                 from_x_slice_assert_ok(&test);
1169 
1170                 // length error
1171                 if false == test.is_ip_payload_fragmented() {
1172                     for len in 0..icmpv4.header_len() {
1173                         // set payload length
1174                         let mut test = test.clone();
1175                         test.set_payload_le_from_ip_on(len as isize);
1176 
1177                         let data = test.to_vec(&[]);
1178                         let base_len = test.len(&[]) - icmpv4.header_len();
1179 
1180                         let err = LenError {
1181                             required_len: icmpv4.header_len(),
1182                             len,
1183                             len_source: match test.net.as_ref().unwrap() {
1184                                 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen,
1185                                 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen,
1186                             },
1187                             layer: Layer::Icmpv4,
1188                             layer_start_offset: base_len,
1189                         };
1190                         assert_test_result(
1191                             &test,
1192                             &[],
1193                             &data[..base_len + len],
1194                             None,
1195                             Some((SliceError::Len(err.clone()), Layer::Icmpv4)),
1196                         );
1197                     }
1198                 }
1199             }
1200 
1201             // icmpv6
1202             {
1203                 let icmpv6 =
1204                     Icmpv6Header::new(Icmpv6Type::EchoReply(IcmpEchoHeader { id: 1, seq: 2 }));
1205                 let mut test = base.clone();
1206                 test.net = Some({
1207                     let mut ip = match ip {
1208                         NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()),
1209                         NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()),
1210                     };
1211                     ip.set_next_headers(ip_number::IPV6_ICMP);
1212                     ip.into()
1213                 });
1214                 test.transport = Some(TransportHeader::Icmpv6(icmpv6.clone()));
1215                 test.set_payload_len(0);
1216 
1217                 // ok decode
1218                 from_x_slice_assert_ok(&test);
1219 
1220                 // length error
1221                 if false == test.is_ip_payload_fragmented() {
1222                     for len in 0..icmpv6.header_len() {
1223                         // set payload length
1224                         let mut test = test.clone();
1225                         test.set_payload_le_from_ip_on(len as isize);
1226 
1227                         let data = test.to_vec(&[]);
1228                         let base_len = test.len(&[]) - icmpv6.header_len();
1229 
1230                         let err = LenError {
1231                             required_len: icmpv6.header_len(),
1232                             len,
1233                             len_source: match test.net.as_ref().unwrap() {
1234                                 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen,
1235                                 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen,
1236                             },
1237                             layer: Layer::Icmpv6,
1238                             layer_start_offset: base_len,
1239                         };
1240                         assert_test_result(
1241                             &test,
1242                             &[],
1243                             &data[..base_len + len],
1244                             None,
1245                             Some((SliceError::Len(err.clone()), Layer::Icmpv6)),
1246                         );
1247                     }
1248                 }
1249             }
1250         }
1251     }
1252 
from_x_slice_assert_ok(test_base: &TestPacket)1253     fn from_x_slice_assert_ok(test_base: &TestPacket) {
1254         // setup payload
1255         let payload = [1, 2, 3, 4];
1256 
1257         // set length fields in ip headers
1258         let test = {
1259             let mut test = test_base.clone();
1260             test.set_payload_len(payload.len());
1261             test
1262         };
1263 
1264         // write data
1265         let data = test.to_vec(&payload);
1266         assert_test_result(&test, &payload, &data, None, None);
1267     }
1268 
1269     /// Check that the given output & errors (if present) are generated based on the given
1270     /// input.
assert_test_result( test: &TestPacket, expected_payload: &[u8], data: &[u8], expected_ip_err: Option<err::ip::LaxHeaderSliceError>, expected_stop_err: Option<(SliceError, Layer)>, )1271     fn assert_test_result(
1272         test: &TestPacket,
1273         expected_payload: &[u8],
1274         data: &[u8],
1275         expected_ip_err: Option<err::ip::LaxHeaderSliceError>,
1276         expected_stop_err: Option<(SliceError, Layer)>,
1277     ) {
1278         fn compare_vlan(test: &TestPacket, data: &[u8], actual: &LaxSlicedPacket) {
1279             let vlan_offset = if let Some(e) = test.link.as_ref() {
1280                 e.header_len()
1281             } else {
1282                 0
1283             };
1284             match test.vlan.as_ref() {
1285                 Some(VlanHeader::Double(d)) => {
1286                     if data.len() >= vlan_offset + DoubleVlanHeader::LEN {
1287                         assert_eq!(test.vlan, actual.vlan.as_ref().map(|v| v.to_header()));
1288                     } else if data.len() >= vlan_offset + SingleVlanHeader::LEN {
1289                         assert_eq!(
1290                             Some(VlanHeader::Single(d.outer.clone())),
1291                             actual.vlan.as_ref().map(|v| v.to_header())
1292                         );
1293                     } else {
1294                         assert_eq!(None, actual.vlan);
1295                     }
1296                 }
1297                 Some(VlanHeader::Single(s)) => {
1298                     if data.len() >= vlan_offset + SingleVlanHeader::LEN {
1299                         assert_eq!(
1300                             Some(VlanHeader::Single(s.clone())),
1301                             actual.vlan.as_ref().map(|v| v.to_header())
1302                         );
1303                     } else {
1304                         assert_eq!(None, actual.vlan);
1305                     }
1306                 }
1307                 None => {
1308                     assert_eq!(None, actual.vlan);
1309                 }
1310             }
1311         }
1312 
1313         fn compare_ip(test: &TestPacket, actual: &LaxSlicedPacket) {
1314             assert_eq!(
1315                 test.net,
1316                 actual.net.as_ref().map(|s| -> NetHeaders {
1317                     match s {
1318                         LaxNetSlice::Ipv4(ipv4) => NetHeaders::Ipv4(
1319                             ipv4.header().to_header(),
1320                             ipv4.extensions().to_header(),
1321                         ),
1322                         LaxNetSlice::Ipv6(ipv6) => NetHeaders::Ipv6(
1323                             ipv6.header().to_header(),
1324                             Ipv6Extensions::from_slice(
1325                                 ipv6.header().next_header(),
1326                                 ipv6.extensions().slice(),
1327                             )
1328                             .unwrap()
1329                             .0,
1330                         ),
1331                     }
1332                 })
1333             );
1334         }
1335 
1336         fn compare_ip_header_only(test: &TestPacket, actual: &LaxSlicedPacket) {
1337             assert_eq!(
1338                 test.net.as_ref().map(|s| -> NetHeaders {
1339                     match s {
1340                         NetHeaders::Ipv4(h, _) => NetHeaders::Ipv4(h.clone(), Default::default()),
1341                         NetHeaders::Ipv6(h, _) => NetHeaders::Ipv6(h.clone(), Default::default()),
1342                     }
1343                 }),
1344                 actual.net.as_ref().map(|s| -> NetHeaders {
1345                     match s {
1346                         LaxNetSlice::Ipv4(ipv4) => {
1347                             NetHeaders::Ipv4(ipv4.header().to_header(), Default::default())
1348                         }
1349                         LaxNetSlice::Ipv6(ipv6) => {
1350                             NetHeaders::Ipv6(ipv6.header().to_header(), Default::default())
1351                         }
1352                     }
1353                 })
1354             );
1355         }
1356 
1357         fn compare_transport(
1358             test: &TestPacket,
1359             is_fragmented: bool,
1360             expected_payload: &[u8],
1361             actual: &LaxSlicedPacket,
1362         ) {
1363             if is_fragmented {
1364                 assert_eq!(actual.transport, None);
1365             } else {
1366                 use TransportHeader as H;
1367                 use TransportSlice as S;
1368                 match &actual.transport {
1369                     Some(S::Icmpv4(icmpv4)) => {
1370                         assert_eq!(&test.transport, &Some(H::Icmpv4(icmpv4.header())));
1371                         assert_eq!(icmpv4.payload(), expected_payload);
1372                     }
1373                     Some(S::Icmpv6(icmpv6)) => {
1374                         assert_eq!(&test.transport, &Some(H::Icmpv6(icmpv6.header())));
1375                         assert_eq!(icmpv6.payload(), expected_payload);
1376                     }
1377                     Some(S::Udp(s)) => {
1378                         assert_eq!(&test.transport, &Some(H::Udp(s.to_header())));
1379                     }
1380                     Some(S::Tcp(s)) => {
1381                         assert_eq!(&test.transport, &Some(H::Tcp(s.to_header())));
1382                     }
1383                     None => {
1384                         assert_eq!(&test.transport, &None);
1385                     }
1386                 }
1387             }
1388         }
1389 
1390         // from_ethernet_slice
1391         if test.link.is_some() {
1392             if data.len() < Ethernet2Header::LEN {
1393                 assert_eq!(
1394                     LenError {
1395                         required_len: Ethernet2Header::LEN,
1396                         len: data.len(),
1397                         len_source: LenSource::Slice,
1398                         layer: Layer::Ethernet2Header,
1399                         layer_start_offset: 0
1400                     },
1401                     LaxSlicedPacket::from_ethernet(&data).unwrap_err()
1402                 );
1403             } else {
1404                 let actual = LaxSlicedPacket::from_ethernet(&data).unwrap();
1405                 assert_eq!(actual.stop_err, expected_stop_err);
1406                 match expected_stop_err.as_ref().map(|v| v.1) {
1407                     None => {
1408                         assert_eq!(
1409                             test.link,
1410                             actual.link.as_ref().map(|v| v.to_header()).flatten()
1411                         );
1412                         compare_vlan(test, data, &actual);
1413                         compare_ip(test, &actual);
1414                         compare_transport(
1415                             test,
1416                             test.is_ip_payload_fragmented(),
1417                             expected_payload,
1418                             &actual,
1419                         );
1420                     }
1421                     Some(Layer::VlanHeader) => {
1422                         assert_eq!(
1423                             test.link,
1424                             actual.link.as_ref().map(|v| v.to_header()).flatten()
1425                         );
1426                         compare_vlan(test, data, &actual);
1427                         assert_eq!(None, actual.net);
1428                         assert_eq!(None, actual.transport);
1429                     }
1430                     Some(Layer::Ipv6Header) | Some(Layer::Ipv4Header) | Some(Layer::IpHeader) => {
1431                         assert_eq!(
1432                             test.link,
1433                             actual.link.as_ref().map(|v| v.to_header()).flatten()
1434                         );
1435                         compare_vlan(test, data, &actual);
1436                         assert_eq!(None, actual.net);
1437                         assert_eq!(None, actual.transport);
1438                     }
1439                     Some(Layer::IpAuthHeader)
1440                     | Some(Layer::Ipv6ExtHeader)
1441                     | Some(Layer::Ipv6HopByHopHeader)
1442                     | Some(Layer::Ipv6DestOptionsHeader)
1443                     | Some(Layer::Ipv6RouteHeader)
1444                     | Some(Layer::Ipv6FragHeader) => {
1445                         assert_eq!(
1446                             test.link,
1447                             actual.link.as_ref().map(|v| v.to_header()).flatten()
1448                         );
1449                         compare_vlan(test, data, &actual);
1450                         compare_ip_header_only(test, &actual);
1451                         assert_eq!(None, actual.transport);
1452                     }
1453                     Some(Layer::TcpHeader)
1454                     | Some(Layer::UdpHeader)
1455                     | Some(Layer::Icmpv4)
1456                     | Some(Layer::Icmpv6) => {
1457                         assert_eq!(
1458                             test.link,
1459                             actual.link.as_ref().map(|v| v.to_header()).flatten()
1460                         );
1461                         compare_vlan(test, data, &actual);
1462                         compare_ip(test, &actual);
1463                         assert_eq!(None, actual.transport);
1464                     }
1465                     _ => unreachable!("error in an unexpected layer"),
1466                 }
1467             }
1468         }
1469         // from_ether_type (vlan at start)
1470         if test.link.is_none() && test.vlan.is_some() {
1471             for ether_type in VLAN_ETHER_TYPES {
1472                 let actual = LaxSlicedPacket::from_ether_type(ether_type, data);
1473                 assert_eq!(actual.stop_err, expected_stop_err);
1474                 assert_eq!(
1475                     Some(LinkSlice::EtherPayload(EtherPayloadSlice {
1476                         ether_type,
1477                         payload: data
1478                     })),
1479                     actual.link
1480                 );
1481                 compare_vlan(test, data, &actual);
1482                 match expected_stop_err.as_ref().map(|v| v.1) {
1483                     None => {
1484                         compare_ip(test, &actual);
1485                         compare_transport(
1486                             test,
1487                             test.is_ip_payload_fragmented(),
1488                             expected_payload,
1489                             &actual,
1490                         );
1491                     }
1492                     Some(Layer::VlanHeader) => {
1493                         assert_eq!(None, actual.net);
1494                         assert_eq!(None, actual.transport);
1495                     }
1496                     Some(Layer::Ipv6Header) | Some(Layer::Ipv4Header) | Some(Layer::IpHeader) => {
1497                         assert_eq!(None, actual.net);
1498                         assert_eq!(None, actual.transport);
1499                     }
1500                     Some(Layer::IpAuthHeader)
1501                     | Some(Layer::Ipv6ExtHeader)
1502                     | Some(Layer::Ipv6HopByHopHeader)
1503                     | Some(Layer::Ipv6DestOptionsHeader)
1504                     | Some(Layer::Ipv6RouteHeader)
1505                     | Some(Layer::Ipv6FragHeader) => {
1506                         compare_ip_header_only(test, &actual);
1507                         assert_eq!(None, actual.transport);
1508                     }
1509                     Some(Layer::TcpHeader)
1510                     | Some(Layer::UdpHeader)
1511                     | Some(Layer::Icmpv4)
1512                     | Some(Layer::Icmpv6) => {
1513                         compare_ip(test, &actual);
1514                         assert_eq!(None, actual.transport);
1515                     }
1516                     _ => unreachable!("error in an unexpected layer"),
1517                 }
1518             }
1519         }
1520         // from_ether_type (ip at start)
1521         if test.link.is_none() && test.vlan.is_none() {
1522             if let Some(ip) = &test.net {
1523                 let ether_type = match ip {
1524                     NetHeaders::Ipv4(_, _) => ether_type::IPV4,
1525                     NetHeaders::Ipv6(_, _) => ether_type::IPV6,
1526                 };
1527                 let actual = LaxSlicedPacket::from_ether_type(ether_type, &data);
1528                 assert_eq!(actual.stop_err, expected_stop_err);
1529                 assert_eq!(
1530                     Some(LinkSlice::EtherPayload(EtherPayloadSlice {
1531                         ether_type,
1532                         payload: data
1533                     })),
1534                     actual.link
1535                 );
1536                 assert_eq!(test.vlan, None);
1537                 match expected_stop_err.as_ref().map(|v| v.1) {
1538                     None => {
1539                         compare_ip(test, &actual);
1540                         compare_transport(
1541                             test,
1542                             test.is_ip_payload_fragmented(),
1543                             expected_payload,
1544                             &actual,
1545                         );
1546                     }
1547                     Some(Layer::Ipv6Header) | Some(Layer::Ipv4Header) | Some(Layer::IpHeader) => {
1548                         assert_eq!(None, actual.net);
1549                         assert_eq!(None, actual.transport);
1550                     }
1551                     Some(Layer::IpAuthHeader)
1552                     | Some(Layer::Ipv6ExtHeader)
1553                     | Some(Layer::Ipv6HopByHopHeader)
1554                     | Some(Layer::Ipv6DestOptionsHeader)
1555                     | Some(Layer::Ipv6RouteHeader)
1556                     | Some(Layer::Ipv6FragHeader) => {
1557                         compare_ip_header_only(test, &actual);
1558                         assert_eq!(None, actual.transport);
1559                     }
1560                     Some(Layer::TcpHeader)
1561                     | Some(Layer::UdpHeader)
1562                     | Some(Layer::Icmpv4)
1563                     | Some(Layer::Icmpv6) => {
1564                         compare_ip(test, &actual);
1565                         assert_eq!(None, actual.transport);
1566                     }
1567                     _ => unreachable!("error in an unexpected layer"),
1568                 }
1569             }
1570         }
1571         // from_ip_slice
1572         if test.link.is_none() && test.vlan.is_none() && test.net.is_some() {
1573             if let Some(err) = expected_ip_err {
1574                 assert_eq!(err, LaxSlicedPacket::from_ip(&data).unwrap_err());
1575             } else {
1576                 let actual = LaxSlicedPacket::from_ip(&data).unwrap();
1577                 assert_eq!(actual.stop_err, expected_stop_err);
1578                 assert_eq!(actual.link, None);
1579                 assert_eq!(test.vlan, None);
1580                 match expected_stop_err.as_ref().map(|v| v.1) {
1581                     None => {
1582                         compare_ip(test, &actual);
1583                         compare_transport(
1584                             test,
1585                             test.is_ip_payload_fragmented(),
1586                             expected_payload,
1587                             &actual,
1588                         );
1589                     }
1590                     Some(Layer::IpAuthHeader)
1591                     | Some(Layer::Ipv6ExtHeader)
1592                     | Some(Layer::Ipv6HopByHopHeader)
1593                     | Some(Layer::Ipv6DestOptionsHeader)
1594                     | Some(Layer::Ipv6RouteHeader)
1595                     | Some(Layer::Ipv6FragHeader) => {
1596                         compare_ip_header_only(test, &actual);
1597                         assert_eq!(None, actual.transport);
1598                     }
1599                     Some(Layer::TcpHeader)
1600                     | Some(Layer::UdpHeader)
1601                     | Some(Layer::Icmpv4)
1602                     | Some(Layer::Icmpv6) => {
1603                         compare_ip(test, &actual);
1604                         assert_eq!(None, actual.transport);
1605                     }
1606                     _ => unreachable!("error in an unexpected layer"),
1607                 }
1608             }
1609         }
1610     }
1611 }
1612