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