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