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