1use core::convert::Infallible as Never;
6use core::fmt::Debug;
7use core::num::NonZeroU16;
8
9use net_types::ip::{
10 GenericOverIp, Ip, IpAddress, IpInvariant, IpVersionMarker, Ipv4, Ipv4Addr, Ipv6, Ipv6Addr,
11};
12use netstack3_base::{Options, PayloadLen, SegmentHeader};
13use packet::{
14 Buf, Buffer, BufferMut, BufferProvider, BufferViewMut, DynSerializer, DynamicSerializer,
15 EitherSerializer, EmptyBuf, GrowBufferMut, InnerSerializer, LayoutBufferAlloc, Nested,
16 PacketBuilder, PacketConstraints, ParsablePacket, ParseBuffer, ParseMetadata,
17 PartialSerializeResult, PartialSerializer, SerializeError, Serializer, SliceBufViewMut,
18 TruncatingSerializer,
19};
20use packet_formats::icmp::mld::{
21 MulticastListenerDone, MulticastListenerQuery, MulticastListenerQueryV2,
22 MulticastListenerReport, MulticastListenerReportV2,
23};
24use packet_formats::icmp::ndp::options::NdpOptionBuilder;
25use packet_formats::icmp::ndp::{
26 NeighborAdvertisement, NeighborSolicitation, Redirect, RouterAdvertisement, RouterSolicitation,
27};
28use packet_formats::icmp::{
29 self, IcmpDestUnreachable, IcmpEchoReply, IcmpEchoRequest, IcmpPacketBuilder, IcmpPacketRaw,
30 IcmpPacketTypeRaw as _, IcmpTimeExceeded, Icmpv4MessageType, Icmpv4PacketRaw,
31 Icmpv4ParameterProblem, Icmpv4Redirect, Icmpv4TimestampReply, Icmpv4TimestampRequest,
32 Icmpv6MessageType, Icmpv6PacketRaw, Icmpv6PacketTooBig, Icmpv6ParameterProblem,
33};
34use packet_formats::igmp::messages::IgmpMembershipReportV3Builder;
35use packet_formats::igmp::{self, IgmpPacketBuilder};
36use packet_formats::ip::{IpExt, IpPacketBuilder, IpProto, Ipv4Proto, Ipv6Proto};
37use packet_formats::ipv4::{Ipv4Header, Ipv4Packet, Ipv4PacketRaw};
38use packet_formats::ipv6::{Ipv6Header, Ipv6Packet, Ipv6PacketRaw};
39use packet_formats::tcp::options::TcpOptionsBuilder;
40use packet_formats::tcp::{TcpSegmentBuilderWithOptions, TcpSegmentRaw};
41use packet_formats::udp::{UdpPacketBuilder, UdpPacketRaw};
42use zerocopy::{SplitByteSlice, SplitByteSliceMut};
43
44use crate::conntrack;
45
46pub trait FilterIpExt: IpExt {
48 type FilterIpPacket<B: SplitByteSliceMut>: IpPacket<Self>;
50
51 type FilterIpPacketRaw<B: SplitByteSliceMut>: IpPacket<Self>;
54
55 fn as_filter_packet<B: SplitByteSliceMut>(
58 packet: &mut Self::Packet<B>,
59 ) -> &mut Self::FilterIpPacket<B>;
60
61 fn as_filter_packet_owned<B: SplitByteSliceMut>(
63 packet: Self::Packet<B>,
64 ) -> Self::FilterIpPacket<B>;
65
66 fn as_filter_packet_raw_owned<B: SplitByteSliceMut>(
69 packet: Self::PacketRaw<B>,
70 ) -> Self::FilterIpPacketRaw<B>;
71}
72
73impl FilterIpExt for Ipv4 {
74 type FilterIpPacket<B: SplitByteSliceMut> = Ipv4Packet<B>;
75 type FilterIpPacketRaw<B: SplitByteSliceMut> = Ipv4PacketRaw<B>;
76
77 #[inline]
78 fn as_filter_packet<B: SplitByteSliceMut>(packet: &mut Ipv4Packet<B>) -> &mut Ipv4Packet<B> {
79 packet
80 }
81
82 #[inline]
83 fn as_filter_packet_owned<B: SplitByteSliceMut>(
84 packet: Self::Packet<B>,
85 ) -> Self::FilterIpPacket<B> {
86 packet
87 }
88
89 #[inline]
90 fn as_filter_packet_raw_owned<B: SplitByteSliceMut>(
91 packet: Self::PacketRaw<B>,
92 ) -> Self::FilterIpPacketRaw<B> {
93 packet
94 }
95}
96
97impl FilterIpExt for Ipv6 {
98 type FilterIpPacket<B: SplitByteSliceMut> = Ipv6Packet<B>;
99 type FilterIpPacketRaw<B: SplitByteSliceMut> = Ipv6PacketRaw<B>;
100
101 #[inline]
102 fn as_filter_packet<B: SplitByteSliceMut>(packet: &mut Ipv6Packet<B>) -> &mut Ipv6Packet<B> {
103 packet
104 }
105
106 #[inline]
107 fn as_filter_packet_owned<B: SplitByteSliceMut>(
108 packet: Self::Packet<B>,
109 ) -> Self::FilterIpPacket<B> {
110 packet
111 }
112
113 #[inline]
114 fn as_filter_packet_raw_owned<B: SplitByteSliceMut>(
115 packet: Self::PacketRaw<B>,
116 ) -> Self::FilterIpPacketRaw<B> {
117 packet
118 }
119}
120
121pub trait IpPacket<I: FilterIpExt> {
123 type TransportPacket<'a>: MaybeTransportPacket
126 where
127 Self: 'a;
128
129 type TransportPacketMut<'a>: MaybeTransportPacketMut<I>
132 where
133 Self: 'a;
134
135 type IcmpError<'a>: MaybeIcmpErrorPayload<I>
138 where
139 Self: 'a;
140
141 type IcmpErrorMut<'a>: MaybeIcmpErrorMut<I>
144 where
145 Self: 'a;
146
147 fn src_addr(&self) -> I::Addr;
149
150 fn set_src_addr(&mut self, addr: I::Addr);
152
153 fn dst_addr(&self) -> I::Addr;
155
156 fn set_dst_addr(&mut self, addr: I::Addr);
158
159 fn protocol(&self) -> Option<I::Proto>;
161
162 fn maybe_transport_packet<'a>(&'a self) -> Self::TransportPacket<'a>;
173
174 fn transport_packet_mut<'a>(&'a mut self) -> Self::TransportPacketMut<'a>;
185
186 fn maybe_icmp_error<'a>(&'a self) -> Self::IcmpError<'a>;
192
193 fn icmp_error_mut<'a>(&'a mut self) -> Self::IcmpErrorMut<'a>;
199
200 fn conntrack_packet(&self) -> Option<conntrack::PacketMetadata<I>> {
216 if let Some(payload) = self.maybe_icmp_error().icmp_error_payload() {
217 (self.dst_addr() == payload.src_ip).then(|| {
244 conntrack::PacketMetadata::new_from_icmp_error(
245 payload.src_ip,
246 payload.dst_ip,
247 payload.src_port,
248 payload.dst_port,
249 I::map_ip(payload.proto, |proto| proto.into(), |proto| proto.into()),
250 )
251 })
252 } else {
253 self.maybe_transport_packet().transport_packet_data().and_then(|transport_data| {
254 Some(conntrack::PacketMetadata::new(
255 self.src_addr(),
256 self.dst_addr(),
257 I::map_ip(self.protocol()?, |proto| proto.into(), |proto| proto.into()),
258 transport_data,
259 ))
260 })
261 }
262 }
263}
264
265pub trait MaybeTransportPacket {
272 fn transport_packet_data(&self) -> Option<TransportPacketData>;
275}
276
277pub trait MaybeTransportPacketMut<I: IpExt> {
285 type TransportPacketMut<'a>: TransportPacketMut<I>
288 where
289 Self: 'a;
290
291 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>>;
294}
295
296pub trait DynamicMaybeTransportPacketMut<I: IpExt> {
306 fn dyn_transport_packet_mut(&mut self) -> Option<&mut dyn TransportPacketMut<I>>;
307}
308
309pub trait MaybeIcmpErrorPayload<I: IpExt> {
313 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>>;
316}
317
318pub trait MaybeIcmpErrorMut<I: FilterIpExt> {
321 type IcmpErrorMut<'a>: IcmpErrorMut<I>
322 where
323 Self: 'a;
324
325 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>>;
326}
327
328pub trait DynamicMaybeIcmpErrorMut<I: IpExt> {
338 fn dyn_icmp_error_mut(&mut self) -> Option<&mut dyn DynamicIcmpErrorMut<I>>;
339}
340
341pub trait TransportPacketSerializer<I: FilterIpExt>:
343 Serializer
344 + PartialSerializer
345 + MaybeTransportPacket
346 + MaybeTransportPacketMut<I>
347 + MaybeIcmpErrorPayload<I>
348 + MaybeIcmpErrorMut<I>
349{
350}
351
352impl<I, S> TransportPacketSerializer<I> for S
353where
354 I: FilterIpExt,
355 S: Serializer
356 + PartialSerializer
357 + MaybeTransportPacket
358 + MaybeTransportPacketMut<I>
359 + MaybeIcmpErrorPayload<I>
360 + MaybeIcmpErrorMut<I>,
361{
362}
363
364pub trait DynamicTransportSerializer<I: FilterIpExt>:
370 DynamicSerializer
371 + PartialSerializer
372 + MaybeTransportPacket
373 + DynamicMaybeTransportPacketMut<I>
374 + DynamicMaybeIcmpErrorMut<I>
375 + MaybeIcmpErrorPayload<I>
376{
377}
378
379impl<O, I> DynamicTransportSerializer<I> for O
380where
381 O: TransportPacketSerializer<I>
382 + DynamicMaybeTransportPacketMut<I>
383 + DynamicMaybeIcmpErrorMut<I>,
384 I: FilterIpExt,
385{
386}
387
388pub struct DynTransportSerializer<'a, I: FilterIpExt>(&'a mut dyn DynamicTransportSerializer<I>);
391
392impl<'a, I: FilterIpExt> DynTransportSerializer<'a, I> {
393 pub fn new(inner: &'a mut dyn DynamicTransportSerializer<I>) -> Self {
396 Self(inner)
397 }
398}
399
400impl<I: FilterIpExt> Serializer for DynTransportSerializer<'_, I> {
401 type Buffer = EmptyBuf;
402
403 fn serialize<B: GrowBufferMut, P: BufferProvider<Self::Buffer, B>>(
404 self,
405 outer: PacketConstraints,
406 provider: P,
407 ) -> Result<B, (SerializeError<P::Error>, Self)> {
408 match DynSerializer::new_dyn(self.0).serialize(outer, provider) {
409 Ok(r) => Ok(r),
410 Err((e, _)) => Err((e, self)),
411 }
412 }
413
414 fn serialize_new_buf<B: GrowBufferMut, A: LayoutBufferAlloc<B>>(
415 &self,
416 outer: PacketConstraints,
417 alloc: A,
418 ) -> Result<B, SerializeError<A::Error>> {
419 DynSerializer::new_dyn(self.0).serialize_new_buf(outer, alloc)
420 }
421}
422
423impl<'a, I: FilterIpExt> PartialSerializer for DynTransportSerializer<'a, I> {
424 fn partial_serialize(
425 &self,
426 outer: PacketConstraints,
427 buffer: &mut [u8],
428 ) -> Result<PartialSerializeResult, SerializeError<Never>> {
429 (*self.0).partial_serialize(outer, buffer)
430 }
431}
432
433impl<'a, I: FilterIpExt> MaybeTransportPacket for DynTransportSerializer<'a, I> {
434 fn transport_packet_data(&self) -> Option<TransportPacketData> {
435 (*self.0).transport_packet_data()
436 }
437}
438
439impl<'a, I: FilterIpExt> MaybeIcmpErrorPayload<I> for DynTransportSerializer<'a, I> {
440 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
441 (*self.0).icmp_error_payload()
442 }
443}
444
445impl<'a, I: FilterIpExt> MaybeIcmpErrorMut<I> for DynTransportSerializer<'a, I> {
446 type IcmpErrorMut<'b>
447 = &'b mut dyn DynamicIcmpErrorMut<I>
448 where
449 Self: 'b;
450
451 fn icmp_error_mut(&mut self) -> Option<Self::IcmpErrorMut<'_>> {
452 (*self.0).dyn_icmp_error_mut()
453 }
454}
455
456impl<'a, I: FilterIpExt> MaybeTransportPacketMut<I> for DynTransportSerializer<'a, I> {
457 type TransportPacketMut<'b>
458 = &'b mut dyn TransportPacketMut<I>
459 where
460 Self: 'b;
461
462 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
463 (*self.0).dyn_transport_packet_mut()
464 }
465}
466
467impl<T: ?Sized> MaybeTransportPacket for &T
468where
469 T: MaybeTransportPacket,
470{
471 fn transport_packet_data(&self) -> Option<TransportPacketData> {
472 (**self).transport_packet_data()
473 }
474}
475
476impl<T: ?Sized, I: IpExt> MaybeIcmpErrorPayload<I> for &T
477where
478 T: MaybeIcmpErrorPayload<I>,
479{
480 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
481 (**self).icmp_error_payload()
482 }
483}
484
485impl<T: ?Sized> MaybeTransportPacket for &mut T
486where
487 T: MaybeTransportPacket,
488{
489 fn transport_packet_data(&self) -> Option<TransportPacketData> {
490 (**self).transport_packet_data()
491 }
492}
493
494impl<I: IpExt, T: ?Sized> MaybeTransportPacketMut<I> for &mut T
495where
496 T: MaybeTransportPacketMut<I>,
497{
498 type TransportPacketMut<'a>
499 = T::TransportPacketMut<'a>
500 where
501 Self: 'a;
502
503 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
504 (**self).transport_packet_mut()
505 }
506}
507
508impl<I: FilterIpExt, T: ?Sized> MaybeIcmpErrorMut<I> for &mut T
509where
510 T: MaybeIcmpErrorMut<I>,
511{
512 type IcmpErrorMut<'a>
513 = T::IcmpErrorMut<'a>
514 where
515 Self: 'a;
516
517 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
518 (**self).icmp_error_mut()
519 }
520}
521
522impl<I: FilterIpExt, T: ?Sized> IcmpErrorMut<I> for &mut T
523where
524 T: IcmpErrorMut<I>,
525{
526 type InnerPacket<'a>
527 = T::InnerPacket<'a>
528 where
529 Self: 'a;
530
531 fn recalculate_checksum(&mut self) -> bool {
532 (**self).recalculate_checksum()
533 }
534
535 fn inner_packet<'a>(&'a mut self) -> Option<Self::InnerPacket<'a>> {
536 (**self).inner_packet()
537 }
538}
539
540impl<I: IpExt, T: TransportPacketMut<I>> MaybeTransportPacketMut<I> for Option<T> {
541 type TransportPacketMut<'a>
542 = &'a mut T
543 where
544 Self: 'a;
545
546 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
547 self.as_mut()
548 }
549}
550
551impl<I: FilterIpExt, T> MaybeIcmpErrorMut<I> for Option<T>
552where
553 T: IcmpErrorMut<I>,
554{
555 type IcmpErrorMut<'a>
556 = &'a mut T
557 where
558 Self: 'a;
559
560 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
561 self.as_mut()
562 }
563}
564
565#[derive(Debug, Clone, GenericOverIp, PartialEq, Eq)]
568#[generic_over_ip()]
569pub enum TransportPacketData {
570 Tcp { src_port: u16, dst_port: u16, segment: SegmentHeader, payload_len: usize },
571 Generic { src_port: u16, dst_port: u16 },
572}
573
574impl TransportPacketData {
575 pub fn src_port(&self) -> u16 {
576 match self {
577 TransportPacketData::Tcp { src_port, .. }
578 | TransportPacketData::Generic { src_port, .. } => *src_port,
579 }
580 }
581
582 pub fn dst_port(&self) -> u16 {
583 match self {
584 TransportPacketData::Tcp { dst_port, .. }
585 | TransportPacketData::Generic { dst_port, .. } => *dst_port,
586 }
587 }
588
589 pub fn tcp_segment_and_len(&self) -> Option<(&SegmentHeader, usize)> {
590 match self {
591 TransportPacketData::Tcp { segment, payload_len, .. } => Some((&segment, *payload_len)),
592 TransportPacketData::Generic { .. } => None,
593 }
594 }
595
596 fn parse_in_ip_packet<I: IpExt, B: ParseBuffer>(
597 src_ip: I::Addr,
598 dst_ip: I::Addr,
599 proto: I::Proto,
600 body: B,
601 ) -> Option<TransportPacketData> {
602 I::map_ip(
603 (src_ip, dst_ip, proto, IpInvariant(body)),
604 |(src_ip, dst_ip, proto, IpInvariant(body))| {
605 parse_transport_header_in_ipv4_packet(src_ip, dst_ip, proto, body)
606 },
607 |(src_ip, dst_ip, proto, IpInvariant(body))| {
608 parse_transport_header_in_ipv6_packet(src_ip, dst_ip, proto, body)
609 },
610 )
611 }
612}
613
614pub trait TransportPacketMut<I: IpExt> {
619 fn set_src_port(&mut self, port: NonZeroU16);
621
622 fn set_dst_port(&mut self, port: NonZeroU16);
624
625 fn update_pseudo_header_src_addr(&mut self, old: I::Addr, new: I::Addr);
627
628 fn update_pseudo_header_dst_addr(&mut self, old: I::Addr, new: I::Addr);
630}
631
632pub trait IcmpErrorMut<I: FilterIpExt> {
635 type InnerPacket<'a>: IpPacket<I>
636 where
637 Self: 'a;
638
639 fn recalculate_checksum(&mut self) -> bool;
646
647 fn inner_packet<'a>(&'a mut self) -> Option<Self::InnerPacket<'a>>;
650}
651
652pub trait DynamicIcmpErrorMut<I: FilterIpExt> {
659 fn dyn_recalculate_checksum(&mut self) -> bool;
660 fn dyn_inner_packet(&mut self) -> Option<I::FilterIpPacketRaw<&mut [u8]>>;
661}
662
663impl<'a, I: FilterIpExt> IcmpErrorMut<I> for dyn DynamicIcmpErrorMut<I> + 'a {
664 type InnerPacket<'b>
665 = I::FilterIpPacketRaw<&'b mut [u8]>
666 where
667 Self: 'b;
668
669 fn recalculate_checksum(&mut self) -> bool {
670 self.dyn_recalculate_checksum()
671 }
672 fn inner_packet<'b>(&'b mut self) -> Option<Self::InnerPacket<'b>> {
673 self.dyn_inner_packet()
674 }
675}
676
677impl<B: SplitByteSliceMut> IpPacket<Ipv4> for Ipv4Packet<B> {
678 type TransportPacket<'a>
679 = &'a Self
680 where
681 Self: 'a;
682 type TransportPacketMut<'a>
683 = Option<ParsedTransportHeaderMut<'a, Ipv4>>
684 where
685 B: 'a;
686 type IcmpError<'a>
687 = &'a Self
688 where
689 Self: 'a;
690 type IcmpErrorMut<'a>
691 = Option<ParsedIcmpErrorMut<'a, Ipv4>>
692 where
693 B: 'a;
694
695 fn src_addr(&self) -> Ipv4Addr {
696 self.src_ip()
697 }
698
699 fn set_src_addr(&mut self, addr: Ipv4Addr) {
700 let old = self.src_addr();
701 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
702 packet.update_pseudo_header_src_addr(old, addr);
703 }
704
705 self.set_src_ip_and_update_checksum(addr);
706 }
707
708 fn dst_addr(&self) -> Ipv4Addr {
709 self.dst_ip()
710 }
711
712 fn set_dst_addr(&mut self, addr: Ipv4Addr) {
713 let old = self.dst_addr();
714 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
715 packet.update_pseudo_header_dst_addr(old, addr);
716 }
717
718 self.set_dst_ip_and_update_checksum(addr);
719 }
720
721 fn protocol(&self) -> Option<Ipv4Proto> {
722 Some(self.proto())
723 }
724
725 fn maybe_transport_packet(&self) -> Self::TransportPacket<'_> {
726 self
727 }
728
729 fn transport_packet_mut(&mut self) -> Self::TransportPacketMut<'_> {
730 ParsedTransportHeaderMut::parse_in_ipv4_packet(
731 self.proto(),
732 SliceBufViewMut::new(self.body_mut()),
733 )
734 }
735
736 fn maybe_icmp_error<'a>(&'a self) -> Self::IcmpError<'a> {
737 self
738 }
739
740 fn icmp_error_mut<'a>(&'a mut self) -> Self::IcmpErrorMut<'a> {
741 ParsedIcmpErrorMut::parse_in_ipv4_packet(
742 self.src_addr(),
743 self.dst_addr(),
744 self.proto(),
745 SliceBufViewMut::new(self.body_mut()),
746 )
747 }
748}
749
750impl<B: SplitByteSlice> MaybeTransportPacket for Ipv4Packet<B> {
751 fn transport_packet_data(&self) -> Option<TransportPacketData> {
752 parse_transport_header_in_ipv4_packet(
753 self.src_ip(),
754 self.dst_ip(),
755 self.proto(),
756 self.body(),
757 )
758 }
759}
760
761impl<B: SplitByteSlice> MaybeIcmpErrorPayload<Ipv4> for Ipv4Packet<B> {
762 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<Ipv4>> {
763 ParsedIcmpErrorPayload::parse_in_outer_ipv4_packet(self.proto(), Buf::new(self.body(), ..))
764 }
765}
766
767impl<B: SplitByteSliceMut> IpPacket<Ipv4> for Ipv4PacketRaw<B> {
768 type TransportPacket<'a>
769 = &'a Self
770 where
771 Self: 'a;
772 type TransportPacketMut<'a>
773 = Option<ParsedTransportHeaderMut<'a, Ipv4>>
774 where
775 B: 'a;
776 type IcmpError<'a>
777 = &'a Self
778 where
779 Self: 'a;
780 type IcmpErrorMut<'a>
781 = Option<ParsedIcmpErrorMut<'a, Ipv4>>
782 where
783 B: 'a;
784
785 fn src_addr(&self) -> Ipv4Addr {
786 self.src_ip()
787 }
788
789 fn set_src_addr(&mut self, addr: Ipv4Addr) {
790 let old = self.src_ip();
791 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
792 packet.update_pseudo_header_src_addr(old, addr);
793 }
794
795 self.set_src_ip_and_update_checksum(addr);
796 }
797
798 fn dst_addr(&self) -> Ipv4Addr {
799 self.dst_ip()
800 }
801
802 fn set_dst_addr(&mut self, addr: Ipv4Addr) {
803 let old = self.dst_ip();
804 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
805 packet.update_pseudo_header_dst_addr(old, addr);
806 }
807
808 self.set_dst_ip_and_update_checksum(addr);
809 }
810
811 fn protocol(&self) -> Option<Ipv4Proto> {
812 Some(self.proto())
813 }
814
815 fn maybe_transport_packet<'a>(&'a self) -> Self::TransportPacket<'a> {
816 self
817 }
818
819 fn transport_packet_mut<'a>(&'a mut self) -> Self::TransportPacketMut<'a> {
820 ParsedTransportHeaderMut::parse_in_ipv4_packet(
821 self.proto(),
822 SliceBufViewMut::new(self.body_mut()),
823 )
824 }
825
826 fn maybe_icmp_error<'a>(&'a self) -> Self::IcmpError<'a> {
827 self
828 }
829
830 fn icmp_error_mut<'a>(&'a mut self) -> Self::IcmpErrorMut<'a> {
831 ParsedIcmpErrorMut::parse_in_ipv4_packet(
832 self.src_addr(),
833 self.dst_addr(),
834 self.proto(),
835 SliceBufViewMut::new(self.body_mut()),
836 )
837 }
838}
839
840impl<B: SplitByteSlice> MaybeTransportPacket for Ipv4PacketRaw<B> {
841 fn transport_packet_data(&self) -> Option<TransportPacketData> {
842 parse_transport_header_in_ipv4_packet(
843 self.src_ip(),
844 self.dst_ip(),
845 self.proto(),
846 self.body().into_inner(),
849 )
850 }
851}
852
853impl<B: SplitByteSlice> MaybeIcmpErrorPayload<Ipv4> for Ipv4PacketRaw<B> {
854 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<Ipv4>> {
855 ParsedIcmpErrorPayload::parse_in_outer_ipv4_packet(
856 self.proto(),
857 Buf::new(self.body().into_inner(), ..),
860 )
861 }
862}
863
864impl<B: SplitByteSliceMut> IpPacket<Ipv6> for Ipv6Packet<B> {
865 type TransportPacket<'a>
866 = &'a Self
867 where
868 Self: 'a;
869 type TransportPacketMut<'a>
870 = Option<ParsedTransportHeaderMut<'a, Ipv6>>
871 where
872 B: 'a;
873 type IcmpError<'a>
874 = &'a Self
875 where
876 Self: 'a;
877 type IcmpErrorMut<'a>
878 = Option<ParsedIcmpErrorMut<'a, Ipv6>>
879 where
880 B: 'a;
881
882 fn src_addr(&self) -> Ipv6Addr {
883 self.src_ip()
884 }
885
886 fn set_src_addr(&mut self, addr: Ipv6Addr) {
887 let old = self.src_addr();
888 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
889 packet.update_pseudo_header_src_addr(old, addr);
890 }
891
892 self.set_src_ip(addr);
893 }
894
895 fn dst_addr(&self) -> Ipv6Addr {
896 self.dst_ip()
897 }
898
899 fn set_dst_addr(&mut self, addr: Ipv6Addr) {
900 let old = self.dst_addr();
901 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
902 packet.update_pseudo_header_dst_addr(old, addr);
903 }
904
905 self.set_dst_ip(addr);
906 }
907
908 fn protocol(&self) -> Option<Ipv6Proto> {
909 Some(self.proto())
910 }
911
912 fn maybe_transport_packet(&self) -> Self::TransportPacket<'_> {
913 self
914 }
915
916 fn transport_packet_mut(&mut self) -> Self::TransportPacketMut<'_> {
917 ParsedTransportHeaderMut::parse_in_ipv6_packet(
918 self.proto(),
919 SliceBufViewMut::new(self.body_mut()),
920 )
921 }
922
923 fn maybe_icmp_error<'a>(&'a self) -> Self::IcmpError<'a> {
924 self
925 }
926
927 fn icmp_error_mut<'a>(&'a mut self) -> Self::IcmpErrorMut<'a> {
928 ParsedIcmpErrorMut::parse_in_ipv6_packet(
929 self.src_addr(),
930 self.dst_addr(),
931 self.proto(),
932 SliceBufViewMut::new(self.body_mut()),
933 )
934 }
935}
936
937impl<B: SplitByteSlice> MaybeTransportPacket for Ipv6Packet<B> {
938 fn transport_packet_data(&self) -> Option<TransportPacketData> {
939 parse_transport_header_in_ipv6_packet(
940 self.src_ip(),
941 self.dst_ip(),
942 self.proto(),
943 self.body(),
944 )
945 }
946}
947
948impl<B: SplitByteSlice> MaybeIcmpErrorPayload<Ipv6> for Ipv6Packet<B> {
949 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<Ipv6>> {
950 ParsedIcmpErrorPayload::parse_in_outer_ipv6_packet(self.proto(), Buf::new(self.body(), ..))
951 }
952}
953
954impl<B: SplitByteSliceMut> IpPacket<Ipv6> for Ipv6PacketRaw<B> {
955 type TransportPacket<'a>
956 = &'a Self
957 where
958 Self: 'a;
959 type TransportPacketMut<'a>
960 = Option<ParsedTransportHeaderMut<'a, Ipv6>>
961 where
962 B: 'a;
963 type IcmpError<'a>
964 = &'a Self
965 where
966 Self: 'a;
967 type IcmpErrorMut<'a>
968 = Option<ParsedIcmpErrorMut<'a, Ipv6>>
969 where
970 B: 'a;
971
972 fn src_addr(&self) -> Ipv6Addr {
973 self.src_ip()
974 }
975
976 fn set_src_addr(&mut self, addr: Ipv6Addr) {
977 let old = self.src_ip();
978 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
979 packet.update_pseudo_header_src_addr(old, addr);
980 }
981
982 self.set_src_ip(addr);
983 }
984
985 fn dst_addr(&self) -> Ipv6Addr {
986 self.dst_ip()
987 }
988
989 fn set_dst_addr(&mut self, addr: Ipv6Addr) {
990 let old = self.dst_ip();
991 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
992 packet.update_pseudo_header_dst_addr(old, addr);
993 }
994
995 self.set_dst_ip(addr);
996 }
997
998 fn protocol(&self) -> Option<Ipv6Proto> {
999 self.proto().ok()
1000 }
1001
1002 fn maybe_transport_packet<'a>(&'a self) -> Self::TransportPacket<'a> {
1003 self
1004 }
1005
1006 fn transport_packet_mut(&mut self) -> Self::TransportPacketMut<'_> {
1007 let proto = self.proto().ok()?;
1008 let body = self.body_mut()?;
1009 ParsedTransportHeaderMut::parse_in_ipv6_packet(proto, SliceBufViewMut::new(body))
1010 }
1011
1012 fn maybe_icmp_error<'a>(&'a self) -> Self::IcmpError<'a> {
1013 self
1014 }
1015
1016 fn icmp_error_mut<'a>(&'a mut self) -> Self::IcmpErrorMut<'a> {
1017 let src_addr = self.src_addr();
1018 let dst_addr = self.dst_addr();
1019 let proto = self.proto().ok()?;
1020 let body = self.body_mut()?;
1021
1022 ParsedIcmpErrorMut::parse_in_ipv6_packet(
1023 src_addr,
1024 dst_addr,
1025 proto,
1026 SliceBufViewMut::new(body),
1027 )
1028 }
1029}
1030
1031impl<B: SplitByteSlice> MaybeTransportPacket for Ipv6PacketRaw<B> {
1032 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1033 let (body, proto) = self.body_proto().ok()?;
1034 parse_transport_header_in_ipv6_packet(
1035 self.src_ip(),
1036 self.dst_ip(),
1037 proto,
1038 body.into_inner(),
1039 )
1040 }
1041}
1042
1043impl<B: SplitByteSlice> MaybeIcmpErrorPayload<Ipv6> for Ipv6PacketRaw<B> {
1044 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<Ipv6>> {
1045 let (body, proto) = self.body_proto().ok()?;
1046 ParsedIcmpErrorPayload::parse_in_outer_ipv6_packet(proto, Buf::new(body.into_inner(), ..))
1047 }
1048}
1049
1050#[derive(Debug, PartialEq, GenericOverIp)]
1053#[generic_over_ip(I, Ip)]
1054pub struct TxPacket<'a, I: IpExt, S> {
1055 src_addr: I::Addr,
1056 dst_addr: I::Addr,
1057 protocol: I::Proto,
1058 serializer: &'a mut S,
1059}
1060
1061impl<'a, I: IpExt, S> TxPacket<'a, I, S> {
1062 pub fn new(
1064 src_addr: I::Addr,
1065 dst_addr: I::Addr,
1066 protocol: I::Proto,
1067 serializer: &'a mut S,
1068 ) -> Self {
1069 Self { src_addr, dst_addr, protocol, serializer }
1070 }
1071
1072 pub fn src_addr(&self) -> I::Addr {
1074 self.src_addr
1075 }
1076
1077 pub fn dst_addr(&self) -> I::Addr {
1079 self.dst_addr
1080 }
1081}
1082
1083impl<I: FilterIpExt, S: TransportPacketSerializer<I>> IpPacket<I> for TxPacket<'_, I, S> {
1084 type TransportPacket<'a>
1085 = &'a S
1086 where
1087 Self: 'a;
1088 type TransportPacketMut<'a>
1089 = &'a mut S
1090 where
1091 Self: 'a;
1092 type IcmpError<'a>
1093 = &'a S
1094 where
1095 Self: 'a;
1096 type IcmpErrorMut<'a>
1097 = &'a mut S
1098 where
1099 Self: 'a;
1100
1101 fn src_addr(&self) -> I::Addr {
1102 self.src_addr
1103 }
1104
1105 fn set_src_addr(&mut self, addr: I::Addr) {
1106 let old = core::mem::replace(&mut self.src_addr, addr);
1107 if let Some(mut packet) = self.transport_packet_mut().transport_packet_mut() {
1108 packet.update_pseudo_header_src_addr(old, addr);
1109 }
1110 }
1111
1112 fn dst_addr(&self) -> I::Addr {
1113 self.dst_addr
1114 }
1115
1116 fn set_dst_addr(&mut self, addr: I::Addr) {
1117 let old = core::mem::replace(&mut self.dst_addr, addr);
1118 if let Some(mut packet) = self.transport_packet_mut().transport_packet_mut() {
1119 packet.update_pseudo_header_dst_addr(old, addr);
1120 }
1121 }
1122
1123 fn protocol(&self) -> Option<I::Proto> {
1124 Some(self.protocol)
1125 }
1126
1127 fn maybe_transport_packet(&self) -> Self::TransportPacket<'_> {
1128 self.serializer
1129 }
1130
1131 fn transport_packet_mut(&mut self) -> Self::TransportPacketMut<'_> {
1132 self.serializer
1133 }
1134
1135 fn maybe_icmp_error<'a>(&'a self) -> Self::IcmpError<'a> {
1136 self.serializer
1137 }
1138
1139 fn icmp_error_mut<'a>(&'a mut self) -> Self::IcmpErrorMut<'a> {
1140 self.serializer
1141 }
1142}
1143
1144pub struct PartialSerializeRef<'a, S> {
1149 reference: &'a S,
1150}
1151
1152impl<'a, S: PartialSerializer> PartialSerializer for PartialSerializeRef<'a, S> {
1153 fn partial_serialize(
1154 &self,
1155 outer: PacketConstraints,
1156 buffer: &mut [u8],
1157 ) -> Result<PartialSerializeResult, SerializeError<Never>> {
1158 self.reference.partial_serialize(outer, buffer)
1159 }
1160}
1161
1162const TX_PACKET_NO_TTL: u8 = 0;
1164
1165impl<I: FilterIpExt, S: TransportPacketSerializer<I> + PartialSerializer> PartialSerializer
1171 for TxPacket<'_, I, S>
1172{
1173 fn partial_serialize(
1174 &self,
1175 outer: PacketConstraints,
1176 buffer: &mut [u8],
1177 ) -> Result<PartialSerializeResult, SerializeError<Never>> {
1178 let packet_builder =
1179 I::PacketBuilder::new(self.src_addr, self.dst_addr, TX_PACKET_NO_TTL, self.protocol);
1180 packet_builder
1181 .wrap_body(PartialSerializeRef { reference: self.serializer })
1182 .partial_serialize(outer, buffer)
1183 }
1184}
1185
1186#[derive(Debug, PartialEq, GenericOverIp)]
1188#[generic_over_ip(I, Ip)]
1189pub struct ForwardedPacket<I: IpExt, B> {
1190 src_addr: I::Addr,
1191 dst_addr: I::Addr,
1192 protocol: I::Proto,
1193 transport_header_offset: usize,
1194 buffer: B,
1195}
1196
1197impl<I: IpExt, B: BufferMut> ForwardedPacket<I, B> {
1198 pub fn new(
1205 src_addr: I::Addr,
1206 dst_addr: I::Addr,
1207 protocol: I::Proto,
1208 meta: ParseMetadata,
1209 mut buffer: B,
1210 ) -> Self {
1211 let transport_header_offset = meta.header_len();
1212 buffer.undo_parse(meta);
1213 Self { src_addr, dst_addr, protocol, transport_header_offset, buffer }
1214 }
1215
1216 pub fn into_buffer(self) -> B {
1222 self.buffer
1223 }
1224
1225 pub fn buffer(&self) -> &B {
1230 &self.buffer
1231 }
1232}
1233
1234impl<I: IpExt, B: BufferMut> Serializer for ForwardedPacket<I, B> {
1235 type Buffer = <B as Serializer>::Buffer;
1236
1237 fn serialize<G: packet::GrowBufferMut, P: packet::BufferProvider<Self::Buffer, G>>(
1238 self,
1239 outer: packet::PacketConstraints,
1240 provider: P,
1241 ) -> Result<G, (packet::SerializeError<P::Error>, Self)> {
1242 let Self { src_addr, dst_addr, protocol, transport_header_offset, buffer } = self;
1243 buffer.serialize(outer, provider).map_err(|(err, buffer)| {
1244 (err, Self { src_addr, dst_addr, protocol, transport_header_offset, buffer })
1245 })
1246 }
1247
1248 fn serialize_new_buf<BB: GrowBufferMut, A: LayoutBufferAlloc<BB>>(
1249 &self,
1250 outer: packet::PacketConstraints,
1251 alloc: A,
1252 ) -> Result<BB, packet::SerializeError<A::Error>> {
1253 self.buffer.serialize_new_buf(outer, alloc)
1254 }
1255}
1256
1257impl<I: FilterIpExt, B: BufferMut> IpPacket<I> for ForwardedPacket<I, B> {
1258 type TransportPacket<'a>
1259 = &'a Self
1260 where
1261 Self: 'a;
1262 type TransportPacketMut<'a>
1263 = Option<ParsedTransportHeaderMut<'a, I>>
1264 where
1265 Self: 'a;
1266 type IcmpError<'a>
1267 = &'a Self
1268 where
1269 Self: 'a;
1270
1271 type IcmpErrorMut<'a>
1272 = Option<ParsedIcmpErrorMut<'a, I>>
1273 where
1274 Self: 'a;
1275
1276 fn src_addr(&self) -> I::Addr {
1277 self.src_addr
1278 }
1279
1280 fn set_src_addr(&mut self, addr: I::Addr) {
1281 I::map_ip::<_, ()>(
1283 (IpInvariant(self.buffer.as_mut()), addr),
1284 |(IpInvariant(buffer), addr)| {
1285 let mut packet = Ipv4PacketRaw::parse_mut(SliceBufViewMut::new(buffer), ())
1286 .expect("ForwardedPacket must have been created from a valid IP packet");
1287 packet.set_src_ip_and_update_checksum(addr);
1288 },
1289 |(IpInvariant(buffer), addr)| {
1290 let mut packet = Ipv6PacketRaw::parse_mut(SliceBufViewMut::new(buffer), ())
1291 .expect("ForwardedPacket must have been created from a valid IP packet");
1292 packet.set_src_ip(addr);
1293 },
1294 );
1295
1296 let old = self.src_addr;
1297 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
1298 packet.update_pseudo_header_src_addr(old, addr);
1299 }
1300
1301 self.src_addr = addr;
1302 }
1303
1304 fn dst_addr(&self) -> I::Addr {
1305 self.dst_addr
1306 }
1307
1308 fn set_dst_addr(&mut self, addr: I::Addr) {
1309 I::map_ip::<_, ()>(
1311 (IpInvariant(self.buffer.as_mut()), addr),
1312 |(IpInvariant(buffer), addr)| {
1313 let mut packet = Ipv4PacketRaw::parse_mut(SliceBufViewMut::new(buffer), ())
1314 .expect("ForwardedPacket must have been created from a valid IP packet");
1315 packet.set_dst_ip_and_update_checksum(addr);
1316 },
1317 |(IpInvariant(buffer), addr)| {
1318 let mut packet = Ipv6PacketRaw::parse_mut(SliceBufViewMut::new(buffer), ())
1319 .expect("ForwardedPacket must have been created from a valid IP packet");
1320 packet.set_dst_ip(addr);
1321 },
1322 );
1323
1324 let old = self.dst_addr;
1325 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
1326 packet.update_pseudo_header_dst_addr(old, addr);
1327 }
1328
1329 self.dst_addr = addr;
1330 }
1331
1332 fn protocol(&self) -> Option<I::Proto> {
1333 Some(self.protocol)
1334 }
1335
1336 fn maybe_transport_packet(&self) -> Self::TransportPacket<'_> {
1337 self
1338 }
1339
1340 fn transport_packet_mut(&mut self) -> Self::TransportPacketMut<'_> {
1341 let ForwardedPacket { src_addr: _, dst_addr: _, protocol, buffer, transport_header_offset } =
1342 self;
1343 ParsedTransportHeaderMut::<I>::parse_in_ip_packet(
1344 *protocol,
1345 SliceBufViewMut::new(&mut buffer.as_mut()[*transport_header_offset..]),
1346 )
1347 }
1348
1349 fn maybe_icmp_error<'a>(&'a self) -> Self::IcmpError<'a> {
1350 self
1351 }
1352
1353 fn icmp_error_mut<'a>(&'a mut self) -> Self::IcmpErrorMut<'a> {
1354 let ForwardedPacket { src_addr, dst_addr, protocol, buffer, transport_header_offset } =
1355 self;
1356
1357 ParsedIcmpErrorMut::<I>::parse_in_ip_packet(
1358 *src_addr,
1359 *dst_addr,
1360 *protocol,
1361 SliceBufViewMut::new(&mut buffer.as_mut()[*transport_header_offset..]),
1362 )
1363 }
1364}
1365
1366impl<I: IpExt, B: BufferMut> MaybeTransportPacket for ForwardedPacket<I, B> {
1367 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1368 let ForwardedPacket { protocol, buffer, src_addr, dst_addr, transport_header_offset } =
1369 self;
1370 TransportPacketData::parse_in_ip_packet::<I, _>(
1371 *src_addr,
1372 *dst_addr,
1373 *protocol,
1374 Buf::new(&buffer.as_ref()[*transport_header_offset..], ..),
1375 )
1376 }
1377}
1378
1379impl<I: IpExt, B: BufferMut> MaybeIcmpErrorPayload<I> for ForwardedPacket<I, B> {
1380 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
1381 let Self { src_addr: _, dst_addr: _, protocol, transport_header_offset, buffer } = self;
1382 ParsedIcmpErrorPayload::parse_in_outer_ip_packet(
1383 *protocol,
1384 Buf::new(&buffer.as_ref()[*transport_header_offset..], ..),
1385 )
1386 }
1387}
1388
1389impl<I: FilterIpExt, S: TransportPacketSerializer<I>, B: IpPacketBuilder<I>> IpPacket<I>
1390 for Nested<S, B>
1391{
1392 type TransportPacket<'a>
1393 = &'a S
1394 where
1395 Self: 'a;
1396 type TransportPacketMut<'a>
1397 = &'a mut S
1398 where
1399 Self: 'a;
1400 type IcmpError<'a>
1401 = &'a S
1402 where
1403 Self: 'a;
1404 type IcmpErrorMut<'a>
1405 = &'a mut S
1406 where
1407 Self: 'a;
1408
1409 fn src_addr(&self) -> I::Addr {
1410 self.outer().src_ip()
1411 }
1412
1413 fn set_src_addr(&mut self, addr: I::Addr) {
1414 let old = self.outer().src_ip();
1415 self.outer_mut().set_src_ip(addr);
1416 if let Some(mut packet) = self.transport_packet_mut().transport_packet_mut() {
1417 packet.update_pseudo_header_src_addr(old, addr);
1418 }
1419 }
1420
1421 fn dst_addr(&self) -> I::Addr {
1422 self.outer().dst_ip()
1423 }
1424
1425 fn set_dst_addr(&mut self, addr: I::Addr) {
1426 let old = self.outer().dst_ip();
1427 self.outer_mut().set_dst_ip(addr);
1428 if let Some(mut packet) = self.transport_packet_mut().transport_packet_mut() {
1429 packet.update_pseudo_header_dst_addr(old, addr);
1430 }
1431 }
1432
1433 fn protocol(&self) -> Option<I::Proto> {
1434 Some(self.outer().proto())
1435 }
1436
1437 fn maybe_transport_packet(&self) -> Self::TransportPacket<'_> {
1438 self.inner()
1439 }
1440
1441 fn transport_packet_mut(&mut self) -> Self::TransportPacketMut<'_> {
1442 self.inner_mut()
1443 }
1444
1445 fn maybe_icmp_error<'a>(&'a self) -> Self::IcmpError<'a> {
1446 self.inner()
1447 }
1448
1449 fn icmp_error_mut<'a>(&'a mut self) -> Self::IcmpErrorMut<'a> {
1450 self.inner_mut()
1451 }
1452}
1453
1454impl<I: IpExt, T: ?Sized> TransportPacketMut<I> for &mut T
1455where
1456 T: TransportPacketMut<I>,
1457{
1458 fn set_src_port(&mut self, port: NonZeroU16) {
1459 (*self).set_src_port(port);
1460 }
1461
1462 fn set_dst_port(&mut self, port: NonZeroU16) {
1463 (*self).set_dst_port(port);
1464 }
1465
1466 fn update_pseudo_header_src_addr(&mut self, old: I::Addr, new: I::Addr) {
1467 (*self).update_pseudo_header_src_addr(old, new);
1468 }
1469
1470 fn update_pseudo_header_dst_addr(&mut self, old: I::Addr, new: I::Addr) {
1471 (*self).update_pseudo_header_dst_addr(old, new);
1472 }
1473}
1474
1475impl<I: FilterIpExt> IpPacket<I> for Never {
1476 type TransportPacket<'a>
1477 = Never
1478 where
1479 Self: 'a;
1480 type TransportPacketMut<'a>
1481 = Never
1482 where
1483 Self: 'a;
1484 type IcmpError<'a>
1485 = Never
1486 where
1487 Self: 'a;
1488 type IcmpErrorMut<'a>
1489 = Never
1490 where
1491 Self: 'a;
1492
1493 fn src_addr(&self) -> I::Addr {
1494 match *self {}
1495 }
1496
1497 fn set_src_addr(&mut self, _addr: I::Addr) {
1498 match *self {}
1499 }
1500
1501 fn dst_addr(&self) -> I::Addr {
1502 match *self {}
1503 }
1504
1505 fn protocol(&self) -> Option<I::Proto> {
1506 match *self {}
1507 }
1508
1509 fn set_dst_addr(&mut self, _addr: I::Addr) {
1510 match *self {}
1511 }
1512
1513 fn maybe_transport_packet<'a>(&'a self) -> Self::TransportPacket<'a> {
1514 match *self {}
1515 }
1516
1517 fn transport_packet_mut<'a>(&'a mut self) -> Self::TransportPacketMut<'a> {
1518 match *self {}
1519 }
1520
1521 fn maybe_icmp_error<'a>(&'a self) -> Self::IcmpError<'a> {
1522 match *self {}
1523 }
1524
1525 fn icmp_error_mut<'a>(&'a mut self) -> Self::IcmpErrorMut<'a> {
1526 match *self {}
1527 }
1528}
1529
1530impl MaybeTransportPacket for Never {
1531 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1532 match *self {}
1533 }
1534}
1535
1536impl<I: IpExt> MaybeTransportPacketMut<I> for Never {
1537 type TransportPacketMut<'a>
1538 = Never
1539 where
1540 Self: 'a;
1541
1542 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1543 match *self {}
1544 }
1545}
1546
1547impl<I: IpExt> TransportPacketMut<I> for Never {
1548 fn set_src_port(&mut self, _: NonZeroU16) {
1549 match *self {}
1550 }
1551
1552 fn set_dst_port(&mut self, _: NonZeroU16) {
1553 match *self {}
1554 }
1555
1556 fn update_pseudo_header_src_addr(&mut self, _: I::Addr, _: I::Addr) {
1557 match *self {}
1558 }
1559
1560 fn update_pseudo_header_dst_addr(&mut self, _: I::Addr, _: I::Addr) {
1561 match *self {}
1562 }
1563}
1564
1565impl<I: IpExt> MaybeIcmpErrorPayload<I> for Never {
1566 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
1567 match *self {}
1568 }
1569}
1570
1571impl<I: FilterIpExt> MaybeIcmpErrorMut<I> for Never {
1572 type IcmpErrorMut<'a>
1573 = Never
1574 where
1575 Self: 'a;
1576
1577 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
1578 match *self {}
1579 }
1580}
1581
1582impl<I: FilterIpExt> IcmpErrorMut<I> for Never {
1583 type InnerPacket<'a>
1584 = Never
1585 where
1586 Self: 'a;
1587
1588 fn inner_packet<'a>(&'a mut self) -> Option<Self::InnerPacket<'a>> {
1589 match *self {}
1590 }
1591
1592 fn recalculate_checksum(&mut self) -> bool {
1593 match *self {}
1594 }
1595}
1596
1597impl<A: IpAddress, Inner> MaybeTransportPacket for Nested<Inner, UdpPacketBuilder<A>> {
1598 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1599 Some(TransportPacketData::Generic {
1600 src_port: self.outer().src_port().map_or(0, NonZeroU16::get),
1601 dst_port: self.outer().dst_port().map_or(0, NonZeroU16::get),
1602 })
1603 }
1604}
1605
1606impl<I: IpExt, Inner> MaybeTransportPacketMut<I> for Nested<Inner, UdpPacketBuilder<I::Addr>> {
1607 type TransportPacketMut<'a>
1608 = &'a mut Self
1609 where
1610 Self: 'a;
1611
1612 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1613 Some(self)
1614 }
1615}
1616
1617impl<I: IpExt, Inner> TransportPacketMut<I> for Nested<Inner, UdpPacketBuilder<I::Addr>> {
1618 fn set_src_port(&mut self, port: NonZeroU16) {
1619 self.outer_mut().set_src_port(port.get());
1620 }
1621
1622 fn set_dst_port(&mut self, port: NonZeroU16) {
1623 self.outer_mut().set_dst_port(port);
1624 }
1625
1626 fn update_pseudo_header_src_addr(&mut self, _old: I::Addr, new: I::Addr) {
1627 self.outer_mut().set_src_ip(new);
1628 }
1629
1630 fn update_pseudo_header_dst_addr(&mut self, _old: I::Addr, new: I::Addr) {
1631 self.outer_mut().set_dst_ip(new);
1632 }
1633}
1634
1635impl<A: IpAddress, I: IpExt, Inner> MaybeIcmpErrorPayload<I>
1636 for Nested<Inner, UdpPacketBuilder<A>>
1637{
1638 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
1639 None
1640 }
1641}
1642
1643impl<A: IpAddress, I: FilterIpExt, Inner> MaybeIcmpErrorMut<I>
1644 for Nested<Inner, UdpPacketBuilder<A>>
1645{
1646 type IcmpErrorMut<'a>
1647 = Never
1648 where
1649 Self: 'a;
1650
1651 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
1652 None
1653 }
1654}
1655
1656impl<'a, A: IpAddress, Inner: PayloadLen> MaybeTransportPacket
1657 for Nested<Inner, TcpSegmentBuilderWithOptions<A, TcpOptionsBuilder<'a>>>
1658{
1659 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1660 Some(TransportPacketData::Tcp {
1661 src_port: self.outer().src_port().map_or(0, NonZeroU16::get),
1662 dst_port: self.outer().dst_port().map_or(0, NonZeroU16::get),
1663 segment: self.outer().try_into().ok()?,
1664 payload_len: self.inner().len(),
1665 })
1666 }
1667}
1668
1669impl<I: IpExt, Outer, Inner> MaybeTransportPacketMut<I>
1670 for Nested<Inner, TcpSegmentBuilderWithOptions<I::Addr, Outer>>
1671{
1672 type TransportPacketMut<'a>
1673 = &'a mut Self
1674 where
1675 Self: 'a;
1676
1677 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1678 Some(self)
1679 }
1680}
1681
1682impl<I: IpExt, Outer, Inner> TransportPacketMut<I>
1683 for Nested<Inner, TcpSegmentBuilderWithOptions<I::Addr, Outer>>
1684{
1685 fn set_src_port(&mut self, port: NonZeroU16) {
1686 self.outer_mut().set_src_port(port);
1687 }
1688
1689 fn set_dst_port(&mut self, port: NonZeroU16) {
1690 self.outer_mut().set_dst_port(port);
1691 }
1692
1693 fn update_pseudo_header_src_addr(&mut self, _old: I::Addr, new: I::Addr) {
1694 self.outer_mut().set_src_ip(new);
1695 }
1696
1697 fn update_pseudo_header_dst_addr(&mut self, _old: I::Addr, new: I::Addr) {
1698 self.outer_mut().set_dst_ip(new);
1699 }
1700}
1701
1702impl<A: IpAddress, I: IpExt, Inner, O> MaybeIcmpErrorPayload<I>
1703 for Nested<Inner, TcpSegmentBuilderWithOptions<A, O>>
1704{
1705 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
1706 None
1707 }
1708}
1709
1710impl<A: IpAddress, I: FilterIpExt, Inner, O> MaybeIcmpErrorMut<I>
1711 for Nested<Inner, TcpSegmentBuilderWithOptions<A, O>>
1712{
1713 type IcmpErrorMut<'a>
1714 = Never
1715 where
1716 Self: 'a;
1717
1718 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
1719 None
1720 }
1721}
1722
1723impl<I: IpExt, Inner, M: IcmpMessage<I>> MaybeTransportPacket
1724 for Nested<Inner, IcmpPacketBuilder<I, M>>
1725{
1726 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1727 self.outer().message().transport_packet_data()
1728 }
1729}
1730
1731impl<I: IpExt, Inner, M: IcmpMessage<I>> MaybeTransportPacketMut<I>
1732 for Nested<Inner, IcmpPacketBuilder<I, M>>
1733{
1734 type TransportPacketMut<'a>
1735 = &'a mut IcmpPacketBuilder<I, M>
1736 where
1737 M: 'a,
1738 Inner: 'a;
1739
1740 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1741 Some(self.outer_mut())
1742 }
1743}
1744
1745impl<I: IpExt, Inner, M: IcmpMessage<I>> DynamicMaybeTransportPacketMut<I>
1746 for Nested<Inner, IcmpPacketBuilder<I, M>>
1747{
1748 fn dyn_transport_packet_mut(&mut self) -> Option<&mut dyn TransportPacketMut<I>> {
1749 MaybeTransportPacketMut::transport_packet_mut(self).map(|x| x as _)
1750 }
1751}
1752
1753impl<I: IpExt, M: IcmpMessage<I>> TransportPacketMut<I> for IcmpPacketBuilder<I, M> {
1754 fn set_src_port(&mut self, id: NonZeroU16) {
1755 if M::IS_REWRITABLE {
1756 let _: u16 = self.message_mut().update_icmp_id(id.get());
1757 }
1758 }
1759
1760 fn set_dst_port(&mut self, id: NonZeroU16) {
1761 if M::IS_REWRITABLE {
1762 let _: u16 = self.message_mut().update_icmp_id(id.get());
1763 }
1764 }
1765
1766 fn update_pseudo_header_src_addr(&mut self, _old: I::Addr, new: I::Addr) {
1767 self.set_src_ip(new);
1768 }
1769
1770 fn update_pseudo_header_dst_addr(&mut self, _old: I::Addr, new: I::Addr) {
1771 self.set_dst_ip(new);
1772 }
1773}
1774
1775impl<Inner, I: IpExt> MaybeIcmpErrorPayload<I>
1776 for Nested<Inner, IcmpPacketBuilder<I, IcmpEchoRequest>>
1777{
1778 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
1779 None
1780 }
1781}
1782
1783impl<Inner, I: FilterIpExt> MaybeIcmpErrorMut<I>
1784 for Nested<Inner, IcmpPacketBuilder<I, IcmpEchoRequest>>
1785{
1786 type IcmpErrorMut<'a>
1787 = Never
1788 where
1789 Self: 'a;
1790
1791 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
1792 None
1793 }
1794}
1795
1796impl<Inner, I: FilterIpExt> DynamicMaybeIcmpErrorMut<I>
1797 for Nested<Inner, IcmpPacketBuilder<I, IcmpEchoRequest>>
1798{
1799 fn dyn_icmp_error_mut(&mut self) -> Option<&mut dyn DynamicIcmpErrorMut<I>> {
1800 MaybeIcmpErrorMut::<I>::icmp_error_mut(self).map(|x| match x {})
1801 }
1802}
1803
1804impl<Inner, I: IpExt> MaybeIcmpErrorPayload<I>
1805 for Nested<Inner, IcmpPacketBuilder<I, IcmpEchoReply>>
1806{
1807 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
1808 None
1809 }
1810}
1811
1812impl<Inner, I: FilterIpExt> MaybeIcmpErrorMut<I>
1813 for Nested<Inner, IcmpPacketBuilder<I, IcmpEchoReply>>
1814{
1815 type IcmpErrorMut<'a>
1816 = Never
1817 where
1818 Self: 'a;
1819
1820 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
1821 None
1822 }
1823}
1824
1825impl<Inner, I: FilterIpExt> DynamicMaybeIcmpErrorMut<I>
1826 for Nested<Inner, IcmpPacketBuilder<I, IcmpEchoReply>>
1827{
1828 fn dyn_icmp_error_mut(&mut self) -> Option<&mut dyn DynamicIcmpErrorMut<I>> {
1829 MaybeIcmpErrorMut::<I>::icmp_error_mut(self).map(|x| match x {})
1830 }
1831}
1832
1833pub trait IcmpMessage<I: IpExt>: icmp::IcmpMessage<I> + MaybeTransportPacket {
1835 const IS_REWRITABLE: bool;
1837
1838 fn is_rewritable(&self) -> bool {
1841 Self::IS_REWRITABLE
1842 }
1843
1844 fn update_icmp_id(&mut self, id: u16) -> u16;
1848}
1849
1850impl MaybeTransportPacket for IcmpEchoReply {
1855 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1856 Some(TransportPacketData::Generic { src_port: self.id(), dst_port: self.id() })
1857 }
1858}
1859
1860impl<I: IpExt> IcmpMessage<I> for IcmpEchoReply {
1861 const IS_REWRITABLE: bool = true;
1862
1863 fn update_icmp_id(&mut self, id: u16) -> u16 {
1864 let old = self.id();
1865 self.set_id(id);
1866 old
1867 }
1868}
1869
1870impl MaybeTransportPacket for IcmpEchoRequest {
1875 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1876 Some(TransportPacketData::Generic { src_port: self.id(), dst_port: self.id() })
1877 }
1878}
1879
1880impl<I: IpExt> IcmpMessage<I> for IcmpEchoRequest {
1881 const IS_REWRITABLE: bool = true;
1882
1883 fn update_icmp_id(&mut self, id: u16) -> u16 {
1884 let old = self.id();
1885 self.set_id(id);
1886 old
1887 }
1888}
1889
1890macro_rules! unsupported_icmp_message_type {
1891 ($message:ty, $($ips:ty),+) => {
1892 impl MaybeTransportPacket for $message {
1893 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1894 None
1895 }
1896 }
1897
1898 $(
1899 impl IcmpMessage<$ips> for $message {
1900 const IS_REWRITABLE: bool = false;
1901
1902 fn update_icmp_id(&mut self, _: u16) -> u16 {
1903 unreachable!("non-echo ICMP packets should never be rewritten")
1904 }
1905 }
1906 )+
1907 };
1908}
1909
1910unsupported_icmp_message_type!(Icmpv4TimestampRequest, Ipv4);
1911unsupported_icmp_message_type!(Icmpv4TimestampReply, Ipv4);
1912unsupported_icmp_message_type!(NeighborSolicitation, Ipv6);
1913unsupported_icmp_message_type!(NeighborAdvertisement, Ipv6);
1914unsupported_icmp_message_type!(RouterSolicitation, Ipv6);
1915unsupported_icmp_message_type!(MulticastListenerDone, Ipv6);
1916unsupported_icmp_message_type!(MulticastListenerReport, Ipv6);
1917unsupported_icmp_message_type!(MulticastListenerReportV2, Ipv6);
1918unsupported_icmp_message_type!(MulticastListenerQuery, Ipv6);
1919unsupported_icmp_message_type!(MulticastListenerQueryV2, Ipv6);
1920unsupported_icmp_message_type!(RouterAdvertisement, Ipv6);
1921unsupported_icmp_message_type!(Redirect, Ipv6);
1924
1925macro_rules! non_error_icmp_message_type {
1927 ($message:ty, $ip:ty) => {
1928 impl<Inner> MaybeIcmpErrorPayload<$ip> for Nested<Inner, IcmpPacketBuilder<$ip, $message>> {
1929 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<$ip>> {
1930 None
1931 }
1932 }
1933
1934 impl<Inner> MaybeIcmpErrorMut<$ip> for Nested<Inner, IcmpPacketBuilder<$ip, $message>> {
1935 type IcmpErrorMut<'a>
1936 = Never
1937 where
1938 Self: 'a;
1939
1940 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
1941 None
1942 }
1943 }
1944
1945 impl<Inner> DynamicMaybeIcmpErrorMut<$ip>
1946 for Nested<Inner, IcmpPacketBuilder<$ip, $message>>
1947 {
1948 fn dyn_icmp_error_mut(&mut self) -> Option<&mut dyn DynamicIcmpErrorMut<$ip>> {
1949 MaybeIcmpErrorMut::icmp_error_mut(self).map(|x| match x {})
1950 }
1951 }
1952 };
1953}
1954
1955non_error_icmp_message_type!(Icmpv4TimestampRequest, Ipv4);
1956non_error_icmp_message_type!(Icmpv4TimestampReply, Ipv4);
1957non_error_icmp_message_type!(RouterSolicitation, Ipv6);
1958non_error_icmp_message_type!(RouterAdvertisement, Ipv6);
1959non_error_icmp_message_type!(NeighborSolicitation, Ipv6);
1960non_error_icmp_message_type!(NeighborAdvertisement, Ipv6);
1961non_error_icmp_message_type!(MulticastListenerReport, Ipv6);
1962non_error_icmp_message_type!(MulticastListenerDone, Ipv6);
1963non_error_icmp_message_type!(MulticastListenerReportV2, Ipv6);
1964
1965macro_rules! icmp_error_message {
1966 ($message:ty, $($ips:ty),+) => {
1967 impl MaybeTransportPacket for $message {
1968 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1969 None
1970 }
1971 }
1972
1973 $(
1974 impl IcmpMessage<$ips> for $message {
1975 const IS_REWRITABLE: bool = false;
1976
1977 fn update_icmp_id(&mut self, _: u16) -> u16 {
1978 unreachable!("non-echo ICMP packets should never be rewritten")
1979 }
1980 }
1981 )+
1982 };
1983}
1984
1985icmp_error_message!(IcmpDestUnreachable, Ipv4, Ipv6);
1986icmp_error_message!(IcmpTimeExceeded, Ipv4, Ipv6);
1987icmp_error_message!(Icmpv4ParameterProblem, Ipv4);
1988icmp_error_message!(Icmpv4Redirect, Ipv4);
1989icmp_error_message!(Icmpv6ParameterProblem, Ipv6);
1990icmp_error_message!(Icmpv6PacketTooBig, Ipv6);
1991
1992macro_rules! icmpv4_error_message {
1993 ($message: ty) => {
1994 impl<Inner: AsRef<[u8]>> MaybeIcmpErrorPayload<Ipv4>
1995 for Nested<Inner, IcmpPacketBuilder<Ipv4, $message>>
1996 {
1997 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<Ipv4>> {
1998 ParsedIcmpErrorPayload::parse_in_icmpv4_error(Buf::new(self.inner(), ..))
1999 }
2000 }
2001
2002 impl<Inner: BufferMut> MaybeIcmpErrorMut<Ipv4>
2003 for Nested<Inner, IcmpPacketBuilder<Ipv4, $message>>
2004 {
2005 type IcmpErrorMut<'a>
2006 = &'a mut Self
2007 where
2008 Self: 'a;
2009
2010 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
2011 Some(self)
2012 }
2013 }
2014
2015 impl<Inner: BufferMut> DynamicMaybeIcmpErrorMut<Ipv4>
2016 for Nested<Inner, IcmpPacketBuilder<Ipv4, $message>>
2017 {
2018 fn dyn_icmp_error_mut(&mut self) -> Option<&mut dyn DynamicIcmpErrorMut<Ipv4>> {
2019 MaybeIcmpErrorMut::icmp_error_mut(self).map(|x| x as _)
2020 }
2021 }
2022
2023 impl<Inner: BufferMut> IcmpErrorMut<Ipv4>
2024 for Nested<Inner, IcmpPacketBuilder<Ipv4, $message>>
2025 {
2026 type InnerPacket<'a>
2027 = Ipv4PacketRaw<&'a mut [u8]>
2028 where
2029 Self: 'a;
2030
2031 fn recalculate_checksum(&mut self) -> bool {
2032 true
2034 }
2035
2036 fn inner_packet<'a>(&'a mut self) -> Option<Self::InnerPacket<'a>> {
2037 let packet =
2038 Ipv4PacketRaw::parse_mut(SliceBufViewMut::new(self.inner_mut().as_mut()), ())
2039 .ok()?;
2040
2041 Some(packet)
2042 }
2043 }
2044
2045 impl<Inner: BufferMut> DynamicIcmpErrorMut<Ipv4>
2046 for Nested<Inner, IcmpPacketBuilder<Ipv4, $message>>
2047 {
2048 fn dyn_recalculate_checksum(&mut self) -> bool {
2049 self.recalculate_checksum()
2050 }
2051
2052 fn dyn_inner_packet(&mut self) -> Option<Ipv4PacketRaw<&mut [u8]>> {
2053 self.inner_packet()
2054 }
2055 }
2056 };
2057}
2058
2059icmpv4_error_message!(IcmpDestUnreachable);
2060icmpv4_error_message!(Icmpv4Redirect);
2061icmpv4_error_message!(IcmpTimeExceeded);
2062icmpv4_error_message!(Icmpv4ParameterProblem);
2063
2064macro_rules! icmpv6_error_message {
2065 ($message: ty) => {
2066 impl<Inner: Buffer> MaybeIcmpErrorPayload<Ipv6>
2067 for Nested<TruncatingSerializer<Inner>, IcmpPacketBuilder<Ipv6, $message>>
2068 {
2069 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<Ipv6>> {
2070 ParsedIcmpErrorPayload::parse_in_icmpv6_error(Buf::new(self.inner().buffer(), ..))
2071 }
2072 }
2073
2074 impl<Inner: BufferMut> MaybeIcmpErrorMut<Ipv6>
2075 for Nested<TruncatingSerializer<Inner>, IcmpPacketBuilder<Ipv6, $message>>
2076 {
2077 type IcmpErrorMut<'a>
2078 = &'a mut Self
2079 where
2080 Self: 'a;
2081
2082 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
2083 Some(self)
2084 }
2085 }
2086
2087 impl<Inner: BufferMut> DynamicMaybeIcmpErrorMut<Ipv6>
2088 for Nested<TruncatingSerializer<Inner>, IcmpPacketBuilder<Ipv6, $message>>
2089 {
2090 fn dyn_icmp_error_mut(&mut self) -> Option<&mut dyn DynamicIcmpErrorMut<Ipv6>> {
2091 MaybeIcmpErrorMut::icmp_error_mut(self).map(|x| x as _)
2092 }
2093 }
2094
2095 impl<Inner: BufferMut> IcmpErrorMut<Ipv6>
2096 for Nested<TruncatingSerializer<Inner>, IcmpPacketBuilder<Ipv6, $message>>
2097 {
2098 type InnerPacket<'a>
2099 = Ipv6PacketRaw<&'a mut [u8]>
2100 where
2101 Self: 'a;
2102
2103 fn recalculate_checksum(&mut self) -> bool {
2104 true
2106 }
2107
2108 fn inner_packet<'a>(&'a mut self) -> Option<Self::InnerPacket<'a>> {
2109 let packet = Ipv6PacketRaw::parse_mut(
2110 SliceBufViewMut::new(self.inner_mut().buffer_mut().as_mut()),
2111 (),
2112 )
2113 .ok()?;
2114
2115 Some(packet)
2116 }
2117 }
2118
2119 impl<Inner: BufferMut> DynamicIcmpErrorMut<Ipv6>
2120 for Nested<TruncatingSerializer<Inner>, IcmpPacketBuilder<Ipv6, $message>>
2121 {
2122 fn dyn_recalculate_checksum(&mut self) -> bool {
2123 self.recalculate_checksum()
2124 }
2125
2126 fn dyn_inner_packet(&mut self) -> Option<Ipv6PacketRaw<&mut [u8]>> {
2127 self.inner_packet()
2128 }
2129 }
2130 };
2131}
2132
2133icmpv6_error_message!(IcmpDestUnreachable);
2134icmpv6_error_message!(Icmpv6PacketTooBig);
2135icmpv6_error_message!(IcmpTimeExceeded);
2136icmpv6_error_message!(Icmpv6ParameterProblem);
2137
2138impl<M: igmp::MessageType<EmptyBuf>> MaybeIcmpErrorMut<Ipv4>
2139 for InnerSerializer<IgmpPacketBuilder<EmptyBuf, M>, EmptyBuf>
2140{
2141 type IcmpErrorMut<'a>
2142 = Never
2143 where
2144 Self: 'a;
2145
2146 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
2147 None
2148 }
2149}
2150
2151impl<M: igmp::MessageType<EmptyBuf>> DynamicMaybeIcmpErrorMut<Ipv4>
2152 for InnerSerializer<IgmpPacketBuilder<EmptyBuf, M>, EmptyBuf>
2153{
2154 fn dyn_icmp_error_mut(&mut self) -> Option<&mut dyn DynamicIcmpErrorMut<Ipv4>> {
2155 self.icmp_error_mut().map(|x| match x {})
2156 }
2157}
2158
2159impl<M: igmp::MessageType<EmptyBuf>> MaybeTransportPacket
2160 for InnerSerializer<IgmpPacketBuilder<EmptyBuf, M>, EmptyBuf>
2161{
2162 fn transport_packet_data(&self) -> Option<TransportPacketData> {
2163 None
2164 }
2165}
2166
2167impl<M: igmp::MessageType<EmptyBuf>> DynamicMaybeTransportPacketMut<Ipv4>
2168 for InnerSerializer<IgmpPacketBuilder<EmptyBuf, M>, EmptyBuf>
2169{
2170 fn dyn_transport_packet_mut(&mut self) -> Option<&mut dyn TransportPacketMut<Ipv4>> {
2171 self.transport_packet_mut().map(|x| match x {})
2172 }
2173}
2174
2175impl<M: igmp::MessageType<EmptyBuf>> MaybeTransportPacketMut<Ipv4>
2176 for InnerSerializer<IgmpPacketBuilder<EmptyBuf, M>, EmptyBuf>
2177{
2178 type TransportPacketMut<'a>
2179 = Never
2180 where
2181 M: 'a;
2182
2183 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
2184 None
2185 }
2186}
2187
2188impl<I: IpExt, M: igmp::MessageType<EmptyBuf>> MaybeIcmpErrorPayload<I>
2189 for InnerSerializer<IgmpPacketBuilder<EmptyBuf, M>, EmptyBuf>
2190{
2191 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
2192 None
2193 }
2194}
2195
2196impl<I> MaybeTransportPacket for InnerSerializer<IgmpMembershipReportV3Builder<I>, EmptyBuf> {
2197 fn transport_packet_data(&self) -> Option<TransportPacketData> {
2198 None
2199 }
2200}
2201
2202impl<I> MaybeTransportPacketMut<Ipv4>
2203 for InnerSerializer<IgmpMembershipReportV3Builder<I>, EmptyBuf>
2204{
2205 type TransportPacketMut<'a>
2206 = Never
2207 where
2208 I: 'a;
2209
2210 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
2211 None
2212 }
2213}
2214
2215impl<I> DynamicMaybeTransportPacketMut<Ipv4>
2216 for InnerSerializer<IgmpMembershipReportV3Builder<I>, EmptyBuf>
2217{
2218 fn dyn_transport_packet_mut(&mut self) -> Option<&mut dyn TransportPacketMut<Ipv4>> {
2219 self.transport_packet_mut().map(|x| match x {})
2220 }
2221}
2222
2223impl<I: IpExt, II, B> MaybeIcmpErrorPayload<I>
2224 for InnerSerializer<IgmpMembershipReportV3Builder<II>, B>
2225{
2226 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
2227 None
2228 }
2229}
2230
2231impl<I, B> MaybeIcmpErrorMut<Ipv4> for InnerSerializer<IgmpMembershipReportV3Builder<I>, B> {
2232 type IcmpErrorMut<'a>
2233 = Never
2234 where
2235 Self: 'a;
2236
2237 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
2238 None
2239 }
2240}
2241
2242impl<I, B> DynamicMaybeIcmpErrorMut<Ipv4> for InnerSerializer<IgmpMembershipReportV3Builder<I>, B> {
2243 fn dyn_icmp_error_mut(&mut self) -> Option<&mut dyn DynamicIcmpErrorMut<Ipv4>> {
2244 self.icmp_error_mut().map(|x| match x {})
2245 }
2246}
2247
2248impl<I> MaybeTransportPacket
2249 for EitherSerializer<
2250 EmptyBuf,
2251 InnerSerializer<packet::records::RecordSequenceBuilder<NdpOptionBuilder<'_>, I>, EmptyBuf>,
2252 >
2253{
2254 fn transport_packet_data(&self) -> Option<TransportPacketData> {
2255 None
2256 }
2257}
2258
2259#[derive(GenericOverIp)]
2264#[generic_over_ip(I, Ip)]
2265pub struct RawIpBody<I: IpExt, B: ParseBuffer> {
2266 protocol: I::Proto,
2269 src_addr: I::Addr,
2272 dst_addr: I::Addr,
2275 body: B,
2278 transport_packet_data: Option<TransportPacketData>,
2281}
2282
2283impl<I: IpExt, B: ParseBuffer> RawIpBody<I, B> {
2284 pub fn new(
2286 protocol: I::Proto,
2287 src_addr: I::Addr,
2288 dst_addr: I::Addr,
2289 body: B,
2290 ) -> RawIpBody<I, B> {
2291 let transport_packet_data = TransportPacketData::parse_in_ip_packet::<I, _>(
2292 src_addr,
2293 dst_addr,
2294 protocol,
2295 Buf::new(&body, ..),
2296 );
2297 RawIpBody { protocol, src_addr, dst_addr, body, transport_packet_data }
2298 }
2299}
2300
2301impl<I: IpExt, B: ParseBuffer> MaybeTransportPacket for RawIpBody<I, B> {
2302 fn transport_packet_data(&self) -> Option<TransportPacketData> {
2303 self.transport_packet_data.clone()
2304 }
2305}
2306
2307impl<I: IpExt, B: BufferMut> MaybeTransportPacketMut<I> for RawIpBody<I, B> {
2308 type TransportPacketMut<'a>
2309 = ParsedTransportHeaderMut<'a, I>
2310 where
2311 Self: 'a;
2312
2313 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
2314 let RawIpBody { protocol, src_addr: _, dst_addr: _, body, transport_packet_data: _ } = self;
2315 ParsedTransportHeaderMut::<I>::parse_in_ip_packet(
2316 *protocol,
2317 SliceBufViewMut::new(body.as_mut()),
2318 )
2319 }
2320}
2321
2322impl<I: IpExt, B: ParseBuffer> MaybeIcmpErrorPayload<I> for RawIpBody<I, B> {
2323 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
2324 ParsedIcmpErrorPayload::parse_in_outer_ip_packet(self.protocol, Buf::new(&self.body, ..))
2325 }
2326}
2327
2328impl<I: FilterIpExt, B: BufferMut> MaybeIcmpErrorMut<I> for RawIpBody<I, B> {
2329 type IcmpErrorMut<'a>
2330 = ParsedIcmpErrorMut<'a, I>
2331 where
2332 Self: 'a;
2333
2334 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
2335 let RawIpBody { protocol, src_addr, dst_addr, body, transport_packet_data: _ } = self;
2336
2337 ParsedIcmpErrorMut::parse_in_ip_packet(
2338 *src_addr,
2339 *dst_addr,
2340 *protocol,
2341 SliceBufViewMut::new(body.as_mut()),
2342 )
2343 }
2344}
2345
2346impl<I: IpExt, B: BufferMut> Serializer for RawIpBody<I, B> {
2347 type Buffer = <B as Serializer>::Buffer;
2348
2349 fn serialize<G: GrowBufferMut, P: BufferProvider<Self::Buffer, G>>(
2350 self,
2351 outer: PacketConstraints,
2352 provider: P,
2353 ) -> Result<G, (SerializeError<P::Error>, Self)> {
2354 let Self { protocol, src_addr, dst_addr, body, transport_packet_data } = self;
2355 body.serialize(outer, provider).map_err(|(err, body)| {
2356 (err, Self { protocol, src_addr, dst_addr, body, transport_packet_data })
2357 })
2358 }
2359
2360 fn serialize_new_buf<BB: GrowBufferMut, A: LayoutBufferAlloc<BB>>(
2361 &self,
2362 outer: PacketConstraints,
2363 alloc: A,
2364 ) -> Result<BB, SerializeError<A::Error>> {
2365 self.body.serialize_new_buf(outer, alloc)
2366 }
2367}
2368
2369impl<I: IpExt, B: BufferMut> PartialSerializer for RawIpBody<I, B> {
2370 fn partial_serialize(
2371 &self,
2372 _outer: PacketConstraints,
2373 buffer: &mut [u8],
2374 ) -> Result<PartialSerializeResult, SerializeError<Never>> {
2375 let bytes_to_copy = core::cmp::min(self.body.len(), buffer.len());
2376 buffer[..bytes_to_copy].copy_from_slice(&self.body.as_ref()[..bytes_to_copy]);
2377 Ok(PartialSerializeResult { bytes_written: bytes_to_copy, total_size: self.body.len() })
2378 }
2379}
2380
2381fn parse_transport_header_in_ipv4_packet<B: ParseBuffer>(
2382 src_ip: Ipv4Addr,
2383 dst_ip: Ipv4Addr,
2384 proto: Ipv4Proto,
2385 body: B,
2386) -> Option<TransportPacketData> {
2387 match proto {
2388 Ipv4Proto::Proto(IpProto::Udp) => parse_udp_header::<_, Ipv4>(body),
2389 Ipv4Proto::Proto(IpProto::Tcp) => parse_tcp_header::<_, Ipv4>(body, src_ip, dst_ip),
2390 Ipv4Proto::Icmp => parse_icmpv4_header(body),
2391 Ipv4Proto::Proto(IpProto::Reserved) | Ipv4Proto::Igmp | Ipv4Proto::Other(_) => None,
2392 }
2393}
2394
2395fn parse_transport_header_in_ipv6_packet<B: ParseBuffer>(
2396 src_ip: Ipv6Addr,
2397 dst_ip: Ipv6Addr,
2398 proto: Ipv6Proto,
2399 body: B,
2400) -> Option<TransportPacketData> {
2401 match proto {
2402 Ipv6Proto::Proto(IpProto::Udp) => parse_udp_header::<_, Ipv6>(body),
2403 Ipv6Proto::Proto(IpProto::Tcp) => parse_tcp_header::<_, Ipv6>(body, src_ip, dst_ip),
2404 Ipv6Proto::Icmpv6 => parse_icmpv6_header(body),
2405 Ipv6Proto::Proto(IpProto::Reserved) | Ipv6Proto::NoNextHeader | Ipv6Proto::Other(_) => None,
2406 }
2407}
2408
2409fn parse_udp_header<B: ParseBuffer, I: Ip>(mut body: B) -> Option<TransportPacketData> {
2410 let packet = body.parse_with::<_, UdpPacketRaw<_>>(I::VERSION_MARKER).ok()?;
2411 Some(TransportPacketData::Generic {
2412 src_port: packet.src_port().map(NonZeroU16::get).unwrap_or(0),
2413 dst_port: packet.dst_port()?.get(),
2416 })
2417}
2418
2419fn parse_tcp_header<B: ParseBuffer, I: IpExt>(
2420 mut body: B,
2421 src_ip: I::Addr,
2422 dst_ip: I::Addr,
2423) -> Option<TransportPacketData> {
2424 let packet = body.parse::<TcpSegmentRaw<_>>().ok()?;
2433
2434 let (builder, options, body) = packet.into_builder_options(src_ip, dst_ip)?;
2435 let options = Options::try_from_options(&builder, &options).ok()?;
2436
2437 let segment = SegmentHeader::from_builder_options(&builder, options).ok()?;
2438
2439 Some(TransportPacketData::Tcp {
2440 src_port: builder.src_port().map(NonZeroU16::get).unwrap_or(0),
2441 dst_port: builder.dst_port().map(NonZeroU16::get).unwrap_or(0),
2442 segment,
2443 payload_len: body.len(),
2444 })
2445}
2446
2447fn parse_icmpv4_header<B: ParseBuffer>(mut body: B) -> Option<TransportPacketData> {
2448 match icmp::peek_message_type(body.as_ref()).ok()? {
2449 Icmpv4MessageType::EchoRequest => {
2450 let packet = body.parse::<IcmpPacketRaw<Ipv4, _, IcmpEchoRequest>>().ok()?;
2451 packet.message().transport_packet_data()
2452 }
2453 Icmpv4MessageType::EchoReply => {
2454 let packet = body.parse::<IcmpPacketRaw<Ipv4, _, IcmpEchoReply>>().ok()?;
2455 packet.message().transport_packet_data()
2456 }
2457 Icmpv4MessageType::DestUnreachable
2459 | Icmpv4MessageType::Redirect
2460 | Icmpv4MessageType::TimeExceeded
2461 | Icmpv4MessageType::ParameterProblem => None,
2462 Icmpv4MessageType::TimestampRequest | Icmpv4MessageType::TimestampReply => None,
2466 }
2467}
2468
2469fn parse_icmpv6_header<B: ParseBuffer>(mut body: B) -> Option<TransportPacketData> {
2470 match icmp::peek_message_type(body.as_ref()).ok()? {
2471 Icmpv6MessageType::EchoRequest => {
2472 let packet = body.parse::<IcmpPacketRaw<Ipv6, _, IcmpEchoRequest>>().ok()?;
2473 packet.message().transport_packet_data()
2474 }
2475 Icmpv6MessageType::EchoReply => {
2476 let packet = body.parse::<IcmpPacketRaw<Ipv6, _, IcmpEchoReply>>().ok()?;
2477 packet.message().transport_packet_data()
2478 }
2479 Icmpv6MessageType::DestUnreachable
2481 | Icmpv6MessageType::PacketTooBig
2482 | Icmpv6MessageType::TimeExceeded
2483 | Icmpv6MessageType::ParameterProblem => None,
2484 Icmpv6MessageType::RouterSolicitation
2485 | Icmpv6MessageType::RouterAdvertisement
2486 | Icmpv6MessageType::NeighborSolicitation
2487 | Icmpv6MessageType::NeighborAdvertisement
2488 | Icmpv6MessageType::Redirect
2489 | Icmpv6MessageType::MulticastListenerQuery
2490 | Icmpv6MessageType::MulticastListenerReport
2491 | Icmpv6MessageType::MulticastListenerDone
2492 | Icmpv6MessageType::MulticastListenerReportV2 => None,
2493 }
2494}
2495
2496#[derive(GenericOverIp)]
2499#[generic_over_ip(I, Ip)]
2500pub enum ParsedTransportHeaderMut<'a, I: IpExt> {
2501 Tcp(TcpSegmentRaw<&'a mut [u8]>),
2502 Udp(UdpPacketRaw<&'a mut [u8]>),
2503 Icmp(I::IcmpPacketTypeRaw<&'a mut [u8]>),
2504}
2505
2506impl<'a> ParsedTransportHeaderMut<'a, Ipv4> {
2507 fn parse_in_ipv4_packet<BV: BufferViewMut<&'a mut [u8]>>(
2508 proto: Ipv4Proto,
2509 body: BV,
2510 ) -> Option<Self> {
2511 match proto {
2512 Ipv4Proto::Proto(IpProto::Udp) => {
2513 Some(Self::Udp(UdpPacketRaw::parse_mut(body, IpVersionMarker::<Ipv4>::new()).ok()?))
2514 }
2515 Ipv4Proto::Proto(IpProto::Tcp) => {
2516 Some(Self::Tcp(TcpSegmentRaw::parse_mut(body, ()).ok()?))
2517 }
2518 Ipv4Proto::Icmp => Some(Self::Icmp(Icmpv4PacketRaw::parse_mut(body, ()).ok()?)),
2519 Ipv4Proto::Proto(IpProto::Reserved) | Ipv4Proto::Igmp | Ipv4Proto::Other(_) => None,
2520 }
2521 }
2522}
2523
2524impl<'a> ParsedTransportHeaderMut<'a, Ipv6> {
2525 fn parse_in_ipv6_packet<BV: BufferViewMut<&'a mut [u8]>>(
2526 proto: Ipv6Proto,
2527 body: BV,
2528 ) -> Option<Self> {
2529 match proto {
2530 Ipv6Proto::Proto(IpProto::Udp) => {
2531 Some(Self::Udp(UdpPacketRaw::parse_mut(body, IpVersionMarker::<Ipv6>::new()).ok()?))
2532 }
2533 Ipv6Proto::Proto(IpProto::Tcp) => {
2534 Some(Self::Tcp(TcpSegmentRaw::parse_mut(body, ()).ok()?))
2535 }
2536 Ipv6Proto::Icmpv6 => Some(Self::Icmp(Icmpv6PacketRaw::parse_mut(body, ()).ok()?)),
2537 Ipv6Proto::Proto(IpProto::Reserved) | Ipv6Proto::NoNextHeader | Ipv6Proto::Other(_) => {
2538 None
2539 }
2540 }
2541 }
2542}
2543
2544impl<'a, I: IpExt> ParsedTransportHeaderMut<'a, I> {
2545 fn parse_in_ip_packet<BV: BufferViewMut<&'a mut [u8]>>(
2546 proto: I::Proto,
2547 body: BV,
2548 ) -> Option<Self> {
2549 I::map_ip(
2550 (proto, IpInvariant(body)),
2551 |(proto, IpInvariant(body))| {
2552 ParsedTransportHeaderMut::<'a, Ipv4>::parse_in_ipv4_packet(proto, body)
2553 },
2554 |(proto, IpInvariant(body))| {
2555 ParsedTransportHeaderMut::<'a, Ipv6>::parse_in_ipv6_packet(proto, body)
2556 },
2557 )
2558 }
2559
2560 fn update_pseudo_header_address(&mut self, old: I::Addr, new: I::Addr) {
2561 match self {
2562 Self::Tcp(segment) => segment.update_checksum_pseudo_header_address(old, new),
2563 Self::Udp(packet) => {
2564 packet.update_checksum_pseudo_header_address(old, new);
2565 }
2566 Self::Icmp(packet) => {
2567 packet.update_checksum_pseudo_header_address(old, new);
2568 }
2569 }
2570 }
2571}
2572
2573#[derive(Debug, PartialEq, Eq, GenericOverIp)]
2575#[generic_over_ip(I, Ip)]
2576pub struct ParsedIcmpErrorPayload<I: IpExt> {
2577 src_ip: I::Addr,
2578 dst_ip: I::Addr,
2579 src_port: u16,
2583 dst_port: u16,
2584 proto: I::Proto,
2585}
2586
2587impl ParsedIcmpErrorPayload<Ipv4> {
2588 fn parse_in_outer_ipv4_packet<B>(protocol: Ipv4Proto, mut body: B) -> Option<Self>
2589 where
2590 B: ParseBuffer,
2591 {
2592 match protocol {
2593 Ipv4Proto::Proto(_) | Ipv4Proto::Igmp | Ipv4Proto::Other(_) => None,
2594 Ipv4Proto::Icmp => {
2595 let message = body.parse::<Icmpv4PacketRaw<_>>().ok()?;
2596 let message_body = match &message {
2597 Icmpv4PacketRaw::EchoRequest(_)
2598 | Icmpv4PacketRaw::EchoReply(_)
2599 | Icmpv4PacketRaw::TimestampRequest(_)
2600 | Icmpv4PacketRaw::TimestampReply(_) => return None,
2601
2602 Icmpv4PacketRaw::DestUnreachable(inner) => inner.message_body(),
2603 Icmpv4PacketRaw::Redirect(inner) => inner.message_body(),
2604 Icmpv4PacketRaw::TimeExceeded(inner) => inner.message_body(),
2605 Icmpv4PacketRaw::ParameterProblem(inner) => inner.message_body(),
2606 };
2607
2608 Self::parse_in_icmpv4_error(Buf::new(message_body, ..))
2609 }
2610 }
2611 }
2612
2613 fn parse_in_icmpv4_error<B>(mut body: B) -> Option<Self>
2614 where
2615 B: ParseBuffer,
2616 {
2617 let packet = body.parse::<Ipv4PacketRaw<_>>().ok()?;
2618
2619 let src_ip = packet.get_header_prefix().src_ip();
2620 let dst_ip = packet.get_header_prefix().dst_ip();
2621 let proto = packet.proto();
2622 let transport_data = parse_transport_header_in_ipv4_packet(
2623 src_ip,
2624 dst_ip,
2625 proto,
2626 packet.body().into_inner(),
2627 )?;
2628 Some(Self {
2629 src_ip,
2630 dst_ip,
2631 src_port: transport_data.src_port(),
2632 dst_port: transport_data.dst_port(),
2633 proto,
2634 })
2635 }
2636}
2637
2638impl ParsedIcmpErrorPayload<Ipv6> {
2639 fn parse_in_outer_ipv6_packet<B>(protocol: Ipv6Proto, mut body: B) -> Option<Self>
2640 where
2641 B: ParseBuffer,
2642 {
2643 match protocol {
2644 Ipv6Proto::NoNextHeader | Ipv6Proto::Proto(_) | Ipv6Proto::Other(_) => None,
2645
2646 Ipv6Proto::Icmpv6 => {
2647 let message = body.parse::<Icmpv6PacketRaw<_>>().ok()?;
2648 let message_body = match &message {
2649 Icmpv6PacketRaw::EchoRequest(_)
2650 | Icmpv6PacketRaw::EchoReply(_)
2651 | Icmpv6PacketRaw::Ndp(_)
2652 | Icmpv6PacketRaw::Mld(_) => return None,
2653
2654 Icmpv6PacketRaw::DestUnreachable(inner) => inner.message_body(),
2655 Icmpv6PacketRaw::PacketTooBig(inner) => inner.message_body(),
2656 Icmpv6PacketRaw::TimeExceeded(inner) => inner.message_body(),
2657 Icmpv6PacketRaw::ParameterProblem(inner) => inner.message_body(),
2658 };
2659
2660 Self::parse_in_icmpv6_error(Buf::new(message_body, ..))
2661 }
2662 }
2663 }
2664
2665 fn parse_in_icmpv6_error<B>(mut body: B) -> Option<Self>
2666 where
2667 B: ParseBuffer,
2668 {
2669 let packet = body.parse::<Ipv6PacketRaw<_>>().ok()?;
2670
2671 let src_ip = packet.get_fixed_header().src_ip();
2672 let dst_ip = packet.get_fixed_header().dst_ip();
2673 let proto = packet.proto().ok()?;
2674 let transport_data = parse_transport_header_in_ipv6_packet(
2675 src_ip,
2676 dst_ip,
2677 proto,
2678 packet.body().ok()?.into_inner(),
2679 )?;
2680 Some(Self {
2681 src_ip,
2682 dst_ip,
2683 src_port: transport_data.src_port(),
2684 dst_port: transport_data.dst_port(),
2685 proto,
2686 })
2687 }
2688}
2689
2690impl<I: IpExt> ParsedIcmpErrorPayload<I> {
2691 fn parse_in_outer_ip_packet<B>(proto: I::Proto, body: B) -> Option<Self>
2692 where
2693 B: ParseBuffer,
2694 {
2695 I::map_ip(
2696 (proto, IpInvariant(body)),
2697 |(proto, IpInvariant(body))| {
2698 ParsedIcmpErrorPayload::<Ipv4>::parse_in_outer_ipv4_packet(proto, body)
2699 },
2700 |(proto, IpInvariant(body))| {
2701 ParsedIcmpErrorPayload::<Ipv6>::parse_in_outer_ipv6_packet(proto, body)
2702 },
2703 )
2704 }
2705}
2706
2707#[derive(GenericOverIp)]
2710#[generic_over_ip(I, Ip)]
2711pub struct ParsedIcmpErrorMut<'a, I: IpExt> {
2712 src_ip: I::Addr,
2713 dst_ip: I::Addr,
2714 message: I::IcmpPacketTypeRaw<&'a mut [u8]>,
2715}
2716
2717impl<'a> ParsedIcmpErrorMut<'a, Ipv4> {
2718 fn parse_in_ipv4_packet<BV: BufferViewMut<&'a mut [u8]>>(
2719 src_ip: Ipv4Addr,
2720 dst_ip: Ipv4Addr,
2721 proto: Ipv4Proto,
2722 body: BV,
2723 ) -> Option<Self> {
2724 match proto {
2725 Ipv4Proto::Proto(_) | Ipv4Proto::Igmp | Ipv4Proto::Other(_) => None,
2726 Ipv4Proto::Icmp => {
2727 let message = Icmpv4PacketRaw::parse_mut(body, ()).ok()?;
2728 match message {
2729 Icmpv4PacketRaw::EchoRequest(_)
2730 | Icmpv4PacketRaw::EchoReply(_)
2731 | Icmpv4PacketRaw::TimestampRequest(_)
2732 | Icmpv4PacketRaw::TimestampReply(_) => None,
2733
2734 Icmpv4PacketRaw::DestUnreachable(_)
2735 | Icmpv4PacketRaw::Redirect(_)
2736 | Icmpv4PacketRaw::TimeExceeded(_)
2737 | Icmpv4PacketRaw::ParameterProblem(_) => {
2738 Some(Self { src_ip, dst_ip, message })
2739 }
2740 }
2741 }
2742 }
2743 }
2744}
2745
2746impl<'a> ParsedIcmpErrorMut<'a, Ipv6> {
2747 fn parse_in_ipv6_packet<BV: BufferViewMut<&'a mut [u8]>>(
2748 src_ip: Ipv6Addr,
2749 dst_ip: Ipv6Addr,
2750 proto: Ipv6Proto,
2751 body: BV,
2752 ) -> Option<Self> {
2753 match proto {
2754 Ipv6Proto::NoNextHeader | Ipv6Proto::Proto(_) | Ipv6Proto::Other(_) => None,
2755
2756 Ipv6Proto::Icmpv6 => {
2757 let message = Icmpv6PacketRaw::parse_mut(body, ()).ok()?;
2758 match message {
2759 Icmpv6PacketRaw::EchoRequest(_)
2760 | Icmpv6PacketRaw::EchoReply(_)
2761 | Icmpv6PacketRaw::Ndp(_)
2762 | Icmpv6PacketRaw::Mld(_) => None,
2763
2764 Icmpv6PacketRaw::DestUnreachable(_)
2765 | Icmpv6PacketRaw::PacketTooBig(_)
2766 | Icmpv6PacketRaw::TimeExceeded(_)
2767 | Icmpv6PacketRaw::ParameterProblem(_) => {
2768 Some(Self { src_ip, dst_ip, message })
2769 }
2770 }
2771 }
2772 }
2773 }
2774}
2775
2776impl<'a, I: FilterIpExt> ParsedIcmpErrorMut<'a, I> {
2777 fn parse_in_ip_packet<BV: BufferViewMut<&'a mut [u8]>>(
2778 src_ip: I::Addr,
2779 dst_ip: I::Addr,
2780 proto: I::Proto,
2781 body: BV,
2782 ) -> Option<Self> {
2783 I::map_ip(
2784 (src_ip, dst_ip, proto, IpInvariant(body)),
2785 |(src_ip, dst_ip, proto, IpInvariant(body))| {
2786 ParsedIcmpErrorMut::<'a, Ipv4>::parse_in_ipv4_packet(src_ip, dst_ip, proto, body)
2787 },
2788 |(src_ip, dst_ip, proto, IpInvariant(body))| {
2789 ParsedIcmpErrorMut::<'a, Ipv6>::parse_in_ipv6_packet(src_ip, dst_ip, proto, body)
2790 },
2791 )
2792 }
2793}
2794
2795impl<'a, I: FilterIpExt> IcmpErrorMut<I> for ParsedIcmpErrorMut<'a, I> {
2796 type InnerPacket<'b>
2797 = I::FilterIpPacketRaw<&'b mut [u8]>
2798 where
2799 Self: 'b;
2800
2801 fn inner_packet<'b>(&'b mut self) -> Option<Self::InnerPacket<'b>> {
2802 Some(I::as_filter_packet_raw_owned(
2803 I::PacketRaw::parse_mut(SliceBufViewMut::new(self.message.message_body_mut()), ())
2804 .ok()?,
2805 ))
2806 }
2807
2808 fn recalculate_checksum(&mut self) -> bool {
2809 let Self { src_ip, dst_ip, message } = self;
2810 message.try_write_checksum(*src_ip, *dst_ip)
2811 }
2812}
2813
2814trait IcmpMessageImplHelper<I: IpExt> {
2816 fn message_impl_mut(&mut self) -> &mut impl IcmpMessage<I>;
2817}
2818
2819impl<I: IpExt, B: SplitByteSliceMut, M: IcmpMessage<I>> IcmpMessageImplHelper<I>
2820 for IcmpPacketRaw<I, B, M>
2821{
2822 fn message_impl_mut(&mut self) -> &mut impl IcmpMessage<I> {
2823 self.message_mut()
2824 }
2825}
2826
2827impl<'a, I: IpExt> TransportPacketMut<I> for ParsedTransportHeaderMut<'a, I> {
2828 fn set_src_port(&mut self, port: NonZeroU16) {
2829 match self {
2830 ParsedTransportHeaderMut::Tcp(segment) => segment.set_src_port(port),
2831 ParsedTransportHeaderMut::Udp(packet) => packet.set_src_port(port.get()),
2832 ParsedTransportHeaderMut::Icmp(packet) => {
2833 I::map_ip::<_, ()>(
2834 packet,
2835 |packet| {
2836 packet_formats::icmpv4_dispatch!(
2837 packet: raw,
2838 p => {
2839 let message = p.message_impl_mut();
2840 if message.is_rewritable() {
2841 let old = message.update_icmp_id(port.get());
2842 p.update_checksum_header_field_u16(old, port.get())
2843 }
2844 }
2845 );
2846 },
2847 |packet| {
2848 packet_formats::icmpv6_dispatch!(
2849 packet: raw,
2850 p => {
2851 let message = p.message_impl_mut();
2852 if message.is_rewritable() {
2853 let old = message.update_icmp_id(port.get());
2854 p.update_checksum_header_field_u16(old, port.get())
2855 }
2856 }
2857 );
2858 },
2859 );
2860 }
2861 }
2862 }
2863
2864 fn set_dst_port(&mut self, port: NonZeroU16) {
2865 match self {
2866 ParsedTransportHeaderMut::Tcp(segment) => segment.set_dst_port(port),
2867 ParsedTransportHeaderMut::Udp(packet) => packet.set_dst_port(port),
2868 ParsedTransportHeaderMut::Icmp(packet) => {
2869 I::map_ip::<_, ()>(
2870 packet,
2871 |packet| {
2872 packet_formats::icmpv4_dispatch!(
2873 packet:raw,
2874 p => {
2875 let message = p.message_impl_mut();
2876 if message.is_rewritable() {
2877 let old = message.update_icmp_id(port.get());
2878 p.update_checksum_header_field_u16(old, port.get())
2879 }
2880 }
2881 );
2882 },
2883 |packet| {
2884 packet_formats::icmpv6_dispatch!(
2885 packet:raw,
2886 p => {
2887 let message = p.message_impl_mut();
2888 if message.is_rewritable() {
2889 let old = message.update_icmp_id(port.get());
2890 p.update_checksum_header_field_u16(old, port.get())
2891 }
2892 }
2893 );
2894 },
2895 );
2896 }
2897 }
2898 }
2899
2900 fn update_pseudo_header_src_addr(&mut self, old: I::Addr, new: I::Addr) {
2901 self.update_pseudo_header_address(old, new);
2902 }
2903
2904 fn update_pseudo_header_dst_addr(&mut self, old: I::Addr, new: I::Addr) {
2905 self.update_pseudo_header_address(old, new);
2906 }
2907}
2908
2909#[cfg(any(test, feature = "testutils"))]
2910pub mod testutil {
2911 use super::*;
2912
2913 impl<B: BufferMut> MaybeTransportPacket for Nested<B, ()> {
2921 fn transport_packet_data(&self) -> Option<TransportPacketData> {
2922 unimplemented!()
2923 }
2924 }
2925
2926 impl<I: IpExt, B: BufferMut> MaybeTransportPacketMut<I> for Nested<B, ()> {
2927 type TransportPacketMut<'a>
2928 = Never
2929 where
2930 B: 'a;
2931
2932 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
2933 unimplemented!()
2934 }
2935 }
2936
2937 impl<I: IpExt, B: BufferMut> MaybeIcmpErrorPayload<I> for Nested<B, ()> {
2938 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
2939 unimplemented!()
2940 }
2941 }
2942
2943 impl<I: FilterIpExt, B: BufferMut> MaybeIcmpErrorMut<I> for Nested<B, ()> {
2944 type IcmpErrorMut<'a>
2945 = Never
2946 where
2947 Self: 'a;
2948
2949 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
2950 unimplemented!()
2951 }
2952 }
2953
2954 impl MaybeTransportPacket for InnerSerializer<&[u8], EmptyBuf> {
2955 fn transport_packet_data(&self) -> Option<TransportPacketData> {
2956 None
2957 }
2958 }
2959
2960 impl<I: IpExt> MaybeTransportPacketMut<I> for InnerSerializer<&[u8], EmptyBuf> {
2961 type TransportPacketMut<'a>
2962 = Never
2963 where
2964 Self: 'a;
2965
2966 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
2967 None
2968 }
2969 }
2970
2971 impl<I: IpExt> MaybeIcmpErrorPayload<I> for InnerSerializer<&[u8], EmptyBuf> {
2972 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
2973 None
2974 }
2975 }
2976
2977 impl<I: FilterIpExt> MaybeIcmpErrorMut<I> for InnerSerializer<&[u8], EmptyBuf> {
2978 type IcmpErrorMut<'a>
2979 = Never
2980 where
2981 Self: 'a;
2982
2983 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
2984 None
2985 }
2986 }
2987
2988 #[cfg(test)]
2989 pub(crate) mod internal {
2990 use alloc::vec::Vec;
2991 use net_declare::{net_ip_v4, net_ip_v6, net_subnet_v4, net_subnet_v6};
2992 use net_types::ip::Subnet;
2993 use netstack3_base::{SeqNum, UnscaledWindowSize};
2994 use packet::{PacketBuilder as _, TruncateDirection};
2995 use packet_formats::icmp::{Icmpv4DestUnreachableCode, Icmpv6DestUnreachableCode};
2996
2997 use super::*;
2998
2999 pub trait TestIpExt: FilterIpExt {
3000 const SRC_IP: Self::Addr;
3001 const SRC_PORT: u16 = 1234;
3002 const DST_IP: Self::Addr;
3003 const DST_PORT: u16 = 9876;
3004 const SRC_IP_2: Self::Addr;
3005 const DST_IP_2: Self::Addr;
3006 const DST_IP_3: Self::Addr;
3007 const IP_OUTSIDE_SUBNET: Self::Addr;
3008 const SUBNET: Subnet<Self::Addr>;
3009 }
3010
3011 impl TestIpExt for Ipv4 {
3012 const SRC_IP: Self::Addr = net_ip_v4!("192.0.2.1");
3013 const DST_IP: Self::Addr = net_ip_v4!("192.0.2.2");
3014 const SRC_IP_2: Self::Addr = net_ip_v4!("192.0.2.3");
3015 const DST_IP_2: Self::Addr = net_ip_v4!("192.0.2.4");
3016 const DST_IP_3: Self::Addr = net_ip_v4!("192.0.2.6");
3017 const IP_OUTSIDE_SUBNET: Self::Addr = net_ip_v4!("192.0.3.1");
3018 const SUBNET: Subnet<Self::Addr> = net_subnet_v4!("192.0.2.0/24");
3019 }
3020
3021 impl TestIpExt for Ipv6 {
3022 const SRC_IP: Self::Addr = net_ip_v6!("2001:db8::1");
3023 const DST_IP: Self::Addr = net_ip_v6!("2001:db8::2");
3024 const SRC_IP_2: Self::Addr = net_ip_v6!("2001:db8::3");
3025 const DST_IP_2: Self::Addr = net_ip_v6!("2001:db8::4");
3026 const DST_IP_3: Self::Addr = net_ip_v6!("2001:db8::6");
3027 const IP_OUTSIDE_SUBNET: Self::Addr = net_ip_v6!("2001:db8:ffff::1");
3028 const SUBNET: Subnet<Self::Addr> = net_subnet_v6!("2001:db8::/64");
3029 }
3030
3031 #[derive(Clone, Debug, PartialEq)]
3032 pub struct FakeIpPacket<I: FilterIpExt, T>
3033 where
3034 for<'a> &'a T: TransportPacketExt<I>,
3035 {
3036 pub src_ip: I::Addr,
3037 pub dst_ip: I::Addr,
3038 pub body: T,
3039 }
3040
3041 impl<I: FilterIpExt> FakeIpPacket<I, FakeUdpPacket> {
3042 pub(crate) fn reply(&self) -> Self {
3043 Self { src_ip: self.dst_ip, dst_ip: self.src_ip, body: self.body.reply() }
3044 }
3045 }
3046
3047 pub trait TransportPacketExt<I: IpExt>:
3048 MaybeTransportPacket + MaybeIcmpErrorPayload<I>
3049 {
3050 fn proto() -> Option<I::Proto>;
3051 }
3052
3053 impl<I: FilterIpExt, T> IpPacket<I> for FakeIpPacket<I, T>
3054 where
3055 for<'a> &'a T: TransportPacketExt<I>,
3056 for<'a> &'a mut T: MaybeTransportPacketMut<I> + MaybeIcmpErrorMut<I>,
3057 {
3058 type TransportPacket<'a>
3059 = &'a T
3060 where
3061 T: 'a;
3062 type TransportPacketMut<'a>
3063 = &'a mut T
3064 where
3065 T: 'a;
3066 type IcmpError<'a>
3067 = &'a T
3068 where
3069 T: 'a;
3070 type IcmpErrorMut<'a>
3071 = &'a mut T
3072 where
3073 T: 'a;
3074
3075 fn src_addr(&self) -> I::Addr {
3076 self.src_ip
3077 }
3078
3079 fn set_src_addr(&mut self, addr: I::Addr) {
3080 self.src_ip = addr;
3081 }
3082
3083 fn dst_addr(&self) -> I::Addr {
3084 self.dst_ip
3085 }
3086
3087 fn set_dst_addr(&mut self, addr: I::Addr) {
3088 self.dst_ip = addr;
3089 }
3090
3091 fn protocol(&self) -> Option<I::Proto> {
3092 <&T>::proto()
3093 }
3094
3095 fn maybe_transport_packet(&self) -> Self::TransportPacket<'_> {
3096 &self.body
3097 }
3098
3099 fn transport_packet_mut(&mut self) -> Self::TransportPacketMut<'_> {
3100 &mut self.body
3101 }
3102
3103 fn maybe_icmp_error<'a>(&'a self) -> Self::IcmpError<'a> {
3104 &self.body
3105 }
3106
3107 fn icmp_error_mut<'a>(&'a mut self) -> Self::IcmpErrorMut<'a> {
3108 &mut self.body
3109 }
3110 }
3111
3112 #[derive(Clone, Debug, PartialEq)]
3113 pub struct FakeTcpSegment {
3114 pub src_port: u16,
3115 pub dst_port: u16,
3116 pub segment: SegmentHeader,
3117 pub payload_len: usize,
3118 }
3119
3120 impl<I: FilterIpExt> TransportPacketExt<I> for &FakeTcpSegment {
3121 fn proto() -> Option<I::Proto> {
3122 Some(I::map_ip_out(
3123 (),
3124 |()| Ipv4Proto::Proto(IpProto::Tcp),
3125 |()| Ipv6Proto::Proto(IpProto::Tcp),
3126 ))
3127 }
3128 }
3129
3130 impl MaybeTransportPacket for &FakeTcpSegment {
3131 fn transport_packet_data(&self) -> Option<TransportPacketData> {
3132 Some(TransportPacketData::Tcp {
3133 src_port: self.src_port,
3134 dst_port: self.dst_port,
3135 segment: self.segment.clone(),
3136 payload_len: self.payload_len,
3137 })
3138 }
3139 }
3140
3141 impl<I: IpExt> MaybeTransportPacketMut<I> for FakeTcpSegment {
3142 type TransportPacketMut<'a> = &'a mut Self;
3143
3144 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
3145 Some(self)
3146 }
3147 }
3148
3149 impl<I: IpExt> TransportPacketMut<I> for FakeTcpSegment {
3150 fn set_src_port(&mut self, port: NonZeroU16) {
3151 self.src_port = port.get();
3152 }
3153
3154 fn set_dst_port(&mut self, port: NonZeroU16) {
3155 self.dst_port = port.get();
3156 }
3157
3158 fn update_pseudo_header_src_addr(&mut self, _: I::Addr, _: I::Addr) {}
3159
3160 fn update_pseudo_header_dst_addr(&mut self, _: I::Addr, _: I::Addr) {}
3161 }
3162
3163 impl<I: IpExt> MaybeIcmpErrorPayload<I> for FakeTcpSegment {
3164 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
3165 None
3166 }
3167 }
3168
3169 impl<I: FilterIpExt> MaybeIcmpErrorMut<I> for FakeTcpSegment {
3170 type IcmpErrorMut<'a>
3171 = Never
3172 where
3173 Self: 'a;
3174
3175 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
3176 None
3177 }
3178 }
3179
3180 #[derive(Clone, Debug, PartialEq)]
3181 pub struct FakeUdpPacket {
3182 pub src_port: u16,
3183 pub dst_port: u16,
3184 }
3185
3186 impl FakeUdpPacket {
3187 fn reply(&self) -> Self {
3188 Self { src_port: self.dst_port, dst_port: self.src_port }
3189 }
3190 }
3191
3192 impl<I: FilterIpExt> TransportPacketExt<I> for &FakeUdpPacket {
3193 fn proto() -> Option<I::Proto> {
3194 Some(I::map_ip_out(
3195 (),
3196 |()| Ipv4Proto::Proto(IpProto::Udp),
3197 |()| Ipv6Proto::Proto(IpProto::Udp),
3198 ))
3199 }
3200 }
3201
3202 impl MaybeTransportPacket for &FakeUdpPacket {
3203 fn transport_packet_data(&self) -> Option<TransportPacketData> {
3204 Some(TransportPacketData::Generic {
3205 src_port: self.src_port,
3206 dst_port: self.dst_port,
3207 })
3208 }
3209 }
3210
3211 impl<I: IpExt> MaybeTransportPacketMut<I> for FakeUdpPacket {
3212 type TransportPacketMut<'a> = &'a mut Self;
3213
3214 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
3215 Some(self)
3216 }
3217 }
3218
3219 impl<I: IpExt> TransportPacketMut<I> for FakeUdpPacket {
3220 fn set_src_port(&mut self, port: NonZeroU16) {
3221 self.src_port = port.get();
3222 }
3223
3224 fn set_dst_port(&mut self, port: NonZeroU16) {
3225 self.dst_port = port.get();
3226 }
3227
3228 fn update_pseudo_header_src_addr(&mut self, _: I::Addr, _: I::Addr) {}
3229
3230 fn update_pseudo_header_dst_addr(&mut self, _: I::Addr, _: I::Addr) {}
3231 }
3232
3233 impl<I: IpExt> MaybeIcmpErrorPayload<I> for FakeUdpPacket {
3234 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
3235 None
3236 }
3237 }
3238
3239 impl<I: FilterIpExt> MaybeIcmpErrorMut<I> for FakeUdpPacket {
3240 type IcmpErrorMut<'a>
3241 = Never
3242 where
3243 Self: 'a;
3244
3245 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
3246 None
3247 }
3248 }
3249
3250 #[derive(Clone, Debug, PartialEq)]
3251 pub struct FakeNullPacket;
3252
3253 impl<I: IpExt> TransportPacketExt<I> for &FakeNullPacket {
3254 fn proto() -> Option<I::Proto> {
3255 None
3256 }
3257 }
3258
3259 impl MaybeTransportPacket for &FakeNullPacket {
3260 fn transport_packet_data(&self) -> Option<TransportPacketData> {
3261 None
3262 }
3263 }
3264
3265 impl<I: IpExt> MaybeTransportPacketMut<I> for FakeNullPacket {
3266 type TransportPacketMut<'a> = Never;
3267
3268 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
3269 None
3270 }
3271 }
3272
3273 impl<I: IpExt> MaybeIcmpErrorPayload<I> for FakeNullPacket {
3274 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
3275 None
3276 }
3277 }
3278
3279 impl<I: FilterIpExt> MaybeIcmpErrorMut<I> for FakeNullPacket {
3280 type IcmpErrorMut<'a>
3281 = Never
3282 where
3283 Self: 'a;
3284
3285 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
3286 None
3287 }
3288 }
3289
3290 pub struct FakeIcmpEchoRequest {
3291 pub id: u16,
3292 }
3293
3294 impl<I: FilterIpExt> TransportPacketExt<I> for &FakeIcmpEchoRequest {
3295 fn proto() -> Option<I::Proto> {
3296 Some(I::map_ip_out((), |()| Ipv4Proto::Icmp, |()| Ipv6Proto::Icmpv6))
3297 }
3298 }
3299
3300 impl MaybeTransportPacket for &FakeIcmpEchoRequest {
3301 fn transport_packet_data(&self) -> Option<TransportPacketData> {
3302 Some(TransportPacketData::Generic { src_port: self.id, dst_port: 0 })
3303 }
3304 }
3305
3306 impl<I: IpExt> MaybeTransportPacketMut<I> for FakeIcmpEchoRequest {
3307 type TransportPacketMut<'a> = &'a mut Self;
3308
3309 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
3310 Some(self)
3311 }
3312 }
3313
3314 impl<I: IpExt> TransportPacketMut<I> for FakeIcmpEchoRequest {
3315 fn set_src_port(&mut self, port: NonZeroU16) {
3316 self.id = port.get();
3317 }
3318
3319 fn set_dst_port(&mut self, _: NonZeroU16) {
3320 panic!("cannot set destination port for ICMP echo request")
3321 }
3322
3323 fn update_pseudo_header_src_addr(&mut self, _: I::Addr, _: I::Addr) {}
3324
3325 fn update_pseudo_header_dst_addr(&mut self, _: I::Addr, _: I::Addr) {}
3326 }
3327
3328 impl<I: IpExt> MaybeIcmpErrorPayload<I> for FakeIcmpEchoRequest {
3329 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
3330 None
3331 }
3332 }
3333
3334 impl<I: FilterIpExt> MaybeIcmpErrorMut<I> for FakeIcmpEchoRequest {
3335 type IcmpErrorMut<'a>
3336 = Never
3337 where
3338 Self: 'a;
3339
3340 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
3341 None
3342 }
3343 }
3344
3345 pub trait ArbitraryValue {
3346 fn arbitrary_value() -> Self;
3347 }
3348
3349 impl<I, T> ArbitraryValue for FakeIpPacket<I, T>
3350 where
3351 I: TestIpExt,
3352 T: ArbitraryValue,
3353 for<'a> &'a T: TransportPacketExt<I>,
3354 {
3355 fn arbitrary_value() -> Self {
3356 FakeIpPacket { src_ip: I::SRC_IP, dst_ip: I::DST_IP, body: T::arbitrary_value() }
3357 }
3358 }
3359
3360 impl ArbitraryValue for FakeTcpSegment {
3361 fn arbitrary_value() -> Self {
3362 FakeTcpSegment {
3363 src_port: 33333,
3364 dst_port: 44444,
3365 segment: SegmentHeader::arbitrary_value(),
3366 payload_len: 8888,
3367 }
3368 }
3369 }
3370
3371 impl ArbitraryValue for FakeUdpPacket {
3372 fn arbitrary_value() -> Self {
3373 FakeUdpPacket { src_port: 33333, dst_port: 44444 }
3374 }
3375 }
3376
3377 impl ArbitraryValue for FakeNullPacket {
3378 fn arbitrary_value() -> Self {
3379 FakeNullPacket
3380 }
3381 }
3382
3383 impl ArbitraryValue for FakeIcmpEchoRequest {
3384 fn arbitrary_value() -> Self {
3385 FakeIcmpEchoRequest { id: 1 }
3386 }
3387 }
3388
3389 impl ArbitraryValue for SegmentHeader {
3390 fn arbitrary_value() -> Self {
3391 SegmentHeader {
3392 seq: SeqNum::new(55555),
3393 wnd: UnscaledWindowSize::from(1234),
3394 ..Default::default()
3395 }
3396 }
3397 }
3398
3399 pub(crate) trait IcmpErrorMessage<I: FilterIpExt> {
3400 type Serializer: TransportPacketSerializer<I, Buffer: packet::ReusableBuffer>
3401 + Debug
3402 + PartialEq;
3403
3404 fn proto() -> I::Proto {
3405 I::map_ip((), |()| Ipv4Proto::Icmp, |()| Ipv6Proto::Icmpv6)
3406 }
3407
3408 fn make_serializer(
3409 src_ip: I::Addr,
3410 dst_ip: I::Addr,
3411 inner: Vec<u8>,
3412 ) -> Self::Serializer;
3413
3414 fn make_serializer_truncated(
3415 src_ip: I::Addr,
3416 dst_ip: I::Addr,
3417 mut payload: Vec<u8>,
3418 truncate_payload: Option<usize>,
3419 ) -> Self::Serializer {
3420 if let Some(len) = truncate_payload {
3421 payload.truncate(len);
3422 }
3423
3424 Self::make_serializer(src_ip, dst_ip, payload)
3425 }
3426 }
3427
3428 pub(crate) struct Icmpv4DestUnreachableError;
3429
3430 impl IcmpErrorMessage<Ipv4> for Icmpv4DestUnreachableError {
3431 type Serializer = Nested<Buf<Vec<u8>>, IcmpPacketBuilder<Ipv4, IcmpDestUnreachable>>;
3432
3433 fn make_serializer(
3434 src_ip: Ipv4Addr,
3435 dst_ip: Ipv4Addr,
3436 payload: Vec<u8>,
3437 ) -> Self::Serializer {
3438 IcmpPacketBuilder::<Ipv4, IcmpDestUnreachable>::new(
3439 src_ip,
3440 dst_ip,
3441 Icmpv4DestUnreachableCode::DestHostUnreachable,
3442 IcmpDestUnreachable::default(),
3443 )
3444 .wrap_body(Buf::new(payload, ..))
3445 }
3446 }
3447
3448 pub(crate) struct Icmpv6DestUnreachableError;
3449
3450 impl IcmpErrorMessage<Ipv6> for Icmpv6DestUnreachableError {
3451 type Serializer = Nested<
3452 TruncatingSerializer<Buf<Vec<u8>>>,
3453 IcmpPacketBuilder<Ipv6, IcmpDestUnreachable>,
3454 >;
3455
3456 fn make_serializer(
3457 src_ip: Ipv6Addr,
3458 dst_ip: Ipv6Addr,
3459 payload: Vec<u8>,
3460 ) -> Self::Serializer {
3461 IcmpPacketBuilder::<Ipv6, IcmpDestUnreachable>::new(
3462 src_ip,
3463 dst_ip,
3464 Icmpv6DestUnreachableCode::AddrUnreachable,
3465 IcmpDestUnreachable::default(),
3466 )
3467 .wrap_body(TruncatingSerializer::new(
3468 Buf::new(payload, ..),
3469 TruncateDirection::DiscardBack,
3470 ))
3471 }
3472 }
3473 }
3474
3475 pub fn new_filter_egress_ip_packet<I: FilterIpExt, S: TransportPacketSerializer<I>>(
3477 src_addr: I::Addr,
3478 dst_addr: I::Addr,
3479 protocol: I::Proto,
3480 body: &'_ mut S,
3481 ) -> impl IpPacket<I> + PartialSerializer + use<'_, I, S> {
3482 TxPacket::new(src_addr, dst_addr, protocol, body)
3483 }
3484}
3485
3486#[cfg(test)]
3487mod tests {
3488 use alloc::vec::Vec;
3489 use core::fmt::Debug;
3490 use core::marker::PhantomData;
3491 use netstack3_base::{SeqNum, UnscaledWindowSize};
3492
3493 use assert_matches::assert_matches;
3494 use ip_test_macro::ip_test;
3495 use packet::{
3496 EmptyBuf, InnerPacketBuilder as _, PacketBuilder as _, ParseBufferMut, PartialSerializer,
3497 };
3498 use packet_formats::icmp::IcmpZeroCode;
3499 use packet_formats::tcp::TcpSegmentBuilder;
3500 use test_case::{test_case, test_matrix};
3501
3502 use crate::conntrack;
3503
3504 use super::testutil::internal::{
3505 IcmpErrorMessage, Icmpv4DestUnreachableError, Icmpv6DestUnreachableError, TestIpExt,
3506 };
3507 use super::*;
3508
3509 const SRC_PORT: NonZeroU16 = NonZeroU16::new(11111).unwrap();
3510 const DST_PORT: NonZeroU16 = NonZeroU16::new(22222).unwrap();
3511 const SRC_PORT_2: NonZeroU16 = NonZeroU16::new(44444).unwrap();
3512 const DST_PORT_2: NonZeroU16 = NonZeroU16::new(55555).unwrap();
3513
3514 const SEQ_NUM: u32 = 1;
3515 const ACK_NUM: Option<u32> = Some(2);
3516 const WINDOW_SIZE: u16 = 3u16;
3517
3518 trait Protocol {
3519 const HEADER_SIZE: usize;
3520
3521 type Serializer<'a, I: FilterIpExt>: TransportPacketSerializer<I, Buffer: packet::ReusableBuffer>
3522 + MaybeTransportPacketMut<I>
3523 + Debug
3524 + PartialEq;
3525
3526 fn proto<I: IpExt>() -> I::Proto;
3527
3528 fn make_serializer_with_ports_data<'a, I: FilterIpExt>(
3529 src_ip: I::Addr,
3530 dst_ip: I::Addr,
3531 src_port: NonZeroU16,
3532 dst_port: NonZeroU16,
3533 data: &'a [u8],
3534 ) -> Self::Serializer<'a, I>;
3535
3536 fn make_serializer_with_ports<'a, I: FilterIpExt>(
3537 src_ip: I::Addr,
3538 dst_ip: I::Addr,
3539 src_port: NonZeroU16,
3540 dst_port: NonZeroU16,
3541 ) -> Self::Serializer<'a, I> {
3542 Self::make_serializer_with_ports_data(src_ip, dst_ip, src_port, dst_port, &[1, 2, 3])
3543 }
3544
3545 fn make_serializer<'a, I: FilterIpExt>(
3546 src_ip: I::Addr,
3547 dst_ip: I::Addr,
3548 ) -> Self::Serializer<'a, I> {
3549 Self::make_serializer_with_ports(src_ip, dst_ip, SRC_PORT, DST_PORT)
3550 }
3551
3552 fn make_packet<I: FilterIpExt>(src_ip: I::Addr, dst_ip: I::Addr) -> Vec<u8> {
3553 Self::make_packet_with_ports::<I>(src_ip, dst_ip, SRC_PORT, DST_PORT)
3554 }
3555
3556 fn make_packet_with_ports<I: FilterIpExt>(
3557 src_ip: I::Addr,
3558 dst_ip: I::Addr,
3559 src_port: NonZeroU16,
3560 dst_port: NonZeroU16,
3561 ) -> Vec<u8> {
3562 Self::make_serializer_with_ports::<I>(src_ip, dst_ip, src_port, dst_port)
3563 .serialize_vec_outer()
3564 .expect("serialize packet")
3565 .unwrap_b()
3566 .into_inner()
3567 }
3568
3569 fn make_ip_packet_with_ports_data<I: FilterIpExt>(
3570 src_ip: I::Addr,
3571 dst_ip: I::Addr,
3572 src_port: NonZeroU16,
3573 dst_port: NonZeroU16,
3574 data: &[u8],
3575 ) -> Vec<u8> {
3576 I::PacketBuilder::new(src_ip, dst_ip, u8::MAX, Self::proto::<I>())
3577 .wrap_body(Self::make_serializer_with_ports_data::<I>(
3578 src_ip, dst_ip, src_port, dst_port, data,
3579 ))
3580 .serialize_vec_outer()
3581 .expect("serialize packet")
3582 .unwrap_b()
3583 .into_inner()
3584 }
3585 }
3586
3587 struct Udp;
3588
3589 impl Protocol for Udp {
3590 const HEADER_SIZE: usize = 8;
3591
3592 type Serializer<'a, I: FilterIpExt> =
3593 Nested<InnerSerializer<&'a [u8], EmptyBuf>, UdpPacketBuilder<I::Addr>>;
3594
3595 fn proto<I: IpExt>() -> I::Proto {
3596 IpProto::Udp.into()
3597 }
3598
3599 fn make_serializer_with_ports_data<'a, I: FilterIpExt>(
3600 src_ip: I::Addr,
3601 dst_ip: I::Addr,
3602 src_port: NonZeroU16,
3603 dst_port: NonZeroU16,
3604 data: &'a [u8],
3605 ) -> Self::Serializer<'a, I> {
3606 UdpPacketBuilder::new(src_ip, dst_ip, Some(src_port), dst_port)
3607 .wrap_body(data.into_serializer())
3608 }
3609 }
3610
3611 impl<A: IpAddress, Inner: PayloadLen> MaybeTransportPacket for Nested<Inner, TcpSegmentBuilder<A>> {
3619 fn transport_packet_data(&self) -> Option<TransportPacketData> {
3620 Some(TransportPacketData::Tcp {
3621 src_port: TcpSegmentBuilder::src_port(self.outer()).map_or(0, NonZeroU16::get),
3622 dst_port: TcpSegmentBuilder::dst_port(self.outer()).map_or(0, NonZeroU16::get),
3623 segment: self.outer().try_into().ok()?,
3624 payload_len: self.inner().len(),
3625 })
3626 }
3627 }
3628
3629 impl<I: IpExt, Inner> MaybeTransportPacketMut<I> for Nested<Inner, TcpSegmentBuilder<I::Addr>> {
3630 type TransportPacketMut<'a>
3631 = &'a mut Self
3632 where
3633 Self: 'a;
3634
3635 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
3636 Some(self)
3637 }
3638 }
3639
3640 impl<I: IpExt, Inner> TransportPacketMut<I> for Nested<Inner, TcpSegmentBuilder<I::Addr>> {
3641 fn set_src_port(&mut self, port: NonZeroU16) {
3642 self.outer_mut().set_src_port(port);
3643 }
3644
3645 fn set_dst_port(&mut self, port: NonZeroU16) {
3646 self.outer_mut().set_dst_port(port);
3647 }
3648
3649 fn update_pseudo_header_src_addr(&mut self, _old: I::Addr, new: I::Addr) {
3650 self.outer_mut().set_src_ip(new);
3651 }
3652
3653 fn update_pseudo_header_dst_addr(&mut self, _old: I::Addr, new: I::Addr) {
3654 self.outer_mut().set_dst_ip(new);
3655 }
3656 }
3657
3658 impl<A: IpAddress, I: IpExt, Inner> MaybeIcmpErrorPayload<I>
3659 for Nested<Inner, TcpSegmentBuilder<A>>
3660 {
3661 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
3662 None
3663 }
3664 }
3665
3666 impl<A: IpAddress, I: FilterIpExt, Inner> MaybeIcmpErrorMut<I>
3667 for Nested<Inner, TcpSegmentBuilder<A>>
3668 {
3669 type IcmpErrorMut<'a>
3670 = Never
3671 where
3672 Self: 'a;
3673
3674 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
3675 None
3676 }
3677 }
3678
3679 enum Tcp {}
3680
3681 impl Protocol for Tcp {
3682 const HEADER_SIZE: usize = 20;
3683
3684 type Serializer<'a, I: FilterIpExt> =
3685 Nested<InnerSerializer<&'a [u8], EmptyBuf>, TcpSegmentBuilder<I::Addr>>;
3686
3687 fn proto<I: IpExt>() -> I::Proto {
3688 IpProto::Tcp.into()
3689 }
3690
3691 fn make_serializer_with_ports_data<'a, I: FilterIpExt>(
3692 src_ip: I::Addr,
3693 dst_ip: I::Addr,
3694 src_port: NonZeroU16,
3695 dst_port: NonZeroU16,
3696 data: &'a [u8],
3697 ) -> Self::Serializer<'a, I> {
3698 TcpSegmentBuilder::new(
3699 src_ip,
3700 dst_ip,
3701 src_port,
3702 dst_port,
3703 SEQ_NUM,
3704 ACK_NUM,
3705 WINDOW_SIZE,
3706 )
3707 .wrap_body(data.into_serializer())
3708 }
3709 }
3710
3711 enum IcmpEchoRequest {}
3712
3713 impl Protocol for IcmpEchoRequest {
3714 const HEADER_SIZE: usize = 8;
3715
3716 type Serializer<'a, I: FilterIpExt> = Nested<
3717 InnerSerializer<&'a [u8], EmptyBuf>,
3718 IcmpPacketBuilder<I, icmp::IcmpEchoRequest>,
3719 >;
3720
3721 fn proto<I: IpExt>() -> I::Proto {
3722 I::map_ip((), |()| Ipv4Proto::Icmp, |()| Ipv6Proto::Icmpv6)
3723 }
3724
3725 fn make_serializer_with_ports_data<'a, I: FilterIpExt>(
3726 src_ip: I::Addr,
3727 dst_ip: I::Addr,
3728 src_port: NonZeroU16,
3729 _dst_port: NonZeroU16,
3730 data: &'a [u8],
3731 ) -> Self::Serializer<'a, I> {
3732 IcmpPacketBuilder::<I, _>::new(
3733 src_ip,
3734 dst_ip,
3735 IcmpZeroCode,
3736 icmp::IcmpEchoRequest::new(src_port.get(), 0),
3737 )
3738 .wrap_body(data.into_serializer())
3739 }
3740 }
3741
3742 enum IcmpEchoReply {}
3743
3744 impl Protocol for IcmpEchoReply {
3745 const HEADER_SIZE: usize = 8;
3746
3747 type Serializer<'a, I: FilterIpExt> =
3748 Nested<InnerSerializer<&'a [u8], EmptyBuf>, IcmpPacketBuilder<I, icmp::IcmpEchoReply>>;
3749
3750 fn proto<I: IpExt>() -> I::Proto {
3751 I::map_ip((), |()| Ipv4Proto::Icmp, |()| Ipv6Proto::Icmpv6)
3752 }
3753
3754 fn make_serializer_with_ports_data<'a, I: FilterIpExt>(
3755 src_ip: I::Addr,
3756 dst_ip: I::Addr,
3757 _src_port: NonZeroU16,
3758 dst_port: NonZeroU16,
3759 data: &'a [u8],
3760 ) -> Self::Serializer<'a, I> {
3761 IcmpPacketBuilder::<I, _>::new(
3762 src_ip,
3763 dst_ip,
3764 IcmpZeroCode,
3765 icmp::IcmpEchoReply::new(dst_port.get(), 0),
3766 )
3767 .wrap_body(data.into_serializer())
3768 }
3769 }
3770
3771 enum TransportPacketDataProtocol {
3772 Tcp,
3773 Udp,
3774 IcmpEchoRequest,
3775 }
3776
3777 impl TransportPacketDataProtocol {
3778 fn make_packet<I: TestIpExt>(&self, src_ip: I::Addr, dst_ip: I::Addr) -> Vec<u8> {
3779 match self {
3780 TransportPacketDataProtocol::Tcp => Tcp::make_packet::<I>(src_ip, dst_ip),
3781 TransportPacketDataProtocol::Udp => Udp::make_packet::<I>(src_ip, dst_ip),
3782 TransportPacketDataProtocol::IcmpEchoRequest => {
3783 IcmpEchoRequest::make_packet::<I>(src_ip, dst_ip)
3784 }
3785 }
3786 }
3787
3788 fn make_ip_packet_with_ports_data<I: TestIpExt>(
3789 &self,
3790 src_ip: I::Addr,
3791 dst_ip: I::Addr,
3792 src_port: NonZeroU16,
3793 dst_port: NonZeroU16,
3794 data: &[u8],
3795 ) -> Vec<u8> {
3796 match self {
3797 TransportPacketDataProtocol::Tcp => Tcp::make_ip_packet_with_ports_data::<I>(
3798 src_ip, dst_ip, src_port, dst_port, data,
3799 ),
3800 TransportPacketDataProtocol::Udp => Udp::make_ip_packet_with_ports_data::<I>(
3801 src_ip, dst_ip, src_port, dst_port, data,
3802 ),
3803 TransportPacketDataProtocol::IcmpEchoRequest => {
3804 IcmpEchoRequest::make_ip_packet_with_ports_data::<I>(
3805 src_ip, dst_ip, src_port, dst_port, data,
3806 )
3807 }
3808 }
3809 }
3810
3811 fn proto<I: TestIpExt>(&self) -> I::Proto {
3812 match self {
3813 TransportPacketDataProtocol::Tcp => Tcp::proto::<I>(),
3814 TransportPacketDataProtocol::Udp => Udp::proto::<I>(),
3815 TransportPacketDataProtocol::IcmpEchoRequest => IcmpEchoRequest::proto::<I>(),
3816 }
3817 }
3818 }
3819
3820 #[ip_test(I)]
3821 #[test_case(TransportPacketDataProtocol::Udp)]
3822 #[test_case(TransportPacketDataProtocol::Tcp)]
3823 #[test_case(TransportPacketDataProtocol::IcmpEchoRequest)]
3824 fn transport_packet_data_from_serialized<I: TestIpExt>(proto: TransportPacketDataProtocol) {
3825 let expected_data = match proto {
3826 TransportPacketDataProtocol::Tcp => TransportPacketData::Tcp {
3827 src_port: SRC_PORT.get(),
3828 dst_port: DST_PORT.get(),
3829 segment: SegmentHeader {
3830 seq: SeqNum::new(SEQ_NUM),
3831 ack: ACK_NUM.map(SeqNum::new),
3832 wnd: UnscaledWindowSize::from(WINDOW_SIZE),
3833 ..Default::default()
3834 },
3835 payload_len: 3,
3836 },
3837 TransportPacketDataProtocol::Udp => {
3838 TransportPacketData::Generic { src_port: SRC_PORT.get(), dst_port: DST_PORT.get() }
3839 }
3840 TransportPacketDataProtocol::IcmpEchoRequest => {
3841 TransportPacketData::Generic { src_port: SRC_PORT.get(), dst_port: SRC_PORT.get() }
3842 }
3843 };
3844
3845 let buf = proto.make_packet::<I>(I::SRC_IP, I::DST_IP);
3846 let parsed_data = TransportPacketData::parse_in_ip_packet::<I, _>(
3847 I::SRC_IP,
3848 I::DST_IP,
3849 proto.proto::<I>(),
3850 buf.as_slice(),
3851 )
3852 .expect("failed to parse transport packet data");
3853
3854 assert_eq!(parsed_data, expected_data);
3855 }
3856
3857 enum PacketType {
3858 FullyParsed,
3859 Raw,
3860 }
3861
3862 #[ip_test(I)]
3863 #[test_matrix(
3864 [
3865 TransportPacketDataProtocol::Udp,
3866 TransportPacketDataProtocol::Tcp,
3867 TransportPacketDataProtocol::IcmpEchoRequest,
3868 ],
3869 [
3870 PacketType::FullyParsed,
3871 PacketType::Raw
3872 ]
3873 )]
3874 fn conntrack_packet_data_from_ip_packet<I: TestIpExt>(
3875 proto: TransportPacketDataProtocol,
3876 packet_type: PacketType,
3877 ) where
3878 for<'a> I::Packet<&'a mut [u8]>: IpPacket<I>,
3879 for<'a> I::PacketRaw<&'a mut [u8]>: IpPacket<I>,
3880 {
3881 let expected_data = match proto {
3882 TransportPacketDataProtocol::Tcp => conntrack::PacketMetadata::new(
3883 I::SRC_IP,
3884 I::DST_IP,
3885 conntrack::TransportProtocol::Tcp,
3886 TransportPacketData::Tcp {
3887 src_port: SRC_PORT.get(),
3888 dst_port: DST_PORT.get(),
3889 segment: SegmentHeader {
3890 seq: SeqNum::new(SEQ_NUM),
3891 ack: ACK_NUM.map(SeqNum::new),
3892 wnd: UnscaledWindowSize::from(WINDOW_SIZE),
3893 ..Default::default()
3894 },
3895 payload_len: 3,
3896 },
3897 ),
3898 TransportPacketDataProtocol::Udp => conntrack::PacketMetadata::new(
3899 I::SRC_IP,
3900 I::DST_IP,
3901 conntrack::TransportProtocol::Udp,
3902 TransportPacketData::Generic { src_port: SRC_PORT.get(), dst_port: DST_PORT.get() },
3903 ),
3904 TransportPacketDataProtocol::IcmpEchoRequest => conntrack::PacketMetadata::new(
3905 I::SRC_IP,
3906 I::DST_IP,
3907 conntrack::TransportProtocol::Icmp,
3908 TransportPacketData::Generic { src_port: SRC_PORT.get(), dst_port: SRC_PORT.get() },
3909 ),
3910 };
3911
3912 let mut buf = proto.make_ip_packet_with_ports_data::<I>(
3913 I::SRC_IP,
3914 I::DST_IP,
3915 SRC_PORT,
3916 DST_PORT,
3917 &[1, 2, 3],
3918 );
3919
3920 let parsed_data = match packet_type {
3921 PacketType::FullyParsed => {
3922 let packet = I::Packet::parse_mut(SliceBufViewMut::new(buf.as_mut()), ())
3923 .expect("parse IP packet");
3924 packet.conntrack_packet().expect("packet should be trackable")
3925 }
3926 PacketType::Raw => {
3927 let packet = I::PacketRaw::parse_mut(SliceBufViewMut::new(buf.as_mut()), ())
3928 .expect("parse IP packet");
3929 packet.conntrack_packet().expect("packet should be trackable")
3930 }
3931 };
3932
3933 assert_eq!(parsed_data, expected_data);
3934 }
3935
3936 #[ip_test(I)]
3937 #[test_case(PhantomData::<Udp>)]
3938 #[test_case(PhantomData::<Tcp>)]
3939 #[test_case(PhantomData::<IcmpEchoRequest>)]
3940 fn update_pseudo_header_address_updates_checksum<I: TestIpExt, P: Protocol>(
3941 _proto: PhantomData<P>,
3942 ) {
3943 let mut buf = P::make_packet::<I>(I::SRC_IP, I::DST_IP);
3944 let view = SliceBufViewMut::new(&mut buf);
3945
3946 let mut packet = ParsedTransportHeaderMut::<I>::parse_in_ip_packet(P::proto::<I>(), view)
3947 .expect("parse transport header");
3948 packet.update_pseudo_header_src_addr(I::SRC_IP, I::SRC_IP_2);
3949 packet.update_pseudo_header_dst_addr(I::DST_IP, I::DST_IP_2);
3950 drop(packet);
3953
3954 let equivalent = P::make_packet::<I>(I::SRC_IP_2, I::DST_IP_2);
3955
3956 assert_eq!(equivalent, buf);
3957 }
3958
3959 #[ip_test(I)]
3960 #[test_case(PhantomData::<Udp>, true, true)]
3961 #[test_case(PhantomData::<Tcp>, true, true)]
3962 #[test_case(PhantomData::<IcmpEchoRequest>, true, false)]
3963 #[test_case(PhantomData::<IcmpEchoReply>, false, true)]
3964 fn parsed_packet_update_src_dst_port_updates_checksum<I: TestIpExt, P: Protocol>(
3965 _proto: PhantomData<P>,
3966 update_src_port: bool,
3967 update_dst_port: bool,
3968 ) {
3969 let mut buf = P::make_packet_with_ports::<I>(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT);
3970 let view = SliceBufViewMut::new(&mut buf);
3971
3972 let mut packet = ParsedTransportHeaderMut::<I>::parse_in_ip_packet(P::proto::<I>(), view)
3973 .expect("parse transport header");
3974 let expected_src_port = if update_src_port {
3975 packet.set_src_port(SRC_PORT_2);
3976 SRC_PORT_2
3977 } else {
3978 SRC_PORT
3979 };
3980 let expected_dst_port = if update_dst_port {
3981 packet.set_dst_port(DST_PORT_2);
3982 DST_PORT_2
3983 } else {
3984 DST_PORT
3985 };
3986 drop(packet);
3987
3988 let equivalent = P::make_packet_with_ports::<I>(
3989 I::SRC_IP,
3990 I::DST_IP,
3991 expected_src_port,
3992 expected_dst_port,
3993 );
3994
3995 assert_eq!(equivalent, buf);
3996 }
3997
3998 #[ip_test(I)]
3999 #[test_case(PhantomData::<Udp>)]
4000 #[test_case(PhantomData::<Tcp>)]
4001 fn serializer_update_src_dst_port_updates_checksum<I: TestIpExt, P: Protocol>(
4002 _proto: PhantomData<P>,
4003 ) {
4004 let mut serializer =
4005 P::make_serializer_with_ports::<I>(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT);
4006 let mut packet =
4007 serializer.transport_packet_mut().expect("packet should support rewriting");
4008 packet.set_src_port(SRC_PORT_2);
4009 packet.set_dst_port(DST_PORT_2);
4010 drop(packet);
4011
4012 let equivalent =
4013 P::make_serializer_with_ports::<I>(I::SRC_IP, I::DST_IP, SRC_PORT_2, DST_PORT_2);
4014
4015 assert_eq!(equivalent, serializer);
4016 }
4017
4018 #[ip_test(I)]
4019 fn icmp_echo_request_update_id_port_updates_checksum<I: TestIpExt>() {
4020 let mut serializer = IcmpPacketBuilder::<I, _>::new(
4021 I::SRC_IP,
4022 I::DST_IP,
4023 IcmpZeroCode,
4024 icmp::IcmpEchoRequest::new(SRC_PORT.get(), 0),
4025 )
4026 .wrap_body(EmptyBuf);
4027 serializer
4028 .transport_packet_mut()
4029 .expect("packet should support rewriting")
4030 .set_src_port(SRC_PORT_2);
4031
4032 let equivalent = IcmpPacketBuilder::<I, _>::new(
4033 I::SRC_IP,
4034 I::DST_IP,
4035 IcmpZeroCode,
4036 icmp::IcmpEchoRequest::new(SRC_PORT_2.get(), 0),
4037 )
4038 .wrap_body(EmptyBuf);
4039
4040 assert_eq!(equivalent, serializer);
4041 }
4042
4043 #[ip_test(I)]
4044 fn icmp_echo_reply_update_id_port_updates_checksum<I: TestIpExt>() {
4045 let mut serializer = IcmpPacketBuilder::<I, _>::new(
4046 I::SRC_IP,
4047 I::DST_IP,
4048 IcmpZeroCode,
4049 icmp::IcmpEchoReply::new(SRC_PORT.get(), 0),
4050 )
4051 .wrap_body(EmptyBuf);
4052 serializer
4053 .transport_packet_mut()
4054 .expect("packet should support rewriting")
4055 .set_dst_port(SRC_PORT_2);
4056
4057 let equivalent = IcmpPacketBuilder::<I, _>::new(
4058 I::SRC_IP,
4059 I::DST_IP,
4060 IcmpZeroCode,
4061 icmp::IcmpEchoReply::new(SRC_PORT_2.get(), 0),
4062 )
4063 .wrap_body(EmptyBuf);
4064
4065 assert_eq!(equivalent, serializer);
4066 }
4067
4068 fn ip_packet<I: FilterIpExt, P: Protocol>(src: I::Addr, dst: I::Addr) -> Buf<Vec<u8>> {
4069 Buf::new(P::make_packet::<I>(src, dst), ..)
4070 .wrap_in(I::PacketBuilder::new(src, dst, u8::MAX, P::proto::<I>()))
4071 .serialize_vec_outer()
4072 .expect("serialize IP packet")
4073 .unwrap_b()
4074 }
4075
4076 #[ip_test(I)]
4077 #[test_matrix(
4078 [
4079 PhantomData::<Udp>,
4080 PhantomData::<Tcp>,
4081 PhantomData::<IcmpEchoRequest>,
4082 ],
4083 [
4084 PacketType::FullyParsed,
4085 PacketType::Raw
4086 ]
4087 )]
4088 fn ip_packet_set_src_dst_addr_updates_checksums<I: TestIpExt, P: Protocol>(
4089 _proto: PhantomData<P>,
4090 packet_type: PacketType,
4091 ) where
4092 for<'a> I::Packet<&'a mut [u8]>: IpPacket<I>,
4093 for<'a> I::PacketRaw<&'a mut [u8]>: IpPacket<I>,
4094 {
4095 let mut buf = ip_packet::<I, P>(I::SRC_IP, I::DST_IP).into_inner();
4096
4097 match packet_type {
4098 PacketType::FullyParsed => {
4099 let mut packet = I::Packet::parse_mut(SliceBufViewMut::new(&mut buf), ())
4100 .expect("parse IP packet");
4101 packet.set_src_addr(I::SRC_IP_2);
4102 packet.set_dst_addr(I::DST_IP_2);
4103 }
4104 PacketType::Raw => {
4105 let mut packet = I::PacketRaw::parse_mut(SliceBufViewMut::new(&mut buf), ())
4106 .expect("parse IP packet");
4107 packet.set_src_addr(I::SRC_IP_2);
4108 packet.set_dst_addr(I::DST_IP_2);
4109 }
4110 }
4111
4112 let equivalent = ip_packet::<I, P>(I::SRC_IP_2, I::DST_IP_2).into_inner();
4113
4114 assert_eq!(equivalent, buf);
4115 }
4116
4117 #[ip_test(I)]
4118 #[test_case(PhantomData::<Udp>)]
4119 #[test_case(PhantomData::<Tcp>)]
4120 #[test_case(PhantomData::<IcmpEchoRequest>)]
4121 fn forwarded_packet_set_src_dst_addr_updates_checksums<I: TestIpExt, P: Protocol>(
4122 _proto: PhantomData<P>,
4123 ) {
4124 let mut buffer = ip_packet::<I, P>(I::SRC_IP, I::DST_IP);
4125 let meta = buffer.parse::<I::Packet<_>>().expect("parse IP packet").parse_metadata();
4126 let mut packet =
4127 ForwardedPacket::<I, _>::new(I::SRC_IP, I::DST_IP, P::proto::<I>(), meta, buffer);
4128 packet.set_src_addr(I::SRC_IP_2);
4129 packet.set_dst_addr(I::DST_IP_2);
4130
4131 let mut buffer = ip_packet::<I, P>(I::SRC_IP_2, I::DST_IP_2);
4132 let meta = buffer.parse::<I::Packet<_>>().expect("parse IP packet").parse_metadata();
4133 let equivalent =
4134 ForwardedPacket::<I, _>::new(I::SRC_IP_2, I::DST_IP_2, P::proto::<I>(), meta, buffer);
4135
4136 assert_eq!(equivalent, packet);
4137 }
4138
4139 #[ip_test(I)]
4140 #[test_case(PhantomData::<Udp>)]
4141 #[test_case(PhantomData::<Tcp>)]
4142 #[test_case(PhantomData::<IcmpEchoRequest>)]
4143 fn tx_packet_set_src_dst_addr_updates_checksums<I: TestIpExt, P: Protocol>(
4144 _proto: PhantomData<P>,
4145 ) {
4146 let mut body = P::make_serializer::<I>(I::SRC_IP, I::DST_IP);
4147 let mut packet = TxPacket::<I, _>::new(I::SRC_IP, I::DST_IP, P::proto::<I>(), &mut body);
4148 packet.set_src_addr(I::SRC_IP_2);
4149 packet.set_dst_addr(I::DST_IP_2);
4150
4151 let mut equivalent_body = P::make_serializer::<I>(I::SRC_IP_2, I::DST_IP_2);
4152 let equivalent =
4153 TxPacket::new(I::SRC_IP_2, I::DST_IP_2, P::proto::<I>(), &mut equivalent_body);
4154
4155 assert_eq!(equivalent, packet);
4156 }
4157
4158 #[ip_test(I)]
4159 #[test_case(PhantomData::<Udp>)]
4160 #[test_case(PhantomData::<Tcp>)]
4161 #[test_case(PhantomData::<IcmpEchoRequest>)]
4162 fn nested_serializer_set_src_dst_addr_updates_checksums<I: TestIpExt, P: Protocol>(
4163 _proto: PhantomData<P>,
4164 ) {
4165 let mut packet =
4166 I::PacketBuilder::new(I::SRC_IP, I::DST_IP, u8::MAX, P::proto::<I>())
4167 .wrap_body(P::make_serializer::<I>(I::SRC_IP, I::DST_IP));
4168 packet.set_src_addr(I::SRC_IP_2);
4169 packet.set_dst_addr(I::DST_IP_2);
4170
4171 let equivalent =
4172 P::make_serializer::<I>(I::SRC_IP_2, I::DST_IP_2).wrap_in(I::PacketBuilder::new(
4173 I::SRC_IP_2,
4174 I::DST_IP_2,
4175 u8::MAX,
4176 P::proto::<I>(),
4177 ));
4178
4179 assert_eq!(equivalent, packet);
4180 }
4181
4182 #[ip_test(I)]
4183 #[test_matrix(
4184 [
4185 PhantomData::<Udp>,
4186 PhantomData::<Tcp>,
4187 PhantomData::<IcmpEchoRequest>,
4188 ],
4189 [
4190 PacketType::FullyParsed,
4191 PacketType::Raw
4192 ]
4193 )]
4194 fn no_icmp_error_for_normal_ip_packet<I: TestIpExt, P: Protocol>(
4195 _proto: PhantomData<P>,
4196 packet_type: PacketType,
4197 ) where
4198 for<'a> I::Packet<&'a mut [u8]>: IpPacket<I>,
4199 for<'a> I::PacketRaw<&'a mut [u8]>: IpPacket<I>,
4200 {
4201 let mut buf = ip_packet::<I, P>(I::SRC_IP, I::DST_IP).into_inner();
4202 let icmp_error = match packet_type {
4203 PacketType::FullyParsed => {
4204 let packet = I::Packet::parse_mut(SliceBufViewMut::new(&mut buf), ())
4205 .expect("parse IP packet");
4206 let icmp_payload = packet.maybe_icmp_error().icmp_error_payload();
4207
4208 icmp_payload
4209 }
4210 PacketType::Raw => {
4211 let packet = I::PacketRaw::parse_mut(SliceBufViewMut::new(&mut buf), ())
4212 .expect("parse IP packet");
4213 let icmp_payload = packet.maybe_icmp_error().icmp_error_payload();
4214
4215 icmp_payload
4216 }
4217 };
4218
4219 assert_matches!(icmp_error, None);
4220 }
4221
4222 #[ip_test(I)]
4223 #[test_matrix(
4224 [
4225 PhantomData::<Udp>,
4226 PhantomData::<Tcp>,
4227 PhantomData::<IcmpEchoRequest>,
4228 ],
4229 [
4230 PacketType::FullyParsed,
4231 PacketType::Raw
4232 ]
4233 )]
4234 fn no_icmp_error_mut_for_normal_ip_packet<I: TestIpExt, P: Protocol>(
4235 _proto: PhantomData<P>,
4236 packet_type: PacketType,
4237 ) where
4238 for<'a> I::Packet<&'a mut [u8]>: IpPacket<I>,
4239 for<'a> I::PacketRaw<&'a mut [u8]>: IpPacket<I>,
4240 {
4241 let mut buf = ip_packet::<I, P>(I::SRC_IP, I::DST_IP).into_inner();
4242 match packet_type {
4243 PacketType::FullyParsed => {
4244 let mut packet = I::Packet::parse_mut(SliceBufViewMut::new(&mut buf), ())
4245 .expect("parse IP packet");
4246 assert!(packet.icmp_error_mut().icmp_error_mut().is_none());
4247 }
4248 PacketType::Raw => {
4249 let mut packet = I::PacketRaw::parse_mut(SliceBufViewMut::new(&mut buf), ())
4250 .expect("parse IP packet");
4251 assert!(packet.icmp_error_mut().icmp_error_mut().is_none());
4252 }
4253 }
4254 }
4255
4256 #[ip_test(I)]
4257 #[test_case(TransportPacketDataProtocol::Udp)]
4258 #[test_case(TransportPacketDataProtocol::Tcp)]
4259 #[test_case(TransportPacketDataProtocol::IcmpEchoRequest)]
4260 fn no_icmp_error_for_normal_bytes<I: TestIpExt>(proto: TransportPacketDataProtocol) {
4261 let buf = proto.make_packet::<I>(I::SRC_IP, I::DST_IP);
4262
4263 assert_matches!(
4264 ParsedIcmpErrorPayload::<I>::parse_in_outer_ip_packet(
4265 proto.proto::<I>(),
4266 buf.as_slice(),
4267 ),
4268 None
4269 );
4270 }
4271
4272 #[ip_test(I)]
4273 #[test_case(TransportPacketDataProtocol::Udp)]
4274 #[test_case(TransportPacketDataProtocol::Tcp)]
4275 #[test_case(TransportPacketDataProtocol::IcmpEchoRequest)]
4276 fn no_icmp_error_mut_for_normal_bytes<I: TestIpExt>(proto: TransportPacketDataProtocol) {
4277 let mut buf = proto.make_packet::<I>(I::SRC_IP, I::DST_IP);
4278
4279 assert!(
4280 ParsedIcmpErrorMut::<I>::parse_in_ip_packet(
4281 I::SRC_IP,
4282 I::DST_IP,
4283 proto.proto::<I>(),
4284 SliceBufViewMut::new(&mut buf),
4285 )
4286 .is_none()
4287 );
4288 }
4289
4290 #[ip_test(I)]
4291 #[test_case(PhantomData::<Udp>)]
4292 #[test_case(PhantomData::<Tcp>)]
4293 #[test_case(PhantomData::<IcmpEchoRequest>)]
4294 fn no_icmp_error_for_normal_serializer<I: TestIpExt, P: Protocol>(_proto: PhantomData<P>) {
4295 let serializer =
4296 P::make_serializer_with_ports::<I>(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT);
4297
4298 assert_matches!(serializer.icmp_error_payload(), None);
4299 }
4300
4301 #[ip_test(I)]
4302 #[test_case(PhantomData::<Udp>)]
4303 #[test_case(PhantomData::<Tcp>)]
4304 #[test_case(PhantomData::<IcmpEchoRequest>)]
4305 fn no_icmp_error_mut_for_normal_serializer<I: TestIpExt, P: Protocol>(_proto: PhantomData<P>) {
4306 let mut serializer =
4307 P::make_serializer_with_ports::<I>(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT);
4308
4309 assert!(serializer.icmp_error_mut().is_none());
4310 }
4311
4312 #[test_matrix(
4313 [
4314 PhantomData::<Icmpv4DestUnreachableError>,
4315 PhantomData::<Icmpv6DestUnreachableError>,
4316 ],
4317 [
4318 TransportPacketDataProtocol::Udp,
4319 TransportPacketDataProtocol::Tcp,
4320 TransportPacketDataProtocol::IcmpEchoRequest,
4321 ],
4322 [
4323 PacketType::FullyParsed,
4324 PacketType::Raw,
4325 ],
4326 [
4327 false,
4328 true,
4329 ]
4330 )]
4331 fn icmp_error_from_bytes<I: TestIpExt, IE: IcmpErrorMessage<I>>(
4332 _icmp_error: PhantomData<IE>,
4333 proto: TransportPacketDataProtocol,
4334 packet_type: PacketType,
4335 truncate_message: bool,
4336 ) {
4337 let serializer = IE::make_serializer_truncated(
4338 I::DST_IP_2,
4339 I::SRC_IP,
4340 proto.make_ip_packet_with_ports_data::<I>(
4341 I::SRC_IP,
4342 I::DST_IP,
4343 SRC_PORT,
4344 DST_PORT,
4345 &[0xAB; 5000],
4346 ),
4347 truncate_message.then_some(1280),
4352 )
4353 .wrap_in(I::PacketBuilder::new(I::DST_IP_2, I::SRC_IP, u8::MAX, IE::proto()));
4354
4355 let mut bytes: Buf<Vec<u8>> = serializer.serialize_vec_outer().unwrap().unwrap_b();
4356 let icmp_payload = match packet_type {
4357 PacketType::FullyParsed => {
4358 let packet = I::as_filter_packet_owned(bytes.parse_mut::<I::Packet<_>>().unwrap());
4359 let icmp_payload =
4360 packet.maybe_icmp_error().icmp_error_payload().expect("no ICMP error found");
4361
4362 icmp_payload
4363 }
4364 PacketType::Raw => {
4365 let packet =
4366 I::as_filter_packet_raw_owned(bytes.parse_mut::<I::PacketRaw<_>>().unwrap());
4367 let icmp_payload =
4368 packet.maybe_icmp_error().icmp_error_payload().expect("no ICMP error found");
4369
4370 icmp_payload
4371 }
4372 };
4373
4374 let expected = match proto {
4375 TransportPacketDataProtocol::Tcp | TransportPacketDataProtocol::Udp => {
4376 ParsedIcmpErrorPayload {
4377 src_ip: I::SRC_IP,
4378 dst_ip: I::DST_IP,
4379 src_port: SRC_PORT.get(),
4380 dst_port: DST_PORT.get(),
4381 proto: proto.proto::<I>(),
4382 }
4383 }
4384 TransportPacketDataProtocol::IcmpEchoRequest => {
4385 ParsedIcmpErrorPayload {
4386 src_ip: I::SRC_IP,
4387 dst_ip: I::DST_IP,
4388 src_port: SRC_PORT.get(),
4391 dst_port: SRC_PORT.get(),
4392 proto: proto.proto::<I>(),
4393 }
4394 }
4395 };
4396
4397 assert_eq!(icmp_payload, expected);
4398 }
4399
4400 #[test_matrix(
4401 [
4402 PhantomData::<Icmpv4DestUnreachableError>,
4403 PhantomData::<Icmpv6DestUnreachableError>,
4404 ],
4405 [
4406 TransportPacketDataProtocol::Udp,
4407 TransportPacketDataProtocol::Tcp,
4408 TransportPacketDataProtocol::IcmpEchoRequest,
4409 ],
4410 [
4411 false,
4412 true,
4413 ]
4414 )]
4415 fn icmp_error_from_serializer<I: TestIpExt, IE: IcmpErrorMessage<I>>(
4416 _icmp_error: PhantomData<IE>,
4417 proto: TransportPacketDataProtocol,
4418 truncate_message: bool,
4419 ) {
4420 let serializer = IE::make_serializer_truncated(
4421 I::DST_IP_2,
4422 I::SRC_IP,
4423 proto.make_ip_packet_with_ports_data::<I>(
4424 I::SRC_IP,
4425 I::DST_IP,
4426 SRC_PORT,
4427 DST_PORT,
4428 &[0xAB; 5000],
4429 ),
4430 truncate_message.then_some(1280),
4435 );
4436
4437 let actual =
4438 serializer.icmp_error_payload().expect("serializer should contain an IP packet");
4439
4440 let expected = match proto {
4441 TransportPacketDataProtocol::Tcp | TransportPacketDataProtocol::Udp => {
4442 ParsedIcmpErrorPayload::<I> {
4443 src_ip: I::SRC_IP,
4444 dst_ip: I::DST_IP,
4445 src_port: SRC_PORT.get(),
4446 dst_port: DST_PORT.get(),
4447 proto: proto.proto::<I>(),
4448 }
4449 }
4450 TransportPacketDataProtocol::IcmpEchoRequest => ParsedIcmpErrorPayload::<I> {
4451 src_ip: I::SRC_IP,
4452 dst_ip: I::DST_IP,
4453 src_port: SRC_PORT.get(),
4456 dst_port: SRC_PORT.get(),
4457 proto: proto.proto::<I>(),
4458 },
4459 };
4460
4461 assert_eq!(actual, expected);
4462 }
4463
4464 #[test_matrix(
4465 [
4466 PhantomData::<Icmpv4DestUnreachableError>,
4467 PhantomData::<Icmpv6DestUnreachableError>,
4468 ],
4469 [
4470 TransportPacketDataProtocol::Udp,
4471 TransportPacketDataProtocol::Tcp,
4472 TransportPacketDataProtocol::IcmpEchoRequest,
4473 ],
4474 [
4475 PacketType::FullyParsed,
4476 PacketType::Raw,
4477 ],
4478 [
4479 false,
4480 true,
4481 ]
4482 )]
4483 fn conntrack_packet_icmp_error_from_bytes<I: TestIpExt, IE: IcmpErrorMessage<I>>(
4484 _icmp_error: PhantomData<IE>,
4485 proto: TransportPacketDataProtocol,
4486 packet_type: PacketType,
4487 truncate_message: bool,
4488 ) {
4489 let serializer = IE::make_serializer_truncated(
4490 I::DST_IP_2,
4491 I::SRC_IP,
4492 proto.make_ip_packet_with_ports_data::<I>(
4493 I::SRC_IP,
4494 I::DST_IP,
4495 SRC_PORT,
4496 DST_PORT,
4497 &[0xAB; 5000],
4498 ),
4499 truncate_message.then_some(1280),
4504 )
4505 .wrap_in(I::PacketBuilder::new(I::DST_IP_2, I::SRC_IP, u8::MAX, IE::proto()));
4506
4507 let mut bytes: Buf<Vec<u8>> = serializer.serialize_vec_outer().unwrap().unwrap_b();
4508
4509 let conntrack_packet = match packet_type {
4510 PacketType::FullyParsed => {
4511 let packet = I::as_filter_packet_owned(bytes.parse_mut::<I::Packet<_>>().unwrap());
4512 packet.conntrack_packet().unwrap()
4513 }
4514 PacketType::Raw => {
4515 let packet =
4516 I::as_filter_packet_raw_owned(bytes.parse_mut::<I::PacketRaw<_>>().unwrap());
4517 packet.conntrack_packet().unwrap()
4518 }
4519 };
4520
4521 let expected = match proto {
4522 TransportPacketDataProtocol::Tcp | TransportPacketDataProtocol::Udp => {
4523 conntrack::PacketMetadata::new_from_icmp_error(
4524 I::SRC_IP,
4525 I::DST_IP,
4526 SRC_PORT.get(),
4527 DST_PORT.get(),
4528 I::map_ip(proto.proto::<I>(), |proto| proto.into(), |proto| proto.into()),
4529 )
4530 }
4531 TransportPacketDataProtocol::IcmpEchoRequest => {
4532 conntrack::PacketMetadata::new_from_icmp_error(
4533 I::SRC_IP,
4534 I::DST_IP,
4535 SRC_PORT.get(),
4538 SRC_PORT.get(),
4539 I::map_ip(proto.proto::<I>(), |proto| proto.into(), |proto| proto.into()),
4540 )
4541 }
4542 };
4543
4544 assert_eq!(conntrack_packet, expected);
4545 }
4546
4547 #[test_matrix(
4548 [
4549 PhantomData::<Icmpv4DestUnreachableError>,
4550 PhantomData::<Icmpv6DestUnreachableError>,
4551 ],
4552 [
4553 TransportPacketDataProtocol::Udp,
4554 TransportPacketDataProtocol::Tcp,
4555 TransportPacketDataProtocol::IcmpEchoRequest,
4556 ],
4557 [
4558 PacketType::FullyParsed,
4559 PacketType::Raw,
4560 ],
4561 [
4562 false,
4563 true,
4564 ]
4565 )]
4566 fn no_conntrack_packet_for_incompatible_outer_and_payload<
4567 I: TestIpExt,
4568 IE: IcmpErrorMessage<I>,
4569 >(
4570 _icmp_error: PhantomData<IE>,
4571 proto: TransportPacketDataProtocol,
4572 packet_type: PacketType,
4573 truncate_message: bool,
4574 ) {
4575 let serializer = IE::make_serializer_truncated(
4581 I::DST_IP_2,
4582 I::SRC_IP_2,
4583 proto.make_ip_packet_with_ports_data::<I>(
4584 I::SRC_IP,
4585 I::DST_IP,
4586 SRC_PORT,
4587 DST_PORT,
4588 &[0xAB; 5000],
4589 ),
4590 truncate_message.then_some(1280),
4595 )
4596 .wrap_in(I::PacketBuilder::new(I::DST_IP_2, I::SRC_IP_2, u8::MAX, IE::proto()));
4597
4598 let mut bytes: Buf<Vec<u8>> = serializer.serialize_vec_outer().unwrap().unwrap_b();
4599
4600 let conntrack_packet = match packet_type {
4601 PacketType::FullyParsed => {
4602 let packet = I::as_filter_packet_owned(bytes.parse_mut::<I::Packet<_>>().unwrap());
4603 packet.conntrack_packet()
4604 }
4605 PacketType::Raw => {
4606 let packet =
4607 I::as_filter_packet_raw_owned(bytes.parse_mut::<I::PacketRaw<_>>().unwrap());
4608 packet.conntrack_packet()
4609 }
4610 };
4611
4612 assert_matches!(conntrack_packet, None);
4615 }
4616
4617 #[test_matrix(
4618 [
4619 PhantomData::<Icmpv4DestUnreachableError>,
4620 PhantomData::<Icmpv6DestUnreachableError>,
4621 ],
4622 [
4623 TransportPacketDataProtocol::Udp,
4624 TransportPacketDataProtocol::Tcp,
4625 TransportPacketDataProtocol::IcmpEchoRequest,
4626 ],
4627 [
4628 false,
4629 true,
4630 ]
4631 )]
4632 fn icmp_error_mut_from_serializer<I: TestIpExt, IE: IcmpErrorMessage<I>>(
4633 _icmp_error: PhantomData<IE>,
4634 proto: TransportPacketDataProtocol,
4635 truncate_message: bool,
4636 ) where
4637 for<'a> I::Packet<&'a mut [u8]>: IpPacket<I>,
4638 {
4639 const LEN: usize = 5000;
4640
4641 let mut payload_bytes = proto.make_ip_packet_with_ports_data::<I>(
4642 I::SRC_IP,
4643 I::DST_IP,
4644 SRC_PORT,
4645 DST_PORT,
4646 &[0xAB; LEN],
4647 );
4648
4649 if truncate_message {
4652 payload_bytes.truncate(1280);
4653 }
4654
4655 let mut serializer = IE::make_serializer(I::SRC_IP, I::DST_IP, payload_bytes)
4656 .wrap_in(I::PacketBuilder::new(I::SRC_IP, I::DST_IP, u8::MAX, IE::proto()));
4657
4658 {
4659 let mut icmp_packet = serializer
4660 .icmp_error_mut()
4661 .icmp_error_mut()
4662 .expect("couldn't find an inner ICMP error");
4663
4664 {
4665 let mut inner_packet = icmp_packet.inner_packet().expect("no inner packet");
4666
4667 inner_packet.set_src_addr(I::SRC_IP_2);
4668 inner_packet.set_dst_addr(I::DST_IP_2);
4669 }
4670
4671 assert!(icmp_packet.recalculate_checksum());
4674 }
4675
4676 let mut expected_payload_bytes = proto.make_ip_packet_with_ports_data::<I>(
4677 I::SRC_IP_2,
4678 I::DST_IP_2,
4679 SRC_PORT,
4680 DST_PORT,
4681 &[0xAB; LEN],
4682 );
4683
4684 if truncate_message {
4687 expected_payload_bytes.truncate(1280);
4688 }
4689
4690 let expected_serializer = IE::make_serializer(I::SRC_IP, I::DST_IP, expected_payload_bytes)
4691 .wrap_in(I::PacketBuilder::new(I::SRC_IP, I::DST_IP, u8::MAX, IE::proto()));
4694
4695 let actual_bytes = serializer.serialize_vec_outer().unwrap().unwrap_b();
4696 let expected_bytes = expected_serializer.serialize_vec_outer().unwrap().unwrap_b();
4697
4698 assert_eq!(actual_bytes, expected_bytes);
4699 }
4700
4701 #[test_matrix(
4702 [
4703 PhantomData::<Icmpv4DestUnreachableError>,
4704 PhantomData::<Icmpv6DestUnreachableError>,
4705 ],
4706 [
4707 TransportPacketDataProtocol::Udp,
4708 TransportPacketDataProtocol::Tcp,
4709 TransportPacketDataProtocol::IcmpEchoRequest,
4710 ],
4711 [
4712 PacketType::FullyParsed,
4713 PacketType::Raw,
4714 ],
4715 [
4716 false,
4717 true,
4718 ]
4719 )]
4720 fn icmp_error_mut_from_bytes<I: TestIpExt, IE: IcmpErrorMessage<I>>(
4721 _icmp_error: PhantomData<IE>,
4722 proto: TransportPacketDataProtocol,
4723 packet_type: PacketType,
4724 truncate_message: bool,
4725 ) where
4726 for<'a> I::Packet<&'a mut [u8]>: IpPacket<I>,
4727 {
4728 const LEN: usize = 5000;
4729
4730 let mut payload_bytes = proto.make_ip_packet_with_ports_data::<I>(
4731 I::SRC_IP,
4732 I::DST_IP,
4733 SRC_PORT,
4734 DST_PORT,
4735 &[0xAB; LEN],
4736 );
4737
4738 if truncate_message {
4741 payload_bytes.truncate(1280);
4742 }
4743
4744 let serializer = IE::make_serializer(I::SRC_IP, I::DST_IP, payload_bytes)
4745 .wrap_in(I::PacketBuilder::new(I::SRC_IP, I::DST_IP, u8::MAX, IE::proto()));
4746
4747 let mut bytes = serializer.serialize_vec_outer().unwrap().unwrap_b().into_inner();
4748
4749 {
4750 fn modify_packet<I: TestIpExt, P: IpPacket<I>>(mut packet: P) {
4751 let mut icmp_error = packet.icmp_error_mut();
4752 let mut icmp_error =
4753 icmp_error.icmp_error_mut().expect("couldn't find an inner ICMP error");
4754
4755 {
4756 let mut inner_packet = icmp_error.inner_packet().expect("no inner packet");
4757
4758 inner_packet.set_src_addr(I::SRC_IP_2);
4759 inner_packet.set_dst_addr(I::DST_IP_2);
4760 }
4761
4762 assert!(icmp_error.recalculate_checksum());
4763 }
4764
4765 let mut bytes = Buf::new(&mut bytes, ..);
4766
4767 match packet_type {
4768 PacketType::FullyParsed => {
4769 let packet =
4770 I::as_filter_packet_owned(bytes.parse_mut::<I::Packet<_>>().unwrap());
4771 modify_packet(packet);
4772 }
4773 PacketType::Raw => {
4774 let packet = I::as_filter_packet_raw_owned(
4775 bytes.parse_mut::<I::PacketRaw<_>>().unwrap(),
4776 );
4777 modify_packet(packet);
4778 }
4779 }
4780 }
4781
4782 let mut expected_payload_bytes = proto.make_ip_packet_with_ports_data::<I>(
4783 I::SRC_IP_2,
4784 I::DST_IP_2,
4785 SRC_PORT,
4786 DST_PORT,
4787 &[0xAB; LEN],
4788 );
4789
4790 if truncate_message {
4791 expected_payload_bytes.truncate(1280);
4792 }
4793
4794 let expected_serializer = IE::make_serializer(I::SRC_IP, I::DST_IP, expected_payload_bytes)
4795 .wrap_in(I::PacketBuilder::new(I::SRC_IP, I::DST_IP, u8::MAX, IE::proto()));
4798
4799 let expected_bytes =
4800 expected_serializer.serialize_vec_outer().unwrap().unwrap_b().into_inner();
4801
4802 assert_eq!(bytes, expected_bytes);
4803 }
4804
4805 #[ip_test(I)]
4806 #[test_case(PhantomData::<Udp>)]
4807 #[test_case(PhantomData::<Tcp>)]
4808 #[test_case(PhantomData::<IcmpEchoRequest>)]
4809 fn tx_packet_partial_serialize<I: TestIpExt, P: Protocol>(_proto: PhantomData<P>) {
4810 const DATA: &[u8] = b"Packet Body";
4811 let mut body =
4812 P::make_serializer_with_ports_data::<I>(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, DATA);
4813 let packet = TxPacket::<I, _>::new(I::SRC_IP, I::DST_IP, P::proto::<I>(), &mut body);
4814
4815 let mut buf = [0u8; 128];
4816 let result = PartialSerializer::partial_serialize(
4817 &packet,
4818 PacketConstraints::UNCONSTRAINED,
4819 &mut buf,
4820 )
4821 .unwrap();
4822
4823 let whole_packet =
4824 P::make_serializer_with_ports_data::<I>(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, DATA)
4825 .wrap_in(I::PacketBuilder::new(
4826 I::SRC_IP,
4827 I::DST_IP,
4828 TX_PACKET_NO_TTL,
4829 P::proto::<I>(),
4830 ))
4831 .serialize_vec_outer()
4832 .expect("serialize packet")
4833 .unwrap_b()
4834 .into_inner();
4835
4836 assert_eq!(result.total_size, whole_packet.len());
4837 assert_eq!(result.bytes_written, I::MIN_HEADER_LENGTH + P::HEADER_SIZE);
4838
4839 let num_bytes_differ = buf[..result.bytes_written]
4842 .iter()
4843 .zip(whole_packet[..result.bytes_written].iter())
4844 .map(|(a, b)| if a != b { 1 } else { 0 })
4845 .sum::<usize>();
4846
4847 let checksum_bytes = I::map_ip((), |()| 4, |()| 2);
4852 assert!(num_bytes_differ <= checksum_bytes);
4853 }
4854}