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