1use arrayvec::ArrayVec;
2
3use crate::*;
4
5#[derive(Clone, Debug, Eq, PartialEq)]
48pub struct SlicedPacket<'a> {
49 pub link: Option<LinkSlice<'a>>,
51
52 pub link_exts: ArrayVec<LinkExtSlice<'a>, { SlicedPacket::LINK_EXTS_CAP }>,
54
55 pub net: Option<NetSlice<'a>>,
57
58 pub transport: Option<TransportSlice<'a>>,
60}
61
62impl<'a> SlicedPacket<'a> {
63 pub const LINK_EXTS_CAP: usize = 3;
65
66 pub fn from_ethernet(data: &'a [u8]) -> Result<SlicedPacket<'a>, err::packet::SliceError> {
102 SlicedPacketCursor::new().slice_ethernet2(data)
103 }
104
105 pub fn from_linux_sll(data: &'a [u8]) -> Result<SlicedPacket<'a>, err::packet::SliceError> {
144 SlicedPacketCursor::new().slice_linux_sll(data)
145 }
146
147 pub fn from_ether_type(
201 ether_type: EtherType,
202 data: &'a [u8],
203 ) -> Result<SlicedPacket<'a>, err::packet::SliceError> {
204 let mut cursor = SlicedPacketCursor::new();
205 cursor.result.link = Some(LinkSlice::EtherPayload(EtherPayloadSlice {
206 ether_type,
207 len_source: LenSource::Slice,
208 payload: data,
209 }));
210 cursor.slice_ether_type(EtherPayloadSlice {
211 ether_type,
212 len_source: LenSource::Slice,
213 payload: data,
214 })
215 }
216
217 pub fn from_ip(data: &'a [u8]) -> Result<SlicedPacket<'a>, err::packet::SliceError> {
254 SlicedPacketCursor::new().slice_ip(data)
255 }
256
257 pub fn payload_ether_type(&self) -> Option<EtherType> {
267 if self.net.is_some() || self.transport.is_some() {
268 None
269 } else if let Some(last_ext) = &self.link_exts.last() {
270 use LinkExtSlice::*;
271 match last_ext {
272 Vlan(single_vlan_slice) => Some(single_vlan_slice.ether_type()),
273 Macsec(macsec_slice) => macsec_slice.next_ether_type(),
274 }
275 } else if let Some(link) = &self.link {
276 use LinkSlice::*;
277 match link {
278 Ethernet2(eth) => Some(eth.ether_type()),
279 LinkSlice::LinuxSll(e) => match e.protocol_type() {
280 LinuxSllProtocolType::EtherType(EtherType(v)) => Some(EtherType(v)),
281 _ => None,
282 },
283 EtherPayload(e) => Some(e.ether_type),
284 LinkSlice::LinuxSllPayload(e) => match e.protocol_type {
285 LinuxSllProtocolType::EtherType(EtherType(v)) => Some(EtherType(v)),
286 _ => None,
287 },
288 }
289 } else {
290 None
291 }
292 }
293
294 pub fn ether_payload(&self) -> Option<EtherPayloadSlice<'a>> {
300 if let Some(last_ext) = self.link_exts.last() {
301 let mut len_source = LenSource::Slice;
302 for e in &self.link_exts {
303 match e {
304 LinkExtSlice::Vlan(_) => {}
305 LinkExtSlice::Macsec(m) => {
306 if m.header.short_len() != MacsecShortLen::ZERO {
307 len_source = LenSource::MacsecShortLength;
308 }
309 }
310 }
311 }
312 match last_ext {
313 LinkExtSlice::Vlan(v) => {
314 let mut p = v.payload();
315 p.len_source = len_source;
316 Some(p)
317 }
318 LinkExtSlice::Macsec(m) => {
319 if let Some(mut p) = m.ether_payload() {
320 p.len_source = len_source;
321 Some(p)
322 } else {
323 None
324 }
325 }
326 }
327 } else if let Some(link) = self.link.as_ref() {
328 match link {
329 LinkSlice::Ethernet2(e) => Some(e.payload()),
330 LinkSlice::LinuxSll(e) => match e.protocol_type() {
331 LinuxSllProtocolType::EtherType(_) => {
332 Some(EtherPayloadSlice::try_from(e.payload()).ok()?)
333 }
334 _ => None,
335 },
336 LinkSlice::EtherPayload(e) => Some(e.clone()),
337 LinkSlice::LinuxSllPayload(e) => match e.protocol_type {
338 LinuxSllProtocolType::EtherType(_) => {
339 Some(EtherPayloadSlice::try_from(e.clone()).ok()?)
340 }
341 _ => None,
342 },
343 }
344 } else {
345 None
346 }
347 }
348
349 pub fn ip_payload(&self) -> Option<&IpPayloadSlice<'a>> {
352 if let Some(net) = self.net.as_ref() {
353 use NetSlice::*;
354 match net {
355 Ipv4(v) => Some(v.payload()),
356 Ipv6(v) => Some(v.payload()),
357 Arp(_) => None,
358 }
359 } else {
360 None
361 }
362 }
363
364 pub fn is_ip_payload_fragmented(&self) -> bool {
366 use NetSlice::*;
367 match &self.net {
368 Some(Ipv4(v)) => v.is_payload_fragmented(),
369 Some(Ipv6(v)) => v.is_payload_fragmented(),
370 Some(Arp(_)) | None => false,
371 }
372 }
373
374 pub fn vlan(&self) -> Option<VlanSlice<'a>> {
376 let mut result = None;
377 for ext in &self.link_exts {
378 if let LinkExtSlice::Vlan(vlan_slice) = ext {
379 if let Some(outer) = result {
380 return Some(VlanSlice::DoubleVlan(DoubleVlanSlice {
381 outer,
382 inner: vlan_slice.clone(),
383 }));
384 } else {
385 result = Some(vlan_slice.clone());
386 }
387 }
388 }
389 result.map(VlanSlice::SingleVlan)
390 }
391
392 pub fn vlan_ids(&self) -> ArrayVec<VlanId, { SlicedPacket::LINK_EXTS_CAP }> {
394 let mut result = ArrayVec::<VlanId, { SlicedPacket::LINK_EXTS_CAP }>::new_const();
395 for e in &self.link_exts {
396 if let LinkExtSlice::Vlan(s) = e {
398 unsafe {
399 result.push_unchecked(s.vlan_identifier());
400 }
401 }
402 }
403 result
404 }
405}
406
407#[cfg(test)]
408mod test {
409 use std::vec::Vec;
410
411 use super::*;
412 use crate::err::macsec;
413 use crate::err::{packet::SliceError, Layer, LenError};
414 use crate::test_gens::*;
415 use crate::test_packet::TestPacket;
416 use proptest::prelude::*;
417
418 const VLAN_ETHER_TYPES: [EtherType; 3] = [
419 ether_type::VLAN_TAGGED_FRAME,
420 ether_type::PROVIDER_BRIDGING,
421 ether_type::VLAN_DOUBLE_TAGGED_FRAME,
422 ];
423 const MACSEC_ETHER_TYPES: [EtherType; 1] = [ether_type::MACSEC];
424
425 #[test]
426 fn clone_eq() {
427 let header = SlicedPacket {
428 link: None,
429 link_exts: ArrayVec::new_const(),
430 net: None,
431 transport: None,
432 };
433 assert_eq!(header.clone(), header);
434 }
435
436 #[test]
437 fn debug() {
438 use alloc::format;
439 let header = SlicedPacket {
440 link: None,
441 link_exts: ArrayVec::new_const(),
442 net: None,
443 transport: None,
444 };
445 assert_eq!(
446 format!("{:?}", header),
447 format!(
448 "SlicedPacket {{ link: {:?}, link_exts: {:?}, net: {:?}, transport: {:?} }}",
449 header.link, header.link_exts, header.net, header.transport,
450 )
451 );
452 }
453
454 #[test]
455 fn ether_payload() {
456 use alloc::vec::*;
457
458 assert_eq!(
460 SlicedPacket {
461 link: None,
462 link_exts: ArrayVec::new_const(),
463 net: None,
464 transport: None,
465 }
466 .ether_payload(),
467 None
468 );
469
470 {
472 let payload = [1, 2, 3, 4];
473 let mut buf = Vec::with_capacity(Ethernet2Header::LEN + 4);
474 buf.extend_from_slice(
475 &Ethernet2Header {
476 ether_type: EtherType::WAKE_ON_LAN,
477 ..Default::default()
478 }
479 .to_bytes(),
480 );
481 buf.extend_from_slice(&payload);
482 assert_eq!(
483 SlicedPacket::from_ethernet(&buf).unwrap().ether_payload(),
484 Some(EtherPayloadSlice {
485 ether_type: EtherType::WAKE_ON_LAN,
486 len_source: LenSource::Slice,
487 payload: &payload
488 })
489 );
490 }
491
492 {
494 let payload = [1, 2, 3, 4];
495 assert_eq!(
496 SlicedPacket {
497 link: Some(LinkSlice::EtherPayload(EtherPayloadSlice {
498 ether_type: EtherType::WAKE_ON_LAN,
499 len_source: LenSource::Slice,
500 payload: &payload
501 })),
502 link_exts: ArrayVec::new_const(),
503 net: None,
504 transport: None,
505 }
506 .ether_payload(),
507 Some(EtherPayloadSlice {
508 ether_type: EtherType::WAKE_ON_LAN,
509 len_source: LenSource::Slice,
510 payload: &payload
511 })
512 );
513 }
514
515 {
517 let payload = [1, 2, 3, 4];
518 let mut buf = Vec::with_capacity(LinuxSllHeader::LEN + 4);
519 buf.extend_from_slice(
520 &LinuxSllHeader {
521 packet_type: LinuxSllPacketType::HOST,
522 arp_hrd_type: ArpHardwareId::ETHERNET,
523 sender_address_valid_length: 6,
524 sender_address: [1, 2, 3, 4, 5, 6, 0, 0],
525 protocol_type: LinuxSllProtocolType::EtherType(EtherType::WAKE_ON_LAN),
526 }
527 .to_bytes(),
528 );
529 buf.extend_from_slice(&payload);
530 assert_eq!(
531 SlicedPacket::from_linux_sll(&buf).unwrap().ether_payload(),
532 Some(EtherPayloadSlice {
533 ether_type: EtherType::WAKE_ON_LAN,
534 len_source: LenSource::Slice,
535 payload: &payload
536 })
537 );
538 }
539 {
541 let test = [
542 (None, ArpHardwareId::FRAD, LinuxSllProtocolType::Ignored(0)),
543 (
544 None,
545 ArpHardwareId::NETLINK,
546 LinuxSllProtocolType::NetlinkProtocolType(0),
547 ),
548 (
549 None,
550 ArpHardwareId::IPGRE,
551 LinuxSllProtocolType::GenericRoutingEncapsulationProtocolType(0),
552 ),
553 (
554 Some(ether_type::WAKE_ON_LAN),
555 ArpHardwareId::ETHERNET,
556 LinuxSllProtocolType::EtherType(ether_type::WAKE_ON_LAN),
557 ),
558 (
559 None,
560 ArpHardwareId::ETHERNET,
561 LinuxSllProtocolType::LinuxNonstandardEtherType(LinuxNonstandardEtherType::CAN),
562 ),
563 ];
564
565 for (expected, arp_hrd_type, protocol_type) in test {
566 {
567 let l = LinuxSllHeader {
568 packet_type: LinuxSllPacketType::HOST,
569 arp_hrd_type,
570 sender_address_valid_length: 6,
571 sender_address: [0; 8],
572 protocol_type,
573 };
574
575 let mut bytes = Vec::with_capacity(l.header_len());
576 l.write(&mut bytes).unwrap();
577
578 let s = SlicedPacket::from_linux_sll(&bytes).unwrap();
579 assert_eq!(
580 expected.map(|ether_type| {
581 EtherPayloadSlice {
582 ether_type,
583 len_source: LenSource::Slice,
584 payload: &[],
585 }
586 }),
587 s.ether_payload()
588 );
589 }
590 {
591 let s = SlicedPacket {
592 link: Some(LinkSlice::LinuxSllPayload(LinuxSllPayloadSlice {
593 protocol_type: protocol_type,
594 payload: &[],
595 })),
596 link_exts: Default::default(),
597 net: None,
598 transport: None,
599 };
600 assert_eq!(
601 expected.map(|ether_type| {
602 EtherPayloadSlice {
603 ether_type,
604 len_source: LenSource::Slice,
605 payload: &[],
606 }
607 }),
608 s.ether_payload()
609 );
610 }
611 }
612 }
613
614 {
616 let payload = [1, 2, 3, 4];
617 assert_eq!(
618 SlicedPacket {
619 link: Some(LinkSlice::LinuxSllPayload(LinuxSllPayloadSlice {
620 protocol_type: LinuxSllProtocolType::EtherType(EtherType::WAKE_ON_LAN),
621 payload: &payload
622 })),
623 link_exts: ArrayVec::new_const(),
624 net: None,
625 transport: None,
626 }
627 .ether_payload(),
628 Some(EtherPayloadSlice {
629 ether_type: EtherType::WAKE_ON_LAN,
630 len_source: LenSource::Slice,
631 payload: &payload
632 })
633 );
634 }
635
636 {
638 let payload = [1, 2, 3, 4];
639 let mut buf = Vec::with_capacity(Ethernet2Header::LEN + SingleVlanHeader::LEN + 4);
640 buf.extend_from_slice(
641 &Ethernet2Header {
642 ether_type: EtherType::VLAN_TAGGED_FRAME,
643 ..Default::default()
644 }
645 .to_bytes(),
646 );
647 buf.extend_from_slice(
648 &SingleVlanHeader {
649 ether_type: EtherType::WAKE_ON_LAN,
650 ..Default::default()
651 }
652 .to_bytes(),
653 );
654 buf.extend_from_slice(&payload);
655 assert_eq!(
656 SlicedPacket::from_ethernet(&buf).unwrap().ether_payload(),
657 Some(EtherPayloadSlice {
658 ether_type: EtherType::WAKE_ON_LAN,
659 len_source: LenSource::Slice,
660 payload: &payload
661 })
662 );
663 }
664
665 {
667 let payload = [1, 2, 3, 4];
668 let mut buf = Vec::with_capacity(Ethernet2Header::LEN + SingleVlanHeader::LEN * 2 + 4);
669 buf.extend_from_slice(
670 &Ethernet2Header {
671 ether_type: EtherType::VLAN_DOUBLE_TAGGED_FRAME,
672 ..Default::default()
673 }
674 .to_bytes(),
675 );
676 buf.extend_from_slice(
677 &SingleVlanHeader {
678 ether_type: EtherType::VLAN_TAGGED_FRAME,
679 ..Default::default()
680 }
681 .to_bytes(),
682 );
683 buf.extend_from_slice(
684 &SingleVlanHeader {
685 ether_type: EtherType::WAKE_ON_LAN,
686 ..Default::default()
687 }
688 .to_bytes(),
689 );
690 buf.extend_from_slice(&payload);
691 assert_eq!(
692 SlicedPacket::from_ethernet(&buf).unwrap().ether_payload(),
693 Some(EtherPayloadSlice {
694 ether_type: EtherType::WAKE_ON_LAN,
695 len_source: LenSource::Slice,
696 payload: &payload
697 })
698 );
699 }
700
701 {
703 let tests = [
704 (
705 Some(ether_type::WAKE_ON_LAN),
706 MacsecPType::Unmodified(ether_type::WAKE_ON_LAN),
707 ),
708 (None, MacsecPType::Modified),
709 (None, MacsecPType::Encrypted),
710 (None, MacsecPType::EncryptedUnmodified),
711 ];
712 for (expected, ptype) in tests {
713 let eth_mod = Ethernet2Header {
714 source: [0; 6],
715 destination: [0; 6],
716 ether_type: ether_type::VLAN_TAGGED_FRAME,
717 };
718 let vlan = SingleVlanHeader {
719 pcp: VlanPcp::ZERO,
720 drop_eligible_indicator: false,
721 vlan_id: VlanId::try_new(1).unwrap(),
722 ether_type: EtherType::MACSEC,
723 };
724 let macsec0 = MacsecHeader {
725 ptype: MacsecPType::Unmodified(EtherType::MACSEC),
726 endstation_id: false,
727 scb: false,
728 an: MacsecAn::ZERO,
729 short_len: MacsecShortLen::ZERO,
730 packet_nr: 0,
731 sci: None,
732 };
733 let mut macsec1 = MacsecHeader {
734 ptype,
735 endstation_id: false,
736 scb: false,
737 an: MacsecAn::ZERO,
738 short_len: MacsecShortLen::ZERO,
739 packet_nr: 0,
740 sci: None,
741 };
742 let payload = [1, 2, 3, 4];
743 macsec1.set_payload_len(payload.len());
744 let mut serialized = Vec::with_capacity(
745 eth_mod.header_len()
746 + vlan.header_len()
747 + macsec0.header_len()
748 + macsec1.header_len()
749 + payload.len(),
750 );
751 eth_mod.write(&mut serialized).unwrap();
752 vlan.write(&mut serialized).unwrap();
753 macsec0.write(&mut serialized).unwrap();
754 macsec1.write(&mut serialized).unwrap();
755 serialized.extend_from_slice(&payload);
756
757 assert_eq!(
758 expected.map(|ether_type| EtherPayloadSlice {
759 ether_type,
760 len_source: LenSource::MacsecShortLength,
761 payload: &payload,
762 }),
763 SlicedPacket::from_ethernet(&serialized)
764 .unwrap()
765 .ether_payload()
766 );
767 }
768 }
769 }
770
771 #[test]
772 fn ip_payload() {
773 use alloc::vec::*;
774
775 assert_eq!(
777 SlicedPacket {
778 link: None,
779 link_exts: ArrayVec::new_const(),
780 net: None,
781 transport: None,
782 }
783 .ip_payload(),
784 None
785 );
786
787 {
789 let mut buf = Vec::with_capacity(Ethernet2Header::LEN + ArpEthIpv4Packet::LEN);
790 buf.extend_from_slice(
791 &Ethernet2Header {
792 source: [0; 6],
793 destination: [0; 6],
794 ether_type: EtherType::ARP,
795 }
796 .to_bytes(),
797 );
798 buf.extend_from_slice(
799 &ArpEthIpv4Packet {
800 operation: ArpOperation::REPLY,
801 sender_mac: [0; 6],
802 sender_ipv4: [0; 4],
803 target_mac: [0; 6],
804 target_ipv4: [0; 4],
805 }
806 .to_bytes(),
807 );
808 assert_eq!(
809 SlicedPacket::from_ethernet(&buf).unwrap().ip_payload(),
810 None
811 );
812 }
813
814 {
816 let payload = [1, 2, 3, 4];
817 let mut buf = Vec::with_capacity(Ipv4Header::MIN_LEN + 4);
818 buf.extend_from_slice(
819 &Ipv4Header {
820 protocol: IpNumber::ARIS,
821 total_len: Ipv4Header::MIN_LEN_U16 + 4,
822 ..Default::default()
823 }
824 .to_bytes(),
825 );
826 buf.extend_from_slice(&payload);
827 assert_eq!(
828 SlicedPacket::from_ip(&buf).unwrap().ip_payload(),
829 Some(&IpPayloadSlice {
830 payload: &payload,
831 ip_number: IpNumber::ARIS,
832 fragmented: false,
833 len_source: LenSource::Ipv4HeaderTotalLen,
834 })
835 );
836 }
837
838 {
840 let payload = [1, 2, 3, 4];
841 let mut buf = Vec::with_capacity(Ipv6Header::LEN + 4);
842 buf.extend_from_slice(
843 &Ipv6Header {
844 payload_length: 4,
845 next_header: IpNumber::ARGUS,
846 ..Default::default()
847 }
848 .to_bytes(),
849 );
850 buf.extend_from_slice(&payload);
851 assert_eq!(
852 SlicedPacket::from_ip(&buf).unwrap().ip_payload(),
853 Some(&IpPayloadSlice {
854 payload: &payload,
855 ip_number: IpNumber::ARGUS,
856 fragmented: false,
857 len_source: LenSource::Ipv6HeaderPayloadLen,
858 })
859 );
860 }
861 }
862
863 #[test]
864 fn is_ip_payload_fragmented() {
865 use alloc::vec::*;
866
867 assert_eq!(
869 SlicedPacket {
870 link: None,
871 link_exts: ArrayVec::new_const(),
872 net: None,
873 transport: None,
874 }
875 .is_ip_payload_fragmented(),
876 false
877 );
878
879 {
881 let mut buf = Vec::with_capacity(Ethernet2Header::LEN + ArpEthIpv4Packet::LEN);
882 buf.extend_from_slice(
883 &Ethernet2Header {
884 source: [0; 6],
885 destination: [0; 6],
886 ether_type: EtherType::ARP,
887 }
888 .to_bytes(),
889 );
890 buf.extend_from_slice(
891 &ArpEthIpv4Packet {
892 operation: ArpOperation::REPLY,
893 sender_mac: [0; 6],
894 sender_ipv4: [0; 4],
895 target_mac: [0; 6],
896 target_ipv4: [0; 4],
897 }
898 .to_bytes(),
899 );
900 assert_eq!(
901 SlicedPacket::from_ethernet(&buf)
902 .unwrap()
903 .is_ip_payload_fragmented(),
904 false
905 );
906 }
907
908 {
910 let payload = [1, 2, 3, 4];
911 let mut buf = Vec::with_capacity(Ipv4Header::MIN_LEN + 4);
912 buf.extend_from_slice(
913 &Ipv4Header {
914 protocol: IpNumber::ARIS,
915 total_len: Ipv4Header::MIN_LEN_U16 + 4,
916 ..Default::default()
917 }
918 .to_bytes(),
919 );
920 buf.extend_from_slice(&payload);
921 assert_eq!(
922 SlicedPacket::from_ip(&buf)
923 .unwrap()
924 .is_ip_payload_fragmented(),
925 false
926 );
927 }
928
929 {
931 let payload = [1, 2, 3, 4];
932 let mut buf = Vec::with_capacity(Ipv4Header::MIN_LEN + 4);
933 buf.extend_from_slice(
934 &Ipv4Header {
935 protocol: IpNumber::ARIS,
936 total_len: Ipv4Header::MIN_LEN_U16 + 4,
937 more_fragments: true,
938 fragment_offset: IpFragOffset::ZERO,
939 ..Default::default()
940 }
941 .to_bytes(),
942 );
943 buf.extend_from_slice(&payload);
944 assert!(SlicedPacket::from_ip(&buf)
945 .unwrap()
946 .is_ip_payload_fragmented());
947 }
948
949 {
951 let payload = [1, 2, 3, 4];
952 let mut buf = Vec::with_capacity(Ipv6Header::LEN + 4);
953 buf.extend_from_slice(
954 &Ipv6Header {
955 payload_length: 4,
956 next_header: IpNumber::ARGUS,
957 ..Default::default()
958 }
959 .to_bytes(),
960 );
961 buf.extend_from_slice(&payload);
962 assert_eq!(
963 SlicedPacket::from_ip(&buf)
964 .unwrap()
965 .is_ip_payload_fragmented(),
966 false
967 );
968 }
969
970 {
972 let payload = [1, 2, 3, 4];
973 let mut buf = Vec::with_capacity(Ipv6Header::LEN + 4);
974 buf.extend_from_slice(
975 &Ipv6Header {
976 payload_length: Ipv6FragmentHeader::LEN as u16 + 4,
977 next_header: IpNumber::IPV6_FRAGMENTATION_HEADER,
978 ..Default::default()
979 }
980 .to_bytes(),
981 );
982 buf.extend_from_slice(
983 &Ipv6FragmentHeader {
984 next_header: IpNumber::ARGUS,
985 fragment_offset: IpFragOffset::ZERO,
986 more_fragments: true,
987 identification: 0,
988 }
989 .to_bytes(),
990 );
991 buf.extend_from_slice(&payload);
992 assert!(SlicedPacket::from_ip(&buf)
993 .unwrap()
994 .is_ip_payload_fragmented());
995 }
996 }
997
998 #[test]
999 fn vlan_vlan_ids() {
1000 assert_eq!(
1002 SlicedPacket {
1003 link: None,
1004 link_exts: ArrayVec::new_const(),
1005 net: None,
1006 transport: None,
1007 }
1008 .vlan(),
1009 None
1010 );
1011 assert_eq!(
1012 SlicedPacket {
1013 link: None,
1014 link_exts: ArrayVec::new_const(),
1015 net: None,
1016 transport: None,
1017 }
1018 .vlan_ids(),
1019 ArrayVec::<VlanId, 3>::new_const()
1020 );
1021
1022 {
1024 let payload = [1, 2, 3, 4];
1025 let mut buf = Vec::with_capacity(SingleVlanHeader::LEN + 4);
1026 buf.extend_from_slice(
1027 &SingleVlanHeader {
1028 pcp: VlanPcp::ZERO,
1029 drop_eligible_indicator: false,
1030 vlan_id: VlanId::try_new(1).unwrap(),
1031 ether_type: EtherType::WAKE_ON_LAN,
1032 }
1033 .to_bytes(),
1034 );
1035 buf.extend_from_slice(&payload);
1036
1037 let slice = SlicedPacket::from_ether_type(ether_type::VLAN_TAGGED_FRAME, &buf).unwrap();
1038
1039 assert_eq!(
1040 slice.vlan(),
1041 Some(VlanSlice::SingleVlan(SingleVlanSlice { slice: &buf[..] }))
1042 );
1043 assert_eq!(slice.vlan_ids(), {
1044 let mut ids = ArrayVec::<VlanId, 3>::new_const();
1045 ids.push(VlanId::try_new(1).unwrap());
1046 ids
1047 });
1048 }
1049
1050 {
1052 let payload = [1, 2, 3, 4];
1053 let mut buf = Vec::with_capacity(SingleVlanHeader::LEN * 2 + 4);
1054 buf.extend_from_slice(
1055 &SingleVlanHeader {
1056 pcp: VlanPcp::ZERO,
1057 drop_eligible_indicator: false,
1058 vlan_id: VlanId::try_new(1).unwrap(),
1059 ether_type: EtherType::VLAN_TAGGED_FRAME,
1060 }
1061 .to_bytes(),
1062 );
1063 buf.extend_from_slice(
1064 &SingleVlanHeader {
1065 pcp: VlanPcp::ZERO,
1066 drop_eligible_indicator: false,
1067 vlan_id: VlanId::try_new(2).unwrap(),
1068 ether_type: EtherType::WAKE_ON_LAN,
1069 }
1070 .to_bytes(),
1071 );
1072 buf.extend_from_slice(&payload);
1073
1074 let slice =
1075 SlicedPacket::from_ether_type(ether_type::VLAN_DOUBLE_TAGGED_FRAME, &buf).unwrap();
1076
1077 assert_eq!(
1078 slice.vlan(),
1079 Some(VlanSlice::DoubleVlan(DoubleVlanSlice {
1080 outer: SingleVlanSlice { slice: &buf },
1081 inner: SingleVlanSlice {
1082 slice: &buf[SingleVlanHeader::LEN..]
1083 },
1084 }))
1085 );
1086 assert_eq!(slice.vlan_ids(), {
1087 let mut ids = ArrayVec::<VlanId, 3>::new_const();
1088 ids.push(VlanId::try_new(1).unwrap());
1089 ids.push(VlanId::try_new(2).unwrap());
1090 ids
1091 });
1092 }
1093
1094 {
1096 let payload = [1, 2, 3, 4];
1097 let macsec = MacsecHeader {
1098 ptype: MacsecPType::Unmodified(ether_type::VLAN_DOUBLE_TAGGED_FRAME),
1099 endstation_id: false,
1100 scb: false,
1101 an: MacsecAn::ZERO,
1102 short_len: MacsecShortLen::ZERO,
1103 packet_nr: 0,
1104 sci: None,
1105 };
1106 let mut buf = Vec::with_capacity(macsec.header_len() + SingleVlanHeader::LEN * 2 + 4);
1107 buf.extend_from_slice(&macsec.to_bytes());
1108 buf.extend_from_slice(
1109 &SingleVlanHeader {
1110 pcp: VlanPcp::ZERO,
1111 drop_eligible_indicator: false,
1112 vlan_id: VlanId::try_new(1).unwrap(),
1113 ether_type: EtherType::VLAN_TAGGED_FRAME,
1114 }
1115 .to_bytes(),
1116 );
1117 buf.extend_from_slice(
1118 &SingleVlanHeader {
1119 pcp: VlanPcp::ZERO,
1120 drop_eligible_indicator: false,
1121 vlan_id: VlanId::try_new(2).unwrap(),
1122 ether_type: EtherType::WAKE_ON_LAN,
1123 }
1124 .to_bytes(),
1125 );
1126 buf.extend_from_slice(&payload);
1127
1128 let slice = SlicedPacket::from_ether_type(ether_type::MACSEC, &buf).unwrap();
1129
1130 assert_eq!(
1131 slice.vlan(),
1132 Some(VlanSlice::DoubleVlan(DoubleVlanSlice {
1133 outer: SingleVlanSlice {
1134 slice: &buf[macsec.header_len()..]
1135 },
1136 inner: SingleVlanSlice {
1137 slice: &buf[macsec.header_len() + SingleVlanHeader::LEN..]
1138 },
1139 }))
1140 );
1141 assert_eq!(slice.vlan_ids(), {
1142 let mut ids = ArrayVec::<VlanId, 3>::new_const();
1143 ids.push(VlanId::try_new(1).unwrap());
1144 ids.push(VlanId::try_new(2).unwrap());
1145 ids
1146 });
1147 }
1148
1149 {
1151 let payload = [1, 2, 3, 4];
1152 let mut buf = Vec::with_capacity(SingleVlanHeader::LEN * 3 + 4);
1153 buf.extend_from_slice(
1154 &SingleVlanHeader {
1155 pcp: VlanPcp::ZERO,
1156 drop_eligible_indicator: false,
1157 vlan_id: VlanId::try_new(1).unwrap(),
1158 ether_type: EtherType::VLAN_TAGGED_FRAME,
1159 }
1160 .to_bytes(),
1161 );
1162 buf.extend_from_slice(
1163 &SingleVlanHeader {
1164 pcp: VlanPcp::ZERO,
1165 drop_eligible_indicator: false,
1166 vlan_id: VlanId::try_new(2).unwrap(),
1167 ether_type: EtherType::VLAN_TAGGED_FRAME,
1168 }
1169 .to_bytes(),
1170 );
1171 buf.extend_from_slice(
1172 &SingleVlanHeader {
1173 pcp: VlanPcp::ZERO,
1174 drop_eligible_indicator: false,
1175 vlan_id: VlanId::try_new(3).unwrap(),
1176 ether_type: EtherType::WAKE_ON_LAN,
1177 }
1178 .to_bytes(),
1179 );
1180 buf.extend_from_slice(&payload);
1181
1182 let slice =
1183 SlicedPacket::from_ether_type(ether_type::VLAN_DOUBLE_TAGGED_FRAME, &buf).unwrap();
1184
1185 assert_eq!(
1186 slice.vlan(),
1187 Some(VlanSlice::DoubleVlan(DoubleVlanSlice {
1188 outer: SingleVlanSlice { slice: &buf },
1189 inner: SingleVlanSlice {
1190 slice: &buf[SingleVlanHeader::LEN..]
1191 },
1192 }))
1193 );
1194 assert_eq!(slice.vlan_ids(), {
1195 let mut ids = ArrayVec::<VlanId, 3>::new_const();
1196 ids.push(VlanId::try_new(1).unwrap());
1197 ids.push(VlanId::try_new(2).unwrap());
1198 ids.push(VlanId::try_new(3).unwrap());
1199 ids
1200 });
1201 }
1202 }
1203
1204 #[test]
1205 fn from_x_slice() {
1206 from_x_slice_link_exts_variants(&TestPacket {
1208 link: None,
1209 link_exts: ArrayVec::new_const(),
1210 net: None,
1211 transport: None,
1212 });
1213
1214 {
1216 let data = [1, 2, 3, 4];
1217 let result = SlicedPacket::from_ether_type(EtherType(0x8221), &data).unwrap();
1218 assert_eq!(
1219 result,
1220 SlicedPacket {
1221 link: Some(LinkSlice::EtherPayload(EtherPayloadSlice {
1222 ether_type: EtherType(0x8221),
1223 len_source: LenSource::Slice,
1224 payload: &data
1225 })),
1226 link_exts: ArrayVec::new_const(),
1227 net: None,
1228 transport: None
1229 }
1230 );
1231 }
1232
1233 {
1235 let eth = Ethernet2Header {
1236 source: [1, 2, 3, 4, 5, 6],
1237 destination: [1, 2, 3, 4, 5, 6],
1238 ether_type: 0.into(),
1239 };
1240 let test = TestPacket {
1241 link: Some(LinkHeader::Ethernet2(eth.clone())),
1242 link_exts: ArrayVec::new_const(),
1243 net: None,
1244 transport: None,
1245 };
1246
1247 from_x_slice_link_exts_variants(&test);
1249
1250 {
1252 let data = test.to_vec(&[]);
1253 for len in 0..data.len() {
1254 let err = LenError {
1255 required_len: eth.header_len(),
1256 len,
1257 len_source: LenSource::Slice,
1258 layer: Layer::Ethernet2Header,
1259 layer_start_offset: 0,
1260 };
1261
1262 from_slice_assert_err(&test, &data[..len], SliceError::Len(err.clone()));
1263 }
1264 }
1265 }
1266
1267 {
1269 let linux_sll = LinuxSllHeader {
1270 packet_type: LinuxSllPacketType::HOST,
1271 arp_hrd_type: ArpHardwareId::ETHERNET,
1272 sender_address_valid_length: 6,
1273 sender_address: [1, 2, 3, 4, 5, 6, 0, 0],
1274 protocol_type: LinuxSllProtocolType::EtherType(EtherType::WAKE_ON_LAN),
1275 };
1276 let test = TestPacket {
1277 link: Some(LinkHeader::LinuxSll(linux_sll.clone())),
1278 link_exts: ArrayVec::new_const(),
1279 net: None,
1280 transport: None,
1281 };
1282
1283 {
1285 let data = test.to_vec(&[]);
1286 for len in 0..data.len() {
1287 let err = LenError {
1288 required_len: linux_sll.header_len(),
1289 len,
1290 len_source: LenSource::Slice,
1291 layer: Layer::LinuxSllHeader,
1292 layer_start_offset: 0,
1293 };
1294
1295 from_slice_assert_err(&test, &data[..len], SliceError::Len(err.clone()));
1296 }
1297 }
1298 }
1299 }
1300
1301 fn from_x_slice_link_exts_variants(base: &TestPacket) {
1302 #[derive(Copy, Clone, Eq, PartialEq)]
1303 enum Ext {
1304 Macsec,
1305 VlanTaggedFrame,
1306 VlanDoubleTaggedFrame,
1307 ProviderBridging,
1308 }
1309
1310 impl Ext {
1311 pub fn ether_type(&self) -> EtherType {
1312 match self {
1313 Ext::Macsec => EtherType::MACSEC,
1314 Ext::VlanTaggedFrame => EtherType::VLAN_TAGGED_FRAME,
1315 Ext::VlanDoubleTaggedFrame => EtherType::VLAN_DOUBLE_TAGGED_FRAME,
1316 Ext::ProviderBridging => EtherType::PROVIDER_BRIDGING,
1317 }
1318 }
1319
1320 pub fn add(&self, base: &TestPacket) -> TestPacket {
1321 let mut test = base.clone();
1322 test.set_ether_type(self.ether_type());
1323 test.link_exts
1324 .try_push(match self {
1325 Ext::Macsec => LinkExtHeader::Macsec(MacsecHeader {
1326 ptype: MacsecPType::Unmodified(EtherType(3)),
1327 endstation_id: false,
1328 scb: false,
1329 an: MacsecAn::ZERO,
1330 short_len: MacsecShortLen::ZERO,
1331 packet_nr: 0,
1332 sci: None,
1333 }),
1334 Ext::VlanTaggedFrame
1335 | Ext::VlanDoubleTaggedFrame
1336 | Ext::ProviderBridging => LinkExtHeader::Vlan(SingleVlanHeader {
1337 pcp: VlanPcp::ZERO,
1338 drop_eligible_indicator: false,
1339 vlan_id: VlanId::try_new(1).unwrap(),
1340 ether_type: 3.into(),
1341 }),
1342 })
1343 .unwrap();
1344 test
1345 }
1346 }
1347
1348 let test_macsec_mod = |test: &TestPacket| {
1349 for ptype in [
1350 MacsecPType::Modified,
1351 MacsecPType::Encrypted,
1352 MacsecPType::EncryptedUnmodified,
1353 ] {
1354 let mut test = test.clone();
1355 if let Some(LinkExtHeader::Macsec(m)) = test.link_exts.last_mut() {
1356 m.ptype = ptype;
1357 }
1358 if matches!(test.link_exts.last(), Some(LinkExtHeader::Macsec(_))) {
1359 from_x_slice_assert_ok(&test);
1360 }
1361 }
1362 };
1363
1364 let len_errors = |test: &TestPacket| {
1365 let data = test.to_vec(&[]);
1366 let req_len = test.link_exts.last().unwrap().header_len();
1367 for len in 0..req_len {
1368 let base_len = test.len(&[]) - req_len;
1369
1370 let (err_req_len, err_layer) = match test.link_exts.last().unwrap() {
1371 LinkExtHeader::Vlan(h) => (h.header_len(), Layer::VlanHeader),
1372 LinkExtHeader::Macsec(_) => {
1373 if len < 6 {
1374 (6, Layer::MacsecHeader)
1375 } else {
1376 (req_len, Layer::MacsecHeader)
1377 }
1378 }
1379 };
1380
1381 let mut len_source = LenSource::Slice;
1382 for prev_exts in test.link_exts.iter().rev().skip(1) {
1383 if let LinkExtHeader::Macsec(m) = prev_exts {
1384 if m.short_len != MacsecShortLen::ZERO {
1385 len_source = LenSource::MacsecShortLength;
1386 }
1387 }
1388 }
1389
1390 let err = LenError {
1391 required_len: err_req_len,
1392 len,
1393 len_source,
1394 layer: err_layer,
1395 layer_start_offset: base_len,
1396 };
1397 from_slice_assert_err(&test, &data[..base_len + len], SliceError::Len(err.clone()));
1398 }
1399 };
1400
1401 let content_errors = |test: &TestPacket| {
1402 if let Some(LinkExtHeader::Macsec(last)) = test.link_exts.last() {
1403 let mut data = test.to_vec(&[]);
1404
1405 let macsec_offset = data.len() - last.header_len();
1407 data[macsec_offset] = data[macsec_offset] | 0b1000_0000;
1408
1409 from_slice_assert_err(
1410 &test,
1411 &data,
1412 SliceError::Macsec(macsec::HeaderError::UnexpectedVersion),
1413 );
1414 }
1415 };
1416
1417 let extensions = [
1419 Ext::Macsec,
1420 Ext::VlanTaggedFrame,
1421 Ext::VlanDoubleTaggedFrame,
1422 Ext::ProviderBridging,
1423 ];
1424
1425 from_x_slice_net_variants(base);
1427
1428 for ext0 in extensions {
1430 let test0 = ext0.add(base);
1431 from_x_slice_net_variants(&test0);
1432 test_macsec_mod(&test0);
1433 len_errors(&test0);
1434 content_errors(&test0);
1435
1436 for ext1 in extensions {
1437 let test1 = ext1.add(&test0);
1438 from_x_slice_net_variants(&test1);
1439 test_macsec_mod(&test1);
1440 len_errors(&test1);
1441 content_errors(&test1);
1442
1443 for ext2 in extensions {
1444 let test2 = ext2.add(&test1);
1445 from_x_slice_net_variants(&test2);
1446 test_macsec_mod(&test2);
1447 len_errors(&test2);
1448 content_errors(&test2);
1449
1450 for ext3 in extensions {
1452 let mut test3 = test2.clone();
1453 let l = test3.link_exts.last_mut().unwrap();
1454 match l {
1455 LinkExtHeader::Vlan(s) => {
1456 s.ether_type = ext3.ether_type();
1457 }
1458 LinkExtHeader::Macsec(m) => {
1459 m.ptype = MacsecPType::Unmodified(ext3.ether_type());
1460 }
1461 }
1462 from_x_slice_assert_ok(&test3);
1463 }
1464 }
1465 }
1466 }
1467 }
1468
1469 fn from_x_slice_net_variants(base: &TestPacket) {
1470 from_x_slice_transport_variants(base);
1472
1473 for fragmented in [false, true] {
1475 let ipv4 = {
1476 let mut ipv4 =
1477 Ipv4Header::new(0, 1, 2.into(), [3, 4, 5, 6], [7, 8, 9, 10]).unwrap();
1478 ipv4.more_fragments = fragmented;
1479 ipv4
1480 };
1481
1482 {
1483 let test = {
1484 let mut test = base.clone();
1485 test.set_ether_type(ether_type::IPV4);
1486 test.net = Some(NetHeaders::Ipv4(ipv4.clone(), Default::default()));
1487 test.set_payload_len(0);
1488 test
1489 };
1490
1491 from_x_slice_transport_variants(&test);
1493
1494 {
1496 for len in 0..ipv4.header_len() {
1497 let mut test = test.clone();
1498 let base_len = test.len(&[]) - ipv4.header_len();
1499 test.set_payload_len_link_ext(len);
1500
1501 let data = test.to_vec(&[]);
1502
1503 let err = LenError {
1504 required_len: ipv4.header_len(),
1505 len,
1506 len_source: LenSource::Slice,
1507 layer: Layer::Ipv4Header,
1508 layer_start_offset: base_len,
1509 };
1510 from_slice_assert_err(
1511 &test,
1512 &data[..base_len + len],
1513 if test.link.is_some() || !test.link_exts.is_empty() {
1514 SliceError::Len(err.clone())
1515 } else {
1516 SliceError::Len({
1517 if len < 1 {
1518 let mut err = err.clone();
1519 err.required_len = 1;
1520 err.layer = Layer::IpHeader;
1521 err
1522 } else {
1523 err.clone()
1524 }
1525 })
1526 },
1527 );
1528 }
1529 }
1530
1531 {
1533 use err::ip::HeaderError::*;
1534
1535 let mut data = test.to_vec(&[]);
1536 let ipv4_offset = data.len() - ipv4.header_len();
1537
1538 data[ipv4_offset] = 0b1111_0000 & data[ipv4_offset];
1540
1541 from_slice_assert_err(
1542 &test,
1543 &data,
1544 if test.link.is_some() || !test.link_exts.is_empty() {
1545 SliceError::Ipv4(
1546 err::ipv4::HeaderError::HeaderLengthSmallerThanHeader { ihl: 0 },
1547 )
1548 } else {
1549 SliceError::Ip(Ipv4HeaderLengthSmallerThanHeader { ihl: 0 })
1550 },
1551 );
1552 }
1553
1554 {
1556 let mut data = test.to_vec(&[]);
1557 let ipv4_offset = data.len() - ipv4.header_len();
1558
1559 data[ipv4_offset + 2] = 0;
1561 data[ipv4_offset + 3] = 0;
1562
1563 let err = LenError {
1564 required_len: ipv4.header_len(),
1565 len: 0,
1566 len_source: LenSource::Ipv4HeaderTotalLen,
1567 layer: Layer::Ipv4Packet,
1568 layer_start_offset: {
1569 test.link.as_ref().map(|h| h.header_len()).unwrap_or(0)
1570 + test
1571 .link_exts
1572 .as_ref()
1573 .iter()
1574 .map(|h| h.header_len())
1575 .sum::<usize>()
1576 },
1577 };
1578
1579 from_slice_assert_err(&test, &data, SliceError::Len(err.clone()));
1580 }
1581 }
1582
1583 {
1585 let auth = IpAuthHeader::new(0.into(), 1, 2, &[]).unwrap();
1586
1587 let mut test = base.clone();
1588 test.set_ether_type(ether_type::IPV4);
1589 test.net = Some(NetHeaders::Ipv4(
1590 {
1591 let mut ipv4 = ipv4.clone();
1592 ipv4.protocol = ip_number::AUTH;
1593 ipv4
1594 },
1595 Ipv4Extensions {
1596 auth: Some(auth.clone()),
1597 },
1598 ));
1599 test.set_payload_len(0);
1600
1601 from_x_slice_transport_variants(&test);
1603
1604 for len in 0..auth.header_len() {
1606 let mut test = test.clone();
1608 test.set_payload_len_link_ext(
1609 test.net.as_ref().map(|v| v.header_len()).unwrap_or(0) + len
1610 - auth.header_len(),
1611 );
1612 test.set_payload_len_ip(-1 * (auth.header_len() as isize) + (len as isize));
1613
1614 let data = test.to_vec(&[]);
1615 let base_len = test.len(&[]) - auth.header_len();
1616
1617 let err = LenError {
1618 required_len: auth.header_len(),
1619 len,
1620 len_source: LenSource::Ipv4HeaderTotalLen,
1621 layer: Layer::IpAuthHeader,
1622 layer_start_offset: base_len,
1623 };
1624
1625 from_slice_assert_err(
1626 &test,
1627 &data[..base_len + len],
1628 SliceError::Len(err.clone()),
1629 );
1630 }
1631
1632 {
1634 let mut data = test.to_vec(&[]);
1635 let auth_offset = data.len() - auth.header_len();
1636
1637 data[auth_offset + 1] = 0;
1639
1640 let err = err::ip_auth::HeaderError::ZeroPayloadLen;
1642 from_slice_assert_err(&test, &data, SliceError::Ipv4Exts(err.clone()));
1643 }
1644 }
1645 }
1646
1647 {
1649 let ipv6 = Ipv6Header {
1650 traffic_class: 0,
1651 flow_label: 1.try_into().unwrap(),
1652 payload_length: 2,
1653 next_header: 3.into(),
1654 hop_limit: 4,
1655 source: [0; 16],
1656 destination: [0; 16],
1657 };
1658
1659 {
1661 let test = {
1662 let mut test = base.clone();
1663 test.set_ether_type(ether_type::IPV6);
1664 test.net = Some(NetHeaders::Ipv6(ipv6.clone(), Default::default()));
1665 test.set_payload_len(0);
1666 test
1667 };
1668
1669 from_x_slice_transport_variants(&test);
1671
1672 for len in 0..ipv6.header_len() {
1674 let base_len = test.len(&[]) - ipv6.header_len();
1675
1676 let mut test = test.clone();
1677 test.set_payload_len_link_ext(len);
1678
1679 let data = test.to_vec(&[]);
1680 let err = err::LenError {
1681 required_len: ipv6.header_len(),
1682 len,
1683 len_source: LenSource::Slice,
1684 layer: Layer::Ipv6Header,
1685 layer_start_offset: base_len,
1686 };
1687
1688 from_slice_assert_err(
1689 &test,
1690 &data[..base_len + len],
1691 if test.link.is_some() || !test.link_exts.is_empty() {
1692 SliceError::Len(err.clone())
1693 } else {
1694 SliceError::Len({
1695 if len < 1 {
1696 let mut err = err.clone();
1697 err.required_len = 1;
1698 err.layer = Layer::IpHeader;
1699 err
1700 } else {
1701 err.clone()
1702 }
1703 })
1704 },
1705 );
1706 }
1707
1708 {
1710 use err::ip::HeaderError::*;
1711
1712 let mut data = test.to_vec(&[]);
1713
1714 let base_len = data.len() - ipv6.header_len();
1716 data[base_len] = data[base_len] & 0b0000_1111;
1717
1718 from_slice_assert_err(
1719 &test,
1720 &data,
1721 if test.link.is_some() || !test.link_exts.is_empty() {
1722 SliceError::Ipv6(err::ipv6::HeaderError::UnexpectedVersion {
1723 version_number: 0,
1724 })
1725 } else {
1726 SliceError::Ip(UnsupportedIpVersion { version_number: 0 })
1727 },
1728 );
1729 }
1730 }
1731
1732 for fragment in [false, true] {
1734 let auth = IpAuthHeader::new(ip_number::GGP, 1, 2, &[]).unwrap();
1735 let frag = Ipv6FragmentHeader {
1736 next_header: ip_number::AUTH,
1737 fragment_offset: 0.try_into().unwrap(),
1738 more_fragments: fragment,
1739 identification: 3,
1740 };
1741
1742 let mut test = base.clone();
1743 test.set_ether_type(ether_type::IPV6);
1744 test.net = Some(NetHeaders::Ipv6(
1745 {
1746 let mut ipv6 = ipv6.clone();
1747 ipv6.next_header = ip_number::IPV6_FRAG;
1748 ipv6
1749 },
1750 {
1751 let mut exts: Ipv6Extensions = Default::default();
1752 exts.fragment = Some(frag.clone());
1753 exts.auth = Some(auth.clone());
1754 exts
1755 },
1756 ));
1757 test.set_payload_len(0);
1758
1759 from_x_slice_transport_variants(&test);
1761
1762 for len in 0..auth.header_len() {
1764 let mut test = test.clone();
1766 test.set_payload_len_link_ext(
1767 test.net.as_ref().map(|v| v.header_len()).unwrap_or(0) + len
1768 - auth.header_len(),
1769 );
1770 test.set_payload_len_ip(-1 * (auth.header_len() as isize) + (len as isize));
1771
1772 let data = test.to_vec(&[]);
1773 let base_len = test.len(&[]) - auth.header_len();
1774
1775 let err = LenError {
1776 required_len: auth.header_len(),
1777 len,
1778 len_source: LenSource::Ipv6HeaderPayloadLen,
1779 layer: Layer::IpAuthHeader,
1780 layer_start_offset: base_len,
1781 };
1782 from_slice_assert_err(
1783 &test,
1784 &data[..base_len + len],
1785 SliceError::Len(err.clone()),
1786 );
1787 }
1788
1789 {
1791 let mut data = test.to_vec(&[]);
1792 let auth_offset = data.len() - auth.header_len();
1793 data[auth_offset + 1] = 0;
1795
1796 let err = err::ip_auth::HeaderError::ZeroPayloadLen;
1797 from_slice_assert_err(
1798 &test,
1799 &data,
1800 SliceError::Ipv6Exts(err::ipv6_exts::HeaderError::IpAuth(err.clone())),
1801 );
1802 }
1803
1804 {
1806 let mut data = test.to_vec(&[]);
1807 let auth_offset = data.len() - auth.header_len();
1808
1809 data[auth_offset] = 0;
1811
1812 from_slice_assert_err(
1813 &test,
1814 &data,
1815 SliceError::Ipv6Exts(err::ipv6_exts::HeaderError::HopByHopNotAtStart),
1816 );
1817 }
1818 }
1819 }
1820 }
1821
1822 fn from_x_slice_transport_variants(base: &TestPacket) {
1823 from_x_slice_assert_ok(base);
1825
1826 if let Some(ip) = &base.net {
1828 {
1830 let udp = UdpHeader {
1831 source_port: 1,
1832 destination_port: 2,
1833 length: 3,
1834 checksum: 4,
1835 };
1836 let mut test = base.clone();
1837 test.net = Some({
1838 let mut ip = match ip {
1839 NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()),
1840 NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()),
1841 NetHeaders::Arp(_) => unreachable!(),
1842 };
1843 ip.set_next_headers(ip_number::UDP);
1844 ip.into()
1845 });
1846 test.transport = Some(TransportHeader::Udp(udp.clone()));
1847 test.set_payload_len(0);
1848
1849 from_x_slice_assert_ok(&test);
1851
1852 if false == test.is_ip_payload_fragmented() {
1854 for len in 0..udp.header_len() {
1855 let mut test = test.clone();
1857
1858 test.set_payload_len_ip(len as isize);
1860 test.set_payload_len_link_ext(
1861 len + test.net.as_ref().map(|v| v.header_len()).unwrap_or(0),
1862 );
1863
1864 let data = test.to_vec(&[]);
1866
1867 let base_len = test.len(&[]) - udp.header_len();
1868 let err = LenError {
1869 required_len: udp.header_len(),
1870 len,
1871 len_source: match test.net.as_ref().unwrap() {
1872 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen,
1873 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen,
1874 NetHeaders::Arp(_) => unreachable!(),
1875 },
1876 layer: Layer::UdpHeader,
1877 layer_start_offset: base_len,
1878 };
1879 from_slice_assert_err(
1880 &test,
1881 &data[..base_len + len],
1882 SliceError::Len(err.clone()),
1883 );
1884 }
1885 }
1886 }
1887
1888 {
1890 let tcp = TcpHeader::new(1, 2, 3, 4);
1891 let mut test = base.clone();
1892 test.net = Some({
1893 let mut ip = match ip {
1894 NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()),
1895 NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()),
1896 NetHeaders::Arp(_) => unreachable!(),
1897 };
1898 ip.set_next_headers(ip_number::TCP);
1899 ip.into()
1900 });
1901 test.transport = Some(TransportHeader::Tcp(tcp.clone()));
1902 test.set_payload_len(0);
1903
1904 from_x_slice_assert_ok(&test);
1906
1907 if false == test.is_ip_payload_fragmented() {
1909 {
1911 for len in 0..(tcp.header_len() as usize) {
1912 let mut test = test.clone();
1914 test.set_payload_len_ip(len as isize);
1915 test.set_payload_len_link_ext(
1916 len + test.net.as_ref().map(|v| v.header_len()).unwrap_or(0),
1917 );
1918
1919 let data = test.to_vec(&[]);
1920 let base_len = test.len(&[]) - (tcp.header_len() as usize);
1921
1922 let err = LenError {
1923 required_len: tcp.header_len() as usize,
1924 len,
1925 len_source: match test.net.as_ref().unwrap() {
1926 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen,
1927 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen,
1928 NetHeaders::Arp(_) => unreachable!(),
1929 },
1930 layer: Layer::TcpHeader,
1931 layer_start_offset: base_len,
1932 };
1933 from_slice_assert_err(
1934 &test,
1935 &data[..base_len + len],
1936 SliceError::Len(err.clone()),
1937 );
1938 }
1939 }
1940
1941 {
1943 let mut data = test.to_vec(&[]);
1944 let base_len = test.len(&[]) - (tcp.header_len() as usize);
1945
1946 data[base_len + 12] = data[base_len + 12] & 0b0000_1111;
1948
1949 let err = err::tcp::HeaderError::DataOffsetTooSmall { data_offset: 0 };
1950 from_slice_assert_err(&test, &data, SliceError::Tcp(err.clone()));
1951 }
1952 }
1953 }
1954
1955 {
1957 let icmpv4 =
1958 Icmpv4Header::new(Icmpv4Type::EchoReply(IcmpEchoHeader { id: 1, seq: 2 }));
1959 let mut test = base.clone();
1960 test.net = Some({
1961 let mut ip = match ip {
1962 NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()),
1963 NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()),
1964 NetHeaders::Arp(_) => unreachable!(),
1965 };
1966 ip.set_next_headers(ip_number::ICMP);
1967 ip.into()
1968 });
1969 test.transport = Some(TransportHeader::Icmpv4(icmpv4.clone()));
1970 test.set_payload_len(0);
1971
1972 from_x_slice_assert_ok(&test);
1974
1975 if false == test.is_ip_payload_fragmented() {
1977 for len in 0..icmpv4.header_len() {
1978 let mut test = test.clone();
1980 test.set_payload_len_ip(len as isize);
1981 test.set_payload_len_link_ext(
1982 len + test.net.as_ref().map(|v| v.header_len()).unwrap_or(0),
1983 );
1984
1985 let data = test.to_vec(&[]);
1986 let base_len = test.len(&[]) - icmpv4.header_len();
1987
1988 let err = LenError {
1989 required_len: icmpv4.header_len(),
1990 len,
1991 len_source: match test.net.as_ref().unwrap() {
1992 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen,
1993 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen,
1994 NetHeaders::Arp(_) => unreachable!(),
1995 },
1996 layer: Layer::Icmpv4,
1997 layer_start_offset: base_len,
1998 };
1999 from_slice_assert_err(
2000 &test,
2001 &data[..base_len + len],
2002 SliceError::Len(err.clone()),
2003 );
2004 }
2005 }
2006 }
2007
2008 {
2010 let icmpv6 =
2011 Icmpv6Header::new(Icmpv6Type::EchoReply(IcmpEchoHeader { id: 1, seq: 2 }));
2012 let mut test = base.clone();
2013 test.net = Some({
2014 let mut ip = match ip {
2015 NetHeaders::Ipv4(h, e) => IpHeaders::Ipv4(h.clone(), e.clone()),
2016 NetHeaders::Ipv6(h, e) => IpHeaders::Ipv6(h.clone(), e.clone()),
2017 NetHeaders::Arp(_) => unreachable!(),
2018 };
2019 ip.set_next_headers(ip_number::IPV6_ICMP);
2020 ip.into()
2021 });
2022 test.transport = Some(TransportHeader::Icmpv6(icmpv6.clone()));
2023 test.set_payload_len(0);
2024
2025 from_x_slice_assert_ok(&test);
2027
2028 if false == test.is_ip_payload_fragmented() {
2030 for len in 0..icmpv6.header_len() {
2031 let mut test = test.clone();
2033 test.set_payload_len_ip(len as isize);
2034 test.set_payload_len_link_ext(
2035 len + test.net.as_ref().map(|v| v.header_len()).unwrap_or(0),
2036 );
2037
2038 let data = test.to_vec(&[]);
2039 let base_len = test.len(&[]) - icmpv6.header_len();
2040
2041 let err = LenError {
2042 required_len: icmpv6.header_len(),
2043 len,
2044 len_source: match test.net.as_ref().unwrap() {
2045 NetHeaders::Ipv4(_, _) => LenSource::Ipv4HeaderTotalLen,
2046 NetHeaders::Ipv6(_, _) => LenSource::Ipv6HeaderPayloadLen,
2047 NetHeaders::Arp(_) => unreachable!(),
2048 },
2049 layer: Layer::Icmpv6,
2050 layer_start_offset: base_len,
2051 };
2052 from_slice_assert_err(
2053 &test,
2054 &data[..base_len + len],
2055 SliceError::Len(err.clone()),
2056 );
2057 }
2058 }
2059 }
2060 }
2061 }
2062
2063 fn from_x_slice_assert_ok(test_base: &TestPacket) {
2064 fn assert_test_result(test: &TestPacket, expected_payload: &[u8], result: &SlicedPacket) {
2065 let is_fragmented = test.is_ip_payload_fragmented();
2067
2068 assert_eq!(
2070 test.link,
2071 match result.link.as_ref() {
2072 Some(s) => match s {
2073 LinkSlice::Ethernet2(e) => Some(LinkHeader::Ethernet2(e.to_header())),
2074 LinkSlice::LinuxSll(e) => Some(LinkHeader::LinuxSll(e.to_header())),
2075 LinkSlice::EtherPayload(_) => None,
2076 LinkSlice::LinuxSllPayload(_) => None,
2077 },
2078 None => None,
2079 }
2080 );
2081 assert_eq!(
2082 test.link_exts,
2083 result
2084 .link_exts
2085 .as_ref()
2086 .iter()
2087 .map(|e| e.to_header())
2088 .collect::<ArrayVec<LinkExtHeader, 3>>()
2089 );
2090 assert_eq!(
2091 test.net,
2092 result.net.as_ref().map(|s: &NetSlice| -> NetHeaders {
2093 match s {
2094 NetSlice::Ipv4(ipv4) => NetHeaders::Ipv4(
2095 ipv4.header().to_header(),
2096 ipv4.extensions().to_header(),
2097 ),
2098 NetSlice::Ipv6(ipv6) => NetHeaders::Ipv6(
2099 ipv6.header().to_header(),
2100 Ipv6Extensions::from_slice(
2101 ipv6.header().next_header(),
2102 ipv6.extensions().slice(),
2103 )
2104 .unwrap()
2105 .0,
2106 ),
2107 NetSlice::Arp(arp) => NetHeaders::Arp(arp.to_packet()),
2108 }
2109 })
2110 );
2111
2112 if is_fragmented {
2114 assert_eq!(result.transport, None);
2115 } else {
2116 use TransportHeader as H;
2117 use TransportSlice as S;
2118 match &result.transport {
2119 Some(S::Icmpv4(icmpv4)) => {
2120 assert_eq!(&test.transport, &Some(H::Icmpv4(icmpv4.header())));
2121 assert_eq!(icmpv4.payload(), expected_payload);
2122 }
2123 Some(S::Icmpv6(icmpv6)) => {
2124 assert_eq!(&test.transport, &Some(H::Icmpv6(icmpv6.header())));
2125 assert_eq!(icmpv6.payload(), expected_payload);
2126 }
2127 Some(S::Udp(s)) => {
2128 assert_eq!(&test.transport, &Some(H::Udp(s.to_header())));
2129 }
2130 Some(S::Tcp(s)) => {
2131 assert_eq!(&test.transport, &Some(H::Tcp(s.to_header())));
2132 }
2133 None => {
2134 assert_eq!(&test.transport, &None);
2135 }
2136 }
2137 }
2138 }
2139
2140 let payload = [1, 2, 3, 4];
2142
2143 let test = {
2145 let mut test = test_base.clone();
2146 test.set_payload_len(payload.len());
2147 test
2148 };
2149
2150 let data = test.to_vec(&payload);
2152
2153 if test.link.is_some() {
2155 let result = SlicedPacket::from_ethernet(&data).unwrap();
2156 assert_test_result(&test, &payload, &result);
2157 }
2158 if test.link.is_none() && !test.link_exts.is_empty() {
2160 let ether_types: &[EtherType] = match test.link_exts.first().unwrap() {
2161 LinkExtHeader::Vlan(_) => &VLAN_ETHER_TYPES,
2162 LinkExtHeader::Macsec(_) => &MACSEC_ETHER_TYPES,
2163 };
2164 for ether_type in ether_types {
2165 let result = SlicedPacket::from_ether_type(*ether_type, &data).unwrap();
2166 assert_eq!(
2167 result.link,
2168 Some(LinkSlice::EtherPayload(EtherPayloadSlice {
2169 ether_type: *ether_type,
2170 len_source: LenSource::Slice,
2171 payload: &data
2172 }))
2173 );
2174 assert_test_result(&test, &payload, &result);
2175 }
2176 }
2177 if test.link.is_none() && test.link_exts.is_empty() {
2179 if let Some(ip) = &test.net {
2180 let ether_type = match ip {
2181 NetHeaders::Ipv4(_, _) => ether_type::IPV4,
2182 NetHeaders::Ipv6(_, _) => ether_type::IPV6,
2183 NetHeaders::Arp(_) => ether_type::ARP,
2184 };
2185 let result = SlicedPacket::from_ether_type(ether_type, &data).unwrap();
2186 assert_eq!(
2187 result.link,
2188 Some(LinkSlice::EtherPayload(EtherPayloadSlice {
2189 ether_type,
2190 len_source: LenSource::Slice,
2191 payload: &data
2192 }))
2193 );
2194 assert_test_result(&test, &payload, &result);
2195 }
2196 }
2197 if test.link.is_none() && test.link_exts.is_empty() && test.net.is_some() {
2199 let result = SlicedPacket::from_ip(&data).unwrap();
2200 assert_test_result(&test, &payload, &result);
2201 }
2202 }
2203
2204 fn from_slice_assert_err(test: &TestPacket, data: &[u8], err: SliceError) {
2207 if let Some(ref header) = test.link {
2209 match header {
2210 LinkHeader::Ethernet2(_) => {
2211 assert_eq!(err.clone(), SlicedPacket::from_ethernet(&data).unwrap_err())
2212 }
2213 LinkHeader::LinuxSll(_) => assert_eq!(
2214 err.clone(),
2215 SlicedPacket::from_linux_sll(&data).unwrap_err()
2216 ),
2217 }
2218 }
2219 if test.link.is_none() && !test.link_exts.is_empty() {
2221 let ether_types: &[EtherType] = match test.link_exts.first().unwrap() {
2222 LinkExtHeader::Vlan(_) => &VLAN_ETHER_TYPES,
2223 LinkExtHeader::Macsec(_) => &MACSEC_ETHER_TYPES,
2224 };
2225 for ether_type in ether_types {
2226 assert_eq!(
2227 err.clone(),
2228 SlicedPacket::from_ether_type(*ether_type, &data).unwrap_err()
2229 );
2230 }
2231 }
2232 if test.link.is_none() && test.link_exts.is_empty() {
2234 if let Some(ip) = &test.net {
2235 let err = SlicedPacket::from_ether_type(
2236 match ip {
2237 NetHeaders::Ipv4(_, _) => ether_type::IPV4,
2238 NetHeaders::Ipv6(_, _) => ether_type::IPV6,
2239 NetHeaders::Arp(_) => ether_type::ARP,
2240 },
2241 &data,
2242 )
2243 .unwrap_err();
2244 assert_eq!(err, err.clone());
2245 }
2246 }
2247 if test.link.is_none() && test.link_exts.is_empty() && test.net.is_some() {
2249 assert_eq!(err, SlicedPacket::from_ip(&data).unwrap_err());
2250 }
2251 }
2252
2253 proptest! {
2254 #[test]
2255 fn payload_ether_type(
2256 ref eth in ethernet_2_unknown(),
2257 ether_type in ether_type_unknown(),
2258 ref linux_sll in linux_sll_any(),
2259 ref vlan_outer in vlan_single_unknown(),
2260 ref vlan_inner in vlan_single_unknown(),
2261 ref macsec in macsec_any(),
2262 ref ipv4 in ipv4_unknown(),
2263 ref udp in udp_any(),
2264 ) {
2265 use IpHeaders::*;
2266 use alloc::vec::Vec;
2267
2268 {
2270 let s = SlicedPacket{
2271 link: None,
2272 link_exts: ArrayVec::new_const(),
2273 net: None,
2274 transport: None,
2275 };
2276 assert_eq!(None, s.payload_ether_type());
2277 }
2278
2279 {
2281 let test = [
2282 (None, ArpHardwareId::FRAD, LinuxSllProtocolType::Ignored(0)),
2283 (None, ArpHardwareId::NETLINK, LinuxSllProtocolType::NetlinkProtocolType(0)),
2284 (None, ArpHardwareId::IPGRE, LinuxSllProtocolType::GenericRoutingEncapsulationProtocolType(0)),
2285 (Some(ether_type::WAKE_ON_LAN), ArpHardwareId::ETHERNET, LinuxSllProtocolType::EtherType(ether_type::WAKE_ON_LAN)),
2286 (None, ArpHardwareId::ETHERNET, LinuxSllProtocolType::LinuxNonstandardEtherType(LinuxNonstandardEtherType::CAN)),
2287 ];
2288
2289 for (expected, arp_hrd_type, protocol_type) in test {
2290 {
2291 let mut l = linux_sll.clone();
2292 l.arp_hrd_type = arp_hrd_type;
2293 l.protocol_type = protocol_type;
2294
2295 let mut bytes = Vec::with_capacity(linux_sll.header_len());
2296 l.write(&mut bytes).unwrap();
2297
2298 let s = SlicedPacket::from_linux_sll(&bytes).unwrap();
2299 assert_eq!(
2300 expected,
2301 s.payload_ether_type()
2302 );
2303 }
2304 {
2305 let s = SlicedPacket{
2306 link: Some(LinkSlice::LinuxSllPayload(LinuxSllPayloadSlice{
2307 protocol_type: protocol_type,
2308 payload: &[]
2309 })),
2310 link_exts: Default::default(),
2311 net: None,
2312 transport: None,
2313 };
2314 assert_eq!(
2315 expected,
2316 s.payload_ether_type()
2317 );
2318 }
2319 }
2320 }
2321
2322 {
2324 let mut serialized = Vec::with_capacity(eth.header_len());
2325 eth.write(&mut serialized).unwrap();
2326 assert_eq!(
2327 Some(eth.ether_type),
2328 SlicedPacket::from_ethernet(&serialized)
2329 .unwrap()
2330 .payload_ether_type()
2331 );
2332 }
2333
2334 {
2336 let s = SlicedPacket {
2337 link: Some(LinkSlice::EtherPayload(EtherPayloadSlice {
2338 ether_type,
2339 len_source: LenSource::Slice,
2340 payload: &[],
2341 })),
2342 link_exts: Default::default(),
2343 net: None,
2344 transport: None,
2345 };
2346 assert_eq!(
2347 Some(ether_type),
2348 s.payload_ether_type()
2349 );
2350 }
2351
2352 {
2354 let mut eth_mod = eth.clone();
2355 eth_mod.ether_type = ether_type::VLAN_TAGGED_FRAME;
2356
2357 let mut serialized = Vec::with_capacity(
2358 eth_mod.header_len() +
2359 vlan_outer.header_len()
2360 );
2361 eth_mod.write(&mut serialized).unwrap();
2362 vlan_outer.write(&mut serialized).unwrap();
2363 assert_eq!(
2364 Some(vlan_outer.ether_type),
2365 SlicedPacket::from_ethernet(&serialized)
2366 .unwrap()
2367 .payload_ether_type()
2368 );
2369 }
2370
2371 {
2373 let mut eth_mod = eth.clone();
2374 eth_mod.ether_type = ether_type::VLAN_TAGGED_FRAME;
2375
2376 let mut vlan_outer_mod = vlan_outer.clone();
2377 vlan_outer_mod.ether_type = ether_type::VLAN_TAGGED_FRAME;
2378
2379 let mut serialized = Vec::with_capacity(
2380 eth_mod.header_len() +
2381 vlan_outer_mod.header_len() +
2382 vlan_inner.header_len()
2383 );
2384 eth_mod.write(&mut serialized).unwrap();
2385 vlan_outer_mod.write(&mut serialized).unwrap();
2386 vlan_inner.write(&mut serialized).unwrap();
2387 assert_eq!(
2388 Some(vlan_inner.ether_type),
2389 SlicedPacket::from_ethernet(&serialized)
2390 .unwrap()
2391 .payload_ether_type()
2392 );
2393 }
2394
2395 {
2397 let tests = [
2398 (Some(ether_type), MacsecPType::Unmodified(ether_type)),
2399 (None, MacsecPType::Modified),
2400 (None, MacsecPType::Encrypted),
2401 (None, MacsecPType::EncryptedUnmodified),
2402 ];
2403 for (expected, ptype) in tests {
2404 let mut eth_mod = eth.clone();
2405 eth_mod.ether_type = ether_type::MACSEC;
2406
2407 let mut serialized = Vec::with_capacity(
2408 eth_mod.header_len() +
2409 macsec.header_len()
2410 );
2411 eth_mod.write(&mut serialized).unwrap();
2412 let mut macsec = macsec.clone();
2413 macsec.ptype = ptype;
2414 macsec.set_payload_len(0);
2415 macsec.write(&mut serialized).unwrap();
2416 assert_eq!(
2417 expected,
2418 SlicedPacket::from_ethernet(&serialized)
2419 .unwrap()
2420 .payload_ether_type()
2421 );
2422 }
2423 }
2424
2425 {
2427 let builder = PacketBuilder::ethernet2(eth.source, eth.destination)
2428 .ip(Ipv4(ipv4.clone(), Default::default()));
2429
2430 let mut serialized = Vec::with_capacity(builder.size(0));
2431 builder.write(&mut serialized, ipv4.protocol, &[]).unwrap();
2432
2433 assert_eq!(
2434 None,
2435 SlicedPacket::from_ethernet(&serialized)
2436 .unwrap()
2437 .payload_ether_type()
2438 );
2439 }
2440
2441 {
2443 let builder = PacketBuilder::ethernet2(eth.source, eth.destination)
2444 .ip(Ipv4(ipv4.clone(), Default::default()))
2445 .udp(udp.source_port, udp.destination_port);
2446 let mut serialized = Vec::with_capacity(builder.size(0));
2447 builder.write(&mut serialized, &[]).unwrap();
2448
2449 assert_eq!(
2450 None,
2451 SlicedPacket::from_ethernet(&serialized)
2452 .unwrap()
2453 .payload_ether_type()
2454 );
2455 }
2456 }
2457 }
2458}