• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::err::LenError;
2 
3 use super::*;
4 
5 /// Decoded packet headers (data link layer and lower).
6 ///
7 /// You can use
8 ///
9 /// * [`PacketHeaders::from_ethernet_slice`]
10 /// * [`PacketHeaders::from_ether_type`]
11 /// * [`PacketHeaders::from_ip_slice`]
12 ///
13 /// depending on your starting header to parse the headers in a slice and get this
14 /// struct as a result.
15 #[derive(Clone, Debug, Eq, PartialEq)]
16 pub struct PacketHeaders<'a> {
17     /// Ethernet II header if present.
18     pub link: Option<LinkHeader>,
19     /// Single or double vlan headers if present.
20     pub vlan: Option<VlanHeader>,
21     /// IPv4 or IPv6 header and IP extension headers if present.
22     pub net: Option<NetHeaders>,
23     /// TCP or UDP header if present.
24     pub transport: Option<TransportHeader>,
25     /// Payload of the last parsed layer.
26     pub payload: PayloadSlice<'a>,
27 }
28 
29 impl<'a> PacketHeaders<'a> {
30     /// Decodes a network packet into different headers from a slice that starts with an Ethernet II header.
31     ///
32     /// The result is returned as a [`PacketHeaders`] struct.
33     ///
34     /// # Example
35     ///
36     /// Basic usage:
37     ///
38     ///```
39     /// # use etherparse::{Ethernet2Header, PacketBuilder};
40     /// # let builder = PacketBuilder::
41     /// #    ethernet2([1,2,3,4,5,6],     //source mac
42     /// #               [7,8,9,10,11,12]) //destination mac
43     /// #    .ipv4([192,168,1,1], //source ip
44     /// #          [192,168,1,2], //destination ip
45     /// #          20)            //time to life
46     /// #    .udp(21,    //source port
47     /// #         1234); // destination port
48     /// # // payload of the udp packet
49     /// # let payload = [1,2,3,4,5,6,7,8];
50     /// # // get some memory to store the serialized data
51     /// # let mut complete_packet = Vec::<u8>::with_capacity(
52     /// #     builder.size(payload.len())
53     /// # );
54     /// # builder.write(&mut complete_packet, &payload).unwrap();
55     /// #
56     /// # // skip ethernet 2 header so we can parse from there downwards
57     /// # let packet = &complete_packet[Ethernet2Header::LEN..];
58     /// #
59     /// use etherparse::{ether_type, PacketHeaders};
60     ///
61     /// match PacketHeaders::from_ether_type(ether_type::IPV4, packet) {
62     ///     Err(value) => println!("Err {:?}", value),
63     ///     Ok(value) => {
64     ///         println!("link: {:?}", value.link);
65     ///         println!("vlan: {:?}", value.vlan);
66     ///         println!("net: {:?}", value.net);
67     ///         println!("transport: {:?}", value.transport);
68     ///     }
69     /// }
70     /// ```
from_ethernet_slice( slice: &'a [u8], ) -> Result<PacketHeaders<'a>, err::packet::SliceError>71     pub fn from_ethernet_slice(
72         slice: &'a [u8],
73     ) -> Result<PacketHeaders<'a>, err::packet::SliceError> {
74         use err::packet::SliceError::Len;
75 
76         let (ethernet, rest) = Ethernet2Header::from_slice(slice).map_err(Len)?;
77         let mut result = Self::from_ether_type(ethernet.ether_type, rest);
78 
79         match &mut result {
80             // inject ethernet header into the result
81             Ok(result) => result.link = Some(LinkHeader::Ethernet2(ethernet)),
82             // add the ethernet header to the overall offset in case there is a length error
83             Err(Len(err)) => err.layer_start_offset += Ethernet2Header::LEN,
84             _ => {}
85         }
86         result
87     }
88 
89     /// Tries to decode a network packet into different headers using the
90     /// given `ether_type` number to identify the first header.
91     ///
92     /// The result is returned as a [`PacketHeaders`] struct. Currently supported
93     /// ether type numbers are:
94     ///
95     /// * `ether_type::ARP`
96     /// * `ether_type::IPV4`
97     /// * `ether_type::IPV6`
98     /// * `ether_type::VLAN_TAGGED_FRAME`
99     /// * `ether_type::PROVIDER_BRIDGING`
100     /// * `ether_type::VLAN_DOUBLE_TAGGED_FRAME`
101     ///
102     /// If an unsupported ether type is given the given slice will be set as payload
103     /// and all other fields will be set to `None`.
104     ///
105     /// # Example
106     ///
107     /// Basic usage:
108     ///
109     ///```
110     /// # use etherparse::{Ethernet2Header, PacketBuilder};
111     /// # let builder = PacketBuilder::
112     /// #    ethernet2([1,2,3,4,5,6],     //source mac
113     /// #               [7,8,9,10,11,12]) //destination mac
114     /// #    .ipv4([192,168,1,1], //source ip
115     /// #          [192,168,1,2], //destination ip
116     /// #          20)            //time to life
117     /// #    .udp(21,    //source port
118     /// #         1234); // destination port
119     /// # // payload of the udp packet
120     /// # let payload = [1,2,3,4,5,6,7,8];
121     /// # // get some memory to store the serialized data
122     /// # let mut complete_packet = Vec::<u8>::with_capacity(
123     /// #     builder.size(payload.len())
124     /// # );
125     /// # builder.write(&mut complete_packet, &payload).unwrap();
126     /// #
127     /// # // skip ethernet 2 header so we can parse from there downwards
128     /// # let packet = &complete_packet[Ethernet2Header::LEN..];
129     /// #
130     /// use etherparse::{ether_type, PacketHeaders};
131     ///
132     /// match PacketHeaders::from_ether_type(ether_type::IPV4, packet) {
133     ///     Err(value) => println!("Err {:?}", value),
134     ///     Ok(value) => {
135     ///         println!("link: {:?}", value.link);
136     ///         println!("vlan: {:?}", value.vlan);
137     ///         println!("net: {:?}", value.net);
138     ///         println!("transport: {:?}", value.transport);
139     ///     }
140     /// }
141     /// ```
from_ether_type( mut ether_type: EtherType, slice: &'a [u8], ) -> Result<PacketHeaders<'a>, err::packet::SliceError>142     pub fn from_ether_type(
143         mut ether_type: EtherType,
144         slice: &'a [u8],
145     ) -> Result<PacketHeaders<'a>, err::packet::SliceError> {
146         use err::packet::SliceError::*;
147 
148         let mut rest = slice;
149 
150         // helper function to add the current offset to length errors
151         let add_offset = |mut len_error: LenError, rest: &[u8]| -> LenError {
152             len_error.layer_start_offset += unsafe {
153                 // SAFETY: Safe as rest is a subslice of slice.
154                 rest.as_ptr().offset_from(slice.as_ptr()) as usize
155             };
156             len_error
157         };
158 
159         let mut result = PacketHeaders {
160             link: None,
161             vlan: None,
162             net: None,
163             transport: None,
164             payload: PayloadSlice::Ether(EtherPayloadSlice {
165                 ether_type,
166                 payload: rest,
167             }),
168         };
169 
170         use ether_type::*;
171 
172         result.vlan = match ether_type {
173             VLAN_TAGGED_FRAME | PROVIDER_BRIDGING | VLAN_DOUBLE_TAGGED_FRAME => {
174                 use crate::VlanHeader::*;
175                 let (outer, outer_rest) = SingleVlanHeader::from_slice(rest).map_err(Len)?;
176 
177                 //set the rest & ether_type for the following operations
178                 rest = outer_rest;
179                 ether_type = outer.ether_type;
180                 result.payload = PayloadSlice::Ether(EtherPayloadSlice {
181                     ether_type,
182                     payload: rest,
183                 });
184 
185                 //parse second vlan header if present
186                 match ether_type {
187                     //second vlan tagging header
188                     VLAN_TAGGED_FRAME | PROVIDER_BRIDGING | VLAN_DOUBLE_TAGGED_FRAME => {
189                         let (inner, inner_rest) = SingleVlanHeader::from_slice(rest)
190                             .map_err(|err| Len(err.add_offset(SingleVlanHeader::LEN)))?;
191 
192                         //set the rest & ether_type for the following operations
193                         rest = inner_rest;
194                         ether_type = inner.ether_type;
195                         result.payload = PayloadSlice::Ether(EtherPayloadSlice {
196                             ether_type,
197                             payload: rest,
198                         });
199 
200                         Some(Double(DoubleVlanHeader { outer, inner }))
201                     }
202                     //no second vlan header detected -> single vlan header
203                     _ => Some(Single(outer)),
204                 }
205             }
206             //no vlan header
207             _ => None,
208         };
209 
210         // parse ip
211         match ether_type {
212             IPV4 => {
213                 // read ipv4 header & extensions and payload slice
214                 let (ip, ip_payload) = IpHeaders::from_ipv4_slice(rest).map_err(|err| {
215                     use err::ipv4::SliceError as I;
216                     match err {
217                         I::Len(err) => Len(add_offset(err, rest)),
218                         I::Header(err) => Ipv4(err),
219                         I::Exts(err) => Ipv4Exts(err),
220                     }
221                 })?;
222 
223                 // set the next
224                 rest = ip_payload.payload;
225                 result.net = Some(ip.into());
226                 result.payload = PayloadSlice::Ip(ip_payload.clone());
227 
228                 // decode transport layer
229                 let (transport, payload) = read_transport(ip_payload).map_err(|err| {
230                     use err::tcp::HeaderSliceError as I;
231                     match err {
232                         I::Len(err) => Len(add_offset(err, rest)),
233                         I::Content(err) => Tcp(err),
234                     }
235                 })?;
236 
237                 result.transport = transport;
238                 result.payload = payload;
239             }
240             IPV6 => {
241                 // read ipv6 header & extensions and payload slice
242                 let (ip, ip_payload) = IpHeaders::from_ipv6_slice(rest).map_err(|err| {
243                     use err::ipv6::SliceError as I;
244                     match err {
245                         I::Len(err) => Len(add_offset(err, rest)),
246                         I::Header(err) => Ipv6(err),
247                         I::Exts(err) => Ipv6Exts(err),
248                     }
249                 })?;
250 
251                 //set the ip result & rest
252                 rest = ip_payload.payload;
253                 result.net = Some(ip.into());
254                 result.payload = PayloadSlice::Ip(ip_payload.clone());
255 
256                 // decode transport layer
257                 let (transport, payload) = read_transport(ip_payload).map_err(|err| {
258                     use err::tcp::HeaderSliceError as I;
259                     match err {
260                         I::Len(err) => Len(add_offset(err, rest)),
261                         I::Content(err) => Tcp(err),
262                     }
263                 })?;
264 
265                 result.transport = transport;
266                 result.payload = payload;
267             }
268             ARP => {
269                 result.net = Some(NetHeaders::Arp(
270                     ArpPacket::from_slice(rest).map_err(|err| Len(add_offset(err, rest)))?,
271                 ));
272 
273                 result.payload = PayloadSlice::Empty;
274             }
275             _ => {}
276         };
277 
278         Ok(result)
279     }
280 
281     /// Tries to decode an ip packet and its transport headers.
282     ///
283     /// Assumes the given slice starts with the first byte of the IP header.
284     ///
285     /// # Example
286     ///
287     /// Basic usage:
288     ///
289     /// ```
290     /// # use etherparse::PacketBuilder;
291     /// # // build a UDP packet
292     /// # let payload = [0u8;18];
293     /// # let builder = PacketBuilder::
294     /// #    ipv4([192,168,1,1], //source ip
295     /// #         [192,168,1,2], //destination ip
296     /// #         20)            //time to life
297     /// #    .udp(21,    //source port
298     /// #        1234); //  destination port
299     /// #
300     /// # // serialize the packet
301     /// # let packet = {
302     /// #     let mut packet = Vec::<u8>::with_capacity(
303     /// #         builder.size(payload.len())
304     /// #     );
305     /// #     builder.write(&mut packet, &payload).unwrap();
306     /// #     packet
307     /// # };
308     /// use etherparse::PacketHeaders;
309     ///
310     /// match PacketHeaders::from_ip_slice(&packet) {
311     ///     Err(value) => println!("Err {:?}", value),
312     ///     Ok(value) => {
313     ///         println!("link: {:?}", value.link);
314     ///         println!("vlan: {:?}", value.vlan);
315     ///         println!("net: {:?}", value.net);
316     ///         println!("transport: {:?}", value.transport);
317     ///     }
318     /// }
319     /// ```
from_ip_slice(slice: &[u8]) -> Result<PacketHeaders, err::packet::SliceError>320     pub fn from_ip_slice(slice: &[u8]) -> Result<PacketHeaders, err::packet::SliceError> {
321         use err::packet::SliceError::*;
322 
323         // read ip headers
324         let (ip_header, ip_payload) = IpHeaders::from_slice(slice).map_err(|err| {
325             use err::ip::HeadersSliceError as I;
326             match err {
327                 I::Len(err) => Len(err),
328                 I::Content(err) => match err {
329                     err::ip::HeadersError::Ip(err) => Ip(err),
330                     err::ip::HeadersError::Ipv4Ext(err) => Ipv4Exts(err),
331                     err::ip::HeadersError::Ipv6Ext(err) => Ipv6Exts(err),
332                 },
333             }
334         })?;
335 
336         let mut result = PacketHeaders {
337             link: None,
338             vlan: None,
339             net: Some(ip_header.into()),
340             transport: None,
341             payload: PayloadSlice::Ip(ip_payload.clone()),
342         };
343 
344         // cache rest for offset addition
345         let rest = ip_payload.payload;
346 
347         // try to parse the transport header (only if data is not fragmented)
348         let (transport, payload) = read_transport(ip_payload).map_err(|err| {
349             use err::tcp::HeaderSliceError as I;
350             match err {
351                 I::Len(mut err) => {
352                     err.layer_start_offset += unsafe {
353                         // SAFETY: Safe as rest is a subslice of slice.
354                         rest.as_ptr().offset_from(slice.as_ptr()) as usize
355                     };
356                     Len(err)
357                 }
358                 I::Content(err) => Tcp(err),
359             }
360         })?;
361 
362         // update output
363         result.transport = transport;
364         result.payload = payload;
365 
366         Ok(result)
367     }
368 }
369 
370 /// helper function to process transport headers
read_transport( ip_payload: IpPayloadSlice, ) -> Result<(Option<TransportHeader>, PayloadSlice), err::tcp::HeaderSliceError>371 fn read_transport(
372     ip_payload: IpPayloadSlice,
373 ) -> Result<(Option<TransportHeader>, PayloadSlice), err::tcp::HeaderSliceError> {
374     if ip_payload.fragmented {
375         Ok((None, PayloadSlice::Ip(ip_payload)))
376     } else {
377         // helper function to set the len source in len errors
378         let add_len_source = |mut len_error: LenError| -> err::tcp::HeaderSliceError {
379             // only change the len source if the lower layer has not set it
380             if LenSource::Slice == len_error.len_source {
381                 len_error.len_source = ip_payload.len_source;
382             }
383             Len(len_error)
384         };
385         use crate::ip_number::*;
386         use err::tcp::HeaderSliceError::*;
387         match ip_payload.ip_number {
388             ICMP => Icmpv4Slice::from_slice(ip_payload.payload)
389                 .map_err(add_len_source)
390                 .map(|value| {
391                     (
392                         Some(TransportHeader::Icmpv4(value.header())),
393                         PayloadSlice::Icmpv4(value.payload()),
394                     )
395                 }),
396             IPV6_ICMP => Icmpv6Slice::from_slice(ip_payload.payload)
397                 .map_err(add_len_source)
398                 .map(|value| {
399                     (
400                         Some(TransportHeader::Icmpv6(value.header())),
401                         PayloadSlice::Icmpv6(value.payload()),
402                     )
403                 }),
404             UDP => UdpHeader::from_slice(ip_payload.payload)
405                 .map_err(add_len_source)
406                 .map(|value| {
407                     (
408                         Some(TransportHeader::Udp(value.0)),
409                         PayloadSlice::Udp(value.1),
410                     )
411                 }),
412             TCP => TcpHeader::from_slice(ip_payload.payload)
413                 .map_err(|err| match err {
414                     Len(err) => add_len_source(err),
415                     Content(err) => Content(err),
416                 })
417                 .map(|value| {
418                     (
419                         Some(TransportHeader::Tcp(value.0)),
420                         PayloadSlice::Tcp(value.1),
421                     )
422                 }),
423             _ => Ok((None, PayloadSlice::Ip(ip_payload))),
424         }
425     }
426 }
427 
428 #[cfg(test)]
429 mod test {
430     use super::*;
431     use crate::err::packet::SliceError;
432     use crate::test_packet::TestPacket;
433 
434     const VLAN_ETHER_TYPES: [EtherType; 3] = [
435         ether_type::VLAN_TAGGED_FRAME,
436         ether_type::PROVIDER_BRIDGING,
437         ether_type::VLAN_DOUBLE_TAGGED_FRAME,
438     ];
439 
440     #[test]
debug()441     fn debug() {
442         use alloc::format;
443         let header = PacketHeaders {
444             link: None,
445             vlan: None,
446             net: None,
447             transport: None,
448             payload: PayloadSlice::Ether(EtherPayloadSlice {
449                 ether_type: EtherType(0),
450                 payload: &[],
451             }),
452         };
453         assert_eq!(
454             &format!("{:?}", header),
455             &format!(
456                 "PacketHeaders {{ link: {:?}, vlan: {:?}, net: {:?}, transport: {:?}, payload: {:?} }}",
457                 header.link,
458                 header.vlan,
459                 header.net,
460                 header.transport,
461                 header.payload
462             )
463         );
464     }
465 
466     #[test]
clone_eq()467     fn clone_eq() {
468         let header = PacketHeaders {
469             link: None,
470             vlan: None,
471             net: None,
472             transport: None,
473             payload: PayloadSlice::Ether(EtherPayloadSlice {
474                 ether_type: EtherType(0),
475                 payload: &[],
476             }),
477         };
478         assert_eq!(header.clone(), header);
479     }
480 
481     #[test]
from_x_slice()482     fn from_x_slice() {
483         // no eth
484         from_x_slice_vlan_variants(&TestPacket {
485             link: None,
486             vlan: None,
487             net: None,
488             transport: None,
489         });
490 
491         // eth
492         {
493             let eth = Ethernet2Header {
494                 source: [1, 2, 3, 4, 5, 6],
495                 destination: [1, 2, 3, 4, 5, 6],
496                 ether_type: 0.into(),
497             };
498             let test = TestPacket {
499                 link: Some(LinkHeader::Ethernet2(eth.clone())),
500                 vlan: None,
501                 net: None,
502                 transport: None,
503             };
504 
505             // ok ethernet header (with unknown next)
506             from_x_slice_vlan_variants(&test);
507 
508             // eth len error
509             {
510                 let data = test.to_vec(&[]);
511                 for len in 0..data.len() {
512                     let err = LenError {
513                         required_len: eth.header_len(),
514                         len,
515                         len_source: LenSource::Slice,
516                         layer: err::Layer::Ethernet2Header,
517                         layer_start_offset: 0,
518                     };
519 
520                     from_slice_assert_err(&test, &data[..len], SliceError::Len(err.clone()));
521                 }
522             }
523         }
524     }
525 
from_x_slice_vlan_variants(base: &TestPacket)526     fn from_x_slice_vlan_variants(base: &TestPacket) {
527         // none
528         from_x_slice_ip_variants(base);
529 
530         // single vlan header
531         {
532             let single = SingleVlanHeader {
533                 pcp: 1.try_into().unwrap(),
534                 drop_eligible_indicator: false,
535                 vlan_id: 2.try_into().unwrap(),
536                 ether_type: 3.into(),
537             };
538 
539             for vlan_ether_type in VLAN_ETHER_TYPES {
540                 let mut test = base.clone();
541                 test.set_ether_type(vlan_ether_type);
542                 test.vlan = Some(VlanHeader::Single(single.clone()));
543 
544                 // ok vlan header
545                 from_x_slice_ip_variants(&test);
546 
547                 // len error
548                 {
549                     let data = test.to_vec(&[]);
550                     for len in 0..single.header_len() {
551                         let base_len = test.len(&[]) - single.header_len();
552 
553                         let err = LenError {
554                             required_len: single.header_len(),
555                             len,
556                             len_source: LenSource::Slice,
557                             layer: err::Layer::VlanHeader,
558                             layer_start_offset: base_len,
559                         };
560                         from_slice_assert_err(
561                             &test,
562                             &data[..base_len + len],
563                             SliceError::Len(err.clone()),
564                         );
565                     }
566                 }
567             }
568         }
569 
570         // double vlan header
571         for outer_vlan_ether_type in VLAN_ETHER_TYPES {
572             for inner_vlan_ether_type in VLAN_ETHER_TYPES {
573                 let double = DoubleVlanHeader {
574                     outer: SingleVlanHeader {
575                         pcp: 1.try_into().unwrap(),
576                         drop_eligible_indicator: false,
577                         vlan_id: 2.try_into().unwrap(),
578                         ether_type: inner_vlan_ether_type,
579                     },
580                     inner: SingleVlanHeader {
581                         pcp: 1.try_into().unwrap(),
582                         drop_eligible_indicator: false,
583                         vlan_id: 2.try_into().unwrap(),
584                         ether_type: 3.into(),
585                     },
586                 };
587                 let mut test = base.clone();
588                 test.set_ether_type(outer_vlan_ether_type);
589                 test.vlan = Some(VlanHeader::Double(double.clone()));
590 
591                 // ok double vlan header
592                 from_x_slice_ip_variants(&test);
593 
594                 // len error
595                 {
596                     let data = test.to_vec(&[]);
597                     for len in 0..SingleVlanHeader::LEN {
598                         let base_len = test.len(&[]) - SingleVlanHeader::LEN;
599 
600                         let err = LenError {
601                             required_len: SingleVlanHeader::LEN,
602                             len,
603                             len_source: LenSource::Slice,
604                             layer: err::Layer::VlanHeader,
605                             layer_start_offset: base_len,
606                         };
607                         from_slice_assert_err(
608                             &test,
609                             &data[..base_len + len],
610                             SliceError::Len(err.clone()),
611                         );
612                     }
613                 }
614             }
615         }
616     }
617 
from_x_slice_ip_variants(base: &TestPacket)618     fn from_x_slice_ip_variants(base: &TestPacket) {
619         // none
620         from_x_slice_transport_variants(base);
621 
622         // ipv4
623         for fragmented in [false, true] {
624             let ipv4 = {
625                 let mut ipv4 =
626                     Ipv4Header::new(0, 1, 2.into(), [3, 4, 5, 6], [7, 8, 9, 10]).unwrap();
627                 ipv4.more_fragments = fragmented;
628                 ipv4
629             };
630 
631             {
632                 let mut test = base.clone();
633                 test.set_ether_type(ether_type::IPV4);
634                 test.net = Some(NetHeaders::Ipv4(ipv4.clone(), Default::default()));
635 
636                 // ok ipv4
637                 from_x_slice_transport_variants(&test);
638 
639                 // ipv4 len error
640                 {
641                     let data = test.to_vec(&[]);
642                     for len in 0..ipv4.header_len() {
643                         let base_len = test.len(&[]) - ipv4.header_len();
644 
645                         let err = LenError {
646                             required_len: ipv4.header_len(),
647                             len,
648                             len_source: LenSource::Slice,
649                             layer: err::Layer::Ipv4Header,
650                             layer_start_offset: base_len,
651                         };
652                         from_slice_assert_err(
653                             &test,
654                             &data[..base_len + len],
655                             if test.link.is_some() || test.vlan.is_some() {
656                                 SliceError::Len(err.clone())
657                             } else {
658                                 SliceError::Len({
659                                     if len < 1 {
660                                         let mut err = err.clone();
661                                         err.required_len = 1;
662                                         err.layer = err::Layer::IpHeader;
663                                         err
664                                     } else {
665                                         err.clone()
666                                     }
667                                 })
668                             },
669                         );
670                     }
671                 }
672 
673                 // ipv4 content error
674                 {
675                     let mut data = test.to_vec(&[]);
676                     let ipv4_offset = data.len() - ipv4.header_len();
677 
678                     // set the ihl to 0 to trigger a content error
679                     data[ipv4_offset] = 0b1111_0000 & data[ipv4_offset];
680 
681                     from_slice_assert_err(
682                         &test,
683                         &data,
684                         if test.link.is_some() || test.vlan.is_some() {
685                             SliceError::Ipv4(
686                                 err::ipv4::HeaderError::HeaderLengthSmallerThanHeader { ihl: 0 },
687                             )
688                         } else {
689                             SliceError::Ip(
690                                 err::ip::HeaderError::Ipv4HeaderLengthSmallerThanHeader { ihl: 0 },
691                             )
692                         },
693                     );
694                 }
695             }
696 
697             // ipv4 extension content error
698             {
699                 let auth = IpAuthHeader::new(0.into(), 1, 2, &[]).unwrap();
700 
701                 let mut test = base.clone();
702                 test.set_ether_type(ether_type::IPV4);
703                 test.net = Some(NetHeaders::Ipv4(
704                     {
705                         let mut ipv4 = ipv4.clone();
706                         ipv4.protocol = ip_number::AUTH;
707                         ipv4
708                     },
709                     Ipv4Extensions {
710                         auth: Some(auth.clone()),
711                     },
712                 ));
713                 test.set_payload_len(0);
714 
715                 // ok ipv4 & extension
716                 from_x_slice_transport_variants(&test);
717 
718                 // ipv4 extension len error
719                 for len in 0..auth.header_len() {
720                     // set payload length
721                     let mut test = test.clone();
722                     test.set_payload_le_from_ip_on(
723                         -1 * (auth.header_len() as isize) + (len as isize),
724                     );
725 
726                     let data = test.to_vec(&[]);
727                     let base_len = test.len(&[]) - auth.header_len();
728 
729                     let err = LenError {
730                         required_len: auth.header_len(),
731                         len,
732                         len_source: LenSource::Ipv4HeaderTotalLen,
733                         layer: err::Layer::IpAuthHeader,
734                         layer_start_offset: base_len,
735                     };
736 
737                     from_slice_assert_err(
738                         &test,
739                         &data[..base_len + len],
740                         SliceError::Len(err.clone()),
741                     );
742                 }
743 
744                 // ipv4 extension content error
745                 {
746                     let mut data = test.to_vec(&[]);
747                     let auth_offset = data.len() - auth.header_len();
748 
749                     // set the icv len too smaller then allowed
750                     data[auth_offset + 1] = 0;
751 
752                     // expect an error
753                     let err = err::ip_auth::HeaderError::ZeroPayloadLen;
754                     from_slice_assert_err(&test, &data, SliceError::Ipv4Exts(err.clone()));
755                 }
756             }
757         }
758 
759         // ipv6
760         {
761             let ipv6 = Ipv6Header {
762                 traffic_class: 0,
763                 flow_label: 1.try_into().unwrap(),
764                 payload_length: 2,
765                 next_header: 3.into(),
766                 hop_limit: 4,
767                 source: [0; 16],
768                 destination: [0; 16],
769             };
770 
771             // ipv6 header only
772             {
773                 let mut test = base.clone();
774                 test.set_ether_type(ether_type::IPV6);
775                 test.net = Some(NetHeaders::Ipv6(ipv6.clone(), Default::default()));
776                 test.set_payload_len(0);
777 
778                 // ok ipv6
779                 from_x_slice_transport_variants(&test);
780 
781                 // header len ipv6
782                 {
783                     let data = test.to_vec(&[]);
784                     for len in 0..ipv6.header_len() {
785                         let base_len = test.len(&[]) - ipv6.header_len();
786 
787                         let err = err::LenError {
788                             required_len: ipv6.header_len(),
789                             len,
790                             len_source: LenSource::Slice,
791                             layer: err::Layer::Ipv6Header,
792                             layer_start_offset: base_len,
793                         };
794 
795                         from_slice_assert_err(
796                             &test,
797                             &data[..base_len + len],
798                             if test.link.is_some() || test.vlan.is_some() {
799                                 SliceError::Len(err.clone())
800                             } else {
801                                 SliceError::Len({
802                                     if len < 1 {
803                                         let mut err = err.clone();
804                                         err.required_len = 1;
805                                         err.layer = err::Layer::IpHeader;
806                                         err
807                                     } else {
808                                         err.clone()
809                                     }
810                                 })
811                             },
812                         );
813                     }
814                 }
815 
816                 // content error ipv6
817                 {
818                     use err::ip::HeaderError::*;
819                     let mut data = test.to_vec(&[]);
820 
821                     // inject an invalid ip version
822                     let base_len = data.len() - ipv6.header_len();
823                     data[base_len] = data[base_len] & 0b0000_1111;
824 
825                     from_slice_assert_err(
826                         &test,
827                         &data,
828                         if test.link.is_some() || test.vlan.is_some() {
829                             SliceError::Ipv6(err::ipv6::HeaderError::UnexpectedVersion {
830                                 version_number: 0,
831                             })
832                         } else {
833                             SliceError::Ip(UnsupportedIpVersion { version_number: 0 })
834                         },
835                     );
836                 }
837             }
838 
839             // ipv6 + extension
840             for fragment in [false, true] {
841                 let auth = IpAuthHeader::new(ip_number::GGP, 1, 2, &[]).unwrap();
842                 let frag = Ipv6FragmentHeader {
843                     next_header: ip_number::AUTH,
844                     fragment_offset: 0.try_into().unwrap(),
845                     more_fragments: fragment,
846                     identification: 3,
847                 };
848 
849                 let mut test = base.clone();
850                 test.set_ether_type(ether_type::IPV6);
851                 test.net = Some(NetHeaders::Ipv6(
852                     {
853                         let mut ipv6 = ipv6.clone();
854                         ipv6.next_header = ip_number::IPV6_FRAG;
855                         ipv6
856                     },
857                     {
858                         let mut exts: Ipv6Extensions = Default::default();
859                         exts.fragment = Some(frag.clone());
860                         exts.auth = Some(auth.clone());
861                         exts
862                     },
863                 ));
864                 test.set_payload_len(0);
865 
866                 // ok ipv6 & extensions
867                 from_x_slice_transport_variants(&test);
868 
869                 // ipv6 extension len error
870                 for len in 0..auth.header_len() {
871                     // set payload length
872                     let mut test = test.clone();
873                     test.set_payload_le_from_ip_on(
874                         -1 * (auth.header_len() as isize) + (len as isize),
875                     );
876 
877                     let data = test.to_vec(&[]);
878                     let base_len = test.len(&[]) - auth.header_len();
879 
880                     let err = LenError {
881                         required_len: auth.header_len(),
882                         len,
883                         len_source: LenSource::Ipv6HeaderPayloadLen,
884                         layer: err::Layer::IpAuthHeader,
885                         layer_start_offset: base_len,
886                     };
887                     from_slice_assert_err(
888                         &test,
889                         &data[..base_len + len],
890                         SliceError::Len(err.clone()),
891                     );
892                 }
893 
894                 // ipv6 extension content error (auth)
895                 {
896                     let mut data = test.to_vec(&[]);
897                     let auth_offset = data.len() - auth.header_len();
898                     // set the icv len too smaller then allowed
899                     data[auth_offset + 1] = 0;
900 
901                     let err = err::ip_auth::HeaderError::ZeroPayloadLen;
902                     from_slice_assert_err(
903                         &test,
904                         &data,
905                         SliceError::Ipv6Exts(err::ipv6_exts::HeaderError::IpAuth(err.clone())),
906                     );
907                 }
908 
909                 // ipv6 extension content error (hop by hop not at start)
910                 {
911                     let mut data = test.to_vec(&[]);
912                     let auth_offset = data.len() - auth.header_len();
913 
914                     // set the next header to be a hop-by-hop header to trigger a "not at start error"
915                     data[auth_offset] = 0;
916 
917                     from_slice_assert_err(
918                         &test,
919                         &data,
920                         SliceError::Ipv6Exts(err::ipv6_exts::HeaderError::HopByHopNotAtStart),
921                     );
922                 }
923             }
924         }
925     }
926 
from_x_slice_transport_variants(base: &TestPacket)927     fn from_x_slice_transport_variants(base: &TestPacket) {
928         // none
929         from_x_slice_assert_ok(base);
930 
931         // transport can only be set if ip is present
932         if let Some(ip) = &base.net {
933             // udp
934             {
935                 let udp = UdpHeader {
936                     source_port: 1,
937                     destination_port: 2,
938                     length: 3,
939                     checksum: 4,
940                 };
941                 let mut test = base.clone();
942                 test.net = Some({
943                     let mut ip = match ip {
944                         NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()),
945                         NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()),
946                         NetHeaders::Arp(_) => unreachable!(),
947                     };
948                     ip.set_next_headers(ip_number::UDP);
949                     ip.into()
950                 });
951                 test.transport = Some(TransportHeader::Udp(udp.clone()));
952                 test.set_payload_len(0);
953 
954                 // ok decode
955                 from_x_slice_assert_ok(&test);
956 
957                 // length error
958                 if false == test.is_ip_payload_fragmented() {
959                     for len in 0..udp.header_len() {
960                         // build new test packet
961                         let mut test = test.clone();
962 
963                         // set payload length
964                         test.set_payload_le_from_ip_on(len as isize);
965 
966                         // generate data
967                         let data = test.to_vec(&[]);
968                         let base_len = test.len(&[]) - udp.header_len();
969 
970                         let err = LenError {
971                             required_len: udp.header_len(),
972                             len,
973                             len_source: match test.net.as_ref().unwrap() {
974                                 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen,
975                                 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen,
976                                 NetHeaders::Arp(_) => unreachable!(),
977                             },
978                             layer: err::Layer::UdpHeader,
979                             layer_start_offset: base_len,
980                         };
981                         from_slice_assert_err(
982                             &test,
983                             &data[..base_len + len],
984                             SliceError::Len(err.clone()),
985                         );
986                     }
987                 }
988             }
989 
990             // tcp
991             {
992                 let tcp = TcpHeader::new(1, 2, 3, 4);
993                 let mut test = base.clone();
994                 test.net = Some({
995                     let mut ip = match ip {
996                         NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()),
997                         NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()),
998                         NetHeaders::Arp(_) => unreachable!(),
999                     };
1000                     ip.set_next_headers(ip_number::TCP);
1001                     ip.into()
1002                 });
1003                 test.transport = Some(TransportHeader::Tcp(tcp.clone()));
1004                 test.set_payload_len(0);
1005 
1006                 // ok decode
1007                 from_x_slice_assert_ok(&test);
1008 
1009                 // error can only occur if ip does not fragment the packet
1010                 if false == test.is_ip_payload_fragmented() {
1011                     // length error
1012                     for len in 0..(tcp.header_len() as usize) {
1013                         // set payload length
1014                         let mut test = test.clone();
1015                         test.set_payload_le_from_ip_on(len as isize);
1016 
1017                         let data = test.to_vec(&[]);
1018                         let base_len = test.len(&[]) - (tcp.header_len() as usize);
1019 
1020                         let err = LenError {
1021                             required_len: tcp.header_len() as usize,
1022                             len,
1023                             len_source: match test.net.as_ref().unwrap() {
1024                                 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen,
1025                                 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen,
1026                                 NetHeaders::Arp(_) => unreachable!(),
1027                             },
1028                             layer: err::Layer::TcpHeader,
1029                             layer_start_offset: base_len,
1030                         };
1031                         from_slice_assert_err(
1032                             &test,
1033                             &data[..base_len + len],
1034                             SliceError::Len(err.clone()),
1035                         );
1036                     }
1037 
1038                     // content error
1039                     {
1040                         let mut data = test.to_vec(&[]);
1041                         let base_len = test.len(&[]) - (tcp.header_len() as usize);
1042 
1043                         // set data offset to 0 to trigger an error
1044                         data[base_len + 12] = data[base_len + 12] & 0b0000_1111;
1045 
1046                         let err = err::tcp::HeaderError::DataOffsetTooSmall { data_offset: 0 };
1047                         from_slice_assert_err(&test, &data, SliceError::Tcp(err.clone()));
1048                     }
1049                 }
1050             }
1051 
1052             // icmpv4
1053             {
1054                 let icmpv4 =
1055                     Icmpv4Header::new(Icmpv4Type::EchoReply(IcmpEchoHeader { id: 1, seq: 2 }));
1056                 let mut test = base.clone();
1057                 test.net = Some({
1058                     let mut ip = match ip {
1059                         NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()),
1060                         NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()),
1061                         NetHeaders::Arp(_) => unreachable!(),
1062                     };
1063                     ip.set_next_headers(ip_number::ICMP);
1064                     ip.into()
1065                 });
1066                 test.transport = Some(TransportHeader::Icmpv4(icmpv4.clone()));
1067 
1068                 // ok decode
1069                 from_x_slice_assert_ok(&test);
1070 
1071                 // length error
1072                 if false == test.is_ip_payload_fragmented() {
1073                     for len in 0..icmpv4.header_len() {
1074                         // set payload length
1075                         let mut test = test.clone();
1076                         test.set_payload_le_from_ip_on(len as isize);
1077 
1078                         let data = test.to_vec(&[]);
1079                         let base_len = test.len(&[]) - icmpv4.header_len();
1080 
1081                         let err = LenError {
1082                             required_len: icmpv4.header_len(),
1083                             len,
1084                             len_source: match test.net.as_ref().unwrap() {
1085                                 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen,
1086                                 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen,
1087                                 NetHeaders::Arp(_) => unreachable!(),
1088                             },
1089                             layer: err::Layer::Icmpv4,
1090                             layer_start_offset: base_len,
1091                         };
1092                         from_slice_assert_err(
1093                             &test,
1094                             &data[..base_len + len],
1095                             SliceError::Len(err.clone()),
1096                         );
1097                     }
1098                 }
1099             }
1100 
1101             // icmpv6
1102             {
1103                 let icmpv6 =
1104                     Icmpv6Header::new(Icmpv6Type::EchoReply(IcmpEchoHeader { id: 1, seq: 2 }));
1105                 let mut test = base.clone();
1106                 test.net = Some({
1107                     let mut ip = match ip {
1108                         NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()),
1109                         NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()),
1110                         NetHeaders::Arp(_) => unreachable!(),
1111                     };
1112                     ip.set_next_headers(ip_number::IPV6_ICMP);
1113                     ip.into()
1114                 });
1115                 test.transport = Some(TransportHeader::Icmpv6(icmpv6.clone()));
1116 
1117                 // ok decode
1118                 from_x_slice_assert_ok(&test);
1119 
1120                 // length error
1121                 if false == test.is_ip_payload_fragmented() {
1122                     for len in 0..icmpv6.header_len() {
1123                         // set payload length
1124                         let mut test = test.clone();
1125                         test.set_payload_le_from_ip_on(len as isize);
1126 
1127                         let data = test.to_vec(&[]);
1128                         let base_len = test.len(&[]) - icmpv6.header_len();
1129 
1130                         let err = LenError {
1131                             required_len: icmpv6.header_len(),
1132                             len,
1133                             len_source: match test.net.as_ref().unwrap() {
1134                                 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen,
1135                                 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen,
1136                                 NetHeaders::Arp(_) => unreachable!(),
1137                             },
1138                             layer: err::Layer::Icmpv6,
1139                             layer_start_offset: base_len,
1140                         };
1141                         from_slice_assert_err(
1142                             &test,
1143                             &data[..base_len + len],
1144                             SliceError::Len(err.clone()),
1145                         );
1146                     }
1147                 }
1148             }
1149         }
1150     }
1151 
from_x_slice_assert_ok(test_base: &TestPacket)1152     fn from_x_slice_assert_ok(test_base: &TestPacket) {
1153         let payload = [1, 2, 3, 4];
1154 
1155         // set length fields in ip headers
1156         let test = {
1157             let mut test = test_base.clone();
1158             test.set_payload_len(payload.len());
1159             test
1160         };
1161 
1162         // check if fragmenting
1163         let is_fragmented = test.is_ip_payload_fragmented();
1164 
1165         // write data
1166         let data = test.to_vec(&payload);
1167 
1168         // from_ethernet_slice
1169         if test.link.is_some() {
1170             let result = PacketHeaders::from_ethernet_slice(&data).unwrap();
1171             assert_eq!(result.link, test.link);
1172             assert_eq!(result.vlan, test.vlan);
1173             assert_eq!(result.net, test.net);
1174             if is_fragmented {
1175                 assert_eq!(result.transport, None);
1176             } else {
1177                 assert_eq!(result.transport, test.transport);
1178                 assert_eq!(result.payload.slice(), &[1, 2, 3, 4]);
1179             }
1180         }
1181         // from_ether_type (vlan at start)
1182         if test.link.is_none() && test.vlan.is_some() {
1183             for ether_type in VLAN_ETHER_TYPES {
1184                 let result = PacketHeaders::from_ether_type(ether_type, &data).unwrap();
1185                 assert_eq!(result.link, test.link);
1186                 assert_eq!(result.vlan, test.vlan);
1187                 assert_eq!(result.net, test.net);
1188                 if is_fragmented {
1189                     assert_eq!(result.transport, None);
1190                 } else {
1191                     assert_eq!(result.transport, test.transport);
1192                     assert_eq!(result.payload.slice(), &[1, 2, 3, 4]);
1193                 }
1194             }
1195         }
1196         // from_ether_type (ip at start)
1197         if test.link.is_none() && test.vlan.is_none() {
1198             if let Some(ip) = &test.net {
1199                 let result = PacketHeaders::from_ether_type(
1200                     match ip {
1201                         NetHeaders::Ipv4(_, _) => ether_type::IPV4,
1202                         NetHeaders::Ipv6(_, _) => ether_type::IPV6,
1203                         NetHeaders::Arp(_) => ether_type::ARP,
1204                     },
1205                     &data,
1206                 )
1207                 .unwrap();
1208                 assert_eq!(result.link, test.link);
1209                 assert_eq!(result.vlan, test.vlan);
1210                 assert_eq!(result.net, test.net);
1211                 if is_fragmented {
1212                     assert_eq!(result.transport, None);
1213                 } else {
1214                     assert_eq!(result.transport, test.transport);
1215                     assert_eq!(result.payload.slice(), &[1, 2, 3, 4]);
1216                 }
1217             }
1218         }
1219         // from_ip_slice
1220         if test.link.is_none() && test.vlan.is_none() && test.net.is_some() {
1221             let result = PacketHeaders::from_ip_slice(&data).unwrap();
1222             assert_eq!(result.link, test.link);
1223             assert_eq!(result.vlan, test.vlan);
1224             assert_eq!(result.net, test.net);
1225             if is_fragmented {
1226                 assert_eq!(result.transport, None);
1227             } else {
1228                 assert_eq!(result.transport, test.transport);
1229                 assert_eq!(result.payload.slice(), &[1, 2, 3, 4]);
1230             }
1231         }
1232     }
1233 
1234     /// Check that the given errors get triggered if presented with the given
1235     /// data.
from_slice_assert_err(test: &TestPacket, data: &[u8], err: SliceError)1236     fn from_slice_assert_err(test: &TestPacket, data: &[u8], err: SliceError) {
1237         // from_ethernet_slice
1238         if test.link.is_some() {
1239             assert_eq!(
1240                 err.clone(),
1241                 PacketHeaders::from_ethernet_slice(&data).unwrap_err()
1242             );
1243         }
1244         // from_ether_type (vlan at start)
1245         if test.link.is_none() && test.vlan.is_some() {
1246             for ether_type in VLAN_ETHER_TYPES {
1247                 assert_eq!(
1248                     err.clone(),
1249                     PacketHeaders::from_ether_type(ether_type, &data).unwrap_err()
1250                 );
1251             }
1252         }
1253         // from_ether_type (ip at start)
1254         if test.link.is_none() && test.vlan.is_none() {
1255             if let Some(ip) = &test.net {
1256                 let err = PacketHeaders::from_ether_type(
1257                     match ip {
1258                         NetHeaders::Ipv4(_, _) => ether_type::IPV4,
1259                         NetHeaders::Ipv6(_, _) => ether_type::IPV6,
1260                         NetHeaders::Arp(_) => ether_type::ARP,
1261                     },
1262                     &data,
1263                 )
1264                 .unwrap_err();
1265                 assert_eq!(err, err.clone());
1266             }
1267         }
1268         // from_ip_slice
1269         if test.link.is_none() && test.vlan.is_none() && test.net.is_some() {
1270             assert_eq!(err, PacketHeaders::from_ip_slice(&data).unwrap_err());
1271         }
1272     }
1273 }
1274