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