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