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 reassembled: bool,
1256}
1257
1258impl<I: IpExt, B: BufferMut> ForwardedPacket<I, B> {
1259 pub fn new(
1266 src_addr: I::Addr,
1267 dst_addr: I::Addr,
1268 protocol: I::Proto,
1269 meta: ParseMetadata,
1270 mut buffer: B,
1271 reassembled: bool,
1272 ) -> Self {
1273 let transport_header_offset = meta.header_len();
1274 buffer.undo_parse(meta);
1275 Self { src_addr, dst_addr, protocol, transport_header_offset, buffer, reassembled }
1276 }
1277
1278 pub fn reassembled(&self) -> bool {
1280 self.reassembled
1281 }
1282
1283 pub fn into_buffer(self) -> B {
1289 self.buffer
1290 }
1291
1292 pub fn buffer(&self) -> &B {
1297 &self.buffer
1298 }
1299}
1300
1301impl<I: IpExt, B: BufferMut + NetworkSerializer> Serializer<NetworkSerializationContext>
1302 for ForwardedPacket<I, B>
1303{
1304 type Buffer = <B as Serializer<NetworkSerializationContext>>::Buffer;
1305
1306 fn serialize<G: packet::GrowBufferMut, P: packet::BufferProvider<Self::Buffer, G>>(
1307 self,
1308 context: &mut NetworkSerializationContext,
1309 constraints: packet::PacketConstraints,
1310 provider: P,
1311 ) -> Result<G, (packet::SerializeError<P::Error>, Self)> {
1312 let Self { src_addr, dst_addr, protocol, transport_header_offset, buffer, reassembled } =
1313 self;
1314 buffer.serialize(context, constraints, provider).map_err(|(err, buffer)| {
1315 (
1316 err,
1317 Self { src_addr, dst_addr, protocol, transport_header_offset, buffer, reassembled },
1318 )
1319 })
1320 }
1321
1322 fn serialize_new_buf<BB: GrowBufferMut, A: LayoutBufferAlloc<BB>>(
1323 &self,
1324 context: &mut NetworkSerializationContext,
1325 outer: packet::PacketConstraints,
1326 alloc: A,
1327 ) -> Result<BB, packet::SerializeError<A::Error>> {
1328 self.buffer.serialize_new_buf(context, outer, alloc)
1329 }
1330}
1331
1332impl<I: IpExt, B: BufferMut + NetworkSerializer> NestableSerializer for ForwardedPacket<I, B> {}
1333
1334impl<C: SerializationContext, I: IpExt, B: BufferMut> PartialSerializer<C>
1335 for ForwardedPacket<I, B>
1336{
1337 fn partial_serialize<BB: GrowBufferMut + ContiguousBuffer, A: LayoutBufferAlloc<BB>>(
1338 &self,
1339 _context: &mut C,
1340 _alloc: A,
1341 ) -> Result<PartialSerializeResult<'_, BB>, SerializeError<A::Error>> {
1342 Ok(PartialSerializeResult::Slice(self.buffer.as_ref()))
1343 }
1344
1345 fn partial_serialize_new_buf<BB: GrowBufferMut, A: LayoutBufferAlloc<BB>>(
1346 &self,
1347 _context: &mut C,
1348 constraints: PacketConstraints,
1349 alloc: A,
1350 ) -> Result<(BB, usize), SerializeError<A::Error>> {
1351 let bytes_to_copy = cmp::min(
1352 self.buffer.as_ref().len(),
1353 self.transport_header_offset + TRANSPORT_HEADER_MAX_SIZE,
1354 );
1355 let mut buffer = alloc.layout_alloc(constraints.header_len(), bytes_to_copy, 0)?;
1356 buffer.with_parts_mut(|_prefix, mut body, _suffix| {
1357 body.copy_from_slice(&self.buffer.as_ref()[..bytes_to_copy]);
1358 });
1359 Ok((buffer, self.buffer.as_ref().len()))
1360 }
1361}
1362
1363impl<I: FilterIpExt, B: BufferMut> IpPacket<I> for ForwardedPacket<I, B> {
1364 type TransportPacket<'a>
1365 = &'a Self
1366 where
1367 Self: 'a;
1368 type TransportPacketMut<'a>
1369 = Option<ParsedTransportHeaderMut<'a, I>>
1370 where
1371 Self: 'a;
1372 type IcmpError<'a>
1373 = &'a Self
1374 where
1375 Self: 'a;
1376
1377 type IcmpErrorMut<'a>
1378 = Option<ParsedIcmpErrorMut<'a, I>>
1379 where
1380 Self: 'a;
1381
1382 fn src_addr(&self) -> I::Addr {
1383 self.src_addr
1384 }
1385
1386 fn set_src_addr(&mut self, addr: I::Addr) {
1387 I::map_ip::<_, ()>(
1389 (IpInvariant(self.buffer.as_mut()), addr),
1390 |(IpInvariant(buffer), addr)| {
1391 let mut packet = Ipv4PacketRaw::parse_mut(SliceBufViewMut::new(buffer), ())
1392 .expect("ForwardedPacket must have been created from a valid IP packet");
1393 packet.set_src_ip_and_update_checksum(addr);
1394 },
1395 |(IpInvariant(buffer), addr)| {
1396 let mut packet = Ipv6PacketRaw::parse_mut(SliceBufViewMut::new(buffer), ())
1397 .expect("ForwardedPacket must have been created from a valid IP packet");
1398 packet.set_src_ip(addr);
1399 },
1400 );
1401
1402 let old = self.src_addr;
1403 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
1404 packet.update_pseudo_header_src_addr(old, addr);
1405 }
1406
1407 self.src_addr = addr;
1408 }
1409
1410 fn dst_addr(&self) -> I::Addr {
1411 self.dst_addr
1412 }
1413
1414 fn set_dst_addr(&mut self, addr: I::Addr) {
1415 I::map_ip::<_, ()>(
1417 (IpInvariant(self.buffer.as_mut()), addr),
1418 |(IpInvariant(buffer), addr)| {
1419 let mut packet = Ipv4PacketRaw::parse_mut(SliceBufViewMut::new(buffer), ())
1420 .expect("ForwardedPacket must have been created from a valid IP packet");
1421 packet.set_dst_ip_and_update_checksum(addr);
1422 },
1423 |(IpInvariant(buffer), addr)| {
1424 let mut packet = Ipv6PacketRaw::parse_mut(SliceBufViewMut::new(buffer), ())
1425 .expect("ForwardedPacket must have been created from a valid IP packet");
1426 packet.set_dst_ip(addr);
1427 },
1428 );
1429
1430 let old = self.dst_addr;
1431 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
1432 packet.update_pseudo_header_dst_addr(old, addr);
1433 }
1434
1435 self.dst_addr = addr;
1436 }
1437
1438 fn protocol(&self) -> Option<I::Proto> {
1439 Some(self.protocol)
1440 }
1441
1442 fn maybe_transport_packet(&self) -> Self::TransportPacket<'_> {
1443 self
1444 }
1445
1446 fn transport_packet_mut(&mut self) -> Self::TransportPacketMut<'_> {
1447 let ForwardedPacket {
1448 src_addr: _,
1449 dst_addr: _,
1450 protocol,
1451 buffer,
1452 transport_header_offset,
1453 reassembled: _,
1454 } = self;
1455 ParsedTransportHeaderMut::<I>::parse_in_ip_packet(
1456 *protocol,
1457 SliceBufViewMut::new(&mut buffer.as_mut()[*transport_header_offset..]),
1458 )
1459 }
1460
1461 fn maybe_icmp_error<'a>(&'a self) -> Self::IcmpError<'a> {
1462 self
1463 }
1464
1465 fn icmp_error_mut<'a>(&'a mut self) -> Self::IcmpErrorMut<'a> {
1466 let ForwardedPacket {
1467 src_addr,
1468 dst_addr,
1469 protocol,
1470 buffer,
1471 transport_header_offset,
1472 reassembled: _,
1473 } = self;
1474
1475 ParsedIcmpErrorMut::<I>::parse_in_ip_packet(
1476 *src_addr,
1477 *dst_addr,
1478 *protocol,
1479 SliceBufViewMut::new(&mut buffer.as_mut()[*transport_header_offset..]),
1480 )
1481 }
1482}
1483
1484impl<I: IpExt, B: BufferMut> MaybeTransportPacket for ForwardedPacket<I, B> {
1485 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1486 let ForwardedPacket {
1487 protocol,
1488 buffer,
1489 src_addr,
1490 dst_addr,
1491 transport_header_offset,
1492 reassembled: _,
1493 } = self;
1494 TransportPacketData::parse_in_ip_packet::<I, _>(
1495 *src_addr,
1496 *dst_addr,
1497 *protocol,
1498 Buf::new(&buffer.as_ref()[*transport_header_offset..], ..),
1499 )
1500 }
1501}
1502
1503impl<I: IpExt, B: BufferMut> MaybeIcmpErrorPayload<I> for ForwardedPacket<I, B> {
1504 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
1505 let Self {
1506 src_addr: _,
1507 dst_addr: _,
1508 protocol,
1509 transport_header_offset,
1510 buffer,
1511 reassembled: _,
1512 } = self;
1513 ParsedIcmpErrorPayload::parse_in_outer_ip_packet(
1514 *protocol,
1515 Buf::new(&buffer.as_ref()[*transport_header_offset..], ..),
1516 )
1517 }
1518}
1519
1520impl<
1521 I: FilterIpExt,
1522 S: TransportPacketSerializer<I>,
1523 B: IpPacketBuilder<NetworkSerializationContext, I>,
1524> IpPacket<I> for Nested<S, B>
1525{
1526 type TransportPacket<'a>
1527 = &'a S
1528 where
1529 Self: 'a;
1530 type TransportPacketMut<'a>
1531 = &'a mut S
1532 where
1533 Self: 'a;
1534 type IcmpError<'a>
1535 = &'a S
1536 where
1537 Self: 'a;
1538 type IcmpErrorMut<'a>
1539 = &'a mut S
1540 where
1541 Self: 'a;
1542
1543 fn src_addr(&self) -> I::Addr {
1544 self.outer().src_ip()
1545 }
1546
1547 fn set_src_addr(&mut self, addr: I::Addr) {
1548 let old = self.outer().src_ip();
1549 self.outer_mut().set_src_ip(addr);
1550 if let Some(mut packet) = self.transport_packet_mut().transport_packet_mut() {
1551 packet.update_pseudo_header_src_addr(old, addr);
1552 }
1553 }
1554
1555 fn dst_addr(&self) -> I::Addr {
1556 self.outer().dst_ip()
1557 }
1558
1559 fn set_dst_addr(&mut self, addr: I::Addr) {
1560 let old = self.outer().dst_ip();
1561 self.outer_mut().set_dst_ip(addr);
1562 if let Some(mut packet) = self.transport_packet_mut().transport_packet_mut() {
1563 packet.update_pseudo_header_dst_addr(old, addr);
1564 }
1565 }
1566
1567 fn protocol(&self) -> Option<I::Proto> {
1568 Some(self.outer().proto())
1569 }
1570
1571 fn maybe_transport_packet(&self) -> Self::TransportPacket<'_> {
1572 self.inner()
1573 }
1574
1575 fn transport_packet_mut(&mut self) -> Self::TransportPacketMut<'_> {
1576 self.inner_mut()
1577 }
1578
1579 fn maybe_icmp_error<'a>(&'a self) -> Self::IcmpError<'a> {
1580 self.inner()
1581 }
1582
1583 fn icmp_error_mut<'a>(&'a mut self) -> Self::IcmpErrorMut<'a> {
1584 self.inner_mut()
1585 }
1586}
1587
1588impl<I: IpExt, T: ?Sized> TransportPacketMut<I> for &mut T
1589where
1590 T: TransportPacketMut<I>,
1591{
1592 fn set_src_port(&mut self, port: NonZeroU16) {
1593 (*self).set_src_port(port);
1594 }
1595
1596 fn set_dst_port(&mut self, port: NonZeroU16) {
1597 (*self).set_dst_port(port);
1598 }
1599
1600 fn update_pseudo_header_src_addr(&mut self, old: I::Addr, new: I::Addr) {
1601 (*self).update_pseudo_header_src_addr(old, new);
1602 }
1603
1604 fn update_pseudo_header_dst_addr(&mut self, old: I::Addr, new: I::Addr) {
1605 (*self).update_pseudo_header_dst_addr(old, new);
1606 }
1607}
1608
1609impl<I: FilterIpExt> IpPacket<I> for Never {
1610 type TransportPacket<'a>
1611 = Never
1612 where
1613 Self: 'a;
1614 type TransportPacketMut<'a>
1615 = Never
1616 where
1617 Self: 'a;
1618 type IcmpError<'a>
1619 = Never
1620 where
1621 Self: 'a;
1622 type IcmpErrorMut<'a>
1623 = Never
1624 where
1625 Self: 'a;
1626
1627 fn src_addr(&self) -> I::Addr {
1628 match *self {}
1629 }
1630
1631 fn set_src_addr(&mut self, _addr: I::Addr) {
1632 match *self {}
1633 }
1634
1635 fn dst_addr(&self) -> I::Addr {
1636 match *self {}
1637 }
1638
1639 fn protocol(&self) -> Option<I::Proto> {
1640 match *self {}
1641 }
1642
1643 fn set_dst_addr(&mut self, _addr: I::Addr) {
1644 match *self {}
1645 }
1646
1647 fn maybe_transport_packet<'a>(&'a self) -> Self::TransportPacket<'a> {
1648 match *self {}
1649 }
1650
1651 fn transport_packet_mut<'a>(&'a mut self) -> Self::TransportPacketMut<'a> {
1652 match *self {}
1653 }
1654
1655 fn maybe_icmp_error<'a>(&'a self) -> Self::IcmpError<'a> {
1656 match *self {}
1657 }
1658
1659 fn icmp_error_mut<'a>(&'a mut self) -> Self::IcmpErrorMut<'a> {
1660 match *self {}
1661 }
1662}
1663
1664impl MaybeTransportPacket for Never {
1665 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1666 match *self {}
1667 }
1668}
1669
1670impl<I: IpExt> MaybeTransportPacketMut<I> for Never {
1671 type TransportPacketMut<'a>
1672 = Never
1673 where
1674 Self: 'a;
1675
1676 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1677 match *self {}
1678 }
1679}
1680
1681impl<I: IpExt> TransportPacketMut<I> for Never {
1682 fn set_src_port(&mut self, _: NonZeroU16) {
1683 match *self {}
1684 }
1685
1686 fn set_dst_port(&mut self, _: NonZeroU16) {
1687 match *self {}
1688 }
1689
1690 fn update_pseudo_header_src_addr(&mut self, _: I::Addr, _: I::Addr) {
1691 match *self {}
1692 }
1693
1694 fn update_pseudo_header_dst_addr(&mut self, _: I::Addr, _: I::Addr) {
1695 match *self {}
1696 }
1697}
1698
1699impl<I: IpExt> MaybeIcmpErrorPayload<I> for Never {
1700 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
1701 match *self {}
1702 }
1703}
1704
1705impl<I: FilterIpExt> MaybeIcmpErrorMut<I> for Never {
1706 type IcmpErrorMut<'a>
1707 = Never
1708 where
1709 Self: 'a;
1710
1711 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
1712 match *self {}
1713 }
1714}
1715
1716impl<I: FilterIpExt> IcmpErrorMut<I> for Never {
1717 type InnerPacket<'a>
1718 = Never
1719 where
1720 Self: 'a;
1721
1722 fn inner_packet<'a>(&'a mut self) -> Option<Self::InnerPacket<'a>> {
1723 match *self {}
1724 }
1725
1726 fn recalculate_checksum(&mut self) -> bool {
1727 match *self {}
1728 }
1729}
1730
1731impl<A: IpAddress, Inner> MaybeTransportPacket for Nested<Inner, UdpPacketBuilder<A>> {
1732 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1733 Some(TransportPacketData::Generic {
1734 src_port: self.outer().src_port().map_or(0, NonZeroU16::get),
1735 dst_port: self.outer().dst_port().map_or(0, NonZeroU16::get),
1736 })
1737 }
1738}
1739
1740impl<I: IpExt, Inner> MaybeTransportPacketMut<I> for Nested<Inner, UdpPacketBuilder<I::Addr>> {
1741 type TransportPacketMut<'a>
1742 = &'a mut Self
1743 where
1744 Self: 'a;
1745
1746 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1747 Some(self)
1748 }
1749}
1750
1751impl<I: IpExt, Inner> TransportPacketMut<I> for Nested<Inner, UdpPacketBuilder<I::Addr>> {
1752 fn set_src_port(&mut self, port: NonZeroU16) {
1753 self.outer_mut().set_src_port(port.get());
1754 }
1755
1756 fn set_dst_port(&mut self, port: NonZeroU16) {
1757 self.outer_mut().set_dst_port(port);
1758 }
1759
1760 fn update_pseudo_header_src_addr(&mut self, _old: I::Addr, new: I::Addr) {
1761 self.outer_mut().set_src_ip(new);
1762 }
1763
1764 fn update_pseudo_header_dst_addr(&mut self, _old: I::Addr, new: I::Addr) {
1765 self.outer_mut().set_dst_ip(new);
1766 }
1767}
1768
1769impl<A: IpAddress, I: IpExt, Inner> MaybeIcmpErrorPayload<I>
1770 for Nested<Inner, UdpPacketBuilder<A>>
1771{
1772 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
1773 None
1774 }
1775}
1776
1777impl<A: IpAddress, I: FilterIpExt, Inner> MaybeIcmpErrorMut<I>
1778 for Nested<Inner, UdpPacketBuilder<A>>
1779{
1780 type IcmpErrorMut<'a>
1781 = Never
1782 where
1783 Self: 'a;
1784
1785 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
1786 None
1787 }
1788}
1789
1790impl<'a, A: IpAddress, Inner: PayloadLen> MaybeTransportPacket
1791 for Nested<Inner, TcpSegmentBuilderWithOptions<A, TcpOptionsBuilder<'a>>>
1792{
1793 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1794 Some(TransportPacketData::Tcp {
1795 src_port: self.outer().src_port().map_or(0, NonZeroU16::get),
1796 dst_port: self.outer().dst_port().map_or(0, NonZeroU16::get),
1797 segment: self.outer().try_into().ok()?,
1798 payload_len: self.inner().len(),
1799 })
1800 }
1801}
1802
1803impl<I: IpExt, Outer, Inner> MaybeTransportPacketMut<I>
1804 for Nested<Inner, TcpSegmentBuilderWithOptions<I::Addr, Outer>>
1805{
1806 type TransportPacketMut<'a>
1807 = &'a mut Self
1808 where
1809 Self: 'a;
1810
1811 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1812 Some(self)
1813 }
1814}
1815
1816impl<I: IpExt, Outer, Inner> TransportPacketMut<I>
1817 for Nested<Inner, TcpSegmentBuilderWithOptions<I::Addr, Outer>>
1818{
1819 fn set_src_port(&mut self, port: NonZeroU16) {
1820 self.outer_mut().set_src_port(port);
1821 }
1822
1823 fn set_dst_port(&mut self, port: NonZeroU16) {
1824 self.outer_mut().set_dst_port(port);
1825 }
1826
1827 fn update_pseudo_header_src_addr(&mut self, _old: I::Addr, new: I::Addr) {
1828 self.outer_mut().set_src_ip(new);
1829 }
1830
1831 fn update_pseudo_header_dst_addr(&mut self, _old: I::Addr, new: I::Addr) {
1832 self.outer_mut().set_dst_ip(new);
1833 }
1834}
1835
1836impl<A: IpAddress, I: IpExt, Inner, O> MaybeIcmpErrorPayload<I>
1837 for Nested<Inner, TcpSegmentBuilderWithOptions<A, O>>
1838{
1839 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
1840 None
1841 }
1842}
1843
1844impl<A: IpAddress, I: FilterIpExt, Inner, O> MaybeIcmpErrorMut<I>
1845 for Nested<Inner, TcpSegmentBuilderWithOptions<A, O>>
1846{
1847 type IcmpErrorMut<'a>
1848 = Never
1849 where
1850 Self: 'a;
1851
1852 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
1853 None
1854 }
1855}
1856
1857impl<I: IpExt, Inner, M: IcmpMessage<I>> MaybeTransportPacket
1858 for Nested<Inner, IcmpPacketBuilder<I, M>>
1859{
1860 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1861 self.outer().message().transport_packet_data()
1862 }
1863}
1864
1865impl<I: IpExt, Inner, M: IcmpMessage<I>> MaybeTransportPacketMut<I>
1866 for Nested<Inner, IcmpPacketBuilder<I, M>>
1867{
1868 type TransportPacketMut<'a>
1869 = &'a mut IcmpPacketBuilder<I, M>
1870 where
1871 M: 'a,
1872 Inner: 'a;
1873
1874 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1875 Some(self.outer_mut())
1876 }
1877}
1878
1879impl<I: IpExt, Inner, M: IcmpMessage<I>> DynamicMaybeTransportPacketMut<I>
1880 for Nested<Inner, IcmpPacketBuilder<I, M>>
1881{
1882 fn dyn_transport_packet_mut(&mut self) -> Option<&mut dyn TransportPacketMut<I>> {
1883 MaybeTransportPacketMut::transport_packet_mut(self).map(|x| x as _)
1884 }
1885}
1886
1887impl<I: IpExt, M: IcmpMessage<I>> TransportPacketMut<I> for IcmpPacketBuilder<I, M> {
1888 fn set_src_port(&mut self, id: NonZeroU16) {
1889 if M::IS_REWRITABLE {
1890 let _: u16 = self.message_mut().update_icmp_id(id.get());
1891 }
1892 }
1893
1894 fn set_dst_port(&mut self, id: NonZeroU16) {
1895 if M::IS_REWRITABLE {
1896 let _: u16 = self.message_mut().update_icmp_id(id.get());
1897 }
1898 }
1899
1900 fn update_pseudo_header_src_addr(&mut self, _old: I::Addr, new: I::Addr) {
1901 self.set_src_ip(new);
1902 }
1903
1904 fn update_pseudo_header_dst_addr(&mut self, _old: I::Addr, new: I::Addr) {
1905 self.set_dst_ip(new);
1906 }
1907}
1908
1909impl<Inner, I: IpExt> MaybeIcmpErrorPayload<I>
1910 for Nested<Inner, IcmpPacketBuilder<I, IcmpEchoRequest>>
1911{
1912 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
1913 None
1914 }
1915}
1916
1917impl<Inner, I: FilterIpExt> MaybeIcmpErrorMut<I>
1918 for Nested<Inner, IcmpPacketBuilder<I, IcmpEchoRequest>>
1919{
1920 type IcmpErrorMut<'a>
1921 = Never
1922 where
1923 Self: 'a;
1924
1925 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
1926 None
1927 }
1928}
1929
1930impl<Inner, I: FilterIpExt> DynamicMaybeIcmpErrorMut<I>
1931 for Nested<Inner, IcmpPacketBuilder<I, IcmpEchoRequest>>
1932{
1933 fn dyn_icmp_error_mut(&mut self) -> Option<&mut dyn DynamicIcmpErrorMut<I>> {
1934 MaybeIcmpErrorMut::<I>::icmp_error_mut(self).map(|x| match x {})
1935 }
1936}
1937
1938impl<Inner, I: IpExt> MaybeIcmpErrorPayload<I>
1939 for Nested<Inner, IcmpPacketBuilder<I, IcmpEchoReply>>
1940{
1941 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
1942 None
1943 }
1944}
1945
1946impl<Inner, I: FilterIpExt> MaybeIcmpErrorMut<I>
1947 for Nested<Inner, IcmpPacketBuilder<I, IcmpEchoReply>>
1948{
1949 type IcmpErrorMut<'a>
1950 = Never
1951 where
1952 Self: 'a;
1953
1954 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
1955 None
1956 }
1957}
1958
1959impl<Inner, I: FilterIpExt> DynamicMaybeIcmpErrorMut<I>
1960 for Nested<Inner, IcmpPacketBuilder<I, IcmpEchoReply>>
1961{
1962 fn dyn_icmp_error_mut(&mut self) -> Option<&mut dyn DynamicIcmpErrorMut<I>> {
1963 MaybeIcmpErrorMut::<I>::icmp_error_mut(self).map(|x| match x {})
1964 }
1965}
1966
1967pub trait IcmpMessage<I: IpExt>: icmp::IcmpMessage<I> + MaybeTransportPacket {
1969 const IS_REWRITABLE: bool;
1971
1972 fn is_rewritable(&self) -> bool {
1975 Self::IS_REWRITABLE
1976 }
1977
1978 fn update_icmp_id(&mut self, id: u16) -> u16;
1982}
1983
1984impl MaybeTransportPacket for IcmpEchoReply {
1989 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1990 Some(TransportPacketData::Generic { src_port: self.id(), dst_port: self.id() })
1991 }
1992}
1993
1994impl<I: IpExt> IcmpMessage<I> for IcmpEchoReply {
1995 const IS_REWRITABLE: bool = true;
1996
1997 fn update_icmp_id(&mut self, id: u16) -> u16 {
1998 let old = self.id();
1999 self.set_id(id);
2000 old
2001 }
2002}
2003
2004impl MaybeTransportPacket for IcmpEchoRequest {
2009 fn transport_packet_data(&self) -> Option<TransportPacketData> {
2010 Some(TransportPacketData::Generic { src_port: self.id(), dst_port: self.id() })
2011 }
2012}
2013
2014impl<I: IpExt> IcmpMessage<I> for IcmpEchoRequest {
2015 const IS_REWRITABLE: bool = true;
2016
2017 fn update_icmp_id(&mut self, id: u16) -> u16 {
2018 let old = self.id();
2019 self.set_id(id);
2020 old
2021 }
2022}
2023
2024macro_rules! unsupported_icmp_message_type {
2025 ($message:ty, $($ips:ty),+) => {
2026 impl MaybeTransportPacket for $message {
2027 fn transport_packet_data(&self) -> Option<TransportPacketData> {
2028 None
2029 }
2030 }
2031
2032 $(
2033 impl IcmpMessage<$ips> for $message {
2034 const IS_REWRITABLE: bool = false;
2035
2036 fn update_icmp_id(&mut self, _: u16) -> u16 {
2037 unreachable!("non-echo ICMP packets should never be rewritten")
2038 }
2039 }
2040 )+
2041 };
2042}
2043
2044unsupported_icmp_message_type!(Icmpv4TimestampRequest, Ipv4);
2045unsupported_icmp_message_type!(Icmpv4TimestampReply, Ipv4);
2046unsupported_icmp_message_type!(NeighborSolicitation, Ipv6);
2047unsupported_icmp_message_type!(NeighborAdvertisement, Ipv6);
2048unsupported_icmp_message_type!(RouterSolicitation, Ipv6);
2049unsupported_icmp_message_type!(MulticastListenerDone, Ipv6);
2050unsupported_icmp_message_type!(MulticastListenerReport, Ipv6);
2051unsupported_icmp_message_type!(MulticastListenerReportV2, Ipv6);
2052unsupported_icmp_message_type!(MulticastListenerQuery, Ipv6);
2053unsupported_icmp_message_type!(MulticastListenerQueryV2, Ipv6);
2054unsupported_icmp_message_type!(RouterAdvertisement, Ipv6);
2055unsupported_icmp_message_type!(Redirect, Ipv6);
2058
2059macro_rules! non_error_icmp_message_type {
2061 ($message:ty, $ip:ty) => {
2062 impl<Inner> MaybeIcmpErrorPayload<$ip> for Nested<Inner, IcmpPacketBuilder<$ip, $message>> {
2063 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<$ip>> {
2064 None
2065 }
2066 }
2067
2068 impl<Inner> MaybeIcmpErrorMut<$ip> for Nested<Inner, IcmpPacketBuilder<$ip, $message>> {
2069 type IcmpErrorMut<'a>
2070 = Never
2071 where
2072 Self: 'a;
2073
2074 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
2075 None
2076 }
2077 }
2078
2079 impl<Inner> DynamicMaybeIcmpErrorMut<$ip>
2080 for Nested<Inner, IcmpPacketBuilder<$ip, $message>>
2081 {
2082 fn dyn_icmp_error_mut(&mut self) -> Option<&mut dyn DynamicIcmpErrorMut<$ip>> {
2083 MaybeIcmpErrorMut::icmp_error_mut(self).map(|x| match x {})
2084 }
2085 }
2086 };
2087}
2088
2089non_error_icmp_message_type!(Icmpv4TimestampRequest, Ipv4);
2090non_error_icmp_message_type!(Icmpv4TimestampReply, Ipv4);
2091non_error_icmp_message_type!(RouterSolicitation, Ipv6);
2092non_error_icmp_message_type!(RouterAdvertisement, Ipv6);
2093non_error_icmp_message_type!(NeighborSolicitation, Ipv6);
2094non_error_icmp_message_type!(NeighborAdvertisement, Ipv6);
2095non_error_icmp_message_type!(MulticastListenerReport, Ipv6);
2096non_error_icmp_message_type!(MulticastListenerDone, Ipv6);
2097non_error_icmp_message_type!(MulticastListenerReportV2, Ipv6);
2098
2099macro_rules! icmp_error_message {
2100 ($message:ty, $($ips:ty),+) => {
2101 impl MaybeTransportPacket for $message {
2102 fn transport_packet_data(&self) -> Option<TransportPacketData> {
2103 None
2104 }
2105 }
2106
2107 $(
2108 impl IcmpMessage<$ips> for $message {
2109 const IS_REWRITABLE: bool = false;
2110
2111 fn update_icmp_id(&mut self, _: u16) -> u16 {
2112 unreachable!("non-echo ICMP packets should never be rewritten")
2113 }
2114 }
2115 )+
2116 };
2117}
2118
2119icmp_error_message!(IcmpDestUnreachable, Ipv4, Ipv6);
2120icmp_error_message!(IcmpTimeExceeded, Ipv4, Ipv6);
2121icmp_error_message!(Icmpv4ParameterProblem, Ipv4);
2122icmp_error_message!(Icmpv4Redirect, Ipv4);
2123icmp_error_message!(Icmpv6ParameterProblem, Ipv6);
2124icmp_error_message!(Icmpv6PacketTooBig, Ipv6);
2125
2126macro_rules! icmpv4_error_message {
2127 ($message: ty) => {
2128 impl<Inner: AsRef<[u8]>> MaybeIcmpErrorPayload<Ipv4>
2129 for Nested<Inner, IcmpPacketBuilder<Ipv4, $message>>
2130 {
2131 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<Ipv4>> {
2132 ParsedIcmpErrorPayload::parse_in_icmpv4_error(Buf::new(self.inner(), ..))
2133 }
2134 }
2135
2136 impl<Inner: BufferMut> MaybeIcmpErrorMut<Ipv4>
2137 for Nested<Inner, IcmpPacketBuilder<Ipv4, $message>>
2138 {
2139 type IcmpErrorMut<'a>
2140 = &'a mut Self
2141 where
2142 Self: 'a;
2143
2144 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
2145 Some(self)
2146 }
2147 }
2148
2149 impl<Inner: BufferMut> DynamicMaybeIcmpErrorMut<Ipv4>
2150 for Nested<Inner, IcmpPacketBuilder<Ipv4, $message>>
2151 {
2152 fn dyn_icmp_error_mut(&mut self) -> Option<&mut dyn DynamicIcmpErrorMut<Ipv4>> {
2153 MaybeIcmpErrorMut::icmp_error_mut(self).map(|x| x as _)
2154 }
2155 }
2156
2157 impl<Inner: BufferMut> IcmpErrorMut<Ipv4>
2158 for Nested<Inner, IcmpPacketBuilder<Ipv4, $message>>
2159 {
2160 type InnerPacket<'a>
2161 = Ipv4PacketRaw<&'a mut [u8]>
2162 where
2163 Self: 'a;
2164
2165 fn recalculate_checksum(&mut self) -> bool {
2166 true
2168 }
2169
2170 fn inner_packet<'a>(&'a mut self) -> Option<Self::InnerPacket<'a>> {
2171 let packet =
2172 Ipv4PacketRaw::parse_mut(SliceBufViewMut::new(self.inner_mut().as_mut()), ())
2173 .ok()?;
2174
2175 Some(packet)
2176 }
2177 }
2178
2179 impl<Inner: BufferMut> DynamicIcmpErrorMut<Ipv4>
2180 for Nested<Inner, IcmpPacketBuilder<Ipv4, $message>>
2181 {
2182 fn dyn_recalculate_checksum(&mut self) -> bool {
2183 self.recalculate_checksum()
2184 }
2185
2186 fn dyn_inner_packet(&mut self) -> Option<Ipv4PacketRaw<&mut [u8]>> {
2187 self.inner_packet()
2188 }
2189 }
2190 };
2191}
2192
2193icmpv4_error_message!(IcmpDestUnreachable);
2194icmpv4_error_message!(Icmpv4Redirect);
2195icmpv4_error_message!(IcmpTimeExceeded);
2196icmpv4_error_message!(Icmpv4ParameterProblem);
2197
2198macro_rules! icmpv6_error_message {
2199 ($message: ty) => {
2200 impl<Inner: Buffer> MaybeIcmpErrorPayload<Ipv6>
2201 for Nested<TruncatingSerializer<Inner>, IcmpPacketBuilder<Ipv6, $message>>
2202 {
2203 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<Ipv6>> {
2204 ParsedIcmpErrorPayload::parse_in_icmpv6_error(Buf::new(self.inner().buffer(), ..))
2205 }
2206 }
2207
2208 impl<Inner: BufferMut> MaybeIcmpErrorMut<Ipv6>
2209 for Nested<TruncatingSerializer<Inner>, IcmpPacketBuilder<Ipv6, $message>>
2210 {
2211 type IcmpErrorMut<'a>
2212 = &'a mut Self
2213 where
2214 Self: 'a;
2215
2216 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
2217 Some(self)
2218 }
2219 }
2220
2221 impl<Inner: BufferMut> DynamicMaybeIcmpErrorMut<Ipv6>
2222 for Nested<TruncatingSerializer<Inner>, IcmpPacketBuilder<Ipv6, $message>>
2223 {
2224 fn dyn_icmp_error_mut(&mut self) -> Option<&mut dyn DynamicIcmpErrorMut<Ipv6>> {
2225 MaybeIcmpErrorMut::icmp_error_mut(self).map(|x| x as _)
2226 }
2227 }
2228
2229 impl<Inner: BufferMut> IcmpErrorMut<Ipv6>
2230 for Nested<TruncatingSerializer<Inner>, IcmpPacketBuilder<Ipv6, $message>>
2231 {
2232 type InnerPacket<'a>
2233 = Ipv6PacketRaw<&'a mut [u8]>
2234 where
2235 Self: 'a;
2236
2237 fn recalculate_checksum(&mut self) -> bool {
2238 true
2240 }
2241
2242 fn inner_packet<'a>(&'a mut self) -> Option<Self::InnerPacket<'a>> {
2243 let packet = Ipv6PacketRaw::parse_mut(
2244 SliceBufViewMut::new(self.inner_mut().buffer_mut().as_mut()),
2245 (),
2246 )
2247 .ok()?;
2248
2249 Some(packet)
2250 }
2251 }
2252
2253 impl<Inner: BufferMut> DynamicIcmpErrorMut<Ipv6>
2254 for Nested<TruncatingSerializer<Inner>, IcmpPacketBuilder<Ipv6, $message>>
2255 {
2256 fn dyn_recalculate_checksum(&mut self) -> bool {
2257 self.recalculate_checksum()
2258 }
2259
2260 fn dyn_inner_packet(&mut self) -> Option<Ipv6PacketRaw<&mut [u8]>> {
2261 self.inner_packet()
2262 }
2263 }
2264 };
2265}
2266
2267icmpv6_error_message!(IcmpDestUnreachable);
2268icmpv6_error_message!(Icmpv6PacketTooBig);
2269icmpv6_error_message!(IcmpTimeExceeded);
2270icmpv6_error_message!(Icmpv6ParameterProblem);
2271
2272impl<M: igmp::MessageType<EmptyBuf>> MaybeIcmpErrorMut<Ipv4>
2273 for InnerSerializer<IgmpPacketBuilder<EmptyBuf, M>, EmptyBuf>
2274{
2275 type IcmpErrorMut<'a>
2276 = Never
2277 where
2278 Self: 'a;
2279
2280 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
2281 None
2282 }
2283}
2284
2285impl<M: igmp::MessageType<EmptyBuf>> DynamicMaybeIcmpErrorMut<Ipv4>
2286 for InnerSerializer<IgmpPacketBuilder<EmptyBuf, M>, EmptyBuf>
2287{
2288 fn dyn_icmp_error_mut(&mut self) -> Option<&mut dyn DynamicIcmpErrorMut<Ipv4>> {
2289 self.icmp_error_mut().map(|x| match x {})
2290 }
2291}
2292
2293impl<M: igmp::MessageType<EmptyBuf>> MaybeTransportPacket
2294 for InnerSerializer<IgmpPacketBuilder<EmptyBuf, M>, EmptyBuf>
2295{
2296 fn transport_packet_data(&self) -> Option<TransportPacketData> {
2297 None
2298 }
2299}
2300
2301impl<M: igmp::MessageType<EmptyBuf>> DynamicMaybeTransportPacketMut<Ipv4>
2302 for InnerSerializer<IgmpPacketBuilder<EmptyBuf, M>, EmptyBuf>
2303{
2304 fn dyn_transport_packet_mut(&mut self) -> Option<&mut dyn TransportPacketMut<Ipv4>> {
2305 self.transport_packet_mut().map(|x| match x {})
2306 }
2307}
2308
2309impl<M: igmp::MessageType<EmptyBuf>> MaybeTransportPacketMut<Ipv4>
2310 for InnerSerializer<IgmpPacketBuilder<EmptyBuf, M>, EmptyBuf>
2311{
2312 type TransportPacketMut<'a>
2313 = Never
2314 where
2315 M: 'a;
2316
2317 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
2318 None
2319 }
2320}
2321
2322impl<I: IpExt, M: igmp::MessageType<EmptyBuf>> MaybeIcmpErrorPayload<I>
2323 for InnerSerializer<IgmpPacketBuilder<EmptyBuf, M>, EmptyBuf>
2324{
2325 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
2326 None
2327 }
2328}
2329
2330impl<I> MaybeTransportPacket for InnerSerializer<IgmpMembershipReportV3Builder<I>, EmptyBuf> {
2331 fn transport_packet_data(&self) -> Option<TransportPacketData> {
2332 None
2333 }
2334}
2335
2336impl<I> MaybeTransportPacketMut<Ipv4>
2337 for InnerSerializer<IgmpMembershipReportV3Builder<I>, EmptyBuf>
2338{
2339 type TransportPacketMut<'a>
2340 = Never
2341 where
2342 I: 'a;
2343
2344 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
2345 None
2346 }
2347}
2348
2349impl<I> DynamicMaybeTransportPacketMut<Ipv4>
2350 for InnerSerializer<IgmpMembershipReportV3Builder<I>, EmptyBuf>
2351{
2352 fn dyn_transport_packet_mut(&mut self) -> Option<&mut dyn TransportPacketMut<Ipv4>> {
2353 self.transport_packet_mut().map(|x| match x {})
2354 }
2355}
2356
2357impl<I: IpExt, II, B> MaybeIcmpErrorPayload<I>
2358 for InnerSerializer<IgmpMembershipReportV3Builder<II>, B>
2359{
2360 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
2361 None
2362 }
2363}
2364
2365impl<I, B> MaybeIcmpErrorMut<Ipv4> for InnerSerializer<IgmpMembershipReportV3Builder<I>, B> {
2366 type IcmpErrorMut<'a>
2367 = Never
2368 where
2369 Self: 'a;
2370
2371 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
2372 None
2373 }
2374}
2375
2376impl<I, B> DynamicMaybeIcmpErrorMut<Ipv4> for InnerSerializer<IgmpMembershipReportV3Builder<I>, B> {
2377 fn dyn_icmp_error_mut(&mut self) -> Option<&mut dyn DynamicIcmpErrorMut<Ipv4>> {
2378 self.icmp_error_mut().map(|x| match x {})
2379 }
2380}
2381
2382impl<I> MaybeTransportPacket
2383 for EitherSerializer<
2384 EmptyBuf,
2385 InnerSerializer<packet::records::RecordSequenceBuilder<NdpOptionBuilder<'_>, I>, EmptyBuf>,
2386 >
2387{
2388 fn transport_packet_data(&self) -> Option<TransportPacketData> {
2389 None
2390 }
2391}
2392
2393#[derive(GenericOverIp)]
2398#[generic_over_ip(I, Ip)]
2399pub struct RawIpBody<I: IpExt, B: ParseBuffer> {
2400 protocol: I::Proto,
2403 src_addr: I::Addr,
2406 dst_addr: I::Addr,
2409 body: B,
2412 transport_packet_data: Option<TransportPacketData>,
2415}
2416
2417impl<I: IpExt, B: ParseBuffer> RawIpBody<I, B> {
2418 pub fn new(
2420 protocol: I::Proto,
2421 src_addr: I::Addr,
2422 dst_addr: I::Addr,
2423 body: B,
2424 ) -> RawIpBody<I, B> {
2425 let transport_packet_data = TransportPacketData::parse_in_ip_packet::<I, _>(
2426 src_addr,
2427 dst_addr,
2428 protocol,
2429 Buf::new(&body, ..),
2430 );
2431 RawIpBody { protocol, src_addr, dst_addr, body, transport_packet_data }
2432 }
2433}
2434
2435impl<I: IpExt, B: ParseBuffer> MaybeTransportPacket for RawIpBody<I, B> {
2436 fn transport_packet_data(&self) -> Option<TransportPacketData> {
2437 self.transport_packet_data.clone()
2438 }
2439}
2440
2441impl<I: IpExt, B: BufferMut> MaybeTransportPacketMut<I> for RawIpBody<I, B> {
2442 type TransportPacketMut<'a>
2443 = ParsedTransportHeaderMut<'a, I>
2444 where
2445 Self: 'a;
2446
2447 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
2448 let RawIpBody { protocol, src_addr: _, dst_addr: _, body, transport_packet_data: _ } = self;
2449 ParsedTransportHeaderMut::<I>::parse_in_ip_packet(
2450 *protocol,
2451 SliceBufViewMut::new(body.as_mut()),
2452 )
2453 }
2454}
2455
2456impl<I: IpExt, B: ParseBuffer> MaybeIcmpErrorPayload<I> for RawIpBody<I, B> {
2457 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
2458 ParsedIcmpErrorPayload::parse_in_outer_ip_packet(self.protocol, Buf::new(&self.body, ..))
2459 }
2460}
2461
2462impl<I: FilterIpExt, B: BufferMut> MaybeIcmpErrorMut<I> for RawIpBody<I, B> {
2463 type IcmpErrorMut<'a>
2464 = ParsedIcmpErrorMut<'a, I>
2465 where
2466 Self: 'a;
2467
2468 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
2469 let RawIpBody { protocol, src_addr, dst_addr, body, transport_packet_data: _ } = self;
2470
2471 ParsedIcmpErrorMut::parse_in_ip_packet(
2472 *src_addr,
2473 *dst_addr,
2474 *protocol,
2475 SliceBufViewMut::new(body.as_mut()),
2476 )
2477 }
2478}
2479
2480impl<I: IpExt, B: BufferMut + NetworkSerializer> Serializer<NetworkSerializationContext>
2481 for RawIpBody<I, B>
2482{
2483 type Buffer = <B as Serializer<NetworkSerializationContext>>::Buffer;
2484
2485 fn serialize<G: GrowBufferMut, P: BufferProvider<Self::Buffer, G>>(
2486 self,
2487 context: &mut NetworkSerializationContext,
2488 constraints: PacketConstraints,
2489 provider: P,
2490 ) -> Result<G, (SerializeError<P::Error>, Self)> {
2491 let Self { protocol, src_addr, dst_addr, body, transport_packet_data } = self;
2492 body.serialize(context, constraints, provider).map_err(|(err, body)| {
2493 (err, Self { protocol, src_addr, dst_addr, body, transport_packet_data })
2494 })
2495 }
2496
2497 fn serialize_new_buf<BB: GrowBufferMut, A: LayoutBufferAlloc<BB>>(
2498 &self,
2499 context: &mut NetworkSerializationContext,
2500 outer: PacketConstraints,
2501 alloc: A,
2502 ) -> Result<BB, SerializeError<A::Error>> {
2503 self.body.serialize_new_buf(context, outer, alloc)
2504 }
2505}
2506
2507impl<I: IpExt, B: BufferMut + NetworkSerializer> NestableSerializer for RawIpBody<I, B> {}
2508
2509impl<I: IpExt, B: BufferMut> PartialSerializer<NetworkSerializationContext> for RawIpBody<I, B> {
2510 fn partial_serialize<BB: GrowBufferMut + ContiguousBuffer, A: LayoutBufferAlloc<BB>>(
2511 &self,
2512 _context: &mut NetworkSerializationContext,
2513 _alloc: A,
2514 ) -> Result<PartialSerializeResult<'_, BB>, SerializeError<A::Error>> {
2515 Ok(PartialSerializeResult::Slice(self.body.as_ref()))
2516 }
2517
2518 fn partial_serialize_new_buf<BB: GrowBufferMut, A: LayoutBufferAlloc<BB>>(
2519 &self,
2520 _context: &mut NetworkSerializationContext,
2521 constraints: PacketConstraints,
2522 alloc: A,
2523 ) -> Result<(BB, usize), SerializeError<A::Error>> {
2524 let bytes_to_copy = cmp::min(self.body.len(), TRANSPORT_HEADER_MAX_SIZE);
2525 let header_len = constraints.header_len();
2526 let mut buffer = alloc.layout_alloc(header_len, bytes_to_copy, 0)?;
2527 buffer.with_parts_mut(|_prefix, mut body, _suffix| {
2528 body.copy_from_slice(&self.body.as_ref()[..bytes_to_copy]);
2529 });
2530 let total_size = cmp::max(
2531 constraints.min_body_len(),
2532 cmp::min(self.body.len(), constraints.max_body_len()),
2533 );
2534 Ok((buffer, total_size))
2535 }
2536}
2537
2538fn parse_transport_header_in_ipv4_packet<B: ParseBuffer>(
2539 src_ip: Ipv4Addr,
2540 dst_ip: Ipv4Addr,
2541 proto: Ipv4Proto,
2542 body: B,
2543) -> Option<TransportPacketData> {
2544 match proto {
2545 Ipv4Proto::Proto(IpProto::Udp) => parse_udp_header::<_, Ipv4>(body),
2546 Ipv4Proto::Proto(IpProto::Tcp) => parse_tcp_header::<_, Ipv4>(body, src_ip, dst_ip),
2547 Ipv4Proto::Icmp => parse_icmpv4_header(body),
2548 Ipv4Proto::Proto(IpProto::Reserved) | Ipv4Proto::Igmp | Ipv4Proto::Other(_) => None,
2549 }
2550}
2551
2552fn parse_transport_header_in_ipv6_packet<B: ParseBuffer>(
2553 src_ip: Ipv6Addr,
2554 dst_ip: Ipv6Addr,
2555 proto: Ipv6Proto,
2556 body: B,
2557) -> Option<TransportPacketData> {
2558 match proto {
2559 Ipv6Proto::Proto(IpProto::Udp) => parse_udp_header::<_, Ipv6>(body),
2560 Ipv6Proto::Proto(IpProto::Tcp) => parse_tcp_header::<_, Ipv6>(body, src_ip, dst_ip),
2561 Ipv6Proto::Icmpv6 => parse_icmpv6_header(body),
2562 Ipv6Proto::Proto(IpProto::Reserved) | Ipv6Proto::NoNextHeader | Ipv6Proto::Other(_) => None,
2563 }
2564}
2565
2566fn parse_udp_header<B: ParseBuffer, I: Ip>(mut body: B) -> Option<TransportPacketData> {
2567 let packet = body.parse_with::<_, UdpPacketRaw<_>>(I::VERSION_MARKER).ok()?;
2568 Some(TransportPacketData::Generic {
2569 src_port: packet.src_port().map(NonZeroU16::get).unwrap_or(0),
2570 dst_port: packet.dst_port()?.get(),
2573 })
2574}
2575
2576fn parse_tcp_header<B: ParseBuffer, I: IpExt>(
2577 mut body: B,
2578 src_ip: I::Addr,
2579 dst_ip: I::Addr,
2580) -> Option<TransportPacketData> {
2581 let packet = body.parse::<TcpSegmentRaw<_>>().ok()?;
2590
2591 let (fallback_src_port, fallback_dst_port) = packet.flow_header().src_dst();
2592 let fallback =
2593 TransportPacketData::Generic { src_port: fallback_src_port, dst_port: fallback_dst_port };
2594
2595 let (builder, options_res, body) = match packet.into_builder_options(src_ip, dst_ip) {
2600 Ok(x) => x,
2601 Err(_) => return Some(fallback),
2602 };
2603 let options = match options_res {
2604 Ok(options) => options,
2605 Err((options, _err)) => options,
2606 };
2607 let options = match Options::try_from_options(&builder, &options) {
2608 Ok(x) => x,
2609 Err(MalformedFlags { .. }) => return Some(fallback),
2610 };
2611
2612 let segment = match SegmentHeader::from_builder_options(&builder, options) {
2613 Ok(x) => x,
2614 Err(MalformedFlags { .. }) => return Some(fallback),
2615 };
2616
2617 Some(TransportPacketData::Tcp {
2618 src_port: builder.src_port().map(NonZeroU16::get).unwrap_or(0),
2619 dst_port: builder.dst_port().map(NonZeroU16::get).unwrap_or(0),
2620 segment,
2621 payload_len: body.len(),
2622 })
2623}
2624
2625fn parse_icmpv4_header<B: ParseBuffer>(mut body: B) -> Option<TransportPacketData> {
2626 match icmp::peek_message_type(body.as_ref()).ok()? {
2627 Icmpv4MessageType::EchoRequest => {
2628 let packet = body.parse::<IcmpPacketRaw<Ipv4, _, IcmpEchoRequest>>().ok()?;
2629 packet.message().transport_packet_data()
2630 }
2631 Icmpv4MessageType::EchoReply => {
2632 let packet = body.parse::<IcmpPacketRaw<Ipv4, _, IcmpEchoReply>>().ok()?;
2633 packet.message().transport_packet_data()
2634 }
2635 Icmpv4MessageType::DestUnreachable
2637 | Icmpv4MessageType::Redirect
2638 | Icmpv4MessageType::TimeExceeded
2639 | Icmpv4MessageType::ParameterProblem => None,
2640 Icmpv4MessageType::TimestampRequest | Icmpv4MessageType::TimestampReply => None,
2644 }
2645}
2646
2647fn parse_icmpv6_header<B: ParseBuffer>(mut body: B) -> Option<TransportPacketData> {
2648 match icmp::peek_message_type(body.as_ref()).ok()? {
2649 Icmpv6MessageType::EchoRequest => {
2650 let packet = body.parse::<IcmpPacketRaw<Ipv6, _, IcmpEchoRequest>>().ok()?;
2651 packet.message().transport_packet_data()
2652 }
2653 Icmpv6MessageType::EchoReply => {
2654 let packet = body.parse::<IcmpPacketRaw<Ipv6, _, IcmpEchoReply>>().ok()?;
2655 packet.message().transport_packet_data()
2656 }
2657 Icmpv6MessageType::DestUnreachable
2659 | Icmpv6MessageType::PacketTooBig
2660 | Icmpv6MessageType::TimeExceeded
2661 | Icmpv6MessageType::ParameterProblem => None,
2662 Icmpv6MessageType::RouterSolicitation
2663 | Icmpv6MessageType::RouterAdvertisement
2664 | Icmpv6MessageType::NeighborSolicitation
2665 | Icmpv6MessageType::NeighborAdvertisement
2666 | Icmpv6MessageType::Redirect
2667 | Icmpv6MessageType::MulticastListenerQuery
2668 | Icmpv6MessageType::MulticastListenerReport
2669 | Icmpv6MessageType::MulticastListenerDone
2670 | Icmpv6MessageType::MulticastListenerReportV2 => None,
2671 }
2672}
2673
2674#[derive(GenericOverIp)]
2677#[generic_over_ip(I, Ip)]
2678pub enum ParsedTransportHeaderMut<'a, I: IpExt> {
2679 Tcp(TcpSegmentRaw<&'a mut [u8]>),
2680 Udp(UdpPacketRaw<&'a mut [u8]>),
2681 Icmp(I::IcmpPacketTypeRaw<&'a mut [u8]>),
2682}
2683
2684impl<'a> ParsedTransportHeaderMut<'a, Ipv4> {
2685 fn parse_in_ipv4_packet<BV: BufferViewMut<&'a mut [u8]>>(
2686 proto: Ipv4Proto,
2687 body: BV,
2688 ) -> Option<Self> {
2689 match proto {
2690 Ipv4Proto::Proto(IpProto::Udp) => {
2691 Some(Self::Udp(UdpPacketRaw::parse_mut(body, IpVersionMarker::<Ipv4>::new()).ok()?))
2692 }
2693 Ipv4Proto::Proto(IpProto::Tcp) => {
2694 Some(Self::Tcp(TcpSegmentRaw::parse_mut(body, ()).ok()?))
2695 }
2696 Ipv4Proto::Icmp => Some(Self::Icmp(Icmpv4PacketRaw::parse_mut(body, ()).ok()?)),
2697 Ipv4Proto::Proto(IpProto::Reserved) | Ipv4Proto::Igmp | Ipv4Proto::Other(_) => None,
2698 }
2699 }
2700}
2701
2702impl<'a> ParsedTransportHeaderMut<'a, Ipv6> {
2703 fn parse_in_ipv6_packet<BV: BufferViewMut<&'a mut [u8]>>(
2704 proto: Ipv6Proto,
2705 body: BV,
2706 ) -> Option<Self> {
2707 match proto {
2708 Ipv6Proto::Proto(IpProto::Udp) => {
2709 Some(Self::Udp(UdpPacketRaw::parse_mut(body, IpVersionMarker::<Ipv6>::new()).ok()?))
2710 }
2711 Ipv6Proto::Proto(IpProto::Tcp) => {
2712 Some(Self::Tcp(TcpSegmentRaw::parse_mut(body, ()).ok()?))
2713 }
2714 Ipv6Proto::Icmpv6 => Some(Self::Icmp(Icmpv6PacketRaw::parse_mut(body, ()).ok()?)),
2715 Ipv6Proto::Proto(IpProto::Reserved) | Ipv6Proto::NoNextHeader | Ipv6Proto::Other(_) => {
2716 None
2717 }
2718 }
2719 }
2720}
2721
2722impl<'a, I: IpExt> ParsedTransportHeaderMut<'a, I> {
2723 fn parse_in_ip_packet<BV: BufferViewMut<&'a mut [u8]>>(
2724 proto: I::Proto,
2725 body: BV,
2726 ) -> Option<Self> {
2727 I::map_ip(
2728 (proto, IpInvariant(body)),
2729 |(proto, IpInvariant(body))| {
2730 ParsedTransportHeaderMut::<'a, Ipv4>::parse_in_ipv4_packet(proto, body)
2731 },
2732 |(proto, IpInvariant(body))| {
2733 ParsedTransportHeaderMut::<'a, Ipv6>::parse_in_ipv6_packet(proto, body)
2734 },
2735 )
2736 }
2737
2738 fn update_pseudo_header_address(&mut self, old: I::Addr, new: I::Addr) {
2739 match self {
2740 Self::Tcp(segment) => segment.update_checksum_pseudo_header_address(old, new),
2741 Self::Udp(packet) => {
2742 packet.update_checksum_pseudo_header_address(old, new);
2743 }
2744 Self::Icmp(packet) => {
2745 packet.update_checksum_pseudo_header_address(old, new);
2746 }
2747 }
2748 }
2749}
2750
2751#[derive(Debug, PartialEq, Eq, GenericOverIp)]
2753#[generic_over_ip(I, Ip)]
2754pub struct ParsedIcmpErrorPayload<I: IpExt> {
2755 src_ip: I::Addr,
2756 dst_ip: I::Addr,
2757 src_port: u16,
2761 dst_port: u16,
2762 proto: I::Proto,
2763}
2764
2765impl ParsedIcmpErrorPayload<Ipv4> {
2766 fn parse_in_outer_ipv4_packet<B>(protocol: Ipv4Proto, mut body: B) -> Option<Self>
2767 where
2768 B: ParseBuffer,
2769 {
2770 match protocol {
2771 Ipv4Proto::Proto(_) | Ipv4Proto::Igmp | Ipv4Proto::Other(_) => None,
2772 Ipv4Proto::Icmp => {
2773 let message = body.parse::<Icmpv4PacketRaw<_>>().ok()?;
2774 let message_body = match &message {
2775 Icmpv4PacketRaw::EchoRequest(_)
2776 | Icmpv4PacketRaw::EchoReply(_)
2777 | Icmpv4PacketRaw::TimestampRequest(_)
2778 | Icmpv4PacketRaw::TimestampReply(_) => return None,
2779
2780 Icmpv4PacketRaw::DestUnreachable(inner) => inner.message_body(),
2781 Icmpv4PacketRaw::Redirect(inner) => inner.message_body(),
2782 Icmpv4PacketRaw::TimeExceeded(inner) => inner.message_body(),
2783 Icmpv4PacketRaw::ParameterProblem(inner) => inner.message_body(),
2784 };
2785
2786 Self::parse_in_icmpv4_error(Buf::new(message_body, ..))
2787 }
2788 }
2789 }
2790
2791 fn parse_in_icmpv4_error<B>(mut body: B) -> Option<Self>
2792 where
2793 B: ParseBuffer,
2794 {
2795 let packet = body.parse::<Ipv4PacketRaw<_>>().ok()?;
2796
2797 let src_ip = packet.get_header_prefix().src_ip();
2798 let dst_ip = packet.get_header_prefix().dst_ip();
2799 let proto = packet.proto();
2800 let transport_data = parse_transport_header_in_ipv4_packet(
2801 src_ip,
2802 dst_ip,
2803 proto,
2804 packet.body().into_inner(),
2805 )?;
2806 Some(Self {
2807 src_ip,
2808 dst_ip,
2809 src_port: transport_data.src_port(),
2810 dst_port: transport_data.dst_port(),
2811 proto,
2812 })
2813 }
2814}
2815
2816impl ParsedIcmpErrorPayload<Ipv6> {
2817 fn parse_in_outer_ipv6_packet<B>(protocol: Ipv6Proto, mut body: B) -> Option<Self>
2818 where
2819 B: ParseBuffer,
2820 {
2821 match protocol {
2822 Ipv6Proto::NoNextHeader | Ipv6Proto::Proto(_) | Ipv6Proto::Other(_) => None,
2823
2824 Ipv6Proto::Icmpv6 => {
2825 let message = body.parse::<Icmpv6PacketRaw<_>>().ok()?;
2826 let message_body = match &message {
2827 Icmpv6PacketRaw::EchoRequest(_)
2828 | Icmpv6PacketRaw::EchoReply(_)
2829 | Icmpv6PacketRaw::Ndp(_)
2830 | Icmpv6PacketRaw::Mld(_) => return None,
2831
2832 Icmpv6PacketRaw::DestUnreachable(inner) => inner.message_body(),
2833 Icmpv6PacketRaw::PacketTooBig(inner) => inner.message_body(),
2834 Icmpv6PacketRaw::TimeExceeded(inner) => inner.message_body(),
2835 Icmpv6PacketRaw::ParameterProblem(inner) => inner.message_body(),
2836 };
2837
2838 Self::parse_in_icmpv6_error(Buf::new(message_body, ..))
2839 }
2840 }
2841 }
2842
2843 fn parse_in_icmpv6_error<B>(mut body: B) -> Option<Self>
2844 where
2845 B: ParseBuffer,
2846 {
2847 let packet = body.parse::<Ipv6PacketRaw<_>>().ok()?;
2848
2849 let src_ip = packet.get_fixed_header().src_ip();
2850 let dst_ip = packet.get_fixed_header().dst_ip();
2851 let proto = packet.proto().ok()?;
2852 let transport_data = parse_transport_header_in_ipv6_packet(
2853 src_ip,
2854 dst_ip,
2855 proto,
2856 packet.body().ok()?.into_inner(),
2857 )?;
2858 Some(Self {
2859 src_ip,
2860 dst_ip,
2861 src_port: transport_data.src_port(),
2862 dst_port: transport_data.dst_port(),
2863 proto,
2864 })
2865 }
2866}
2867
2868impl<I: IpExt> ParsedIcmpErrorPayload<I> {
2869 fn parse_in_outer_ip_packet<B>(proto: I::Proto, body: B) -> Option<Self>
2870 where
2871 B: ParseBuffer,
2872 {
2873 I::map_ip(
2874 (proto, IpInvariant(body)),
2875 |(proto, IpInvariant(body))| {
2876 ParsedIcmpErrorPayload::<Ipv4>::parse_in_outer_ipv4_packet(proto, body)
2877 },
2878 |(proto, IpInvariant(body))| {
2879 ParsedIcmpErrorPayload::<Ipv6>::parse_in_outer_ipv6_packet(proto, body)
2880 },
2881 )
2882 }
2883}
2884
2885#[derive(GenericOverIp)]
2888#[generic_over_ip(I, Ip)]
2889pub struct ParsedIcmpErrorMut<'a, I: IpExt> {
2890 src_ip: I::Addr,
2891 dst_ip: I::Addr,
2892 message: I::IcmpPacketTypeRaw<&'a mut [u8]>,
2893}
2894
2895impl<'a> ParsedIcmpErrorMut<'a, Ipv4> {
2896 fn parse_in_ipv4_packet<BV: BufferViewMut<&'a mut [u8]>>(
2897 src_ip: Ipv4Addr,
2898 dst_ip: Ipv4Addr,
2899 proto: Ipv4Proto,
2900 body: BV,
2901 ) -> Option<Self> {
2902 match proto {
2903 Ipv4Proto::Proto(_) | Ipv4Proto::Igmp | Ipv4Proto::Other(_) => None,
2904 Ipv4Proto::Icmp => {
2905 let message = Icmpv4PacketRaw::parse_mut(body, ()).ok()?;
2906 match message {
2907 Icmpv4PacketRaw::EchoRequest(_)
2908 | Icmpv4PacketRaw::EchoReply(_)
2909 | Icmpv4PacketRaw::TimestampRequest(_)
2910 | Icmpv4PacketRaw::TimestampReply(_) => None,
2911
2912 Icmpv4PacketRaw::DestUnreachable(_)
2913 | Icmpv4PacketRaw::Redirect(_)
2914 | Icmpv4PacketRaw::TimeExceeded(_)
2915 | Icmpv4PacketRaw::ParameterProblem(_) => {
2916 Some(Self { src_ip, dst_ip, message })
2917 }
2918 }
2919 }
2920 }
2921 }
2922}
2923
2924impl<'a> ParsedIcmpErrorMut<'a, Ipv6> {
2925 fn parse_in_ipv6_packet<BV: BufferViewMut<&'a mut [u8]>>(
2926 src_ip: Ipv6Addr,
2927 dst_ip: Ipv6Addr,
2928 proto: Ipv6Proto,
2929 body: BV,
2930 ) -> Option<Self> {
2931 match proto {
2932 Ipv6Proto::NoNextHeader | Ipv6Proto::Proto(_) | Ipv6Proto::Other(_) => None,
2933
2934 Ipv6Proto::Icmpv6 => {
2935 let message = Icmpv6PacketRaw::parse_mut(body, ()).ok()?;
2936 match message {
2937 Icmpv6PacketRaw::EchoRequest(_)
2938 | Icmpv6PacketRaw::EchoReply(_)
2939 | Icmpv6PacketRaw::Ndp(_)
2940 | Icmpv6PacketRaw::Mld(_) => None,
2941
2942 Icmpv6PacketRaw::DestUnreachable(_)
2943 | Icmpv6PacketRaw::PacketTooBig(_)
2944 | Icmpv6PacketRaw::TimeExceeded(_)
2945 | Icmpv6PacketRaw::ParameterProblem(_) => {
2946 Some(Self { src_ip, dst_ip, message })
2947 }
2948 }
2949 }
2950 }
2951 }
2952}
2953
2954impl<'a, I: FilterIpExt> ParsedIcmpErrorMut<'a, I> {
2955 fn parse_in_ip_packet<BV: BufferViewMut<&'a mut [u8]>>(
2956 src_ip: I::Addr,
2957 dst_ip: I::Addr,
2958 proto: I::Proto,
2959 body: BV,
2960 ) -> Option<Self> {
2961 I::map_ip(
2962 (src_ip, dst_ip, proto, IpInvariant(body)),
2963 |(src_ip, dst_ip, proto, IpInvariant(body))| {
2964 ParsedIcmpErrorMut::<'a, Ipv4>::parse_in_ipv4_packet(src_ip, dst_ip, proto, body)
2965 },
2966 |(src_ip, dst_ip, proto, IpInvariant(body))| {
2967 ParsedIcmpErrorMut::<'a, Ipv6>::parse_in_ipv6_packet(src_ip, dst_ip, proto, body)
2968 },
2969 )
2970 }
2971}
2972
2973impl<'a, I: FilterIpExt> IcmpErrorMut<I> for ParsedIcmpErrorMut<'a, I> {
2974 type InnerPacket<'b>
2975 = I::FilterIpPacketRaw<&'b mut [u8]>
2976 where
2977 Self: 'b;
2978
2979 fn inner_packet<'b>(&'b mut self) -> Option<Self::InnerPacket<'b>> {
2980 Some(I::as_filter_packet_raw_owned(
2981 I::PacketRaw::parse_mut(SliceBufViewMut::new(self.message.message_body_mut()), ())
2982 .ok()?,
2983 ))
2984 }
2985
2986 fn recalculate_checksum(&mut self) -> bool {
2987 let Self { src_ip, dst_ip, message } = self;
2988 message.try_write_checksum(*src_ip, *dst_ip)
2989 }
2990}
2991
2992trait IcmpMessageImplHelper<I: IpExt> {
2994 fn message_impl_mut(&mut self) -> &mut impl IcmpMessage<I>;
2995}
2996
2997impl<I: IpExt, B: SplitByteSliceMut, M: IcmpMessage<I>> IcmpMessageImplHelper<I>
2998 for IcmpPacketRaw<I, B, M>
2999{
3000 fn message_impl_mut(&mut self) -> &mut impl IcmpMessage<I> {
3001 self.message_mut()
3002 }
3003}
3004
3005impl<'a, I: IpExt> TransportPacketMut<I> for ParsedTransportHeaderMut<'a, I> {
3006 fn set_src_port(&mut self, port: NonZeroU16) {
3007 match self {
3008 ParsedTransportHeaderMut::Tcp(segment) => segment.set_src_port(port),
3009 ParsedTransportHeaderMut::Udp(packet) => packet.set_src_port(port.get()),
3010 ParsedTransportHeaderMut::Icmp(packet) => {
3011 I::map_ip::<_, ()>(
3012 packet,
3013 |packet| {
3014 packet_formats::icmpv4_dispatch!(
3015 packet: raw,
3016 p => {
3017 let message = p.message_impl_mut();
3018 if message.is_rewritable() {
3019 let old = message.update_icmp_id(port.get());
3020 p.update_checksum_header_field_u16(old, port.get())
3021 }
3022 }
3023 );
3024 },
3025 |packet| {
3026 packet_formats::icmpv6_dispatch!(
3027 packet: raw,
3028 p => {
3029 let message = p.message_impl_mut();
3030 if message.is_rewritable() {
3031 let old = message.update_icmp_id(port.get());
3032 p.update_checksum_header_field_u16(old, port.get())
3033 }
3034 }
3035 );
3036 },
3037 );
3038 }
3039 }
3040 }
3041
3042 fn set_dst_port(&mut self, port: NonZeroU16) {
3043 match self {
3044 ParsedTransportHeaderMut::Tcp(segment) => segment.set_dst_port(port),
3045 ParsedTransportHeaderMut::Udp(packet) => packet.set_dst_port(port),
3046 ParsedTransportHeaderMut::Icmp(packet) => {
3047 I::map_ip::<_, ()>(
3048 packet,
3049 |packet| {
3050 packet_formats::icmpv4_dispatch!(
3051 packet:raw,
3052 p => {
3053 let message = p.message_impl_mut();
3054 if message.is_rewritable() {
3055 let old = message.update_icmp_id(port.get());
3056 p.update_checksum_header_field_u16(old, port.get())
3057 }
3058 }
3059 );
3060 },
3061 |packet| {
3062 packet_formats::icmpv6_dispatch!(
3063 packet:raw,
3064 p => {
3065 let message = p.message_impl_mut();
3066 if message.is_rewritable() {
3067 let old = message.update_icmp_id(port.get());
3068 p.update_checksum_header_field_u16(old, port.get())
3069 }
3070 }
3071 );
3072 },
3073 );
3074 }
3075 }
3076 }
3077
3078 fn update_pseudo_header_src_addr(&mut self, old: I::Addr, new: I::Addr) {
3079 self.update_pseudo_header_address(old, new);
3080 }
3081
3082 fn update_pseudo_header_dst_addr(&mut self, old: I::Addr, new: I::Addr) {
3083 self.update_pseudo_header_address(old, new);
3084 }
3085}
3086
3087#[cfg(any(test, feature = "testutils"))]
3088pub mod testutil {
3089 use super::*;
3090
3091 impl<B: BufferMut> MaybeTransportPacket for Nested<B, ()> {
3099 fn transport_packet_data(&self) -> Option<TransportPacketData> {
3100 unimplemented!()
3101 }
3102 }
3103
3104 impl<I: IpExt, B: BufferMut> MaybeTransportPacketMut<I> for Nested<B, ()> {
3105 type TransportPacketMut<'a>
3106 = Never
3107 where
3108 B: 'a;
3109
3110 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
3111 unimplemented!()
3112 }
3113 }
3114
3115 impl<I: IpExt, B: BufferMut> MaybeIcmpErrorPayload<I> for Nested<B, ()> {
3116 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
3117 unimplemented!()
3118 }
3119 }
3120
3121 impl<I: FilterIpExt, B: BufferMut> MaybeIcmpErrorMut<I> for Nested<B, ()> {
3122 type IcmpErrorMut<'a>
3123 = Never
3124 where
3125 Self: 'a;
3126
3127 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
3128 unimplemented!()
3129 }
3130 }
3131
3132 impl MaybeTransportPacket for InnerSerializer<&[u8], EmptyBuf> {
3133 fn transport_packet_data(&self) -> Option<TransportPacketData> {
3134 None
3135 }
3136 }
3137
3138 impl<I: IpExt> MaybeTransportPacketMut<I> for InnerSerializer<&[u8], EmptyBuf> {
3139 type TransportPacketMut<'a>
3140 = Never
3141 where
3142 Self: 'a;
3143
3144 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
3145 None
3146 }
3147 }
3148
3149 impl<I: IpExt> MaybeIcmpErrorPayload<I> for InnerSerializer<&[u8], EmptyBuf> {
3150 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
3151 None
3152 }
3153 }
3154
3155 impl<I: FilterIpExt> MaybeIcmpErrorMut<I> for InnerSerializer<&[u8], EmptyBuf> {
3156 type IcmpErrorMut<'a>
3157 = Never
3158 where
3159 Self: 'a;
3160
3161 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
3162 None
3163 }
3164 }
3165
3166 #[cfg(test)]
3167 pub(crate) mod internal {
3168 use alloc::vec::Vec;
3169 use net_declare::{net_ip_v4, net_ip_v6, net_subnet_v4, net_subnet_v6};
3170 use net_types::ip::Subnet;
3171 use netstack3_base::{SeqNum, UnscaledWindowSize};
3172 use packet::{PartialPacketBuilder as _, TruncateDirection};
3173 use packet_formats::icmp::{Icmpv4DestUnreachableCode, Icmpv6DestUnreachableCode};
3174
3175 use super::*;
3176
3177 pub trait TestIpExt: FilterIpExt {
3178 const SRC_IP: Self::Addr;
3179 const SRC_PORT: u16 = 1234;
3180 const DST_IP: Self::Addr;
3181 const DST_PORT: u16 = 9876;
3182 const SRC_IP_2: Self::Addr;
3183 const DST_IP_2: Self::Addr;
3184 const DST_IP_3: Self::Addr;
3185 const IP_OUTSIDE_SUBNET: Self::Addr;
3186 const SUBNET: Subnet<Self::Addr>;
3187 const PACKET_TTL: u8 = u8::MAX;
3188 }
3189
3190 impl TestIpExt for Ipv4 {
3191 const SRC_IP: Self::Addr = net_ip_v4!("192.0.2.1");
3192 const DST_IP: Self::Addr = net_ip_v4!("192.0.2.2");
3193 const SRC_IP_2: Self::Addr = net_ip_v4!("192.0.2.3");
3194 const DST_IP_2: Self::Addr = net_ip_v4!("192.0.2.4");
3195 const DST_IP_3: Self::Addr = net_ip_v4!("192.0.2.6");
3196 const IP_OUTSIDE_SUBNET: Self::Addr = net_ip_v4!("192.0.3.1");
3197 const SUBNET: Subnet<Self::Addr> = net_subnet_v4!("192.0.2.0/24");
3198 }
3199
3200 impl TestIpExt for Ipv6 {
3201 const SRC_IP: Self::Addr = net_ip_v6!("2001:db8::1");
3202 const DST_IP: Self::Addr = net_ip_v6!("2001:db8::2");
3203 const SRC_IP_2: Self::Addr = net_ip_v6!("2001:db8::3");
3204 const DST_IP_2: Self::Addr = net_ip_v6!("2001:db8::4");
3205 const DST_IP_3: Self::Addr = net_ip_v6!("2001:db8::6");
3206 const IP_OUTSIDE_SUBNET: Self::Addr = net_ip_v6!("2001:db8:ffff::1");
3207 const SUBNET: Subnet<Self::Addr> = net_subnet_v6!("2001:db8::/64");
3208 }
3209
3210 #[derive(Clone, Debug, PartialEq)]
3211 pub struct FakeIpPacket<I: FilterIpExt, T>
3212 where
3213 for<'a> &'a T: TransportPacketExt<I>,
3214 {
3215 pub src_ip: I::Addr,
3216 pub dst_ip: I::Addr,
3217 pub body: T,
3218 }
3219
3220 impl<I: FilterIpExt> FakeIpPacket<I, FakeUdpPacket> {
3221 pub(crate) fn reply(&self) -> Self {
3222 Self { src_ip: self.dst_ip, dst_ip: self.src_ip, body: self.body.reply() }
3223 }
3224 }
3225
3226 pub trait TransportPacketExt<I: IpExt>:
3227 MaybeTransportPacket + MaybeIcmpErrorPayload<I>
3228 {
3229 fn proto() -> Option<I::Proto>;
3230 fn len(&self) -> usize;
3231 }
3232
3233 impl<I: FilterIpExt, T> IpPacket<I> for FakeIpPacket<I, T>
3234 where
3235 for<'a> &'a T: TransportPacketExt<I>,
3236 for<'a> &'a mut T: MaybeTransportPacketMut<I> + MaybeIcmpErrorMut<I>,
3237 {
3238 type TransportPacket<'a>
3239 = &'a T
3240 where
3241 T: 'a;
3242 type TransportPacketMut<'a>
3243 = &'a mut T
3244 where
3245 T: 'a;
3246 type IcmpError<'a>
3247 = &'a T
3248 where
3249 T: 'a;
3250 type IcmpErrorMut<'a>
3251 = &'a mut T
3252 where
3253 T: 'a;
3254
3255 fn src_addr(&self) -> I::Addr {
3256 self.src_ip
3257 }
3258
3259 fn set_src_addr(&mut self, addr: I::Addr) {
3260 self.src_ip = addr;
3261 }
3262
3263 fn dst_addr(&self) -> I::Addr {
3264 self.dst_ip
3265 }
3266
3267 fn set_dst_addr(&mut self, addr: I::Addr) {
3268 self.dst_ip = addr;
3269 }
3270
3271 fn protocol(&self) -> Option<I::Proto> {
3272 <&T>::proto()
3273 }
3274
3275 fn maybe_transport_packet(&self) -> Self::TransportPacket<'_> {
3276 &self.body
3277 }
3278
3279 fn transport_packet_mut(&mut self) -> Self::TransportPacketMut<'_> {
3280 &mut self.body
3281 }
3282
3283 fn maybe_icmp_error<'a>(&'a self) -> Self::IcmpError<'a> {
3284 &self.body
3285 }
3286
3287 fn icmp_error_mut<'a>(&'a mut self) -> Self::IcmpErrorMut<'a> {
3288 &mut self.body
3289 }
3290 }
3291
3292 impl<I: TestIpExt, T> PartialSerializer<NetworkSerializationContext> for FakeIpPacket<I, T>
3293 where
3294 for<'a> &'a T: TransportPacketExt<I>,
3295 {
3296 fn partial_serialize_new_buf<B: GrowBufferMut, A: LayoutBufferAlloc<B>>(
3297 &self,
3298 context: &mut NetworkSerializationContext,
3299 constraints: PacketConstraints,
3300 alloc: A,
3301 ) -> Result<(B, usize), SerializeError<A::Error>> {
3302 assert!(constraints == PacketConstraints::UNCONSTRAINED);
3303
3304 let Some(proto) = <&T>::proto() else {
3305 let buffer = alloc.layout_alloc(0, 0, 0)?;
3306 return Ok((buffer, 0));
3307 };
3308 let builder = I::PacketBuilder::new(self.src_ip, self.dst_ip, I::PACKET_TTL, proto);
3309 let constraints = builder.constraints();
3310 let header_len = constraints.header_len();
3311 let body_len = (&self.body).len();
3312
3313 let mut buffer = alloc.layout_alloc(header_len, 0, 0)?;
3314 buffer.with_parts_mut(|prefix, _body, _suffix| {
3315 builder.partial_serialize(context, body_len, prefix);
3316 });
3317
3318 Ok((buffer, header_len + body_len))
3319 }
3320 }
3321
3322 #[derive(Clone, Debug, PartialEq)]
3323 pub struct FakeTcpSegment {
3324 pub src_port: u16,
3325 pub dst_port: u16,
3326 pub segment: SegmentHeader,
3327 pub payload_len: usize,
3328 }
3329
3330 impl<I: FilterIpExt> TransportPacketExt<I> for &FakeTcpSegment {
3331 fn proto() -> Option<I::Proto> {
3332 Some(I::map_ip_out(
3333 (),
3334 |()| Ipv4Proto::Proto(IpProto::Tcp),
3335 |()| Ipv6Proto::Proto(IpProto::Tcp),
3336 ))
3337 }
3338
3339 fn len(&self) -> usize {
3340 packet_formats::tcp::HDR_PREFIX_LEN + self.payload_len
3341 }
3342 }
3343
3344 impl MaybeTransportPacket for &FakeTcpSegment {
3345 fn transport_packet_data(&self) -> Option<TransportPacketData> {
3346 Some(TransportPacketData::Tcp {
3347 src_port: self.src_port,
3348 dst_port: self.dst_port,
3349 segment: self.segment.clone(),
3350 payload_len: self.payload_len,
3351 })
3352 }
3353 }
3354
3355 impl<I: IpExt> MaybeTransportPacketMut<I> for FakeTcpSegment {
3356 type TransportPacketMut<'a> = &'a mut Self;
3357
3358 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
3359 Some(self)
3360 }
3361 }
3362
3363 impl<I: IpExt> TransportPacketMut<I> for FakeTcpSegment {
3364 fn set_src_port(&mut self, port: NonZeroU16) {
3365 self.src_port = port.get();
3366 }
3367
3368 fn set_dst_port(&mut self, port: NonZeroU16) {
3369 self.dst_port = port.get();
3370 }
3371
3372 fn update_pseudo_header_src_addr(&mut self, _: I::Addr, _: I::Addr) {}
3373
3374 fn update_pseudo_header_dst_addr(&mut self, _: I::Addr, _: I::Addr) {}
3375 }
3376
3377 impl<I: IpExt> MaybeIcmpErrorPayload<I> for FakeTcpSegment {
3378 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
3379 None
3380 }
3381 }
3382
3383 impl<I: FilterIpExt> MaybeIcmpErrorMut<I> for FakeTcpSegment {
3384 type IcmpErrorMut<'a>
3385 = Never
3386 where
3387 Self: 'a;
3388
3389 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
3390 None
3391 }
3392 }
3393
3394 #[derive(Clone, Debug, PartialEq)]
3395 pub struct FakeUdpPacket {
3396 pub src_port: u16,
3397 pub dst_port: u16,
3398 }
3399
3400 impl FakeUdpPacket {
3401 const PAYLOAD_LEN: usize = 4;
3402
3403 fn reply(&self) -> Self {
3404 Self { src_port: self.dst_port, dst_port: self.src_port }
3405 }
3406 }
3407
3408 impl<I: FilterIpExt> TransportPacketExt<I> for &FakeUdpPacket {
3409 fn proto() -> Option<I::Proto> {
3410 Some(I::map_ip_out(
3411 (),
3412 |()| Ipv4Proto::Proto(IpProto::Udp),
3413 |()| Ipv6Proto::Proto(IpProto::Udp),
3414 ))
3415 }
3416
3417 fn len(&self) -> usize {
3418 packet_formats::udp::HEADER_BYTES + FakeUdpPacket::PAYLOAD_LEN
3419 }
3420 }
3421
3422 impl MaybeTransportPacket for &FakeUdpPacket {
3423 fn transport_packet_data(&self) -> Option<TransportPacketData> {
3424 Some(TransportPacketData::Generic {
3425 src_port: self.src_port,
3426 dst_port: self.dst_port,
3427 })
3428 }
3429 }
3430
3431 impl<I: IpExt> MaybeTransportPacketMut<I> for FakeUdpPacket {
3432 type TransportPacketMut<'a> = &'a mut Self;
3433
3434 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
3435 Some(self)
3436 }
3437 }
3438
3439 impl<I: IpExt> TransportPacketMut<I> for FakeUdpPacket {
3440 fn set_src_port(&mut self, port: NonZeroU16) {
3441 self.src_port = port.get();
3442 }
3443
3444 fn set_dst_port(&mut self, port: NonZeroU16) {
3445 self.dst_port = port.get();
3446 }
3447
3448 fn update_pseudo_header_src_addr(&mut self, _: I::Addr, _: I::Addr) {}
3449
3450 fn update_pseudo_header_dst_addr(&mut self, _: I::Addr, _: I::Addr) {}
3451 }
3452
3453 impl<I: IpExt> MaybeIcmpErrorPayload<I> for FakeUdpPacket {
3454 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
3455 None
3456 }
3457 }
3458
3459 impl<I: FilterIpExt> MaybeIcmpErrorMut<I> for FakeUdpPacket {
3460 type IcmpErrorMut<'a>
3461 = Never
3462 where
3463 Self: 'a;
3464
3465 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
3466 None
3467 }
3468 }
3469
3470 #[derive(Clone, Debug, PartialEq)]
3471 pub struct FakeNullPacket;
3472
3473 impl<I: IpExt> TransportPacketExt<I> for &FakeNullPacket {
3474 fn proto() -> Option<I::Proto> {
3475 None
3476 }
3477
3478 fn len(&self) -> usize {
3479 0
3480 }
3481 }
3482
3483 impl MaybeTransportPacket for &FakeNullPacket {
3484 fn transport_packet_data(&self) -> Option<TransportPacketData> {
3485 None
3486 }
3487 }
3488
3489 impl<I: IpExt> MaybeTransportPacketMut<I> for FakeNullPacket {
3490 type TransportPacketMut<'a> = Never;
3491
3492 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
3493 None
3494 }
3495 }
3496
3497 impl<I: IpExt> MaybeIcmpErrorPayload<I> for FakeNullPacket {
3498 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
3499 None
3500 }
3501 }
3502
3503 impl<I: FilterIpExt> MaybeIcmpErrorMut<I> for FakeNullPacket {
3504 type IcmpErrorMut<'a>
3505 = Never
3506 where
3507 Self: 'a;
3508
3509 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
3510 None
3511 }
3512 }
3513
3514 pub struct FakeIcmpEchoRequest {
3515 pub id: u16,
3516 }
3517
3518 impl<I: FilterIpExt> TransportPacketExt<I> for &FakeIcmpEchoRequest {
3519 fn proto() -> Option<I::Proto> {
3520 Some(I::map_ip_out((), |()| Ipv4Proto::Icmp, |()| Ipv6Proto::Icmpv6))
3521 }
3522
3523 fn len(&self) -> usize {
3524 8
3526 }
3527 }
3528
3529 impl MaybeTransportPacket for &FakeIcmpEchoRequest {
3530 fn transport_packet_data(&self) -> Option<TransportPacketData> {
3531 Some(TransportPacketData::Generic { src_port: self.id, dst_port: 0 })
3532 }
3533 }
3534
3535 impl<I: IpExt> MaybeTransportPacketMut<I> for FakeIcmpEchoRequest {
3536 type TransportPacketMut<'a> = &'a mut Self;
3537
3538 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
3539 Some(self)
3540 }
3541 }
3542
3543 impl<I: IpExt> TransportPacketMut<I> for FakeIcmpEchoRequest {
3544 fn set_src_port(&mut self, port: NonZeroU16) {
3545 self.id = port.get();
3546 }
3547
3548 fn set_dst_port(&mut self, _: NonZeroU16) {
3549 panic!("cannot set destination port for ICMP echo request")
3550 }
3551
3552 fn update_pseudo_header_src_addr(&mut self, _: I::Addr, _: I::Addr) {}
3553
3554 fn update_pseudo_header_dst_addr(&mut self, _: I::Addr, _: I::Addr) {}
3555 }
3556
3557 impl<I: IpExt> MaybeIcmpErrorPayload<I> for FakeIcmpEchoRequest {
3558 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
3559 None
3560 }
3561 }
3562
3563 impl<I: FilterIpExt> MaybeIcmpErrorMut<I> for FakeIcmpEchoRequest {
3564 type IcmpErrorMut<'a>
3565 = Never
3566 where
3567 Self: 'a;
3568
3569 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
3570 None
3571 }
3572 }
3573
3574 pub trait ArbitraryValue {
3575 fn arbitrary_value() -> Self;
3576 }
3577
3578 impl<I, T> ArbitraryValue for FakeIpPacket<I, T>
3579 where
3580 I: TestIpExt,
3581 T: ArbitraryValue,
3582 for<'a> &'a T: TransportPacketExt<I>,
3583 {
3584 fn arbitrary_value() -> Self {
3585 FakeIpPacket { src_ip: I::SRC_IP, dst_ip: I::DST_IP, body: T::arbitrary_value() }
3586 }
3587 }
3588
3589 impl ArbitraryValue for FakeTcpSegment {
3590 fn arbitrary_value() -> Self {
3591 FakeTcpSegment {
3592 src_port: 33333,
3593 dst_port: 44444,
3594 segment: SegmentHeader::arbitrary_value(),
3595 payload_len: 8888,
3596 }
3597 }
3598 }
3599
3600 impl ArbitraryValue for FakeUdpPacket {
3601 fn arbitrary_value() -> Self {
3602 FakeUdpPacket { src_port: 33333, dst_port: 44444 }
3603 }
3604 }
3605
3606 impl ArbitraryValue for FakeNullPacket {
3607 fn arbitrary_value() -> Self {
3608 FakeNullPacket
3609 }
3610 }
3611
3612 impl ArbitraryValue for FakeIcmpEchoRequest {
3613 fn arbitrary_value() -> Self {
3614 FakeIcmpEchoRequest { id: 1 }
3615 }
3616 }
3617
3618 impl ArbitraryValue for SegmentHeader {
3619 fn arbitrary_value() -> Self {
3620 SegmentHeader {
3621 seq: SeqNum::new(55555),
3622 wnd: UnscaledWindowSize::from(1234),
3623 ..Default::default()
3624 }
3625 }
3626 }
3627
3628 pub(crate) trait IcmpErrorMessage<I: FilterIpExt> {
3629 type Serializer: TransportPacketSerializer<I, Buffer: packet::ReusableBuffer>
3630 + Debug
3631 + PartialEq;
3632
3633 fn proto() -> I::Proto {
3634 I::map_ip((), |()| Ipv4Proto::Icmp, |()| Ipv6Proto::Icmpv6)
3635 }
3636
3637 fn make_serializer(
3638 src_ip: I::Addr,
3639 dst_ip: I::Addr,
3640 inner: Vec<u8>,
3641 ) -> Self::Serializer;
3642
3643 fn make_serializer_truncated(
3644 src_ip: I::Addr,
3645 dst_ip: I::Addr,
3646 mut payload: Vec<u8>,
3647 truncate_payload: Option<usize>,
3648 ) -> Self::Serializer {
3649 if let Some(len) = truncate_payload {
3650 payload.truncate(len);
3651 }
3652
3653 Self::make_serializer(src_ip, dst_ip, payload)
3654 }
3655 }
3656
3657 pub(crate) struct Icmpv4DestUnreachableError;
3658
3659 impl IcmpErrorMessage<Ipv4> for Icmpv4DestUnreachableError {
3660 type Serializer = Nested<Buf<Vec<u8>>, IcmpPacketBuilder<Ipv4, IcmpDestUnreachable>>;
3661
3662 fn make_serializer(
3663 src_ip: Ipv4Addr,
3664 dst_ip: Ipv4Addr,
3665 payload: Vec<u8>,
3666 ) -> Self::Serializer {
3667 IcmpPacketBuilder::<Ipv4, IcmpDestUnreachable>::new(
3668 src_ip,
3669 dst_ip,
3670 Icmpv4DestUnreachableCode::DestHostUnreachable,
3671 IcmpDestUnreachable::default(),
3672 )
3673 .wrap_body(Buf::new(payload, ..))
3674 }
3675 }
3676
3677 pub(crate) struct Icmpv6DestUnreachableError;
3678
3679 impl IcmpErrorMessage<Ipv6> for Icmpv6DestUnreachableError {
3680 type Serializer = Nested<
3681 TruncatingSerializer<Buf<Vec<u8>>>,
3682 IcmpPacketBuilder<Ipv6, IcmpDestUnreachable>,
3683 >;
3684
3685 fn make_serializer(
3686 src_ip: Ipv6Addr,
3687 dst_ip: Ipv6Addr,
3688 payload: Vec<u8>,
3689 ) -> Self::Serializer {
3690 IcmpPacketBuilder::<Ipv6, IcmpDestUnreachable>::new(
3691 src_ip,
3692 dst_ip,
3693 Icmpv6DestUnreachableCode::AddrUnreachable,
3694 IcmpDestUnreachable::default(),
3695 )
3696 .wrap_body(TruncatingSerializer::new(
3697 Buf::new(payload, ..),
3698 TruncateDirection::DiscardBack,
3699 ))
3700 }
3701 }
3702 }
3703
3704 pub fn new_filter_egress_ip_packet<I: FilterIpExt, S: TransportPacketSerializer<I>>(
3706 src_addr: I::Addr,
3707 dst_addr: I::Addr,
3708 protocol: I::Proto,
3709 body: &'_ mut S,
3710 ) -> impl FilterIpPacket<I> + use<'_, I, S> {
3711 TxPacket::new(src_addr, dst_addr, protocol, body)
3712 }
3713}
3714
3715#[cfg(test)]
3716mod tests {
3717 use alloc::vec::Vec;
3718 use core::fmt::Debug;
3719 use core::marker::PhantomData;
3720 use netstack3_base::{NetworkSerializationContext, SeqNum, UnscaledWindowSize};
3721
3722 use assert_matches::assert_matches;
3723 use ip_test_macro::ip_test;
3724 use packet::{
3725 EmptyBuf, FragmentedBuffer as _, InnerPacketBuilder as _, ParseBufferMut, PartialSerializer,
3726 };
3727 use packet_formats::icmp::IcmpZeroCode;
3728 use packet_formats::tcp::TcpSegmentBuilder;
3729 use test_case::{test_case, test_matrix};
3730
3731 use crate::conntrack;
3732
3733 use super::testutil::internal::{
3734 IcmpErrorMessage, Icmpv4DestUnreachableError, Icmpv6DestUnreachableError, TestIpExt,
3735 };
3736 use super::*;
3737
3738 const SRC_PORT: NonZeroU16 = NonZeroU16::new(11111).unwrap();
3739 const DST_PORT: NonZeroU16 = NonZeroU16::new(22222).unwrap();
3740 const SRC_PORT_2: NonZeroU16 = NonZeroU16::new(44444).unwrap();
3741 const DST_PORT_2: NonZeroU16 = NonZeroU16::new(55555).unwrap();
3742
3743 const SEQ_NUM: u32 = 1;
3744 const ACK_NUM: Option<u32> = Some(2);
3745 const WINDOW_SIZE: u16 = 3u16;
3746
3747 trait Protocol {
3748 const HEADER_SIZE: usize;
3749
3750 type Serializer<'a, I: FilterIpExt>: TransportPacketSerializer<I, Buffer: packet::ReusableBuffer>
3751 + MaybeTransportPacketMut<I>
3752 + Debug
3753 + PartialEq;
3754
3755 fn proto<I: IpExt>() -> I::Proto;
3756
3757 fn make_serializer_with_ports_data<'a, I: FilterIpExt>(
3758 src_ip: I::Addr,
3759 dst_ip: I::Addr,
3760 src_port: NonZeroU16,
3761 dst_port: NonZeroU16,
3762 data: &'a [u8],
3763 ) -> Self::Serializer<'a, I>;
3764
3765 fn make_serializer_with_ports<'a, I: FilterIpExt>(
3766 src_ip: I::Addr,
3767 dst_ip: I::Addr,
3768 src_port: NonZeroU16,
3769 dst_port: NonZeroU16,
3770 ) -> Self::Serializer<'a, I> {
3771 Self::make_serializer_with_ports_data(src_ip, dst_ip, src_port, dst_port, &[1, 2, 3])
3772 }
3773
3774 fn make_serializer<'a, I: FilterIpExt>(
3775 src_ip: I::Addr,
3776 dst_ip: I::Addr,
3777 ) -> Self::Serializer<'a, I> {
3778 Self::make_serializer_with_ports(src_ip, dst_ip, SRC_PORT, DST_PORT)
3779 }
3780
3781 fn make_packet<I: FilterIpExt>(src_ip: I::Addr, dst_ip: I::Addr) -> Vec<u8> {
3782 Self::make_packet_with_ports::<I>(src_ip, dst_ip, SRC_PORT, DST_PORT)
3783 }
3784
3785 fn make_packet_with_ports<I: FilterIpExt>(
3786 src_ip: I::Addr,
3787 dst_ip: I::Addr,
3788 src_port: NonZeroU16,
3789 dst_port: NonZeroU16,
3790 ) -> Vec<u8> {
3791 Self::make_serializer_with_ports::<I>(src_ip, dst_ip, src_port, dst_port)
3792 .serialize_vec_outer(&mut NetworkSerializationContext::default())
3793 .expect("serialize packet")
3794 .unwrap_b()
3795 .into_inner()
3796 }
3797
3798 fn make_ip_packet_with_ports_data<I: FilterIpExt>(
3799 src_ip: I::Addr,
3800 dst_ip: I::Addr,
3801 src_port: NonZeroU16,
3802 dst_port: NonZeroU16,
3803 data: &[u8],
3804 ) -> Vec<u8> {
3805 I::PacketBuilder::new(src_ip, dst_ip, u8::MAX, Self::proto::<I>())
3806 .wrap_body(Self::make_serializer_with_ports_data::<I>(
3807 src_ip, dst_ip, src_port, dst_port, data,
3808 ))
3809 .serialize_vec_outer(&mut NetworkSerializationContext::default())
3810 .expect("serialize packet")
3811 .unwrap_b()
3812 .into_inner()
3813 }
3814 }
3815
3816 struct Udp;
3817
3818 impl Protocol for Udp {
3819 const HEADER_SIZE: usize = 8;
3820
3821 type Serializer<'a, I: FilterIpExt> =
3822 Nested<InnerSerializer<&'a [u8], EmptyBuf>, UdpPacketBuilder<I::Addr>>;
3823
3824 fn proto<I: IpExt>() -> I::Proto {
3825 IpProto::Udp.into()
3826 }
3827
3828 fn make_serializer_with_ports_data<'a, I: FilterIpExt>(
3829 src_ip: I::Addr,
3830 dst_ip: I::Addr,
3831 src_port: NonZeroU16,
3832 dst_port: NonZeroU16,
3833 data: &'a [u8],
3834 ) -> Self::Serializer<'a, I> {
3835 UdpPacketBuilder::new(src_ip, dst_ip, Some(src_port), dst_port)
3836 .wrap_body(data.into_serializer())
3837 }
3838 }
3839
3840 impl<A: IpAddress, Inner: PayloadLen> MaybeTransportPacket for Nested<Inner, TcpSegmentBuilder<A>> {
3848 fn transport_packet_data(&self) -> Option<TransportPacketData> {
3849 Some(TransportPacketData::Tcp {
3850 src_port: TcpSegmentBuilder::src_port(self.outer()).map_or(0, NonZeroU16::get),
3851 dst_port: TcpSegmentBuilder::dst_port(self.outer()).map_or(0, NonZeroU16::get),
3852 segment: self.outer().try_into().ok()?,
3853 payload_len: self.inner().len(),
3854 })
3855 }
3856 }
3857
3858 impl<I: IpExt, Inner> MaybeTransportPacketMut<I> for Nested<Inner, TcpSegmentBuilder<I::Addr>> {
3859 type TransportPacketMut<'a>
3860 = &'a mut Self
3861 where
3862 Self: 'a;
3863
3864 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
3865 Some(self)
3866 }
3867 }
3868
3869 impl<I: IpExt, Inner> TransportPacketMut<I> for Nested<Inner, TcpSegmentBuilder<I::Addr>> {
3870 fn set_src_port(&mut self, port: NonZeroU16) {
3871 self.outer_mut().set_src_port(port);
3872 }
3873
3874 fn set_dst_port(&mut self, port: NonZeroU16) {
3875 self.outer_mut().set_dst_port(port);
3876 }
3877
3878 fn update_pseudo_header_src_addr(&mut self, _old: I::Addr, new: I::Addr) {
3879 self.outer_mut().set_src_ip(new);
3880 }
3881
3882 fn update_pseudo_header_dst_addr(&mut self, _old: I::Addr, new: I::Addr) {
3883 self.outer_mut().set_dst_ip(new);
3884 }
3885 }
3886
3887 impl<A: IpAddress, I: IpExt, Inner> MaybeIcmpErrorPayload<I>
3888 for Nested<Inner, TcpSegmentBuilder<A>>
3889 {
3890 fn icmp_error_payload(&self) -> Option<ParsedIcmpErrorPayload<I>> {
3891 None
3892 }
3893 }
3894
3895 impl<A: IpAddress, I: FilterIpExt, Inner> MaybeIcmpErrorMut<I>
3896 for Nested<Inner, TcpSegmentBuilder<A>>
3897 {
3898 type IcmpErrorMut<'a>
3899 = Never
3900 where
3901 Self: 'a;
3902
3903 fn icmp_error_mut<'a>(&'a mut self) -> Option<Self::IcmpErrorMut<'a>> {
3904 None
3905 }
3906 }
3907
3908 enum Tcp {}
3909
3910 impl Protocol for Tcp {
3911 const HEADER_SIZE: usize = 20;
3912
3913 type Serializer<'a, I: FilterIpExt> =
3914 Nested<InnerSerializer<&'a [u8], EmptyBuf>, TcpSegmentBuilder<I::Addr>>;
3915
3916 fn proto<I: IpExt>() -> I::Proto {
3917 IpProto::Tcp.into()
3918 }
3919
3920 fn make_serializer_with_ports_data<'a, I: FilterIpExt>(
3921 src_ip: I::Addr,
3922 dst_ip: I::Addr,
3923 src_port: NonZeroU16,
3924 dst_port: NonZeroU16,
3925 data: &'a [u8],
3926 ) -> Self::Serializer<'a, I> {
3927 TcpSegmentBuilder::new(
3928 src_ip,
3929 dst_ip,
3930 src_port,
3931 dst_port,
3932 SEQ_NUM,
3933 ACK_NUM,
3934 WINDOW_SIZE,
3935 )
3936 .wrap_body(data.into_serializer())
3937 }
3938 }
3939
3940 enum IcmpEchoRequest {}
3941
3942 impl Protocol for IcmpEchoRequest {
3943 const HEADER_SIZE: usize = 8;
3944
3945 type Serializer<'a, I: FilterIpExt> = Nested<
3946 InnerSerializer<&'a [u8], EmptyBuf>,
3947 IcmpPacketBuilder<I, icmp::IcmpEchoRequest>,
3948 >;
3949
3950 fn proto<I: IpExt>() -> I::Proto {
3951 I::map_ip((), |()| Ipv4Proto::Icmp, |()| Ipv6Proto::Icmpv6)
3952 }
3953
3954 fn make_serializer_with_ports_data<'a, I: FilterIpExt>(
3955 src_ip: I::Addr,
3956 dst_ip: I::Addr,
3957 src_port: NonZeroU16,
3958 _dst_port: NonZeroU16,
3959 data: &'a [u8],
3960 ) -> Self::Serializer<'a, I> {
3961 IcmpPacketBuilder::<I, _>::new(
3962 src_ip,
3963 dst_ip,
3964 IcmpZeroCode,
3965 icmp::IcmpEchoRequest::new(src_port.get(), 0),
3966 )
3967 .wrap_body(data.into_serializer())
3968 }
3969 }
3970
3971 enum IcmpEchoReply {}
3972
3973 impl Protocol for IcmpEchoReply {
3974 const HEADER_SIZE: usize = 8;
3975
3976 type Serializer<'a, I: FilterIpExt> =
3977 Nested<InnerSerializer<&'a [u8], EmptyBuf>, IcmpPacketBuilder<I, icmp::IcmpEchoReply>>;
3978
3979 fn proto<I: IpExt>() -> I::Proto {
3980 I::map_ip((), |()| Ipv4Proto::Icmp, |()| Ipv6Proto::Icmpv6)
3981 }
3982
3983 fn make_serializer_with_ports_data<'a, I: FilterIpExt>(
3984 src_ip: I::Addr,
3985 dst_ip: I::Addr,
3986 _src_port: NonZeroU16,
3987 dst_port: NonZeroU16,
3988 data: &'a [u8],
3989 ) -> Self::Serializer<'a, I> {
3990 IcmpPacketBuilder::<I, _>::new(
3991 src_ip,
3992 dst_ip,
3993 IcmpZeroCode,
3994 icmp::IcmpEchoReply::new(dst_port.get(), 0),
3995 )
3996 .wrap_body(data.into_serializer())
3997 }
3998 }
3999
4000 enum TransportPacketDataProtocol {
4001 Tcp,
4002 Udp,
4003 IcmpEchoRequest,
4004 }
4005
4006 impl TransportPacketDataProtocol {
4007 fn make_packet<I: TestIpExt>(&self, src_ip: I::Addr, dst_ip: I::Addr) -> Vec<u8> {
4008 match self {
4009 TransportPacketDataProtocol::Tcp => Tcp::make_packet::<I>(src_ip, dst_ip),
4010 TransportPacketDataProtocol::Udp => Udp::make_packet::<I>(src_ip, dst_ip),
4011 TransportPacketDataProtocol::IcmpEchoRequest => {
4012 IcmpEchoRequest::make_packet::<I>(src_ip, dst_ip)
4013 }
4014 }
4015 }
4016
4017 fn make_ip_packet_with_ports_data<I: TestIpExt>(
4018 &self,
4019 src_ip: I::Addr,
4020 dst_ip: I::Addr,
4021 src_port: NonZeroU16,
4022 dst_port: NonZeroU16,
4023 data: &[u8],
4024 ) -> Vec<u8> {
4025 match self {
4026 TransportPacketDataProtocol::Tcp => Tcp::make_ip_packet_with_ports_data::<I>(
4027 src_ip, dst_ip, src_port, dst_port, data,
4028 ),
4029 TransportPacketDataProtocol::Udp => Udp::make_ip_packet_with_ports_data::<I>(
4030 src_ip, dst_ip, src_port, dst_port, data,
4031 ),
4032 TransportPacketDataProtocol::IcmpEchoRequest => {
4033 IcmpEchoRequest::make_ip_packet_with_ports_data::<I>(
4034 src_ip, dst_ip, src_port, dst_port, data,
4035 )
4036 }
4037 }
4038 }
4039
4040 fn proto<I: TestIpExt>(&self) -> I::Proto {
4041 match self {
4042 TransportPacketDataProtocol::Tcp => Tcp::proto::<I>(),
4043 TransportPacketDataProtocol::Udp => Udp::proto::<I>(),
4044 TransportPacketDataProtocol::IcmpEchoRequest => IcmpEchoRequest::proto::<I>(),
4045 }
4046 }
4047 }
4048
4049 #[ip_test(I)]
4050 #[test_case(TransportPacketDataProtocol::Udp)]
4051 #[test_case(TransportPacketDataProtocol::Tcp)]
4052 #[test_case(TransportPacketDataProtocol::IcmpEchoRequest)]
4053 fn transport_packet_data_from_serialized<I: TestIpExt>(proto: TransportPacketDataProtocol) {
4054 let expected_data = match proto {
4055 TransportPacketDataProtocol::Tcp => TransportPacketData::Tcp {
4056 src_port: SRC_PORT.get(),
4057 dst_port: DST_PORT.get(),
4058 segment: SegmentHeader {
4059 seq: SeqNum::new(SEQ_NUM),
4060 ack: ACK_NUM.map(SeqNum::new),
4061 wnd: UnscaledWindowSize::from(WINDOW_SIZE),
4062 ..Default::default()
4063 },
4064 payload_len: 3,
4065 },
4066 TransportPacketDataProtocol::Udp => {
4067 TransportPacketData::Generic { src_port: SRC_PORT.get(), dst_port: DST_PORT.get() }
4068 }
4069 TransportPacketDataProtocol::IcmpEchoRequest => {
4070 TransportPacketData::Generic { src_port: SRC_PORT.get(), dst_port: SRC_PORT.get() }
4071 }
4072 };
4073
4074 let buf = proto.make_packet::<I>(I::SRC_IP, I::DST_IP);
4075 let parsed_data = TransportPacketData::parse_in_ip_packet::<I, _>(
4076 I::SRC_IP,
4077 I::DST_IP,
4078 proto.proto::<I>(),
4079 buf.as_slice(),
4080 )
4081 .expect("failed to parse transport packet data");
4082
4083 assert_eq!(parsed_data, expected_data);
4084 }
4085
4086 #[ip_test(I)]
4090 fn transport_packet_data_from_serialized_invalid_tcp_options<I: TestIpExt>() {
4091 let mut buf = TransportPacketDataProtocol::Tcp.make_packet::<I>(I::SRC_IP, I::DST_IP);
4092
4093 assert!(buf.len() >= 20);
4095
4096 buf[12] = (6 << 4) | (buf[12] & 0x0F);
4099
4100 let mut new_buf = Vec::new();
4102 new_buf.extend_from_slice(&buf[..20]);
4103 new_buf.extend_from_slice(&[255, 0, 0, 0]);
4104 new_buf.extend_from_slice(&buf[20..]);
4105
4106 let parsed_data = TransportPacketData::parse_in_ip_packet::<I, _>(
4107 I::SRC_IP,
4108 I::DST_IP,
4109 IpProto::Tcp.into(),
4110 new_buf.as_slice(),
4111 );
4112
4113 assert_matches!(
4114 parsed_data,
4115 Some(TransportPacketData::Tcp { src_port, dst_port, .. }) => {
4116 assert_eq!(src_port, SRC_PORT.get());
4117 assert_eq!(dst_port, DST_PORT.get());
4118 }
4119 );
4120 }
4121
4122 #[ip_test(I)]
4126 fn transport_packet_data_from_serialized_malformed_tcp_flags<I: TestIpExt>() {
4127 let mut buf = TransportPacketDataProtocol::Tcp.make_packet::<I>(I::SRC_IP, I::DST_IP);
4128
4129 assert!(buf.len() >= 20);
4132
4133 buf[13] |= 0x02 | 0x04;
4136
4137 let parsed_data = TransportPacketData::parse_in_ip_packet::<I, _>(
4138 I::SRC_IP,
4139 I::DST_IP,
4140 IpProto::Tcp.into(),
4141 buf.as_slice(),
4142 );
4143
4144 assert_matches!(
4145 parsed_data,
4146 Some(TransportPacketData::Generic { src_port, dst_port }) => {
4147 assert_eq!(src_port, SRC_PORT.get());
4148 assert_eq!(dst_port, DST_PORT.get());
4149 }
4150 );
4151 }
4152
4153 enum PacketType {
4154 FullyParsed,
4155 Raw,
4156 }
4157
4158 #[ip_test(I)]
4159 #[test_matrix(
4160 [
4161 TransportPacketDataProtocol::Udp,
4162 TransportPacketDataProtocol::Tcp,
4163 TransportPacketDataProtocol::IcmpEchoRequest,
4164 ],
4165 [
4166 PacketType::FullyParsed,
4167 PacketType::Raw
4168 ]
4169 )]
4170 fn conntrack_packet_data_from_ip_packet<I: TestIpExt>(
4171 proto: TransportPacketDataProtocol,
4172 packet_type: PacketType,
4173 ) where
4174 for<'a> I::Packet<&'a mut [u8]>: IpPacket<I>,
4175 for<'a> I::PacketRaw<&'a mut [u8]>: IpPacket<I>,
4176 {
4177 let expected_data = match proto {
4178 TransportPacketDataProtocol::Tcp => conntrack::PacketMetadata::new(
4179 I::SRC_IP,
4180 I::DST_IP,
4181 conntrack::TransportProtocol::Tcp,
4182 TransportPacketData::Tcp {
4183 src_port: SRC_PORT.get(),
4184 dst_port: DST_PORT.get(),
4185 segment: SegmentHeader {
4186 seq: SeqNum::new(SEQ_NUM),
4187 ack: ACK_NUM.map(SeqNum::new),
4188 wnd: UnscaledWindowSize::from(WINDOW_SIZE),
4189 ..Default::default()
4190 },
4191 payload_len: 3,
4192 },
4193 ),
4194 TransportPacketDataProtocol::Udp => conntrack::PacketMetadata::new(
4195 I::SRC_IP,
4196 I::DST_IP,
4197 conntrack::TransportProtocol::Udp,
4198 TransportPacketData::Generic { src_port: SRC_PORT.get(), dst_port: DST_PORT.get() },
4199 ),
4200 TransportPacketDataProtocol::IcmpEchoRequest => conntrack::PacketMetadata::new(
4201 I::SRC_IP,
4202 I::DST_IP,
4203 conntrack::TransportProtocol::Icmp,
4204 TransportPacketData::Generic { src_port: SRC_PORT.get(), dst_port: SRC_PORT.get() },
4205 ),
4206 };
4207
4208 let mut buf = proto.make_ip_packet_with_ports_data::<I>(
4209 I::SRC_IP,
4210 I::DST_IP,
4211 SRC_PORT,
4212 DST_PORT,
4213 &[1, 2, 3],
4214 );
4215
4216 let parsed_data = match packet_type {
4217 PacketType::FullyParsed => {
4218 let packet = I::Packet::parse_mut(SliceBufViewMut::new(buf.as_mut()), ())
4219 .expect("parse IP packet");
4220 packet.conntrack_packet().expect("packet should be trackable")
4221 }
4222 PacketType::Raw => {
4223 let packet = I::PacketRaw::parse_mut(SliceBufViewMut::new(buf.as_mut()), ())
4224 .expect("parse IP packet");
4225 packet.conntrack_packet().expect("packet should be trackable")
4226 }
4227 };
4228
4229 assert_eq!(parsed_data, expected_data);
4230 }
4231
4232 #[ip_test(I)]
4233 #[test_case(PhantomData::<Udp>)]
4234 #[test_case(PhantomData::<Tcp>)]
4235 #[test_case(PhantomData::<IcmpEchoRequest>)]
4236 fn update_pseudo_header_address_updates_checksum<I: TestIpExt, P: Protocol>(
4237 _proto: PhantomData<P>,
4238 ) {
4239 let mut buf = P::make_packet::<I>(I::SRC_IP, I::DST_IP);
4240 let view = SliceBufViewMut::new(&mut buf);
4241
4242 let mut packet = ParsedTransportHeaderMut::<I>::parse_in_ip_packet(P::proto::<I>(), view)
4243 .expect("parse transport header");
4244 packet.update_pseudo_header_src_addr(I::SRC_IP, I::SRC_IP_2);
4245 packet.update_pseudo_header_dst_addr(I::DST_IP, I::DST_IP_2);
4246 drop(packet);
4249
4250 let equivalent = P::make_packet::<I>(I::SRC_IP_2, I::DST_IP_2);
4251
4252 assert_eq!(equivalent, buf);
4253 }
4254
4255 #[ip_test(I)]
4256 #[test_case(PhantomData::<Udp>, true, true)]
4257 #[test_case(PhantomData::<Tcp>, true, true)]
4258 #[test_case(PhantomData::<IcmpEchoRequest>, true, false)]
4259 #[test_case(PhantomData::<IcmpEchoReply>, false, true)]
4260 fn parsed_packet_update_src_dst_port_updates_checksum<I: TestIpExt, P: Protocol>(
4261 _proto: PhantomData<P>,
4262 update_src_port: bool,
4263 update_dst_port: bool,
4264 ) {
4265 let mut buf = P::make_packet_with_ports::<I>(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT);
4266 let view = SliceBufViewMut::new(&mut buf);
4267
4268 let mut packet = ParsedTransportHeaderMut::<I>::parse_in_ip_packet(P::proto::<I>(), view)
4269 .expect("parse transport header");
4270 let expected_src_port = if update_src_port {
4271 packet.set_src_port(SRC_PORT_2);
4272 SRC_PORT_2
4273 } else {
4274 SRC_PORT
4275 };
4276 let expected_dst_port = if update_dst_port {
4277 packet.set_dst_port(DST_PORT_2);
4278 DST_PORT_2
4279 } else {
4280 DST_PORT
4281 };
4282 drop(packet);
4283
4284 let equivalent = P::make_packet_with_ports::<I>(
4285 I::SRC_IP,
4286 I::DST_IP,
4287 expected_src_port,
4288 expected_dst_port,
4289 );
4290
4291 assert_eq!(equivalent, buf);
4292 }
4293
4294 #[ip_test(I)]
4295 #[test_case(PhantomData::<Udp>)]
4296 #[test_case(PhantomData::<Tcp>)]
4297 fn serializer_update_src_dst_port_updates_checksum<I: TestIpExt, P: Protocol>(
4298 _proto: PhantomData<P>,
4299 ) {
4300 let mut serializer =
4301 P::make_serializer_with_ports::<I>(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT);
4302 let mut packet =
4303 serializer.transport_packet_mut().expect("packet should support rewriting");
4304 packet.set_src_port(SRC_PORT_2);
4305 packet.set_dst_port(DST_PORT_2);
4306 drop(packet);
4307
4308 let equivalent =
4309 P::make_serializer_with_ports::<I>(I::SRC_IP, I::DST_IP, SRC_PORT_2, DST_PORT_2);
4310
4311 assert_eq!(equivalent, serializer);
4312 }
4313
4314 #[ip_test(I)]
4315 fn icmp_echo_request_update_id_port_updates_checksum<I: TestIpExt>() {
4316 let mut serializer = IcmpPacketBuilder::<I, _>::new(
4317 I::SRC_IP,
4318 I::DST_IP,
4319 IcmpZeroCode,
4320 icmp::IcmpEchoRequest::new(SRC_PORT.get(), 0),
4321 )
4322 .wrap_body(EmptyBuf);
4323 serializer
4324 .transport_packet_mut()
4325 .expect("packet should support rewriting")
4326 .set_src_port(SRC_PORT_2);
4327
4328 let equivalent = IcmpPacketBuilder::<I, _>::new(
4329 I::SRC_IP,
4330 I::DST_IP,
4331 IcmpZeroCode,
4332 icmp::IcmpEchoRequest::new(SRC_PORT_2.get(), 0),
4333 )
4334 .wrap_body(EmptyBuf);
4335
4336 assert_eq!(equivalent, serializer);
4337 }
4338
4339 #[ip_test(I)]
4340 fn icmp_echo_reply_update_id_port_updates_checksum<I: TestIpExt>() {
4341 let mut serializer = IcmpPacketBuilder::<I, _>::new(
4342 I::SRC_IP,
4343 I::DST_IP,
4344 IcmpZeroCode,
4345 icmp::IcmpEchoReply::new(SRC_PORT.get(), 0),
4346 )
4347 .wrap_body(EmptyBuf);
4348 serializer
4349 .transport_packet_mut()
4350 .expect("packet should support rewriting")
4351 .set_dst_port(SRC_PORT_2);
4352
4353 let equivalent = IcmpPacketBuilder::<I, _>::new(
4354 I::SRC_IP,
4355 I::DST_IP,
4356 IcmpZeroCode,
4357 icmp::IcmpEchoReply::new(SRC_PORT_2.get(), 0),
4358 )
4359 .wrap_body(EmptyBuf);
4360
4361 assert_eq!(equivalent, serializer);
4362 }
4363
4364 fn ip_packet<I: TestIpExt, P: Protocol>(src: I::Addr, dst: I::Addr) -> Buf<Vec<u8>> {
4365 Buf::new(P::make_packet::<I>(src, dst), ..)
4366 .wrap_in(I::PacketBuilder::new(src, dst, I::PACKET_TTL, P::proto::<I>()))
4367 .serialize_vec_outer(&mut NetworkSerializationContext::default())
4368 .expect("serialize IP packet")
4369 .unwrap_b()
4370 }
4371
4372 #[ip_test(I)]
4373 #[test_matrix(
4374 [
4375 PhantomData::<Udp>,
4376 PhantomData::<Tcp>,
4377 PhantomData::<IcmpEchoRequest>,
4378 ],
4379 [
4380 PacketType::FullyParsed,
4381 PacketType::Raw
4382 ]
4383 )]
4384 fn ip_packet_set_src_dst_addr_updates_checksums<I: TestIpExt, P: Protocol>(
4385 _proto: PhantomData<P>,
4386 packet_type: PacketType,
4387 ) where
4388 for<'a> I::Packet<&'a mut [u8]>: IpPacket<I>,
4389 for<'a> I::PacketRaw<&'a mut [u8]>: IpPacket<I>,
4390 {
4391 let mut buf = ip_packet::<I, P>(I::SRC_IP, I::DST_IP).into_inner();
4392
4393 match packet_type {
4394 PacketType::FullyParsed => {
4395 let mut packet = I::Packet::parse_mut(SliceBufViewMut::new(&mut buf), ())
4396 .expect("parse IP packet");
4397 packet.set_src_addr(I::SRC_IP_2);
4398 packet.set_dst_addr(I::DST_IP_2);
4399 }
4400 PacketType::Raw => {
4401 let mut packet = I::PacketRaw::parse_mut(SliceBufViewMut::new(&mut buf), ())
4402 .expect("parse IP packet");
4403 packet.set_src_addr(I::SRC_IP_2);
4404 packet.set_dst_addr(I::DST_IP_2);
4405 }
4406 }
4407
4408 let equivalent = ip_packet::<I, P>(I::SRC_IP_2, I::DST_IP_2).into_inner();
4409
4410 assert_eq!(equivalent, buf);
4411 }
4412
4413 #[ip_test(I)]
4414 #[test_case(PhantomData::<Udp>)]
4415 #[test_case(PhantomData::<Tcp>)]
4416 #[test_case(PhantomData::<IcmpEchoRequest>)]
4417 fn forwarded_packet_set_src_dst_addr_updates_checksums<I: TestIpExt, P: Protocol>(
4418 _proto: PhantomData<P>,
4419 ) {
4420 let mut buffer = ip_packet::<I, P>(I::SRC_IP, I::DST_IP);
4421 let meta = buffer.parse::<I::Packet<_>>().expect("parse IP packet").parse_metadata();
4422 let mut packet = ForwardedPacket::<I, _>::new(
4423 I::SRC_IP,
4424 I::DST_IP,
4425 P::proto::<I>(),
4426 meta,
4427 buffer,
4428 false,
4429 );
4430 packet.set_src_addr(I::SRC_IP_2);
4431 packet.set_dst_addr(I::DST_IP_2);
4432
4433 let mut buffer = ip_packet::<I, P>(I::SRC_IP_2, I::DST_IP_2);
4434 let meta = buffer.parse::<I::Packet<_>>().expect("parse IP packet").parse_metadata();
4435 let equivalent = ForwardedPacket::<I, _>::new(
4436 I::SRC_IP_2,
4437 I::DST_IP_2,
4438 P::proto::<I>(),
4439 meta,
4440 buffer,
4441 false,
4442 );
4443
4444 assert_eq!(equivalent, packet);
4445 }
4446
4447 #[ip_test(I)]
4448 #[test_case(PhantomData::<Udp>)]
4449 #[test_case(PhantomData::<Tcp>)]
4450 #[test_case(PhantomData::<IcmpEchoRequest>)]
4451 fn tx_packet_set_src_dst_addr_updates_checksums<I: TestIpExt, P: Protocol>(
4452 _proto: PhantomData<P>,
4453 ) {
4454 let mut body = P::make_serializer::<I>(I::SRC_IP, I::DST_IP);
4455 let mut packet = TxPacket::<I, _>::new(I::SRC_IP, I::DST_IP, P::proto::<I>(), &mut body);
4456 packet.set_src_addr(I::SRC_IP_2);
4457 packet.set_dst_addr(I::DST_IP_2);
4458
4459 let mut equivalent_body = P::make_serializer::<I>(I::SRC_IP_2, I::DST_IP_2);
4460 let equivalent =
4461 TxPacket::new(I::SRC_IP_2, I::DST_IP_2, P::proto::<I>(), &mut equivalent_body);
4462
4463 assert_eq!(equivalent, packet);
4464 }
4465
4466 #[ip_test(I)]
4467 #[test_case(PhantomData::<Udp>)]
4468 #[test_case(PhantomData::<Tcp>)]
4469 #[test_case(PhantomData::<IcmpEchoRequest>)]
4470 fn nested_serializer_set_src_dst_addr_updates_checksums<I: TestIpExt, P: Protocol>(
4471 _proto: PhantomData<P>,
4472 ) {
4473 let mut packet =
4474 I::PacketBuilder::new(I::SRC_IP, I::DST_IP, I::PACKET_TTL, P::proto::<I>())
4475 .wrap_body(P::make_serializer::<I>(I::SRC_IP, I::DST_IP));
4476 packet.set_src_addr(I::SRC_IP_2);
4477 packet.set_dst_addr(I::DST_IP_2);
4478
4479 let equivalent = P::make_serializer::<I>(I::SRC_IP_2, I::DST_IP_2).wrap_in(
4480 I::PacketBuilder::new(I::SRC_IP_2, I::DST_IP_2, I::PACKET_TTL, P::proto::<I>()),
4481 );
4482
4483 assert_eq!(equivalent, packet);
4484 }
4485
4486 #[ip_test(I)]
4487 #[test_matrix(
4488 [
4489 PhantomData::<Udp>,
4490 PhantomData::<Tcp>,
4491 PhantomData::<IcmpEchoRequest>,
4492 ],
4493 [
4494 PacketType::FullyParsed,
4495 PacketType::Raw
4496 ]
4497 )]
4498 fn no_icmp_error_for_normal_ip_packet<I: TestIpExt, P: Protocol>(
4499 _proto: PhantomData<P>,
4500 packet_type: PacketType,
4501 ) where
4502 for<'a> I::Packet<&'a mut [u8]>: IpPacket<I>,
4503 for<'a> I::PacketRaw<&'a mut [u8]>: IpPacket<I>,
4504 {
4505 let mut buf = ip_packet::<I, P>(I::SRC_IP, I::DST_IP).into_inner();
4506 let icmp_error = match packet_type {
4507 PacketType::FullyParsed => {
4508 let packet = I::Packet::parse_mut(SliceBufViewMut::new(&mut buf), ())
4509 .expect("parse IP packet");
4510 let icmp_payload = packet.maybe_icmp_error().icmp_error_payload();
4511
4512 icmp_payload
4513 }
4514 PacketType::Raw => {
4515 let packet = I::PacketRaw::parse_mut(SliceBufViewMut::new(&mut buf), ())
4516 .expect("parse IP packet");
4517 let icmp_payload = packet.maybe_icmp_error().icmp_error_payload();
4518
4519 icmp_payload
4520 }
4521 };
4522
4523 assert_matches!(icmp_error, None);
4524 }
4525
4526 #[ip_test(I)]
4527 #[test_matrix(
4528 [
4529 PhantomData::<Udp>,
4530 PhantomData::<Tcp>,
4531 PhantomData::<IcmpEchoRequest>,
4532 ],
4533 [
4534 PacketType::FullyParsed,
4535 PacketType::Raw
4536 ]
4537 )]
4538 fn no_icmp_error_mut_for_normal_ip_packet<I: TestIpExt, P: Protocol>(
4539 _proto: PhantomData<P>,
4540 packet_type: PacketType,
4541 ) where
4542 for<'a> I::Packet<&'a mut [u8]>: IpPacket<I>,
4543 for<'a> I::PacketRaw<&'a mut [u8]>: IpPacket<I>,
4544 {
4545 let mut buf = ip_packet::<I, P>(I::SRC_IP, I::DST_IP).into_inner();
4546 match packet_type {
4547 PacketType::FullyParsed => {
4548 let mut packet = I::Packet::parse_mut(SliceBufViewMut::new(&mut buf), ())
4549 .expect("parse IP packet");
4550 assert!(packet.icmp_error_mut().icmp_error_mut().is_none());
4551 }
4552 PacketType::Raw => {
4553 let mut packet = I::PacketRaw::parse_mut(SliceBufViewMut::new(&mut buf), ())
4554 .expect("parse IP packet");
4555 assert!(packet.icmp_error_mut().icmp_error_mut().is_none());
4556 }
4557 }
4558 }
4559
4560 #[ip_test(I)]
4561 #[test_case(TransportPacketDataProtocol::Udp)]
4562 #[test_case(TransportPacketDataProtocol::Tcp)]
4563 #[test_case(TransportPacketDataProtocol::IcmpEchoRequest)]
4564 fn no_icmp_error_for_normal_bytes<I: TestIpExt>(proto: TransportPacketDataProtocol) {
4565 let buf = proto.make_packet::<I>(I::SRC_IP, I::DST_IP);
4566
4567 assert_matches!(
4568 ParsedIcmpErrorPayload::<I>::parse_in_outer_ip_packet(
4569 proto.proto::<I>(),
4570 buf.as_slice(),
4571 ),
4572 None
4573 );
4574 }
4575
4576 #[ip_test(I)]
4577 #[test_case(TransportPacketDataProtocol::Udp)]
4578 #[test_case(TransportPacketDataProtocol::Tcp)]
4579 #[test_case(TransportPacketDataProtocol::IcmpEchoRequest)]
4580 fn no_icmp_error_mut_for_normal_bytes<I: TestIpExt>(proto: TransportPacketDataProtocol) {
4581 let mut buf = proto.make_packet::<I>(I::SRC_IP, I::DST_IP);
4582
4583 assert!(
4584 ParsedIcmpErrorMut::<I>::parse_in_ip_packet(
4585 I::SRC_IP,
4586 I::DST_IP,
4587 proto.proto::<I>(),
4588 SliceBufViewMut::new(&mut buf),
4589 )
4590 .is_none()
4591 );
4592 }
4593
4594 #[ip_test(I)]
4595 #[test_case(PhantomData::<Udp>)]
4596 #[test_case(PhantomData::<Tcp>)]
4597 #[test_case(PhantomData::<IcmpEchoRequest>)]
4598 fn no_icmp_error_for_normal_serializer<I: TestIpExt, P: Protocol>(_proto: PhantomData<P>) {
4599 let serializer =
4600 P::make_serializer_with_ports::<I>(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT);
4601
4602 assert_matches!(serializer.icmp_error_payload(), None);
4603 }
4604
4605 #[ip_test(I)]
4606 #[test_case(PhantomData::<Udp>)]
4607 #[test_case(PhantomData::<Tcp>)]
4608 #[test_case(PhantomData::<IcmpEchoRequest>)]
4609 fn no_icmp_error_mut_for_normal_serializer<I: TestIpExt, P: Protocol>(_proto: PhantomData<P>) {
4610 let mut serializer =
4611 P::make_serializer_with_ports::<I>(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT);
4612
4613 assert!(serializer.icmp_error_mut().is_none());
4614 }
4615
4616 #[test_matrix(
4617 [
4618 PhantomData::<Icmpv4DestUnreachableError>,
4619 PhantomData::<Icmpv6DestUnreachableError>,
4620 ],
4621 [
4622 TransportPacketDataProtocol::Udp,
4623 TransportPacketDataProtocol::Tcp,
4624 TransportPacketDataProtocol::IcmpEchoRequest,
4625 ],
4626 [
4627 PacketType::FullyParsed,
4628 PacketType::Raw,
4629 ],
4630 [
4631 false,
4632 true,
4633 ]
4634 )]
4635 fn icmp_error_from_bytes<I: TestIpExt, IE: IcmpErrorMessage<I>>(
4636 _icmp_error: PhantomData<IE>,
4637 proto: TransportPacketDataProtocol,
4638 packet_type: PacketType,
4639 truncate_message: bool,
4640 ) {
4641 let serializer = IE::make_serializer_truncated(
4642 I::DST_IP_2,
4643 I::SRC_IP,
4644 proto.make_ip_packet_with_ports_data::<I>(
4645 I::SRC_IP,
4646 I::DST_IP,
4647 SRC_PORT,
4648 DST_PORT,
4649 &[0xAB; 5000],
4650 ),
4651 truncate_message.then_some(1280),
4656 )
4657 .wrap_in(I::PacketBuilder::new(I::DST_IP_2, I::SRC_IP, u8::MAX, IE::proto()));
4658
4659 let mut bytes: Buf<Vec<u8>> = serializer
4660 .serialize_vec_outer(&mut NetworkSerializationContext::default())
4661 .unwrap()
4662 .unwrap_b();
4663 let icmp_payload = match packet_type {
4664 PacketType::FullyParsed => {
4665 let packet = I::as_filter_packet_owned(bytes.parse_mut::<I::Packet<_>>().unwrap());
4666 let icmp_payload =
4667 packet.maybe_icmp_error().icmp_error_payload().expect("no ICMP error found");
4668
4669 icmp_payload
4670 }
4671 PacketType::Raw => {
4672 let packet =
4673 I::as_filter_packet_raw_owned(bytes.parse_mut::<I::PacketRaw<_>>().unwrap());
4674 let icmp_payload =
4675 packet.maybe_icmp_error().icmp_error_payload().expect("no ICMP error found");
4676
4677 icmp_payload
4678 }
4679 };
4680
4681 let expected = match proto {
4682 TransportPacketDataProtocol::Tcp | TransportPacketDataProtocol::Udp => {
4683 ParsedIcmpErrorPayload {
4684 src_ip: I::SRC_IP,
4685 dst_ip: I::DST_IP,
4686 src_port: SRC_PORT.get(),
4687 dst_port: DST_PORT.get(),
4688 proto: proto.proto::<I>(),
4689 }
4690 }
4691 TransportPacketDataProtocol::IcmpEchoRequest => {
4692 ParsedIcmpErrorPayload {
4693 src_ip: I::SRC_IP,
4694 dst_ip: I::DST_IP,
4695 src_port: SRC_PORT.get(),
4698 dst_port: SRC_PORT.get(),
4699 proto: proto.proto::<I>(),
4700 }
4701 }
4702 };
4703
4704 assert_eq!(icmp_payload, expected);
4705 }
4706
4707 #[test_matrix(
4708 [
4709 PhantomData::<Icmpv4DestUnreachableError>,
4710 PhantomData::<Icmpv6DestUnreachableError>,
4711 ],
4712 [
4713 TransportPacketDataProtocol::Udp,
4714 TransportPacketDataProtocol::Tcp,
4715 TransportPacketDataProtocol::IcmpEchoRequest,
4716 ],
4717 [
4718 false,
4719 true,
4720 ]
4721 )]
4722 fn icmp_error_from_serializer<I: TestIpExt, IE: IcmpErrorMessage<I>>(
4723 _icmp_error: PhantomData<IE>,
4724 proto: TransportPacketDataProtocol,
4725 truncate_message: bool,
4726 ) {
4727 let serializer = IE::make_serializer_truncated(
4728 I::DST_IP_2,
4729 I::SRC_IP,
4730 proto.make_ip_packet_with_ports_data::<I>(
4731 I::SRC_IP,
4732 I::DST_IP,
4733 SRC_PORT,
4734 DST_PORT,
4735 &[0xAB; 5000],
4736 ),
4737 truncate_message.then_some(1280),
4742 );
4743
4744 let actual =
4745 serializer.icmp_error_payload().expect("serializer should contain an IP packet");
4746
4747 let expected = match proto {
4748 TransportPacketDataProtocol::Tcp | TransportPacketDataProtocol::Udp => {
4749 ParsedIcmpErrorPayload::<I> {
4750 src_ip: I::SRC_IP,
4751 dst_ip: I::DST_IP,
4752 src_port: SRC_PORT.get(),
4753 dst_port: DST_PORT.get(),
4754 proto: proto.proto::<I>(),
4755 }
4756 }
4757 TransportPacketDataProtocol::IcmpEchoRequest => ParsedIcmpErrorPayload::<I> {
4758 src_ip: I::SRC_IP,
4759 dst_ip: I::DST_IP,
4760 src_port: SRC_PORT.get(),
4763 dst_port: SRC_PORT.get(),
4764 proto: proto.proto::<I>(),
4765 },
4766 };
4767
4768 assert_eq!(actual, expected);
4769 }
4770
4771 #[test_matrix(
4772 [
4773 PhantomData::<Icmpv4DestUnreachableError>,
4774 PhantomData::<Icmpv6DestUnreachableError>,
4775 ],
4776 [
4777 TransportPacketDataProtocol::Udp,
4778 TransportPacketDataProtocol::Tcp,
4779 TransportPacketDataProtocol::IcmpEchoRequest,
4780 ],
4781 [
4782 PacketType::FullyParsed,
4783 PacketType::Raw,
4784 ],
4785 [
4786 false,
4787 true,
4788 ]
4789 )]
4790 fn conntrack_packet_icmp_error_from_bytes<I: TestIpExt, IE: IcmpErrorMessage<I>>(
4791 _icmp_error: PhantomData<IE>,
4792 proto: TransportPacketDataProtocol,
4793 packet_type: PacketType,
4794 truncate_message: bool,
4795 ) {
4796 let serializer = IE::make_serializer_truncated(
4797 I::DST_IP_2,
4798 I::SRC_IP,
4799 proto.make_ip_packet_with_ports_data::<I>(
4800 I::SRC_IP,
4801 I::DST_IP,
4802 SRC_PORT,
4803 DST_PORT,
4804 &[0xAB; 5000],
4805 ),
4806 truncate_message.then_some(1280),
4811 )
4812 .wrap_in(I::PacketBuilder::new(I::DST_IP_2, I::SRC_IP, u8::MAX, IE::proto()));
4813
4814 let mut bytes: Buf<Vec<u8>> = serializer
4815 .serialize_vec_outer(&mut NetworkSerializationContext::default())
4816 .unwrap()
4817 .unwrap_b();
4818
4819 let conntrack_packet = match packet_type {
4820 PacketType::FullyParsed => {
4821 let packet = I::as_filter_packet_owned(bytes.parse_mut::<I::Packet<_>>().unwrap());
4822 packet.conntrack_packet().unwrap()
4823 }
4824 PacketType::Raw => {
4825 let packet =
4826 I::as_filter_packet_raw_owned(bytes.parse_mut::<I::PacketRaw<_>>().unwrap());
4827 packet.conntrack_packet().unwrap()
4828 }
4829 };
4830
4831 let expected = match proto {
4832 TransportPacketDataProtocol::Tcp | TransportPacketDataProtocol::Udp => {
4833 conntrack::PacketMetadata::new_from_icmp_error(
4834 I::SRC_IP,
4835 I::DST_IP,
4836 SRC_PORT.get(),
4837 DST_PORT.get(),
4838 I::map_ip(proto.proto::<I>(), |proto| proto.into(), |proto| proto.into()),
4839 )
4840 }
4841 TransportPacketDataProtocol::IcmpEchoRequest => {
4842 conntrack::PacketMetadata::new_from_icmp_error(
4843 I::SRC_IP,
4844 I::DST_IP,
4845 SRC_PORT.get(),
4848 SRC_PORT.get(),
4849 I::map_ip(proto.proto::<I>(), |proto| proto.into(), |proto| proto.into()),
4850 )
4851 }
4852 };
4853
4854 assert_eq!(conntrack_packet, expected);
4855 }
4856
4857 #[test_matrix(
4858 [
4859 PhantomData::<Icmpv4DestUnreachableError>,
4860 PhantomData::<Icmpv6DestUnreachableError>,
4861 ],
4862 [
4863 TransportPacketDataProtocol::Udp,
4864 TransportPacketDataProtocol::Tcp,
4865 TransportPacketDataProtocol::IcmpEchoRequest,
4866 ],
4867 [
4868 PacketType::FullyParsed,
4869 PacketType::Raw,
4870 ],
4871 [
4872 false,
4873 true,
4874 ]
4875 )]
4876 fn no_conntrack_packet_for_incompatible_outer_and_payload<
4877 I: TestIpExt,
4878 IE: IcmpErrorMessage<I>,
4879 >(
4880 _icmp_error: PhantomData<IE>,
4881 proto: TransportPacketDataProtocol,
4882 packet_type: PacketType,
4883 truncate_message: bool,
4884 ) {
4885 let serializer = IE::make_serializer_truncated(
4891 I::DST_IP_2,
4892 I::SRC_IP_2,
4893 proto.make_ip_packet_with_ports_data::<I>(
4894 I::SRC_IP,
4895 I::DST_IP,
4896 SRC_PORT,
4897 DST_PORT,
4898 &[0xAB; 5000],
4899 ),
4900 truncate_message.then_some(1280),
4905 )
4906 .wrap_in(I::PacketBuilder::new(I::DST_IP_2, I::SRC_IP_2, u8::MAX, IE::proto()));
4907
4908 let mut bytes: Buf<Vec<u8>> = serializer
4909 .serialize_vec_outer(&mut NetworkSerializationContext::default())
4910 .unwrap()
4911 .unwrap_b();
4912
4913 let conntrack_packet = match packet_type {
4914 PacketType::FullyParsed => {
4915 let packet = I::as_filter_packet_owned(bytes.parse_mut::<I::Packet<_>>().unwrap());
4916 packet.conntrack_packet()
4917 }
4918 PacketType::Raw => {
4919 let packet =
4920 I::as_filter_packet_raw_owned(bytes.parse_mut::<I::PacketRaw<_>>().unwrap());
4921 packet.conntrack_packet()
4922 }
4923 };
4924
4925 assert_matches!(conntrack_packet, None);
4928 }
4929
4930 #[test_matrix(
4931 [
4932 PhantomData::<Icmpv4DestUnreachableError>,
4933 PhantomData::<Icmpv6DestUnreachableError>,
4934 ],
4935 [
4936 TransportPacketDataProtocol::Udp,
4937 TransportPacketDataProtocol::Tcp,
4938 TransportPacketDataProtocol::IcmpEchoRequest,
4939 ],
4940 [
4941 false,
4942 true,
4943 ]
4944 )]
4945 fn icmp_error_mut_from_serializer<I: TestIpExt, IE: IcmpErrorMessage<I>>(
4946 _icmp_error: PhantomData<IE>,
4947 proto: TransportPacketDataProtocol,
4948 truncate_message: bool,
4949 ) where
4950 for<'a> I::Packet<&'a mut [u8]>: IpPacket<I>,
4951 {
4952 const LEN: usize = 5000;
4953
4954 let mut payload_bytes = proto.make_ip_packet_with_ports_data::<I>(
4955 I::SRC_IP,
4956 I::DST_IP,
4957 SRC_PORT,
4958 DST_PORT,
4959 &[0xAB; LEN],
4960 );
4961
4962 if truncate_message {
4965 payload_bytes.truncate(1280);
4966 }
4967
4968 let mut serializer = IE::make_serializer(I::SRC_IP, I::DST_IP, payload_bytes)
4969 .wrap_in(I::PacketBuilder::new(I::SRC_IP, I::DST_IP, u8::MAX, IE::proto()));
4970
4971 {
4972 let mut icmp_packet = serializer
4973 .icmp_error_mut()
4974 .icmp_error_mut()
4975 .expect("couldn't find an inner ICMP error");
4976
4977 {
4978 let mut inner_packet = icmp_packet.inner_packet().expect("no inner packet");
4979
4980 inner_packet.set_src_addr(I::SRC_IP_2);
4981 inner_packet.set_dst_addr(I::DST_IP_2);
4982 }
4983
4984 assert!(icmp_packet.recalculate_checksum());
4987 }
4988
4989 let mut expected_payload_bytes = proto.make_ip_packet_with_ports_data::<I>(
4990 I::SRC_IP_2,
4991 I::DST_IP_2,
4992 SRC_PORT,
4993 DST_PORT,
4994 &[0xAB; LEN],
4995 );
4996
4997 if truncate_message {
5000 expected_payload_bytes.truncate(1280);
5001 }
5002
5003 let expected_serializer = IE::make_serializer(I::SRC_IP, I::DST_IP, expected_payload_bytes)
5004 .wrap_in(I::PacketBuilder::new(I::SRC_IP, I::DST_IP, u8::MAX, IE::proto()));
5007
5008 let actual_bytes = serializer
5009 .serialize_vec_outer(&mut NetworkSerializationContext::default())
5010 .unwrap()
5011 .unwrap_b();
5012 let expected_bytes = expected_serializer
5013 .serialize_vec_outer(&mut NetworkSerializationContext::default())
5014 .unwrap()
5015 .unwrap_b();
5016
5017 assert_eq!(actual_bytes, expected_bytes);
5018 }
5019
5020 #[test_matrix(
5021 [
5022 PhantomData::<Icmpv4DestUnreachableError>,
5023 PhantomData::<Icmpv6DestUnreachableError>,
5024 ],
5025 [
5026 TransportPacketDataProtocol::Udp,
5027 TransportPacketDataProtocol::Tcp,
5028 TransportPacketDataProtocol::IcmpEchoRequest,
5029 ],
5030 [
5031 PacketType::FullyParsed,
5032 PacketType::Raw,
5033 ],
5034 [
5035 false,
5036 true,
5037 ]
5038 )]
5039 fn icmp_error_mut_from_bytes<I: TestIpExt, IE: IcmpErrorMessage<I>>(
5040 _icmp_error: PhantomData<IE>,
5041 proto: TransportPacketDataProtocol,
5042 packet_type: PacketType,
5043 truncate_message: bool,
5044 ) where
5045 for<'a> I::Packet<&'a mut [u8]>: IpPacket<I>,
5046 {
5047 const LEN: usize = 5000;
5048
5049 let mut payload_bytes = proto.make_ip_packet_with_ports_data::<I>(
5050 I::SRC_IP,
5051 I::DST_IP,
5052 SRC_PORT,
5053 DST_PORT,
5054 &[0xAB; LEN],
5055 );
5056
5057 if truncate_message {
5060 payload_bytes.truncate(1280);
5061 }
5062
5063 let serializer = IE::make_serializer(I::SRC_IP, I::DST_IP, payload_bytes)
5064 .wrap_in(I::PacketBuilder::new(I::SRC_IP, I::DST_IP, u8::MAX, IE::proto()));
5065
5066 let mut bytes = serializer
5067 .serialize_vec_outer(&mut NetworkSerializationContext::default())
5068 .unwrap()
5069 .unwrap_b()
5070 .into_inner();
5071
5072 {
5073 fn modify_packet<I: TestIpExt, P: IpPacket<I>>(mut packet: P) {
5074 let mut icmp_error = packet.icmp_error_mut();
5075 let mut icmp_error =
5076 icmp_error.icmp_error_mut().expect("couldn't find an inner ICMP error");
5077
5078 {
5079 let mut inner_packet = icmp_error.inner_packet().expect("no inner packet");
5080
5081 inner_packet.set_src_addr(I::SRC_IP_2);
5082 inner_packet.set_dst_addr(I::DST_IP_2);
5083 }
5084
5085 assert!(icmp_error.recalculate_checksum());
5086 }
5087
5088 let mut bytes = Buf::new(&mut bytes, ..);
5089
5090 match packet_type {
5091 PacketType::FullyParsed => {
5092 let packet =
5093 I::as_filter_packet_owned(bytes.parse_mut::<I::Packet<_>>().unwrap());
5094 modify_packet(packet);
5095 }
5096 PacketType::Raw => {
5097 let packet = I::as_filter_packet_raw_owned(
5098 bytes.parse_mut::<I::PacketRaw<_>>().unwrap(),
5099 );
5100 modify_packet(packet);
5101 }
5102 }
5103 }
5104
5105 let mut expected_payload_bytes = proto.make_ip_packet_with_ports_data::<I>(
5106 I::SRC_IP_2,
5107 I::DST_IP_2,
5108 SRC_PORT,
5109 DST_PORT,
5110 &[0xAB; LEN],
5111 );
5112
5113 if truncate_message {
5114 expected_payload_bytes.truncate(1280);
5115 }
5116
5117 let expected_serializer = IE::make_serializer(I::SRC_IP, I::DST_IP, expected_payload_bytes)
5118 .wrap_in(I::PacketBuilder::new(I::SRC_IP, I::DST_IP, u8::MAX, IE::proto()));
5121
5122 let expected_bytes = expected_serializer
5123 .serialize_vec_outer(&mut NetworkSerializationContext::default())
5124 .unwrap()
5125 .unwrap_b()
5126 .into_inner();
5127
5128 assert_eq!(bytes, expected_bytes);
5129 }
5130
5131 #[ip_test(I)]
5132 #[test_case(PhantomData::<Udp>)]
5133 #[test_case(PhantomData::<Tcp>)]
5134 #[test_case(PhantomData::<IcmpEchoRequest>)]
5135 fn tx_packet_partial_serialize<I: TestIpExt, P: Protocol>(_proto: PhantomData<P>) {
5136 const DATA: &[u8] = b"Packet Body";
5137 let mut body =
5138 P::make_serializer_with_ports_data::<I>(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, DATA);
5139 let packet = TxPacket::<I, _>::new(I::SRC_IP, I::DST_IP, P::proto::<I>(), &mut body);
5140
5141 let (buf, total_size) = PartialSerializer::partial_serialize_new_buf(
5142 &packet,
5143 &mut NetworkSerializationContext::default(),
5144 PacketConstraints::UNCONSTRAINED,
5145 packet::new_buf_vec,
5146 )
5147 .unwrap();
5148
5149 let whole_packet =
5150 P::make_serializer_with_ports_data::<I>(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, DATA)
5151 .wrap_in(I::PacketBuilder::new(
5152 I::SRC_IP,
5153 I::DST_IP,
5154 TX_PACKET_NO_TTL,
5155 P::proto::<I>(),
5156 ))
5157 .serialize_vec_outer(&mut NetworkSerializationContext::default())
5158 .expect("serialize packet")
5159 .unwrap_b()
5160 .into_inner();
5161
5162 let headers_size = I::MIN_HEADER_LENGTH + P::HEADER_SIZE;
5163 assert_eq!(total_size, whole_packet.len());
5164 assert_eq!(buf.len(), headers_size);
5165
5166 let num_bytes_differ = buf
5169 .as_ref()
5170 .iter()
5171 .zip(whole_packet[..headers_size].iter())
5172 .map(|(a, b)| if a != b { 1 } else { 0 })
5173 .sum::<usize>();
5174
5175 let checksum_bytes = I::map_ip((), |()| 4, |()| 2);
5180 assert!(num_bytes_differ <= checksum_bytes);
5181 }
5182
5183 #[ip_test(I)]
5184 #[test_case(PhantomData::<Udp>)]
5185 #[test_case(PhantomData::<Tcp>)]
5186 #[test_case(PhantomData::<IcmpEchoRequest>)]
5187 fn tx_packet_raw_ip_body_partial_serialize<I: TestIpExt, P: Protocol>(_proto: PhantomData<P>) {
5188 const DATA: &[u8] = b"Packet Body";
5189 let body_bytes =
5190 P::make_serializer_with_ports_data::<I>(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT, DATA)
5191 .serialize_vec_outer(&mut NetworkSerializationContext::default())
5192 .unwrap()
5193 .unwrap_b()
5194 .into_inner();
5195 let body_bytes_len = body_bytes.len();
5196 let mut body =
5197 RawIpBody::new(P::proto::<I>(), I::SRC_IP, I::DST_IP, Buf::new(body_bytes.clone(), ..));
5198 let packet = TxPacket::<I, _>::new(I::SRC_IP, I::DST_IP, P::proto::<I>(), &mut body);
5199
5200 let (buf, total_size) = PartialSerializer::partial_serialize_new_buf(
5201 &packet,
5202 &mut NetworkSerializationContext::default(),
5203 PacketConstraints::UNCONSTRAINED,
5204 packet::new_buf_vec,
5205 )
5206 .unwrap();
5207
5208 let whole_packet = Buf::new(body_bytes, ..)
5209 .wrap_in(I::PacketBuilder::new(I::SRC_IP, I::DST_IP, TX_PACKET_NO_TTL, P::proto::<I>()))
5210 .serialize_vec_outer(&mut NetworkSerializationContext::default())
5211 .expect("serialize packet")
5212 .unwrap_b()
5213 .into_inner();
5214
5215 let headers_size =
5216 I::MIN_HEADER_LENGTH + cmp::min(body_bytes_len, TRANSPORT_HEADER_MAX_SIZE);
5217 assert_eq!(total_size, whole_packet.len());
5218 assert_eq!(buf.len(), headers_size);
5219
5220 let num_bytes_differ = buf
5223 .as_ref()
5224 .iter()
5225 .zip(whole_packet[..headers_size].iter())
5226 .map(|(a, b)| if a != b { 1 } else { 0 })
5227 .sum::<usize>();
5228
5229 let checksum_bytes = I::map_ip((), |()| 2, |()| 0);
5234 assert!(num_bytes_differ <= checksum_bytes);
5235 }
5236
5237 #[ip_test(I)]
5238 #[test_case(PhantomData::<Udp>)]
5239 #[test_case(PhantomData::<Tcp>)]
5240 #[test_case(PhantomData::<IcmpEchoRequest>)]
5241 fn forwarded_packet_partial_serialize<I: TestIpExt, P: Protocol>(_proto: PhantomData<P>) {
5242 let mut packet_buf = ip_packet::<I, P>(I::SRC_IP, I::DST_IP);
5243 let packet_bytes = packet_buf.to_flattened_vec();
5244 let meta = packet_buf.parse::<I::Packet<_>>().expect("parse IP packet").parse_metadata();
5245 let packet = ForwardedPacket::<I, _>::new(
5246 I::SRC_IP,
5247 I::DST_IP,
5248 P::proto::<I>(),
5249 meta,
5250 packet_buf,
5251 false,
5252 );
5253
5254 let result = packet
5255 .partial_serialize(&mut NetworkSerializationContext::default(), packet::new_buf_vec)
5256 .unwrap();
5257 assert_eq!(result, PartialSerializeResult::Slice(&packet_bytes[..]));
5258
5259 let (buf, total_size) = PartialSerializer::partial_serialize_new_buf(
5260 &packet,
5261 &mut NetworkSerializationContext::default(),
5262 PacketConstraints::UNCONSTRAINED,
5263 packet::new_buf_vec,
5264 )
5265 .unwrap();
5266
5267 let expected_len =
5268 cmp::min(packet_bytes.len(), meta.header_len() + TRANSPORT_HEADER_MAX_SIZE);
5269 assert_eq!(total_size, packet_bytes.len());
5270 assert_eq!(buf.as_ref(), &packet_bytes[..expected_len]);
5271 }
5272}