1use arrayvec::ArrayVec;
2
3use crate::{err::Layer, *};
4
5#[derive(Clone, Debug, Eq, PartialEq)]
8pub struct LaxSlicedPacket<'a> {
9 pub link: Option<LinkSlice<'a>>,
11
12 pub link_exts: ArrayVec<LaxLinkExtSlice<'a>, { LaxSlicedPacket::LINK_EXTS_CAP }>,
14
15 pub net: Option<LaxNetSlice<'a>>,
17
18 pub transport: Option<TransportSlice<'a>>,
20
21 pub stop_err: Option<(err::packet::SliceError, Layer)>,
23}
24
25impl<'a> LaxSlicedPacket<'a> {
26 pub const LINK_EXTS_CAP: usize = 3;
28
29 pub fn from_ethernet(slice: &'a [u8]) -> Result<LaxSlicedPacket<'a>, err::LenError> {
92 LaxSlicedPacketCursor::parse_from_ethernet2(slice)
93 }
94
95 pub fn from_ether_type(ether_type: EtherType, slice: &'a [u8]) -> LaxSlicedPacket<'a> {
152 LaxSlicedPacketCursor::parse_from_ether_type(ether_type, slice)
153 }
154
155 pub fn from_ip(slice: &'a [u8]) -> Result<LaxSlicedPacket<'a>, err::ip::LaxHeaderSliceError> {
226 LaxSlicedPacketCursor::parse_from_ip(slice)
227 }
228
229 pub fn vlan(&self) -> Option<VlanSlice<'a>> {
231 let mut result = None;
232 for ext in &self.link_exts {
233 if let LaxLinkExtSlice::Vlan(s) = ext {
234 if let Some(outer) = result {
235 return Some(VlanSlice::DoubleVlan(DoubleVlanSlice {
236 outer,
237 inner: s.clone(),
238 }));
239 } else {
240 result = Some(s.clone());
241 }
242 }
243 }
244 result.map(VlanSlice::SingleVlan)
245 }
246
247 pub fn vlan_ids(&self) -> ArrayVec<VlanId, { SlicedPacket::LINK_EXTS_CAP }> {
249 let mut result = ArrayVec::<VlanId, { SlicedPacket::LINK_EXTS_CAP }>::new_const();
250 for e in &self.link_exts {
251 if let LaxLinkExtSlice::Vlan(s) = e {
252 unsafe {
254 result.push_unchecked(s.vlan_identifier());
255 }
256 }
257 }
258 result
259 }
260
261 pub fn ether_payload(&self) -> Option<LaxEtherPayloadSlice<'a>> {
267 if let Some(link_ext) = self.link_exts.last() {
268 match link_ext {
269 LaxLinkExtSlice::Vlan(vlan_slice) => Some(LaxEtherPayloadSlice {
270 incomplete: false,
271 ether_type: vlan_slice.ether_type(),
272 len_source: {
273 let mut len_source = LenSource::Slice;
274 for ext in &self.link_exts {
275 if let Some(l) = ext.payload().as_ref() {
276 if l.len_source != LenSource::Slice {
277 len_source = l.len_source;
278 }
279 }
280 }
281 len_source
282 },
283 payload: vlan_slice.payload_slice(),
284 }),
285 LaxLinkExtSlice::Macsec(macsec_slice) => macsec_slice.ether_payload(),
286 }
287 } else if let Some(link) = self.link.as_ref() {
288 match link {
289 LinkSlice::Ethernet2(e) => {
290 let p = e.payload();
291 Some(LaxEtherPayloadSlice {
292 incomplete: false,
293 ether_type: p.ether_type,
294 len_source: LenSource::Slice,
295 payload: p.payload,
296 })
297 }
298 LinkSlice::LinuxSll(e) => match e.protocol_type() {
299 LinuxSllProtocolType::EtherType(_)
300 | LinuxSllProtocolType::LinuxNonstandardEtherType(_) => {
301 let p = EtherPayloadSlice::try_from(e.payload()).ok()?;
302 Some(LaxEtherPayloadSlice {
303 incomplete: false,
304 ether_type: p.ether_type,
305 len_source: LenSource::Slice,
306 payload: p.payload,
307 })
308 }
309 _ => None,
310 },
311 LinkSlice::EtherPayload(p) => Some(LaxEtherPayloadSlice {
312 incomplete: false,
313 ether_type: p.ether_type,
314 len_source: LenSource::Slice,
315 payload: p.payload,
316 }),
317 LinkSlice::LinuxSllPayload(e) => match e.protocol_type {
318 LinuxSllProtocolType::EtherType(_)
319 | LinuxSllProtocolType::LinuxNonstandardEtherType(_) => {
320 let p = EtherPayloadSlice::try_from(e.clone()).ok()?;
321 Some(LaxEtherPayloadSlice {
322 incomplete: false,
323 ether_type: p.ether_type,
324 len_source: LenSource::Slice,
325 payload: p.payload,
326 })
327 }
328 _ => None,
329 },
330 }
331 } else {
332 None
333 }
334 }
335
336 pub fn ip_payload(&self) -> Option<&LaxIpPayloadSlice<'a>> {
339 if let Some(net) = self.net.as_ref() {
340 use LaxNetSlice::*;
341 match net {
342 Ipv4(v) => Some(v.payload()),
343 Ipv6(v) => Some(v.payload()),
344 Arp(_) => None,
345 }
346 } else {
347 None
348 }
349 }
350}
351
352#[cfg(test)]
353mod test {
354 use std::vec::Vec;
355
356 use super::*;
357 use crate::err::{packet::SliceError, LenError};
358 use crate::test_packet::TestPacket;
359
360 const VLAN_ETHER_TYPES: [EtherType; 3] = [
361 ether_type::VLAN_TAGGED_FRAME,
362 ether_type::PROVIDER_BRIDGING,
363 ether_type::VLAN_DOUBLE_TAGGED_FRAME,
364 ];
365 const MACSEC_ETHER_TYPES: [EtherType; 1] = [ether_type::MACSEC];
366
367 #[test]
368 fn clone_eq() {
369 let header = LaxSlicedPacket {
370 link: None,
371 link_exts: ArrayVec::new_const(),
372 net: None,
373 transport: None,
374 stop_err: None,
375 };
376 assert_eq!(header.clone(), header);
377 }
378
379 #[test]
380 fn debug() {
381 use alloc::format;
382 let header = LaxSlicedPacket {
383 link: None,
384 link_exts: ArrayVec::new_const(),
385 net: None,
386 transport: None,
387 stop_err: None,
388 };
389 assert_eq!(
390 format!("{:?}", header),
391 format!(
392 "LaxSlicedPacket {{ link: {:?}, link_exts: {:?}, net: {:?}, transport: {:?}, stop_err: {:?} }}",
393 header.link, header.link_exts, header.net, header.transport, header.stop_err
394 )
395 );
396 }
397
398 #[test]
399 fn vlan_vlan_ids() {
400 assert_eq!(
402 LaxSlicedPacket {
403 link: None,
404 link_exts: ArrayVec::new_const(),
405 net: None,
406 transport: None,
407 stop_err: None
408 }
409 .vlan(),
410 None
411 );
412 assert_eq!(
413 LaxSlicedPacket {
414 link: None,
415 link_exts: ArrayVec::new_const(),
416 net: None,
417 transport: None,
418 stop_err: None
419 }
420 .vlan_ids(),
421 ArrayVec::<VlanId, 3>::new_const()
422 );
423
424 {
426 let payload = [1, 2, 3, 4];
427 let mut buf = Vec::with_capacity(SingleVlanHeader::LEN + 4);
428 buf.extend_from_slice(
429 &SingleVlanHeader {
430 pcp: VlanPcp::ZERO,
431 drop_eligible_indicator: false,
432 vlan_id: VlanId::try_new(1).unwrap(),
433 ether_type: EtherType::WAKE_ON_LAN,
434 }
435 .to_bytes(),
436 );
437 buf.extend_from_slice(&payload);
438
439 let slice = LaxSlicedPacket::from_ether_type(ether_type::VLAN_TAGGED_FRAME, &buf);
440
441 assert_eq!(
442 slice.vlan(),
443 Some(VlanSlice::SingleVlan(SingleVlanSlice { slice: &buf[..] }))
444 );
445 assert_eq!(slice.vlan_ids(), {
446 let mut ids = ArrayVec::<VlanId, 3>::new_const();
447 ids.push(VlanId::try_new(1).unwrap());
448 ids
449 });
450 }
451
452 {
454 let payload = [1, 2, 3, 4];
455 let mut buf = Vec::with_capacity(SingleVlanHeader::LEN * 2 + 4);
456 buf.extend_from_slice(
457 &SingleVlanHeader {
458 pcp: VlanPcp::ZERO,
459 drop_eligible_indicator: false,
460 vlan_id: VlanId::try_new(1).unwrap(),
461 ether_type: EtherType::VLAN_TAGGED_FRAME,
462 }
463 .to_bytes(),
464 );
465 buf.extend_from_slice(
466 &SingleVlanHeader {
467 pcp: VlanPcp::ZERO,
468 drop_eligible_indicator: false,
469 vlan_id: VlanId::try_new(2).unwrap(),
470 ether_type: EtherType::WAKE_ON_LAN,
471 }
472 .to_bytes(),
473 );
474 buf.extend_from_slice(&payload);
475
476 let slice =
477 LaxSlicedPacket::from_ether_type(ether_type::VLAN_DOUBLE_TAGGED_FRAME, &buf);
478
479 assert_eq!(
480 slice.vlan(),
481 Some(VlanSlice::DoubleVlan(DoubleVlanSlice {
482 outer: SingleVlanSlice { slice: &buf },
483 inner: SingleVlanSlice {
484 slice: &buf[SingleVlanHeader::LEN..]
485 },
486 }))
487 );
488 assert_eq!(slice.vlan_ids(), {
489 let mut ids = ArrayVec::<VlanId, 3>::new_const();
490 ids.push(VlanId::try_new(1).unwrap());
491 ids.push(VlanId::try_new(2).unwrap());
492 ids
493 });
494 }
495
496 {
498 let payload = [1, 2, 3, 4];
499 let macsec = MacsecHeader {
500 ptype: MacsecPType::Unmodified(EtherType::VLAN_DOUBLE_TAGGED_FRAME),
501 endstation_id: false,
502 scb: false,
503 an: MacsecAn::ZERO,
504 short_len: MacsecShortLen::ZERO,
505 packet_nr: 0,
506 sci: None,
507 };
508 let mut buf = Vec::with_capacity(macsec.header_len() + SingleVlanHeader::LEN * 2 + 4);
509 buf.extend_from_slice(&macsec.to_bytes());
510 buf.extend_from_slice(
511 &SingleVlanHeader {
512 pcp: VlanPcp::ZERO,
513 drop_eligible_indicator: false,
514 vlan_id: VlanId::try_new(1).unwrap(),
515 ether_type: EtherType::VLAN_TAGGED_FRAME,
516 }
517 .to_bytes(),
518 );
519 buf.extend_from_slice(
520 &SingleVlanHeader {
521 pcp: VlanPcp::ZERO,
522 drop_eligible_indicator: false,
523 vlan_id: VlanId::try_new(2).unwrap(),
524 ether_type: EtherType::WAKE_ON_LAN,
525 }
526 .to_bytes(),
527 );
528 buf.extend_from_slice(&payload);
529
530 let slice = LaxSlicedPacket::from_ether_type(ether_type::MACSEC, &buf);
531
532 let vlan_start = macsec.header_len();
533 assert_eq!(
534 slice.vlan(),
535 Some(VlanSlice::DoubleVlan(DoubleVlanSlice {
536 outer: SingleVlanSlice {
537 slice: &buf[vlan_start..]
538 },
539 inner: SingleVlanSlice {
540 slice: &buf[vlan_start + SingleVlanHeader::LEN..]
541 },
542 }))
543 );
544 assert_eq!(slice.vlan_ids(), {
545 let mut ids = ArrayVec::<VlanId, 3>::new_const();
546 ids.push(VlanId::try_new(1).unwrap());
547 ids.push(VlanId::try_new(2).unwrap());
548 ids
549 });
550 }
551
552 {
554 let payload = [1, 2, 3, 4];
555 let mut buf = Vec::with_capacity(SingleVlanHeader::LEN * 3 + 4);
556 buf.extend_from_slice(
557 &SingleVlanHeader {
558 pcp: VlanPcp::ZERO,
559 drop_eligible_indicator: false,
560 vlan_id: VlanId::try_new(1).unwrap(),
561 ether_type: EtherType::VLAN_TAGGED_FRAME,
562 }
563 .to_bytes(),
564 );
565 buf.extend_from_slice(
566 &SingleVlanHeader {
567 pcp: VlanPcp::ZERO,
568 drop_eligible_indicator: false,
569 vlan_id: VlanId::try_new(2).unwrap(),
570 ether_type: EtherType::VLAN_TAGGED_FRAME,
571 }
572 .to_bytes(),
573 );
574 buf.extend_from_slice(
575 &SingleVlanHeader {
576 pcp: VlanPcp::ZERO,
577 drop_eligible_indicator: false,
578 vlan_id: VlanId::try_new(3).unwrap(),
579 ether_type: EtherType::WAKE_ON_LAN,
580 }
581 .to_bytes(),
582 );
583 buf.extend_from_slice(&payload);
584
585 let slice =
586 LaxSlicedPacket::from_ether_type(ether_type::VLAN_DOUBLE_TAGGED_FRAME, &buf);
587
588 assert_eq!(
589 slice.vlan(),
590 Some(VlanSlice::DoubleVlan(DoubleVlanSlice {
591 outer: SingleVlanSlice { slice: &buf },
592 inner: SingleVlanSlice {
593 slice: &buf[SingleVlanHeader::LEN..]
594 },
595 }))
596 );
597 assert_eq!(slice.vlan_ids(), {
598 let mut ids = ArrayVec::<VlanId, 3>::new_const();
599 ids.push(VlanId::try_new(1).unwrap());
600 ids.push(VlanId::try_new(2).unwrap());
601 ids.push(VlanId::try_new(3).unwrap());
602 ids
603 });
604 }
605 }
606
607 #[test]
608 fn ether_payload() {
609 use alloc::vec::*;
610
611 assert_eq!(
613 LaxSlicedPacket {
614 link: None,
615 link_exts: ArrayVec::new_const(),
616 net: None,
617 transport: None,
618 stop_err: None
619 }
620 .ether_payload(),
621 None
622 );
623
624 {
626 let payload = [1, 2, 3, 4];
627 let mut buf = Vec::with_capacity(Ethernet2Header::LEN + 4);
628 buf.extend_from_slice(
629 &Ethernet2Header {
630 ether_type: EtherType::WAKE_ON_LAN,
631 ..Default::default()
632 }
633 .to_bytes(),
634 );
635 buf.extend_from_slice(&payload);
636 assert_eq!(
637 LaxSlicedPacket::from_ethernet(&buf)
638 .unwrap()
639 .ether_payload(),
640 Some(LaxEtherPayloadSlice {
641 incomplete: false,
642 ether_type: EtherType::WAKE_ON_LAN,
643 len_source: LenSource::Slice,
644 payload: &payload
645 })
646 );
647 }
648
649 {
651 let payload = [1, 2, 3, 4];
652 assert_eq!(
653 LaxSlicedPacket {
654 link: Some(LinkSlice::EtherPayload(EtherPayloadSlice {
655 ether_type: EtherType::WAKE_ON_LAN,
656 len_source: LenSource::Slice,
657 payload: &payload
658 })),
659 link_exts: ArrayVec::new_const(),
660 net: None,
661 transport: None,
662 stop_err: None,
663 }
664 .ether_payload(),
665 Some(LaxEtherPayloadSlice {
666 incomplete: false,
667 ether_type: EtherType::WAKE_ON_LAN,
668 len_source: LenSource::Slice,
669 payload: &payload
670 })
671 );
672 }
673
674 {
676 let payload = [1, 2, 3, 4];
677 let mut buf = Vec::with_capacity(Ethernet2Header::LEN + SingleVlanHeader::LEN + 4);
678 buf.extend_from_slice(
679 &Ethernet2Header {
680 ether_type: EtherType::VLAN_TAGGED_FRAME,
681 ..Default::default()
682 }
683 .to_bytes(),
684 );
685 buf.extend_from_slice(
686 &SingleVlanHeader {
687 ether_type: EtherType::WAKE_ON_LAN,
688 ..Default::default()
689 }
690 .to_bytes(),
691 );
692 buf.extend_from_slice(&payload);
693 assert_eq!(
694 LaxSlicedPacket::from_ethernet(&buf)
695 .unwrap()
696 .ether_payload(),
697 Some(LaxEtherPayloadSlice {
698 incomplete: false,
699 ether_type: EtherType::WAKE_ON_LAN,
700 len_source: LenSource::Slice,
701 payload: &payload
702 })
703 );
704 }
705
706 {
708 let payload = [1, 2, 3, 4];
709 let mut buf = Vec::with_capacity(Ethernet2Header::LEN + SingleVlanHeader::LEN * 2 + 4);
710 buf.extend_from_slice(
711 &Ethernet2Header {
712 ether_type: EtherType::VLAN_DOUBLE_TAGGED_FRAME,
713 ..Default::default()
714 }
715 .to_bytes(),
716 );
717 buf.extend_from_slice(
718 &SingleVlanHeader {
719 ether_type: EtherType::VLAN_TAGGED_FRAME,
720 ..Default::default()
721 }
722 .to_bytes(),
723 );
724 buf.extend_from_slice(
725 &SingleVlanHeader {
726 ether_type: EtherType::WAKE_ON_LAN,
727 ..Default::default()
728 }
729 .to_bytes(),
730 );
731 buf.extend_from_slice(&payload);
732 assert_eq!(
733 LaxSlicedPacket::from_ethernet(&buf)
734 .unwrap()
735 .ether_payload(),
736 Some(LaxEtherPayloadSlice {
737 incomplete: false,
738 ether_type: EtherType::WAKE_ON_LAN,
739 len_source: LenSource::Slice,
740 payload: &payload
741 })
742 );
743 }
744 }
745
746 #[test]
747 fn ip_payload() {
748 use alloc::vec::*;
749
750 assert_eq!(
752 LaxSlicedPacket {
753 link: None,
754 link_exts: ArrayVec::new_const(),
755 net: None,
756 transport: None,
757 stop_err: None,
758 }
759 .ip_payload(),
760 None
761 );
762
763 {
765 let payload = [1, 2, 3, 4];
766 let mut buf = Vec::with_capacity(Ipv4Header::MIN_LEN + 4);
767 buf.extend_from_slice(
768 &Ipv4Header {
769 protocol: IpNumber::ARIS,
770 total_len: Ipv4Header::MIN_LEN_U16 + 4,
771 ..Default::default()
772 }
773 .to_bytes(),
774 );
775 buf.extend_from_slice(&payload);
776 assert_eq!(
777 LaxSlicedPacket::from_ip(&buf).unwrap().ip_payload(),
778 Some(&LaxIpPayloadSlice {
779 payload: &payload,
780 ip_number: IpNumber::ARIS,
781 fragmented: false,
782 len_source: LenSource::Ipv4HeaderTotalLen,
783 incomplete: false,
784 })
785 );
786 }
787
788 {
790 let payload = [1, 2, 3, 4];
791 let mut buf = Vec::with_capacity(Ipv6Header::LEN + 4);
792 buf.extend_from_slice(
793 &Ipv6Header {
794 payload_length: 4,
795 next_header: IpNumber::ARGUS,
796 ..Default::default()
797 }
798 .to_bytes(),
799 );
800 buf.extend_from_slice(&payload);
801 assert_eq!(
802 LaxSlicedPacket::from_ip(&buf).unwrap().ip_payload(),
803 Some(&LaxIpPayloadSlice {
804 payload: &payload,
805 ip_number: IpNumber::ARGUS,
806 fragmented: false,
807 len_source: LenSource::Ipv6HeaderPayloadLen,
808 incomplete: false,
809 })
810 );
811 }
812 }
813
814 #[test]
815 fn from_x_slice() {
816 from_x_slice_link_exts_variants(&TestPacket {
818 link: None,
819 link_exts: ArrayVec::new_const(),
820 net: None,
821 transport: None,
822 });
823
824 {
826 let eth = Ethernet2Header {
827 source: [1, 2, 3, 4, 5, 6],
828 destination: [1, 2, 3, 4, 5, 6],
829 ether_type: 0.into(),
830 };
831 let test = TestPacket {
832 link: Some(LinkHeader::Ethernet2(eth.clone())),
833 link_exts: ArrayVec::new_const(),
834 net: None,
835 transport: None,
836 };
837
838 from_x_slice_link_exts_variants(&test);
840
841 {
843 let data = test.to_vec(&[]);
844 for len in 0..data.len() {
845 assert_test_result(&test, &[], &data[..len], None, None);
846 }
847 }
848 }
849
850 {
852 let payload = [1, 2, 3, 4];
853 let actual = LaxSlicedPacket::from_ether_type(0.into(), &payload);
854 assert_eq!(
855 actual.link,
856 Some(LinkSlice::EtherPayload(EtherPayloadSlice {
857 ether_type: 0.into(),
858 len_source: LenSource::Slice,
859 payload: &payload
860 }))
861 );
862 assert!(actual.link_exts.is_empty());
863 assert_eq!(None, actual.net);
864 assert_eq!(None, actual.transport);
865 assert_eq!(None, actual.stop_err);
866 }
867 }
868
869 fn from_x_slice_link_exts_variants(base: &TestPacket) {
870 #[derive(Copy, Clone, Eq, PartialEq)]
871 enum Ext {
872 Macsec,
873 VlanTaggedFrame,
874 VlanDoubleTaggedFrame,
875 ProviderBridging,
876 }
877
878 impl Ext {
879 pub fn ether_type(&self) -> EtherType {
880 match self {
881 Ext::Macsec => EtherType::MACSEC,
882 Ext::VlanTaggedFrame => EtherType::VLAN_TAGGED_FRAME,
883 Ext::VlanDoubleTaggedFrame => EtherType::VLAN_DOUBLE_TAGGED_FRAME,
884 Ext::ProviderBridging => EtherType::PROVIDER_BRIDGING,
885 }
886 }
887
888 pub fn add(&self, base: &TestPacket) -> TestPacket {
889 let mut test = base.clone();
890 test.set_ether_type(self.ether_type());
891 test.link_exts
892 .try_push(match self {
893 Ext::Macsec => LinkExtHeader::Macsec(MacsecHeader {
894 ptype: MacsecPType::Unmodified(EtherType(3)),
895 endstation_id: false,
896 scb: false,
897 an: MacsecAn::ZERO,
898 short_len: MacsecShortLen::ZERO,
899 packet_nr: 0,
900 sci: None,
901 }),
902 Ext::VlanTaggedFrame
903 | Ext::VlanDoubleTaggedFrame
904 | Ext::ProviderBridging => LinkExtHeader::Vlan(SingleVlanHeader {
905 pcp: VlanPcp::ZERO,
906 drop_eligible_indicator: false,
907 vlan_id: VlanId::try_new(1).unwrap(),
908 ether_type: 3.into(),
909 }),
910 })
911 .unwrap();
912 test
913 }
914 }
915
916 let len_errors = |test: &TestPacket| {
917 let data = test.to_vec(&[]);
918 let req_len = test.link_exts.last().unwrap().header_len();
919 for len in 0..req_len {
920 let base_len = test.len(&[]) - req_len;
921
922 let (err_req_len, err_layer) = match test.link_exts.last().unwrap() {
923 LinkExtHeader::Vlan(h) => (h.header_len(), Layer::VlanHeader),
924 LinkExtHeader::Macsec(_) => {
925 if len < 6 {
926 (6, Layer::MacsecHeader)
927 } else {
928 (req_len, Layer::MacsecHeader)
929 }
930 }
931 };
932
933 let mut len_source = LenSource::Slice;
934 for prev_exts in test.link_exts.iter().rev().skip(1) {
935 if let LinkExtHeader::Macsec(m) = prev_exts {
936 if m.short_len != MacsecShortLen::ZERO {
937 len_source = LenSource::MacsecShortLength;
938 }
939 }
940 }
941
942 let err = LenError {
943 required_len: err_req_len,
944 len,
945 len_source,
946 layer: err_layer,
947 layer_start_offset: base_len,
948 };
949 assert_test_result(
950 &test,
951 &[],
952 &data[..base_len + len],
953 None,
954 Some((SliceError::Len(err.clone()), err_layer)),
955 );
956 }
957 };
958
959 let content_errors = |test: &TestPacket| {
960 if let Some(LinkExtHeader::Macsec(last)) = test.link_exts.last() {
961 let mut data = test.to_vec(&[]);
962
963 let macsec_offset = data.len() - last.header_len();
965 data[macsec_offset] = data[macsec_offset] | 0b1000_0000;
966
967 assert_test_result(
968 &{
969 let mut expected = test.clone();
970 expected.link_exts.pop();
971 expected
972 },
973 &[],
974 &data,
975 None,
976 Some((
977 SliceError::Macsec(err::macsec::HeaderError::UnexpectedVersion),
978 Layer::MacsecHeader,
979 )),
980 );
981 }
982 };
983
984 let extensions = [
986 Ext::Macsec,
987 Ext::VlanTaggedFrame,
988 Ext::VlanDoubleTaggedFrame,
989 Ext::ProviderBridging,
990 ];
991
992 from_x_slice_net_variants(base);
994
995 for ext0 in extensions {
997 let test0 = ext0.add(base);
998 from_x_slice_net_variants(&test0);
999 len_errors(&test0);
1000 content_errors(&test0);
1001
1002 for ext1 in extensions {
1003 let test1 = ext1.add(&test0);
1004 from_x_slice_net_variants(&test1);
1005 len_errors(&test1);
1006 content_errors(&test1);
1007
1008 for ext2 in extensions {
1009 let test2 = ext2.add(&test1);
1010 from_x_slice_net_variants(&test2);
1011 len_errors(&test2);
1012 content_errors(&test2);
1013
1014 for ext3 in extensions {
1016 let mut test3 = test2.clone();
1017 let l = test3.link_exts.last_mut().unwrap();
1018 match l {
1019 LinkExtHeader::Vlan(s) => {
1020 s.ether_type = ext3.ether_type();
1021 }
1022 LinkExtHeader::Macsec(m) => {
1023 m.ptype = MacsecPType::Unmodified(ext3.ether_type());
1024 }
1025 }
1026 from_x_slice_assert_ok(&test3);
1027 }
1028 }
1029 }
1030 }
1031 }
1032
1033 fn from_x_slice_net_variants(base: &TestPacket) {
1034 from_x_slice_transport_variants(base);
1036
1037 for fragmented in [false, true] {
1039 let ipv4 = {
1040 let mut ipv4 =
1041 Ipv4Header::new(0, 1, 2.into(), [3, 4, 5, 6], [7, 8, 9, 10]).unwrap();
1042 ipv4.more_fragments = fragmented;
1043 ipv4
1044 };
1045
1046 {
1047 let mut test = base.clone();
1048 test.set_ether_type(ether_type::IPV4);
1049 test.net = Some(NetHeaders::Ipv4(ipv4.clone(), Default::default()));
1050 test.set_payload_len(0);
1051
1052 from_x_slice_transport_variants(&test);
1054
1055 {
1057 let data = test.to_vec(&[]);
1058 for len in 0..ipv4.header_len() {
1059 let base_len = test.len(&[]) - ipv4.header_len();
1060
1061 let err = LenError {
1062 required_len: if len < 1 { 1 } else { ipv4.header_len() },
1063 len,
1064 len_source: LenSource::Slice,
1065 layer: if len < 1 {
1066 Layer::IpHeader
1067 } else {
1068 Layer::Ipv4Header
1069 },
1070 layer_start_offset: base_len,
1071 };
1072
1073 assert_test_result(
1074 &test,
1075 &[],
1076 &data[..base_len + len],
1077 Some(err::ip::LaxHeaderSliceError::Len(err.clone())),
1078 Some((SliceError::Len(err.clone()), Layer::IpHeader)),
1079 );
1080 }
1081 }
1082
1083 {
1085 use err::ip::HeaderError::*;
1086
1087 let mut data = test.to_vec(&[]);
1088 let ipv4_offset = data.len() - ipv4.header_len();
1089
1090 data[ipv4_offset] = 0b1111_0000 & data[ipv4_offset];
1092
1093 assert_test_result(
1094 &test,
1095 &[],
1096 &data,
1097 Some(err::ip::LaxHeaderSliceError::Content(
1098 Ipv4HeaderLengthSmallerThanHeader { ihl: 0 },
1099 )),
1100 Some((
1101 SliceError::Ip(Ipv4HeaderLengthSmallerThanHeader { ihl: 0 }),
1102 Layer::IpHeader,
1103 )),
1104 );
1105 }
1106
1107 {
1109 let mut data = test.to_vec(&[]);
1110 let ipv4_offset = data.len() - ipv4.header_len();
1111
1112 data[ipv4_offset + 2] = 0;
1114 data[ipv4_offset + 3] = 0;
1115
1116 let mut mod_test = test.clone();
1117 mod_test.net = Some({
1118 let (h, e) = test.net.as_ref().map(|v| v.ipv4_ref()).flatten().unwrap();
1119 let mut ipv4 = h.clone();
1120 ipv4.total_len = 0;
1121 NetHeaders::Ipv4(ipv4, e.clone())
1122 });
1123
1124 assert_test_result(&mod_test, &[], &data, None, None);
1125 }
1126 }
1127
1128 {
1130 let auth = IpAuthHeader::new(0.into(), 1, 2, &[]).unwrap();
1131
1132 let mut test = base.clone();
1133 test.set_ether_type(ether_type::IPV4);
1134 test.net = Some(NetHeaders::Ipv4(
1135 {
1136 let mut ipv4 = ipv4.clone();
1137 ipv4.protocol = ip_number::AUTH;
1138 ipv4
1139 },
1140 Ipv4Extensions {
1141 auth: Some(auth.clone()),
1142 },
1143 ));
1144 test.set_payload_len(0);
1145
1146 from_x_slice_transport_variants(&test);
1148
1149 for len in 0..auth.header_len() {
1151 let mut test = test.clone();
1153 test.set_payload_len_ip(-1 * (auth.header_len() as isize) + (len as isize));
1154
1155 let data = test.to_vec(&[]);
1156 let base_len = test.len(&[]) - auth.header_len();
1157
1158 let err = LenError {
1159 required_len: auth.header_len(),
1160 len,
1161 len_source: LenSource::Ipv4HeaderTotalLen,
1162 layer: Layer::IpAuthHeader,
1163 layer_start_offset: base_len,
1164 };
1165
1166 assert_test_result(
1167 &test,
1168 &[],
1169 &data,
1170 None,
1171 Some((SliceError::Len(err.clone()), Layer::IpAuthHeader)),
1172 );
1173 }
1174
1175 {
1177 let mut data = test.to_vec(&[]);
1178 let auth_offset = data.len() - auth.header_len();
1179
1180 data[auth_offset + 1] = 0;
1182
1183 assert_test_result(
1185 &test,
1186 &[],
1187 &data,
1188 None,
1189 Some((
1190 SliceError::Ipv4Exts(err::ip_auth::HeaderError::ZeroPayloadLen),
1191 Layer::IpAuthHeader,
1192 )),
1193 );
1194 }
1195 }
1196 }
1197
1198 {
1200 let ipv6 = Ipv6Header {
1201 traffic_class: 0,
1202 flow_label: 1.try_into().unwrap(),
1203 payload_length: 2,
1204 next_header: 3.into(),
1205 hop_limit: 4,
1206 source: [0; 16],
1207 destination: [0; 16],
1208 };
1209
1210 {
1212 let mut test = base.clone();
1213 test.set_ether_type(ether_type::IPV6);
1214 test.net = Some(NetHeaders::Ipv6(ipv6.clone(), Default::default()));
1215 test.set_payload_len(0);
1216
1217 from_x_slice_transport_variants(&test);
1219
1220 {
1222 let data = test.to_vec(&[]);
1223 for len in 0..ipv6.header_len() {
1224 let base_len = test.len(&[]) - ipv6.header_len();
1225
1226 let err = err::LenError {
1227 required_len: if len < 1 { 1 } else { ipv6.header_len() },
1228 len,
1229 len_source: LenSource::Slice,
1230 layer: if len < 1 {
1231 Layer::IpHeader
1232 } else {
1233 Layer::Ipv6Header
1234 },
1235 layer_start_offset: base_len,
1236 };
1237
1238 assert_test_result(
1239 &test,
1240 &[],
1241 &data[..base_len + len],
1242 Some(err::ip::LaxHeaderSliceError::Len(err.clone())),
1243 Some((
1244 SliceError::Len({
1245 if len < 1 {
1246 let mut err = err.clone();
1247 err.required_len = 1;
1248 err.layer = Layer::IpHeader;
1249 err
1250 } else {
1251 err.clone()
1252 }
1253 }),
1254 Layer::IpHeader,
1255 )),
1256 );
1257 }
1258 }
1259
1260 {
1262 use err::ip::{HeaderError::*, LaxHeaderSliceError::Content};
1263
1264 let mut data = test.to_vec(&[]);
1265
1266 let base_len = data.len() - ipv6.header_len();
1268 data[base_len] = data[base_len] & 0b0000_1111;
1269
1270 assert_test_result(
1271 &test,
1272 &[],
1273 &data,
1274 Some(Content(UnsupportedIpVersion { version_number: 0 })),
1275 Some((
1276 SliceError::Ip(UnsupportedIpVersion { version_number: 0 }),
1277 Layer::IpHeader,
1278 )),
1279 );
1280 }
1281 }
1282
1283 for fragment in [false, true] {
1285 let auth = IpAuthHeader::new(ip_number::GGP, 1, 2, &[]).unwrap();
1286 let frag = Ipv6FragmentHeader {
1287 next_header: ip_number::AUTH,
1288 fragment_offset: 0.try_into().unwrap(),
1289 more_fragments: fragment,
1290 identification: 3,
1291 };
1292
1293 let mut test = base.clone();
1294 test.set_ether_type(ether_type::IPV6);
1295 test.net = Some(NetHeaders::Ipv6(
1296 {
1297 let mut ipv6 = ipv6.clone();
1298 ipv6.next_header = ip_number::IPV6_FRAG;
1299 ipv6
1300 },
1301 {
1302 let mut exts: Ipv6Extensions = Default::default();
1303 exts.fragment = Some(frag.clone());
1304 exts.auth = Some(auth.clone());
1305 exts
1306 },
1307 ));
1308 test.set_payload_len(0);
1309
1310 from_x_slice_transport_variants(&test);
1312
1313 for len in 0..auth.header_len() {
1315 let mut test = test.clone();
1317 test.set_payload_len_ip(-1 * (auth.header_len() as isize) + (len as isize));
1318
1319 let data = test.to_vec(&[]);
1320 let base_len = test.len(&[]) - auth.header_len();
1321
1322 let err = LenError {
1323 required_len: auth.header_len(),
1324 len,
1325 len_source: LenSource::Ipv6HeaderPayloadLen,
1326 layer: Layer::IpAuthHeader,
1327 layer_start_offset: base_len,
1328 };
1329 assert_test_result(
1330 &test,
1331 &[],
1332 &data[..base_len + len],
1333 None,
1334 Some((SliceError::Len(err.clone()), Layer::IpAuthHeader)),
1335 );
1336 }
1337
1338 {
1340 let mut data = test.to_vec(&[]);
1341 let auth_offset = data.len() - auth.header_len();
1342 data[auth_offset + 1] = 0;
1344
1345 assert_test_result(
1346 &test,
1347 &[],
1348 &data,
1349 None,
1350 Some((
1351 SliceError::Ipv6Exts(err::ipv6_exts::HeaderError::IpAuth(
1352 err::ip_auth::HeaderError::ZeroPayloadLen,
1353 )),
1354 Layer::IpAuthHeader,
1355 )),
1356 );
1357 }
1358
1359 {
1361 let mut data = test.to_vec(&[]);
1362 let auth_offset = data.len() - auth.header_len();
1363
1364 data[auth_offset] = 0;
1366
1367 assert_test_result(
1368 &test,
1369 &[],
1370 &data,
1371 None,
1372 Some((
1373 SliceError::Ipv6Exts(err::ipv6_exts::HeaderError::HopByHopNotAtStart),
1374 Layer::Ipv6HopByHopHeader,
1375 )),
1376 );
1377 }
1378 }
1379 }
1380
1381 {
1383 let arp = ArpPacket::new(
1384 ArpHardwareId::ETHERNET,
1385 EtherType::IPV4,
1386 ArpOperation::REPLY,
1387 &[0u8; 6],
1388 &[0u8; 4],
1389 &[0u8; 6],
1390 &[0u8; 4],
1391 )
1392 .unwrap();
1393
1394 let mut test = base.clone();
1395 test.set_ether_type(ether_type::ARP);
1396 test.net = Some(NetHeaders::Arp(arp.clone()));
1397 test.set_payload_len(0);
1398
1399 from_x_slice_assert_ok(&test);
1401
1402 {
1404 let data = test.to_vec(&[]);
1405 for len in 0..arp.packet_len() {
1406 let base_len = test.len(&[]) - arp.packet_len();
1407
1408 let err = err::LenError {
1409 required_len: if len < 8 { 8 } else { arp.packet_len() },
1410 len,
1411 len_source: if len < 8 {
1412 LenSource::Slice
1413 } else {
1414 LenSource::ArpAddrLengths
1415 },
1416 layer: Layer::Arp,
1417 layer_start_offset: base_len,
1418 };
1419
1420 assert_test_result(
1421 &test,
1422 &[],
1423 &data[..base_len + len],
1424 Some(err::ip::LaxHeaderSliceError::Len(err.clone())),
1425 Some((
1426 SliceError::Len({
1427 if len < 8 {
1428 let mut err = err.clone();
1429 err.required_len = 8;
1430 err.layer = Layer::Arp;
1431 err
1432 } else {
1433 err.clone()
1434 }
1435 }),
1436 Layer::Arp,
1437 )),
1438 );
1439 }
1440 }
1441 }
1442 }
1443
1444 fn from_x_slice_transport_variants(base: &TestPacket) {
1445 from_x_slice_assert_ok(base);
1447
1448 if let Some(ip) = &base.net {
1450 {
1452 let udp = UdpHeader {
1453 source_port: 1,
1454 destination_port: 2,
1455 length: 3,
1456 checksum: 4,
1457 };
1458 let mut test = base.clone();
1459 test.net = Some({
1460 let mut ip = match ip {
1461 NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()),
1462 NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()),
1463 NetHeaders::Arp(_) => unreachable!(),
1464 };
1465 ip.set_next_headers(ip_number::UDP);
1466 ip.into()
1467 });
1468 test.transport = Some(TransportHeader::Udp(udp.clone()));
1469 test.set_payload_len(0);
1470
1471 from_x_slice_assert_ok(&test);
1473
1474 if false == test.is_ip_payload_fragmented() {
1476 for len in 0..udp.header_len() {
1477 let mut test = test.clone();
1479
1480 test.set_payload_len_ip(len as isize);
1482
1483 let data = test.to_vec(&[]);
1485
1486 let base_len = test.len(&[]) - udp.header_len();
1487 let err = LenError {
1488 required_len: udp.header_len(),
1489 len,
1490 len_source: match test.net.as_ref().unwrap() {
1491 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen,
1492 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen,
1493 NetHeaders::Arp(_) => unreachable!(),
1494 },
1495 layer: Layer::UdpHeader,
1496 layer_start_offset: base_len,
1497 };
1498 assert_test_result(
1499 &test,
1500 &[],
1501 &data[..base_len + len],
1502 None,
1503 Some((SliceError::Len(err.clone()), Layer::UdpHeader)),
1504 );
1505 }
1506 }
1507 }
1508
1509 {
1511 let tcp = TcpHeader::new(1, 2, 3, 4);
1512 let mut test = base.clone();
1513 test.net = Some({
1514 let mut ip = match ip {
1515 NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()),
1516 NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()),
1517 NetHeaders::Arp(_) => unreachable!(),
1518 };
1519 ip.set_next_headers(ip_number::TCP);
1520 ip.into()
1521 });
1522 test.transport = Some(TransportHeader::Tcp(tcp.clone()));
1523 test.set_payload_len(0);
1524
1525 from_x_slice_assert_ok(&test);
1527
1528 if false == test.is_ip_payload_fragmented() {
1530 {
1532 for len in 0..(tcp.header_len() as usize) {
1533 let mut test = test.clone();
1535 test.set_payload_len_ip(len as isize);
1536
1537 let data = test.to_vec(&[]);
1538 let base_len = test.len(&[]) - (tcp.header_len() as usize);
1539
1540 let err = LenError {
1541 required_len: tcp.header_len() as usize,
1542 len,
1543 len_source: match test.net.as_ref().unwrap() {
1544 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen,
1545 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen,
1546 NetHeaders::Arp(_) => unreachable!(),
1547 },
1548 layer: Layer::TcpHeader,
1549 layer_start_offset: base_len,
1550 };
1551 assert_test_result(
1552 &test,
1553 &[],
1554 &data[..base_len + len],
1555 None,
1556 Some((SliceError::Len(err.clone()), Layer::TcpHeader)),
1557 );
1558 }
1559 }
1560
1561 {
1563 let mut data = test.to_vec(&[]);
1564 let base_len = test.len(&[]) - (tcp.header_len() as usize);
1565
1566 data[base_len + 12] = data[base_len + 12] & 0b0000_1111;
1568
1569 let err = err::tcp::HeaderError::DataOffsetTooSmall { data_offset: 0 };
1570 assert_test_result(
1571 &test,
1572 &[],
1573 &data,
1574 None,
1575 Some((SliceError::Tcp(err.clone()), Layer::TcpHeader)),
1576 );
1577 }
1578 }
1579 }
1580
1581 {
1583 let icmpv4 =
1584 Icmpv4Header::new(Icmpv4Type::EchoReply(IcmpEchoHeader { id: 1, seq: 2 }));
1585 let mut test = base.clone();
1586 test.net = Some({
1587 let mut ip = match ip {
1588 NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()),
1589 NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()),
1590 NetHeaders::Arp(_) => unreachable!(),
1591 };
1592 ip.set_next_headers(ip_number::ICMP);
1593 ip.into()
1594 });
1595 test.transport = Some(TransportHeader::Icmpv4(icmpv4.clone()));
1596 test.set_payload_len(0);
1597
1598 from_x_slice_assert_ok(&test);
1600
1601 if false == test.is_ip_payload_fragmented() {
1603 for len in 0..icmpv4.header_len() {
1604 let mut test = test.clone();
1606 test.set_payload_len_ip(len as isize);
1607
1608 let data = test.to_vec(&[]);
1609 let base_len = test.len(&[]) - icmpv4.header_len();
1610
1611 let err = LenError {
1612 required_len: icmpv4.header_len(),
1613 len,
1614 len_source: match test.net.as_ref().unwrap() {
1615 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen,
1616 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen,
1617 NetHeaders::Arp(_) => unreachable!(),
1618 },
1619 layer: Layer::Icmpv4,
1620 layer_start_offset: base_len,
1621 };
1622 assert_test_result(
1623 &test,
1624 &[],
1625 &data[..base_len + len],
1626 None,
1627 Some((SliceError::Len(err.clone()), Layer::Icmpv4)),
1628 );
1629 }
1630 }
1631 }
1632
1633 {
1635 let icmpv6 =
1636 Icmpv6Header::new(Icmpv6Type::EchoReply(IcmpEchoHeader { id: 1, seq: 2 }));
1637 let mut test = base.clone();
1638 test.net = Some({
1639 let mut ip = match ip {
1640 NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()),
1641 NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()),
1642 NetHeaders::Arp(_) => unreachable!(),
1643 };
1644 ip.set_next_headers(ip_number::IPV6_ICMP);
1645 ip.into()
1646 });
1647 test.transport = Some(TransportHeader::Icmpv6(icmpv6.clone()));
1648 test.set_payload_len(0);
1649
1650 from_x_slice_assert_ok(&test);
1652
1653 if false == test.is_ip_payload_fragmented() {
1655 for len in 0..icmpv6.header_len() {
1656 let mut test = test.clone();
1658 test.set_payload_len_ip(len as isize);
1659
1660 let data = test.to_vec(&[]);
1661 let base_len = test.len(&[]) - icmpv6.header_len();
1662
1663 let err = LenError {
1664 required_len: icmpv6.header_len(),
1665 len,
1666 len_source: match test.net.as_ref().unwrap() {
1667 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen,
1668 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen,
1669 NetHeaders::Arp(_) => unreachable!(),
1670 },
1671 layer: Layer::Icmpv6,
1672 layer_start_offset: base_len,
1673 };
1674 assert_test_result(
1675 &test,
1676 &[],
1677 &data[..base_len + len],
1678 None,
1679 Some((SliceError::Len(err.clone()), Layer::Icmpv6)),
1680 );
1681 }
1682 }
1683 }
1684 }
1685 }
1686
1687 fn from_x_slice_assert_ok(test_base: &TestPacket) {
1688 let payload = [1, 2, 3, 4];
1690
1691 let test = {
1693 let mut test = test_base.clone();
1694 test.set_payload_len(payload.len());
1695 test
1696 };
1697
1698 let data = test.to_vec(&payload);
1700 assert_test_result(&test, &payload, &data, None, None);
1701 }
1702
1703 fn assert_test_result(
1706 test: &TestPacket,
1707 expected_payload: &[u8],
1708 data: &[u8],
1709 expected_ip_err: Option<err::ip::LaxHeaderSliceError>,
1710 expected_stop_err: Option<(SliceError, Layer)>,
1711 ) {
1712 fn compare_link_exts(test: &TestPacket, data: &[u8], actual: &LaxSlicedPacket) {
1713 let mut next_offset = if let Some(e) = test.link.as_ref() {
1714 e.header_len()
1715 } else {
1716 0
1717 };
1718 let mut expected = ArrayVec::<LinkExtHeader, 3>::new();
1719 for e in &test.link_exts {
1720 match &e {
1721 LinkExtHeader::Vlan(s) => {
1722 if data.len() >= next_offset + s.header_len() {
1723 expected.push(e.clone());
1724 next_offset += s.header_len();
1725 } else {
1726 break;
1727 }
1728 }
1729 LinkExtHeader::Macsec(m) => {
1730 if data.len() >= next_offset + m.header_len() {
1731 expected.push(e.clone());
1732 next_offset += m.header_len();
1733 } else {
1734 break;
1735 }
1736 }
1737 }
1738 }
1739 assert_eq!(
1740 expected,
1741 actual
1742 .link_exts
1743 .as_ref()
1744 .iter()
1745 .map(|v| v.to_header())
1746 .collect::<ArrayVec<LinkExtHeader, 3>>()
1747 );
1748 }
1749
1750 fn compare_ip(test: &TestPacket, actual: &LaxSlicedPacket) {
1751 assert_eq!(
1752 test.net,
1753 actual.net.as_ref().map(|s| -> NetHeaders {
1754 match s {
1755 LaxNetSlice::Ipv4(ipv4) => NetHeaders::Ipv4(
1756 ipv4.header().to_header(),
1757 ipv4.extensions().to_header(),
1758 ),
1759 LaxNetSlice::Ipv6(ipv6) => NetHeaders::Ipv6(
1760 ipv6.header().to_header(),
1761 Ipv6Extensions::from_slice(
1762 ipv6.header().next_header(),
1763 ipv6.extensions().slice(),
1764 )
1765 .unwrap()
1766 .0,
1767 ),
1768 LaxNetSlice::Arp(arp) => NetHeaders::Arp(arp.to_packet()),
1769 }
1770 })
1771 );
1772 }
1773
1774 fn compare_net_header_only(test: &TestPacket, actual: &LaxSlicedPacket) {
1775 assert_eq!(
1776 test.net.as_ref().map(|s| -> NetHeaders {
1777 match s {
1778 NetHeaders::Ipv4(h, _) => NetHeaders::Ipv4(h.clone(), Default::default()),
1779 NetHeaders::Ipv6(h, _) => NetHeaders::Ipv6(h.clone(), Default::default()),
1780 NetHeaders::Arp(h) => NetHeaders::Arp(h.clone()),
1781 }
1782 }),
1783 actual.net.as_ref().map(|s| -> NetHeaders {
1784 match s {
1785 LaxNetSlice::Ipv4(ipv4) => {
1786 NetHeaders::Ipv4(ipv4.header().to_header(), Default::default())
1787 }
1788 LaxNetSlice::Ipv6(ipv6) => {
1789 NetHeaders::Ipv6(ipv6.header().to_header(), Default::default())
1790 }
1791 LaxNetSlice::Arp(arp) => NetHeaders::Arp(arp.to_packet()),
1792 }
1793 })
1794 );
1795 }
1796
1797 fn compare_transport(
1798 test: &TestPacket,
1799 is_fragmented: bool,
1800 expected_payload: &[u8],
1801 actual: &LaxSlicedPacket,
1802 ) {
1803 if is_fragmented {
1804 assert_eq!(actual.transport, None);
1805 } else {
1806 use TransportHeader as H;
1807 use TransportSlice as S;
1808 match &actual.transport {
1809 Some(S::Icmpv4(icmpv4)) => {
1810 assert_eq!(&test.transport, &Some(H::Icmpv4(icmpv4.header())));
1811 assert_eq!(icmpv4.payload(), expected_payload);
1812 }
1813 Some(S::Icmpv6(icmpv6)) => {
1814 assert_eq!(&test.transport, &Some(H::Icmpv6(icmpv6.header())));
1815 assert_eq!(icmpv6.payload(), expected_payload);
1816 }
1817 Some(S::Udp(s)) => {
1818 assert_eq!(&test.transport, &Some(H::Udp(s.to_header())));
1819 }
1820 Some(S::Tcp(s)) => {
1821 assert_eq!(&test.transport, &Some(H::Tcp(s.to_header())));
1822 }
1823 None => {
1824 assert_eq!(&test.transport, &None);
1825 }
1826 }
1827 }
1828 }
1829
1830 if test.link.is_some() {
1832 if data.len() < Ethernet2Header::LEN {
1833 assert_eq!(
1834 LenError {
1835 required_len: Ethernet2Header::LEN,
1836 len: data.len(),
1837 len_source: LenSource::Slice,
1838 layer: Layer::Ethernet2Header,
1839 layer_start_offset: 0
1840 },
1841 LaxSlicedPacket::from_ethernet(&data).unwrap_err()
1842 );
1843 } else {
1844 let actual = LaxSlicedPacket::from_ethernet(&data).unwrap();
1845 assert_eq!(actual.stop_err, expected_stop_err);
1846 match expected_stop_err.as_ref().map(|v| v.1) {
1847 None => {
1848 assert_eq!(
1849 test.link,
1850 actual.link.as_ref().map(|v| v.to_header()).flatten()
1851 );
1852 compare_link_exts(test, data, &actual);
1853 compare_ip(test, &actual);
1854 compare_transport(
1855 test,
1856 test.is_ip_payload_fragmented(),
1857 expected_payload,
1858 &actual,
1859 );
1860 }
1861 Some(Layer::VlanHeader) | Some(Layer::MacsecHeader) => {
1862 assert_eq!(
1863 test.link,
1864 actual.link.as_ref().map(|v| v.to_header()).flatten()
1865 );
1866 compare_link_exts(test, data, &actual);
1867 assert_eq!(None, actual.net);
1868 assert_eq!(None, actual.transport);
1869 }
1870 Some(Layer::Ipv6Header)
1871 | Some(Layer::Ipv4Header)
1872 | Some(Layer::IpHeader)
1873 | Some(Layer::Arp) => {
1874 assert_eq!(
1875 test.link,
1876 actual.link.as_ref().map(|v| v.to_header()).flatten()
1877 );
1878 compare_link_exts(test, data, &actual);
1879 assert_eq!(None, actual.net);
1880 assert_eq!(None, actual.transport);
1881 }
1882 Some(Layer::IpAuthHeader)
1883 | Some(Layer::Ipv6ExtHeader)
1884 | Some(Layer::Ipv6HopByHopHeader)
1885 | Some(Layer::Ipv6DestOptionsHeader)
1886 | Some(Layer::Ipv6RouteHeader)
1887 | Some(Layer::Ipv6FragHeader) => {
1888 assert_eq!(
1889 test.link,
1890 actual.link.as_ref().map(|v| v.to_header()).flatten()
1891 );
1892 compare_link_exts(test, data, &actual);
1893 compare_net_header_only(test, &actual);
1894 assert_eq!(None, actual.transport);
1895 }
1896 Some(Layer::TcpHeader)
1897 | Some(Layer::UdpHeader)
1898 | Some(Layer::Icmpv4)
1899 | Some(Layer::Icmpv6) => {
1900 assert_eq!(
1901 test.link,
1902 actual.link.as_ref().map(|v| v.to_header()).flatten()
1903 );
1904 compare_link_exts(test, data, &actual);
1905 compare_ip(test, &actual);
1906 assert_eq!(None, actual.transport);
1907 }
1908 _ => unreachable!("error in an unexpected layer"),
1909 }
1910 }
1911 }
1912 if test.link.is_none() && !test.link_exts.is_empty() {
1914 let ether_types: &[EtherType] = match test.link_exts.first().unwrap() {
1915 LinkExtHeader::Vlan(_) => &VLAN_ETHER_TYPES,
1916 LinkExtHeader::Macsec(_) => &MACSEC_ETHER_TYPES,
1917 };
1918 for ether_type in ether_types {
1919 let actual = LaxSlicedPacket::from_ether_type(*ether_type, data);
1920 assert_eq!(actual.stop_err, expected_stop_err);
1921 assert_eq!(
1922 Some(LinkSlice::EtherPayload(EtherPayloadSlice {
1923 ether_type: *ether_type,
1924 len_source: LenSource::Slice,
1925 payload: data
1926 })),
1927 actual.link
1928 );
1929 compare_link_exts(test, data, &actual);
1930 match expected_stop_err.as_ref().map(|v| v.1) {
1931 None => {
1932 compare_ip(test, &actual);
1933 compare_transport(
1934 test,
1935 test.is_ip_payload_fragmented(),
1936 expected_payload,
1937 &actual,
1938 );
1939 }
1940 Some(Layer::VlanHeader) | Some(Layer::MacsecHeader) => {
1941 assert_eq!(None, actual.net);
1942 assert_eq!(None, actual.transport);
1943 }
1944 Some(Layer::Ipv6Header)
1945 | Some(Layer::Ipv4Header)
1946 | Some(Layer::IpHeader)
1947 | Some(Layer::Arp) => {
1948 assert_eq!(None, actual.net);
1949 assert_eq!(None, actual.transport);
1950 }
1951 Some(Layer::IpAuthHeader)
1952 | Some(Layer::Ipv6ExtHeader)
1953 | Some(Layer::Ipv6HopByHopHeader)
1954 | Some(Layer::Ipv6DestOptionsHeader)
1955 | Some(Layer::Ipv6RouteHeader)
1956 | Some(Layer::Ipv6FragHeader) => {
1957 compare_net_header_only(test, &actual);
1958 assert_eq!(None, actual.transport);
1959 }
1960 Some(Layer::TcpHeader)
1961 | Some(Layer::UdpHeader)
1962 | Some(Layer::Icmpv4)
1963 | Some(Layer::Icmpv6) => {
1964 compare_ip(test, &actual);
1965 assert_eq!(None, actual.transport);
1966 }
1967 _ => unreachable!("error in an unexpected layer"),
1968 }
1969 }
1970 }
1971 if test.link.is_none() && test.link_exts.is_empty() {
1973 if let Some(ip) = &test.net {
1974 let ether_type = match ip {
1975 NetHeaders::Ipv4(_, _) => ether_type::IPV4,
1976 NetHeaders::Ipv6(_, _) => ether_type::IPV6,
1977 NetHeaders::Arp(_) => ether_type::ARP,
1978 };
1979 let actual = LaxSlicedPacket::from_ether_type(ether_type, &data);
1980 assert_eq!(actual.stop_err, expected_stop_err);
1981 assert_eq!(
1982 Some(LinkSlice::EtherPayload(EtherPayloadSlice {
1983 ether_type,
1984 len_source: LenSource::Slice,
1985 payload: data
1986 })),
1987 actual.link
1988 );
1989 assert!(actual.link_exts.is_empty());
1990 match expected_stop_err.as_ref().map(|v| v.1) {
1991 None => {
1992 compare_ip(test, &actual);
1993 compare_transport(
1994 test,
1995 test.is_ip_payload_fragmented(),
1996 expected_payload,
1997 &actual,
1998 );
1999 }
2000 Some(Layer::Ipv6Header)
2001 | Some(Layer::Ipv4Header)
2002 | Some(Layer::IpHeader)
2003 | Some(Layer::Arp) => {
2004 assert_eq!(None, actual.net);
2005 assert_eq!(None, actual.transport);
2006 }
2007 Some(Layer::IpAuthHeader)
2008 | Some(Layer::Ipv6ExtHeader)
2009 | Some(Layer::Ipv6HopByHopHeader)
2010 | Some(Layer::Ipv6DestOptionsHeader)
2011 | Some(Layer::Ipv6RouteHeader)
2012 | Some(Layer::Ipv6FragHeader) => {
2013 compare_net_header_only(test, &actual);
2014 assert_eq!(None, actual.transport);
2015 }
2016 Some(Layer::TcpHeader)
2017 | Some(Layer::UdpHeader)
2018 | Some(Layer::Icmpv4)
2019 | Some(Layer::Icmpv6) => {
2020 compare_ip(test, &actual);
2021 assert_eq!(None, actual.transport);
2022 }
2023 _ => unreachable!("error in an unexpected layer"),
2024 }
2025 }
2026 }
2027 if test.link.is_none()
2029 && test.link_exts.is_empty()
2030 && matches!(
2031 test.net,
2032 Some(NetHeaders::Ipv4(_, _)) | Some(NetHeaders::Ipv6(_, _))
2033 )
2034 {
2035 if let Some(err) = expected_ip_err {
2036 assert_eq!(err, LaxSlicedPacket::from_ip(&data).unwrap_err());
2037 } else {
2038 let actual = LaxSlicedPacket::from_ip(&data).unwrap();
2039 assert_eq!(actual.stop_err, expected_stop_err);
2040 assert_eq!(actual.link, None);
2041 assert!(actual.link_exts.is_empty());
2042 match expected_stop_err.as_ref().map(|v| v.1) {
2043 None => {
2044 compare_ip(test, &actual);
2045 compare_transport(
2046 test,
2047 test.is_ip_payload_fragmented(),
2048 expected_payload,
2049 &actual,
2050 );
2051 }
2052 Some(Layer::IpAuthHeader)
2053 | Some(Layer::Ipv6ExtHeader)
2054 | Some(Layer::Ipv6HopByHopHeader)
2055 | Some(Layer::Ipv6DestOptionsHeader)
2056 | Some(Layer::Ipv6RouteHeader)
2057 | Some(Layer::Ipv6FragHeader) => {
2058 compare_net_header_only(test, &actual);
2059 assert_eq!(None, actual.transport);
2060 }
2061 Some(Layer::TcpHeader)
2062 | Some(Layer::UdpHeader)
2063 | Some(Layer::Icmpv4)
2064 | Some(Layer::Icmpv6) => {
2065 compare_ip(test, &actual);
2066 assert_eq!(None, actual.transport);
2067 }
2068 _ => unreachable!("error in an unexpected layer"),
2069 }
2070 }
2071 }
2072 }
2073}