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