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