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