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