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