1use core::borrow::Borrow;
6use core::convert::Infallible as Never;
7use core::num::NonZeroU16;
8
9use net_types::ip::{GenericOverIp, Ip, IpAddress, IpInvariant, Ipv4, Ipv4Addr, Ipv6, Ipv6Addr};
10use netstack3_base::{Options, PayloadLen, SegmentHeader};
11use packet::records::options::OptionSequenceBuilder;
12use packet::{
13 Buf, BufferAlloc, BufferMut, BufferProvider, BufferViewMut, EitherSerializer, EmptyBuf,
14 GrowBufferMut, InnerSerializer, Nested, PacketConstraints, ParsablePacket, ParseBuffer,
15 ParseMetadata, ReusableBuffer, SerializeError, Serializer, SliceBufViewMut,
16};
17use packet_formats::icmp::mld::{
18 MulticastListenerDone, MulticastListenerQuery, MulticastListenerQueryV2,
19 MulticastListenerReport, MulticastListenerReportV2,
20};
21use packet_formats::icmp::ndp::options::NdpOptionBuilder;
22use packet_formats::icmp::ndp::{
23 NeighborAdvertisement, NeighborSolicitation, Redirect, RouterAdvertisement, RouterSolicitation,
24};
25use packet_formats::icmp::{
26 self, IcmpDestUnreachable, IcmpEchoReply, IcmpEchoRequest, IcmpPacketBuilder, IcmpPacketRaw,
27 IcmpPacketTypeRaw as _, IcmpTimeExceeded, Icmpv4MessageType, Icmpv4PacketRaw,
28 Icmpv4ParameterProblem, Icmpv4Redirect, Icmpv4TimestampReply, Icmpv4TimestampRequest,
29 Icmpv6MessageType, Icmpv6PacketRaw, Icmpv6PacketTooBig, Icmpv6ParameterProblem,
30};
31use packet_formats::igmp::messages::IgmpMembershipReportV3Builder;
32use packet_formats::igmp::{self, IgmpPacketBuilder};
33use packet_formats::ip::{IpExt, IpPacket as _, IpPacketBuilder, IpProto, Ipv4Proto, Ipv6Proto};
34use packet_formats::ipv4::{Ipv4Packet, Ipv4PacketRaw};
35use packet_formats::ipv6::{Ipv6Packet, Ipv6PacketRaw};
36use packet_formats::tcp::options::TcpOption;
37use packet_formats::tcp::{TcpParseArgs, TcpSegment, TcpSegmentBuilderWithOptions, TcpSegmentRaw};
38use packet_formats::udp::{UdpPacket, UdpPacketBuilder, UdpPacketRaw, UdpParseArgs};
39use zerocopy::{SplitByteSlice, SplitByteSliceMut};
40
41pub trait FilterIpExt: IpExt {
43 type FilterIpPacket<B: SplitByteSliceMut>: IpPacket<Self>;
45
46 fn as_filter_packet<B: SplitByteSliceMut>(
49 packet: &mut Self::Packet<B>,
50 ) -> &mut Self::FilterIpPacket<B>;
51}
52
53impl FilterIpExt for Ipv4 {
54 type FilterIpPacket<B: SplitByteSliceMut> = Ipv4Packet<B>;
55
56 #[inline]
57 fn as_filter_packet<B: SplitByteSliceMut>(packet: &mut Ipv4Packet<B>) -> &mut Ipv4Packet<B> {
58 packet
59 }
60}
61
62impl FilterIpExt for Ipv6 {
63 type FilterIpPacket<B: SplitByteSliceMut> = Ipv6Packet<B>;
64
65 #[inline]
66 fn as_filter_packet<B: SplitByteSliceMut>(packet: &mut Ipv6Packet<B>) -> &mut Ipv6Packet<B> {
67 packet
68 }
69}
70
71pub trait IpPacket<I: IpExt> {
73 type TransportPacket<'a>: MaybeTransportPacket
76 where
77 Self: 'a;
78
79 type TransportPacketMut<'a>: MaybeTransportPacketMut<I>
82 where
83 Self: 'a;
84
85 fn src_addr(&self) -> I::Addr;
87
88 fn set_src_addr(&mut self, addr: I::Addr);
90
91 fn dst_addr(&self) -> I::Addr;
93
94 fn set_dst_addr(&mut self, addr: I::Addr);
96
97 fn protocol(&self) -> I::Proto;
99
100 fn maybe_transport_packet<'a>(&'a self) -> Self::TransportPacket<'a>;
111
112 fn transport_packet_mut<'a>(&'a mut self) -> Self::TransportPacketMut<'a>;
123}
124
125pub trait MaybeTransportPacket {
132 fn transport_packet_data(&self) -> Option<TransportPacketData>;
135}
136
137pub trait MaybeTransportPacketMut<I: IpExt> {
145 type TransportPacketMut<'a>: TransportPacketMut<I>
148 where
149 Self: 'a;
150
151 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>>;
154}
155
156pub trait TransportPacketSerializer<I: IpExt>:
158 Serializer + MaybeTransportPacket + MaybeTransportPacketMut<I>
159{
160}
161
162impl<I, S> TransportPacketSerializer<I> for S
163where
164 I: IpExt,
165 S: Serializer + MaybeTransportPacket + MaybeTransportPacketMut<I>,
166{
167}
168
169impl<T: ?Sized> MaybeTransportPacket for &T
170where
171 T: MaybeTransportPacket,
172{
173 fn transport_packet_data(&self) -> Option<TransportPacketData> {
174 (**self).transport_packet_data()
175 }
176}
177
178impl<T: ?Sized> MaybeTransportPacket for &mut T
179where
180 T: MaybeTransportPacket,
181{
182 fn transport_packet_data(&self) -> Option<TransportPacketData> {
183 (**self).transport_packet_data()
184 }
185}
186
187impl<I: IpExt, T: ?Sized> MaybeTransportPacketMut<I> for &mut T
188where
189 T: MaybeTransportPacketMut<I>,
190{
191 type TransportPacketMut<'a>
192 = T::TransportPacketMut<'a>
193 where
194 Self: 'a;
195
196 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
197 (**self).transport_packet_mut()
198 }
199}
200
201impl<I: IpExt, T: TransportPacketMut<I>> MaybeTransportPacketMut<I> for Option<T> {
202 type TransportPacketMut<'a>
203 = &'a mut T
204 where
205 Self: 'a;
206
207 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
208 self.as_mut()
209 }
210}
211
212#[derive(Debug, Clone, GenericOverIp, PartialEq, Eq)]
215#[generic_over_ip()]
216pub enum TransportPacketData {
217 Tcp { src_port: u16, dst_port: u16, segment: SegmentHeader, payload_len: usize },
218 Generic { src_port: u16, dst_port: u16 },
219}
220
221impl TransportPacketData {
222 pub fn src_port(&self) -> u16 {
223 match self {
224 TransportPacketData::Tcp { src_port, .. }
225 | TransportPacketData::Generic { src_port, .. } => *src_port,
226 }
227 }
228
229 pub fn dst_port(&self) -> u16 {
230 match self {
231 TransportPacketData::Tcp { dst_port, .. }
232 | TransportPacketData::Generic { dst_port, .. } => *dst_port,
233 }
234 }
235
236 pub fn tcp_segment_and_len(&self) -> Option<(&SegmentHeader, usize)> {
237 match self {
238 TransportPacketData::Tcp { segment, payload_len, .. } => Some((&segment, *payload_len)),
239 TransportPacketData::Generic { .. } => None,
240 }
241 }
242
243 fn parse_in_ip_packet<I: IpExt, B: ParseBuffer>(
244 src_ip: I::Addr,
245 dst_ip: I::Addr,
246 proto: I::Proto,
247 body: B,
248 ) -> Option<TransportPacketData> {
249 I::map_ip(
250 (src_ip, dst_ip, proto, IpInvariant(body)),
251 |(src_ip, dst_ip, proto, IpInvariant(body))| {
252 parse_transport_header_in_ipv4_packet(src_ip, dst_ip, proto, body)
253 },
254 |(src_ip, dst_ip, proto, IpInvariant(body))| {
255 parse_transport_header_in_ipv6_packet(src_ip, dst_ip, proto, body)
256 },
257 )
258 }
259}
260
261pub trait TransportPacketMut<I: IpExt> {
266 fn set_src_port(&mut self, port: NonZeroU16);
268
269 fn set_dst_port(&mut self, port: NonZeroU16);
271
272 fn update_pseudo_header_src_addr(&mut self, old: I::Addr, new: I::Addr);
274
275 fn update_pseudo_header_dst_addr(&mut self, old: I::Addr, new: I::Addr);
277}
278
279impl<B: SplitByteSliceMut> IpPacket<Ipv4> for Ipv4Packet<B> {
280 type TransportPacket<'a>
281 = &'a Self
282 where
283 Self: 'a;
284 type TransportPacketMut<'a>
285 = Option<ParsedTransportHeaderMut<'a, Ipv4>>
286 where
287 B: 'a;
288
289 fn src_addr(&self) -> Ipv4Addr {
290 self.src_ip()
291 }
292
293 fn set_src_addr(&mut self, addr: Ipv4Addr) {
294 let old = self.src_addr();
295 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
296 packet.update_pseudo_header_src_addr(old, addr);
297 }
298 self.set_src_ip_and_update_checksum(addr);
307 }
308
309 fn dst_addr(&self) -> Ipv4Addr {
310 self.dst_ip()
311 }
312
313 fn set_dst_addr(&mut self, addr: Ipv4Addr) {
314 let old = self.dst_addr();
315 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
316 packet.update_pseudo_header_dst_addr(old, addr);
317 }
318 self.set_dst_ip_and_update_checksum(addr);
328 }
329
330 fn protocol(&self) -> Ipv4Proto {
331 self.proto()
332 }
333
334 fn maybe_transport_packet(&self) -> Self::TransportPacket<'_> {
335 self
336 }
337
338 fn transport_packet_mut(&mut self) -> Self::TransportPacketMut<'_> {
339 ParsedTransportHeaderMut::parse_in_ipv4_packet(
340 self.src_ip(),
341 self.dst_ip(),
342 self.proto(),
343 SliceBufViewMut::new(self.body_mut()),
344 )
345 }
346}
347
348impl<B: SplitByteSlice> MaybeTransportPacket for Ipv4Packet<B> {
349 fn transport_packet_data(&self) -> Option<TransportPacketData> {
350 parse_transport_header_in_ipv4_packet(
351 self.src_ip(),
352 self.dst_ip(),
353 self.proto(),
354 self.body(),
355 )
356 }
357}
358
359impl<B: SplitByteSliceMut> IpPacket<Ipv6> for Ipv6Packet<B> {
360 type TransportPacket<'a>
361 = &'a Self
362 where
363 Self: 'a;
364 type TransportPacketMut<'a>
365 = Option<ParsedTransportHeaderMut<'a, Ipv6>>
366 where
367 B: 'a;
368
369 fn src_addr(&self) -> Ipv6Addr {
370 self.src_ip()
371 }
372
373 fn set_src_addr(&mut self, addr: Ipv6Addr) {
374 let old = self.src_addr();
375 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
376 packet.update_pseudo_header_src_addr(old, addr);
377 }
378 self.set_src_ip(addr);
387 }
388
389 fn dst_addr(&self) -> Ipv6Addr {
390 self.dst_ip()
391 }
392
393 fn set_dst_addr(&mut self, addr: Ipv6Addr) {
394 let old = self.dst_addr();
395 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
396 packet.update_pseudo_header_dst_addr(old, addr);
397 }
398 self.set_dst_ip(addr);
408 }
409
410 fn protocol(&self) -> Ipv6Proto {
411 self.proto()
412 }
413
414 fn maybe_transport_packet(&self) -> Self::TransportPacket<'_> {
415 self
416 }
417
418 fn transport_packet_mut(&mut self) -> Self::TransportPacketMut<'_> {
419 ParsedTransportHeaderMut::parse_in_ipv6_packet(
420 self.src_ip(),
421 self.dst_ip(),
422 self.proto(),
423 SliceBufViewMut::new(self.body_mut()),
424 )
425 }
426}
427
428impl<B: SplitByteSlice> MaybeTransportPacket for Ipv6Packet<B> {
429 fn transport_packet_data(&self) -> Option<TransportPacketData> {
430 parse_transport_header_in_ipv6_packet(
431 self.src_ip(),
432 self.dst_ip(),
433 self.proto(),
434 self.body(),
435 )
436 }
437}
438
439#[derive(Debug, PartialEq, GenericOverIp)]
442#[generic_over_ip(I, Ip)]
443pub struct TxPacket<'a, I: IpExt, S> {
444 src_addr: I::Addr,
445 dst_addr: I::Addr,
446 protocol: I::Proto,
447 serializer: &'a mut S,
448}
449
450impl<'a, I: IpExt, S> TxPacket<'a, I, S> {
451 pub fn new(
453 src_addr: I::Addr,
454 dst_addr: I::Addr,
455 protocol: I::Proto,
456 serializer: &'a mut S,
457 ) -> Self {
458 Self { src_addr, dst_addr, protocol, serializer }
459 }
460
461 pub fn src_addr(&self) -> I::Addr {
463 self.src_addr
464 }
465
466 pub fn dst_addr(&self) -> I::Addr {
468 self.dst_addr
469 }
470}
471
472impl<I: IpExt, S: TransportPacketSerializer<I>> IpPacket<I> for TxPacket<'_, I, S> {
473 type TransportPacket<'a>
474 = &'a S
475 where
476 Self: 'a;
477 type TransportPacketMut<'a>
478 = &'a mut S
479 where
480 Self: 'a;
481
482 fn src_addr(&self) -> I::Addr {
483 self.src_addr
484 }
485
486 fn set_src_addr(&mut self, addr: I::Addr) {
487 let old = core::mem::replace(&mut self.src_addr, addr);
488 if let Some(mut packet) = self.transport_packet_mut().transport_packet_mut() {
489 packet.update_pseudo_header_src_addr(old, addr);
490 }
491 }
492
493 fn dst_addr(&self) -> I::Addr {
494 self.dst_addr
495 }
496
497 fn set_dst_addr(&mut self, addr: I::Addr) {
498 let old = core::mem::replace(&mut self.dst_addr, addr);
499 if let Some(mut packet) = self.transport_packet_mut().transport_packet_mut() {
500 packet.update_pseudo_header_dst_addr(old, addr);
501 }
502 }
503
504 fn protocol(&self) -> I::Proto {
505 self.protocol
506 }
507
508 fn maybe_transport_packet(&self) -> Self::TransportPacket<'_> {
509 self.serializer
510 }
511
512 fn transport_packet_mut(&mut self) -> Self::TransportPacketMut<'_> {
513 self.serializer
514 }
515}
516
517#[derive(Debug, PartialEq, GenericOverIp)]
519#[generic_over_ip(I, Ip)]
520pub struct ForwardedPacket<I: IpExt, B> {
521 src_addr: I::Addr,
522 dst_addr: I::Addr,
523 protocol: I::Proto,
524 transport_header_offset: usize,
525 buffer: B,
526}
527
528impl<I: IpExt, B: BufferMut> ForwardedPacket<I, B> {
529 pub fn new(
536 src_addr: I::Addr,
537 dst_addr: I::Addr,
538 protocol: I::Proto,
539 meta: ParseMetadata,
540 mut buffer: B,
541 ) -> Self {
542 let transport_header_offset = meta.header_len();
543 buffer.undo_parse(meta);
544 Self { src_addr, dst_addr, protocol, transport_header_offset, buffer }
545 }
546
547 pub fn into_buffer(self) -> B {
553 self.buffer
554 }
555
556 pub fn buffer(&self) -> &B {
561 &self.buffer
562 }
563}
564
565impl<I: IpExt, B: BufferMut> Serializer for ForwardedPacket<I, B> {
566 type Buffer = <B as Serializer>::Buffer;
567
568 fn serialize<G: packet::GrowBufferMut, P: packet::BufferProvider<Self::Buffer, G>>(
569 self,
570 outer: packet::PacketConstraints,
571 provider: P,
572 ) -> Result<G, (packet::SerializeError<P::Error>, Self)> {
573 let Self { src_addr, dst_addr, protocol, transport_header_offset, buffer } = self;
574 buffer.serialize(outer, provider).map_err(|(err, buffer)| {
575 (err, Self { src_addr, dst_addr, protocol, transport_header_offset, buffer })
576 })
577 }
578
579 fn serialize_new_buf<BB: packet::ReusableBuffer, A: packet::BufferAlloc<BB>>(
580 &self,
581 outer: packet::PacketConstraints,
582 alloc: A,
583 ) -> Result<BB, packet::SerializeError<A::Error>> {
584 self.buffer.serialize_new_buf(outer, alloc)
585 }
586}
587
588impl<I: IpExt, B: BufferMut> IpPacket<I> for ForwardedPacket<I, B> {
589 type TransportPacket<'a>
590 = &'a Self
591 where
592 Self: 'a;
593 type TransportPacketMut<'a>
594 = Option<ParsedTransportHeaderMut<'a, I>>
595 where
596 Self: 'a;
597
598 fn src_addr(&self) -> I::Addr {
599 self.src_addr
600 }
601
602 fn set_src_addr(&mut self, addr: I::Addr) {
603 I::map_ip::<_, ()>(
605 (IpInvariant(self.buffer.as_mut()), addr),
606 |(IpInvariant(buffer), addr)| {
607 let mut packet = Ipv4PacketRaw::parse_mut(SliceBufViewMut::new(buffer), ())
608 .expect("ForwardedPacket must have been created from a valid IP packet");
609 packet.set_src_ip_and_update_checksum(addr);
610 },
611 |(IpInvariant(buffer), addr)| {
612 let mut packet = Ipv6PacketRaw::parse_mut(SliceBufViewMut::new(buffer), ())
613 .expect("ForwardedPacket must have been created from a valid IP packet");
614 packet.set_src_ip(addr);
615 },
616 );
617
618 let old = self.src_addr;
619 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
620 packet.update_pseudo_header_src_addr(old, addr);
621 }
622 self.src_addr = addr;
631 }
632
633 fn dst_addr(&self) -> I::Addr {
634 self.dst_addr
635 }
636
637 fn set_dst_addr(&mut self, addr: I::Addr) {
638 I::map_ip::<_, ()>(
640 (IpInvariant(self.buffer.as_mut()), addr),
641 |(IpInvariant(buffer), addr)| {
642 let mut packet = Ipv4PacketRaw::parse_mut(SliceBufViewMut::new(buffer), ())
643 .expect("ForwardedPacket must have been created from a valid IP packet");
644 packet.set_dst_ip_and_update_checksum(addr);
645 },
646 |(IpInvariant(buffer), addr)| {
647 let mut packet = Ipv6PacketRaw::parse_mut(SliceBufViewMut::new(buffer), ())
648 .expect("ForwardedPacket must have been created from a valid IP packet");
649 packet.set_dst_ip(addr);
650 },
651 );
652
653 let old = self.dst_addr;
654 if let Some(packet) = self.transport_packet_mut().transport_packet_mut() {
655 packet.update_pseudo_header_dst_addr(old, addr);
656 }
657 self.dst_addr = addr;
666 }
667
668 fn protocol(&self) -> I::Proto {
669 self.protocol
670 }
671
672 fn maybe_transport_packet(&self) -> Self::TransportPacket<'_> {
673 self
674 }
675
676 fn transport_packet_mut(&mut self) -> Self::TransportPacketMut<'_> {
677 let ForwardedPacket { src_addr, dst_addr, protocol, buffer, transport_header_offset } =
678 self;
679 ParsedTransportHeaderMut::<I>::parse_in_ip_packet(
680 *src_addr,
681 *dst_addr,
682 *protocol,
683 SliceBufViewMut::new(&mut buffer.as_mut()[*transport_header_offset..]),
684 )
685 }
686}
687
688impl<I: IpExt, B: BufferMut> MaybeTransportPacket for ForwardedPacket<I, B> {
689 fn transport_packet_data(&self) -> Option<TransportPacketData> {
690 let ForwardedPacket { protocol, buffer, src_addr, dst_addr, transport_header_offset } =
691 self;
692 TransportPacketData::parse_in_ip_packet::<I, _>(
693 *src_addr,
694 *dst_addr,
695 *protocol,
696 Buf::new(&buffer.as_ref()[*transport_header_offset..], ..),
697 )
698 }
699}
700
701impl<I: IpExt, S: TransportPacketSerializer<I>, B: IpPacketBuilder<I>> IpPacket<I>
702 for Nested<S, B>
703{
704 type TransportPacket<'a>
705 = &'a S
706 where
707 Self: 'a;
708 type TransportPacketMut<'a>
709 = &'a mut S
710 where
711 Self: 'a;
712
713 fn src_addr(&self) -> I::Addr {
714 self.outer().src_ip()
715 }
716
717 fn set_src_addr(&mut self, addr: I::Addr) {
718 let old = self.outer().src_ip();
719 self.outer_mut().set_src_ip(addr);
720 if let Some(mut packet) = self.transport_packet_mut().transport_packet_mut() {
721 packet.update_pseudo_header_src_addr(old, addr);
722 }
723 }
724
725 fn dst_addr(&self) -> I::Addr {
726 self.outer().dst_ip()
727 }
728
729 fn set_dst_addr(&mut self, addr: I::Addr) {
730 let old = self.outer().dst_ip();
731 self.outer_mut().set_dst_ip(addr);
732 if let Some(mut packet) = self.transport_packet_mut().transport_packet_mut() {
733 packet.update_pseudo_header_dst_addr(old, addr);
734 }
735 }
736
737 fn protocol(&self) -> I::Proto {
738 self.outer().proto()
739 }
740
741 fn maybe_transport_packet(&self) -> Self::TransportPacket<'_> {
742 self.inner()
743 }
744
745 fn transport_packet_mut(&mut self) -> Self::TransportPacketMut<'_> {
746 self.inner_mut()
747 }
748}
749
750impl<I: IpExt, T: ?Sized> TransportPacketMut<I> for &mut T
751where
752 T: TransportPacketMut<I>,
753{
754 fn set_src_port(&mut self, port: NonZeroU16) {
755 (*self).set_src_port(port);
756 }
757
758 fn set_dst_port(&mut self, port: NonZeroU16) {
759 (*self).set_dst_port(port);
760 }
761
762 fn update_pseudo_header_src_addr(&mut self, old: I::Addr, new: I::Addr) {
763 (*self).update_pseudo_header_src_addr(old, new);
764 }
765
766 fn update_pseudo_header_dst_addr(&mut self, old: I::Addr, new: I::Addr) {
767 (*self).update_pseudo_header_dst_addr(old, new);
768 }
769}
770
771impl MaybeTransportPacket for Never {
772 fn transport_packet_data(&self) -> Option<TransportPacketData> {
773 match *self {}
774 }
775}
776
777impl<I: IpExt> MaybeTransportPacketMut<I> for Never {
778 type TransportPacketMut<'a>
779 = Never
780 where
781 Self: 'a;
782
783 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
784 match *self {}
785 }
786}
787
788impl<I: IpExt> TransportPacketMut<I> for Never {
789 fn set_src_port(&mut self, _: NonZeroU16) {
790 match *self {}
791 }
792
793 fn set_dst_port(&mut self, _: NonZeroU16) {
794 match *self {}
795 }
796
797 fn update_pseudo_header_src_addr(&mut self, _: I::Addr, _: I::Addr) {
798 match *self {}
799 }
800
801 fn update_pseudo_header_dst_addr(&mut self, _: I::Addr, _: I::Addr) {
802 match *self {}
803 }
804}
805
806impl<A: IpAddress, Inner> MaybeTransportPacket for Nested<Inner, UdpPacketBuilder<A>> {
807 fn transport_packet_data(&self) -> Option<TransportPacketData> {
808 Some(TransportPacketData::Generic {
809 src_port: self.outer().src_port().map_or(0, NonZeroU16::get),
810 dst_port: self.outer().dst_port().map_or(0, NonZeroU16::get),
811 })
812 }
813}
814
815impl<I: IpExt, Inner> MaybeTransportPacketMut<I> for Nested<Inner, UdpPacketBuilder<I::Addr>> {
816 type TransportPacketMut<'a>
817 = &'a mut Self
818 where
819 Self: 'a;
820
821 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
822 Some(self)
823 }
824}
825
826impl<I: IpExt, Inner> TransportPacketMut<I> for Nested<Inner, UdpPacketBuilder<I::Addr>> {
827 fn set_src_port(&mut self, port: NonZeroU16) {
828 self.outer_mut().set_src_port(port.get());
829 }
830
831 fn set_dst_port(&mut self, port: NonZeroU16) {
832 self.outer_mut().set_dst_port(port);
833 }
834
835 fn update_pseudo_header_src_addr(&mut self, _old: I::Addr, new: I::Addr) {
836 self.outer_mut().set_src_ip(new);
837 }
838
839 fn update_pseudo_header_dst_addr(&mut self, _old: I::Addr, new: I::Addr) {
840 self.outer_mut().set_dst_ip(new);
841 }
842}
843
844impl<'a, A: IpAddress, Inner: PayloadLen, I> MaybeTransportPacket
845 for Nested<Inner, TcpSegmentBuilderWithOptions<A, OptionSequenceBuilder<TcpOption<'a>, I>>>
846where
847 I: Iterator + Clone,
848 I::Item: Borrow<TcpOption<'a>>,
849{
850 fn transport_packet_data(&self) -> Option<TransportPacketData> {
851 Some(TransportPacketData::Tcp {
852 src_port: self.outer().src_port().map_or(0, NonZeroU16::get),
853 dst_port: self.outer().dst_port().map_or(0, NonZeroU16::get),
854 segment: self.outer().try_into().ok()?,
855 payload_len: self.inner().len(),
856 })
857 }
858}
859
860impl<I: IpExt, Outer, Inner> MaybeTransportPacketMut<I>
861 for Nested<Inner, TcpSegmentBuilderWithOptions<I::Addr, Outer>>
862{
863 type TransportPacketMut<'a>
864 = &'a mut Self
865 where
866 Self: 'a;
867
868 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
869 Some(self)
870 }
871}
872
873impl<I: IpExt, Outer, Inner> TransportPacketMut<I>
874 for Nested<Inner, TcpSegmentBuilderWithOptions<I::Addr, Outer>>
875{
876 fn set_src_port(&mut self, port: NonZeroU16) {
877 self.outer_mut().set_src_port(port);
878 }
879
880 fn set_dst_port(&mut self, port: NonZeroU16) {
881 self.outer_mut().set_dst_port(port);
882 }
883
884 fn update_pseudo_header_src_addr(&mut self, _old: I::Addr, new: I::Addr) {
885 self.outer_mut().set_src_ip(new);
886 }
887
888 fn update_pseudo_header_dst_addr(&mut self, _old: I::Addr, new: I::Addr) {
889 self.outer_mut().set_dst_ip(new);
890 }
891}
892
893impl<I: IpExt, Inner, M: IcmpMessage<I>> MaybeTransportPacket
894 for Nested<Inner, IcmpPacketBuilder<I, M>>
895{
896 fn transport_packet_data(&self) -> Option<TransportPacketData> {
897 self.outer().message().transport_packet_data()
898 }
899}
900
901impl<I: IpExt, Inner, M: IcmpMessage<I>> MaybeTransportPacketMut<I>
902 for Nested<Inner, IcmpPacketBuilder<I, M>>
903{
904 type TransportPacketMut<'a>
905 = &'a mut IcmpPacketBuilder<I, M>
906 where
907 M: 'a,
908 Inner: 'a;
909
910 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
911 Some(self.outer_mut())
912 }
913}
914
915impl<I: IpExt, M: IcmpMessage<I>> TransportPacketMut<I> for IcmpPacketBuilder<I, M> {
916 fn set_src_port(&mut self, id: NonZeroU16) {
917 let _: u16 = self.message_mut().update_icmp_id(id.get());
918 }
919
920 fn set_dst_port(&mut self, id: NonZeroU16) {
921 let _: u16 = self.message_mut().update_icmp_id(id.get());
922 }
923
924 fn update_pseudo_header_src_addr(&mut self, _old: I::Addr, new: I::Addr) {
925 self.set_src_ip(new);
926 }
927
928 fn update_pseudo_header_dst_addr(&mut self, _old: I::Addr, new: I::Addr) {
929 self.set_dst_ip(new);
930 }
931}
932
933pub trait IcmpMessage<I: IpExt>: icmp::IcmpMessage<I> + MaybeTransportPacket {
935 fn update_icmp_id(&mut self, id: u16) -> u16;
939}
940
941impl MaybeTransportPacket for IcmpEchoReply {
946 fn transport_packet_data(&self) -> Option<TransportPacketData> {
947 Some(TransportPacketData::Generic { src_port: self.id(), dst_port: self.id() })
948 }
949}
950
951impl<I: IpExt> IcmpMessage<I> for IcmpEchoReply {
952 fn update_icmp_id(&mut self, id: u16) -> u16 {
953 let old = self.id();
954 self.set_id(id);
955 old
956 }
957}
958
959impl MaybeTransportPacket for IcmpEchoRequest {
964 fn transport_packet_data(&self) -> Option<TransportPacketData> {
965 Some(TransportPacketData::Generic { src_port: self.id(), dst_port: self.id() })
966 }
967}
968
969impl<I: IpExt> IcmpMessage<I> for IcmpEchoRequest {
970 fn update_icmp_id(&mut self, id: u16) -> u16 {
971 let old = self.id();
972 self.set_id(id);
973 old
974 }
975}
976
977macro_rules! unsupported_icmp_message_type {
978 ($message:ty, $($ips:ty),+) => {
979 impl MaybeTransportPacket for $message {
980 fn transport_packet_data(&self) -> Option<TransportPacketData> {
981 None
982 }
983 }
984
985 $(
986 impl IcmpMessage<$ips> for $message {
987 fn update_icmp_id(&mut self, _: u16) -> u16 {
988 unreachable!("non-echo ICMP packets should never be rewritten")
989 }
990 }
991 )+
992 };
993}
994
995unsupported_icmp_message_type!(Icmpv4TimestampRequest, Ipv4);
996unsupported_icmp_message_type!(Icmpv4TimestampReply, Ipv4);
997unsupported_icmp_message_type!(Icmpv4Redirect, Ipv4);
998unsupported_icmp_message_type!(NeighborSolicitation, Ipv6);
999unsupported_icmp_message_type!(NeighborAdvertisement, Ipv6);
1000unsupported_icmp_message_type!(RouterSolicitation, Ipv6);
1001unsupported_icmp_message_type!(MulticastListenerDone, Ipv6);
1002unsupported_icmp_message_type!(MulticastListenerReport, Ipv6);
1003unsupported_icmp_message_type!(MulticastListenerReportV2, Ipv6);
1004unsupported_icmp_message_type!(MulticastListenerQuery, Ipv6);
1005unsupported_icmp_message_type!(MulticastListenerQueryV2, Ipv6);
1006unsupported_icmp_message_type!(RouterAdvertisement, Ipv6);
1007unsupported_icmp_message_type!(Redirect, Ipv6);
1008
1009macro_rules! icmp_error_message {
1015 ($message:ty, $($ips:ty),+) => {
1016 unsupported_icmp_message_type!($message, $( $ips ),+);
1017 };
1018}
1019
1020icmp_error_message!(IcmpDestUnreachable, Ipv4, Ipv6);
1021icmp_error_message!(IcmpTimeExceeded, Ipv4, Ipv6);
1022icmp_error_message!(Icmpv4ParameterProblem, Ipv4);
1023icmp_error_message!(Icmpv6ParameterProblem, Ipv6);
1024icmp_error_message!(Icmpv6PacketTooBig, Ipv6);
1025
1026impl<M: igmp::MessageType<EmptyBuf>> MaybeTransportPacket
1027 for InnerSerializer<IgmpPacketBuilder<EmptyBuf, M>, EmptyBuf>
1028{
1029 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1030 None
1031 }
1032}
1033
1034impl<M: igmp::MessageType<EmptyBuf>> MaybeTransportPacketMut<Ipv4>
1035 for InnerSerializer<IgmpPacketBuilder<EmptyBuf, M>, EmptyBuf>
1036{
1037 type TransportPacketMut<'a>
1038 = Never
1039 where
1040 M: 'a;
1041
1042 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1043 None
1044 }
1045}
1046
1047impl<I> MaybeTransportPacket for InnerSerializer<IgmpMembershipReportV3Builder<I>, EmptyBuf> {
1048 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1049 None
1050 }
1051}
1052
1053impl<I> MaybeTransportPacketMut<Ipv4>
1054 for InnerSerializer<IgmpMembershipReportV3Builder<I>, EmptyBuf>
1055{
1056 type TransportPacketMut<'a>
1057 = Never
1058 where
1059 I: 'a;
1060
1061 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1062 None
1063 }
1064}
1065
1066impl<I> MaybeTransportPacket
1067 for EitherSerializer<
1068 EmptyBuf,
1069 InnerSerializer<packet::records::RecordSequenceBuilder<NdpOptionBuilder<'_>, I>, EmptyBuf>,
1070 >
1071{
1072 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1073 None
1074 }
1075}
1076
1077#[derive(GenericOverIp)]
1082#[generic_over_ip(I, Ip)]
1083pub struct RawIpBody<I: IpExt, B: ParseBuffer> {
1084 protocol: I::Proto,
1087 src_addr: I::Addr,
1090 dst_addr: I::Addr,
1093 body: B,
1096 transport_packet_data: Option<TransportPacketData>,
1099}
1100
1101impl<I: IpExt, B: ParseBuffer> RawIpBody<I, B> {
1102 pub fn new(
1104 protocol: I::Proto,
1105 src_addr: I::Addr,
1106 dst_addr: I::Addr,
1107 body: B,
1108 ) -> RawIpBody<I, B> {
1109 let transport_packet_data = TransportPacketData::parse_in_ip_packet::<I, _>(
1110 src_addr,
1111 dst_addr,
1112 protocol,
1113 Buf::new(&body, ..),
1114 );
1115 RawIpBody { protocol, src_addr, dst_addr, body, transport_packet_data }
1116 }
1117}
1118
1119impl<I: IpExt, B: ParseBuffer> MaybeTransportPacket for RawIpBody<I, B> {
1120 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1121 self.transport_packet_data.clone()
1122 }
1123}
1124
1125impl<I: IpExt, B: BufferMut> MaybeTransportPacketMut<I> for RawIpBody<I, B> {
1126 type TransportPacketMut<'a>
1127 = ParsedTransportHeaderMut<'a, I>
1128 where
1129 Self: 'a;
1130
1131 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1132 let RawIpBody { protocol, src_addr, dst_addr, body, transport_packet_data: _ } = self;
1133 ParsedTransportHeaderMut::<I>::parse_in_ip_packet(
1134 *src_addr,
1135 *dst_addr,
1136 *protocol,
1137 SliceBufViewMut::new(body.as_mut()),
1138 )
1139 }
1140}
1141
1142impl<I: IpExt, B: BufferMut> Serializer for RawIpBody<I, B> {
1143 type Buffer = <B as Serializer>::Buffer;
1144
1145 fn serialize<G: GrowBufferMut, P: BufferProvider<Self::Buffer, G>>(
1146 self,
1147 outer: PacketConstraints,
1148 provider: P,
1149 ) -> Result<G, (SerializeError<P::Error>, Self)> {
1150 let Self { protocol, src_addr, dst_addr, body, transport_packet_data } = self;
1151 body.serialize(outer, provider).map_err(|(err, body)| {
1152 (err, Self { protocol, src_addr, dst_addr, body, transport_packet_data })
1153 })
1154 }
1155
1156 fn serialize_new_buf<BB: ReusableBuffer, A: BufferAlloc<BB>>(
1157 &self,
1158 outer: PacketConstraints,
1159 alloc: A,
1160 ) -> Result<BB, SerializeError<A::Error>> {
1161 self.body.serialize_new_buf(outer, alloc)
1162 }
1163}
1164
1165fn parse_transport_header_in_ipv4_packet<B: ParseBuffer>(
1166 src_ip: Ipv4Addr,
1167 dst_ip: Ipv4Addr,
1168 proto: Ipv4Proto,
1169 body: B,
1170) -> Option<TransportPacketData> {
1171 match proto {
1172 Ipv4Proto::Proto(IpProto::Udp) => parse_udp_header::<_, Ipv4>(body),
1173 Ipv4Proto::Proto(IpProto::Tcp) => parse_tcp_header::<_, Ipv4>(body, src_ip, dst_ip),
1174 Ipv4Proto::Icmp => parse_icmpv4_header(body),
1175 Ipv4Proto::Proto(IpProto::Reserved) | Ipv4Proto::Igmp | Ipv4Proto::Other(_) => None,
1176 }
1177}
1178
1179fn parse_transport_header_in_ipv6_packet<B: ParseBuffer>(
1180 src_ip: Ipv6Addr,
1181 dst_ip: Ipv6Addr,
1182 proto: Ipv6Proto,
1183 body: B,
1184) -> Option<TransportPacketData> {
1185 match proto {
1186 Ipv6Proto::Proto(IpProto::Udp) => parse_udp_header::<_, Ipv6>(body),
1187 Ipv6Proto::Proto(IpProto::Tcp) => parse_tcp_header::<_, Ipv6>(body, src_ip, dst_ip),
1188 Ipv6Proto::Icmpv6 => parse_icmpv6_header(body),
1189 Ipv6Proto::Proto(IpProto::Reserved) | Ipv6Proto::NoNextHeader | Ipv6Proto::Other(_) => None,
1190 }
1191}
1192
1193fn parse_udp_header<B: ParseBuffer, I: Ip>(mut body: B) -> Option<TransportPacketData> {
1194 let packet = body.parse_with::<_, UdpPacketRaw<_>>(I::VERSION_MARKER).ok()?;
1195 Some(TransportPacketData::Generic {
1196 src_port: packet.src_port().map(NonZeroU16::get).unwrap_or(0),
1197 dst_port: packet.dst_port()?.get(),
1200 })
1201}
1202
1203fn parse_tcp_header<B: ParseBuffer, I: IpExt>(
1204 mut body: B,
1205 src_ip: I::Addr,
1206 dst_ip: I::Addr,
1207) -> Option<TransportPacketData> {
1208 let packet = body.parse::<TcpSegmentRaw<_>>().ok()?;
1217
1218 let (builder, options, body) = packet.into_builder_options(src_ip, dst_ip)?;
1219 let options = Options::from_iter(builder.syn_set(), options.iter());
1220
1221 let segment = SegmentHeader::from_builder_options(&builder, options).ok()?;
1222
1223 Some(TransportPacketData::Tcp {
1224 src_port: builder.src_port().map(NonZeroU16::get).unwrap_or(0),
1225 dst_port: builder.dst_port().map(NonZeroU16::get).unwrap_or(0),
1226 segment,
1227 payload_len: body.len(),
1228 })
1229}
1230
1231fn parse_icmpv4_header<B: ParseBuffer>(mut body: B) -> Option<TransportPacketData> {
1232 match icmp::peek_message_type(body.as_ref()).ok()? {
1233 Icmpv4MessageType::EchoRequest => {
1234 let packet = body.parse::<IcmpPacketRaw<Ipv4, _, IcmpEchoRequest>>().ok()?;
1235 packet.message().transport_packet_data()
1236 }
1237 Icmpv4MessageType::EchoReply => {
1238 let packet = body.parse::<IcmpPacketRaw<Ipv4, _, IcmpEchoReply>>().ok()?;
1239 packet.message().transport_packet_data()
1240 }
1241 Icmpv4MessageType::DestUnreachable
1244 | Icmpv4MessageType::Redirect
1245 | Icmpv4MessageType::TimeExceeded
1246 | Icmpv4MessageType::ParameterProblem
1247 | Icmpv4MessageType::TimestampRequest
1251 | Icmpv4MessageType::TimestampReply => None,
1252 }
1253}
1254
1255fn parse_icmpv6_header<B: ParseBuffer>(mut body: B) -> Option<TransportPacketData> {
1256 match icmp::peek_message_type(body.as_ref()).ok()? {
1257 Icmpv6MessageType::EchoRequest => {
1258 let packet = body.parse::<IcmpPacketRaw<Ipv6, _, IcmpEchoRequest>>().ok()?;
1259 packet.message().transport_packet_data()
1260 }
1261 Icmpv6MessageType::EchoReply => {
1262 let packet = body.parse::<IcmpPacketRaw<Ipv6, _, IcmpEchoReply>>().ok()?;
1263 packet.message().transport_packet_data()
1264 }
1265 Icmpv6MessageType::DestUnreachable
1268 | Icmpv6MessageType::PacketTooBig
1269 | Icmpv6MessageType::TimeExceeded
1270 | Icmpv6MessageType::ParameterProblem
1271 | Icmpv6MessageType::RouterSolicitation
1272 | Icmpv6MessageType::RouterAdvertisement
1273 | Icmpv6MessageType::NeighborSolicitation
1274 | Icmpv6MessageType::NeighborAdvertisement
1275 | Icmpv6MessageType::Redirect
1276 | Icmpv6MessageType::MulticastListenerQuery
1277 | Icmpv6MessageType::MulticastListenerReport
1278 | Icmpv6MessageType::MulticastListenerDone
1279 | Icmpv6MessageType::MulticastListenerReportV2 => None,
1280 }
1281}
1282
1283#[derive(GenericOverIp)]
1286#[generic_over_ip(I, Ip)]
1287pub enum ParsedTransportHeaderMut<'a, I: IpExt> {
1288 Tcp(TcpSegment<&'a mut [u8]>),
1289 Udp(UdpPacket<&'a mut [u8]>),
1290 Icmp(I::IcmpPacketTypeRaw<&'a mut [u8]>),
1291}
1292
1293impl<'a> ParsedTransportHeaderMut<'a, Ipv4> {
1294 fn parse_in_ipv4_packet<BV: BufferViewMut<&'a mut [u8]>>(
1295 src_ip: Ipv4Addr,
1296 dst_ip: Ipv4Addr,
1297 proto: Ipv4Proto,
1298 body: BV,
1299 ) -> Option<Self> {
1300 match proto {
1301 Ipv4Proto::Proto(IpProto::Udp) => {
1302 Some(Self::Udp(UdpPacket::parse_mut(body, UdpParseArgs::new(src_ip, dst_ip)).ok()?))
1303 }
1304 Ipv4Proto::Proto(IpProto::Tcp) => Some(Self::Tcp(
1305 TcpSegment::parse_mut(body, TcpParseArgs::new(src_ip, dst_ip)).ok()?,
1306 )),
1307 Ipv4Proto::Icmp => Some(Self::Icmp(Icmpv4PacketRaw::parse_mut(body, ()).ok()?)),
1308 Ipv4Proto::Proto(IpProto::Reserved) | Ipv4Proto::Igmp | Ipv4Proto::Other(_) => None,
1309 }
1310 }
1311}
1312
1313impl<'a> ParsedTransportHeaderMut<'a, Ipv6> {
1314 fn parse_in_ipv6_packet<BV: BufferViewMut<&'a mut [u8]>>(
1315 src_ip: Ipv6Addr,
1316 dst_ip: Ipv6Addr,
1317 proto: Ipv6Proto,
1318 body: BV,
1319 ) -> Option<Self> {
1320 match proto {
1321 Ipv6Proto::Proto(IpProto::Udp) => {
1322 Some(Self::Udp(UdpPacket::parse_mut(body, UdpParseArgs::new(src_ip, dst_ip)).ok()?))
1323 }
1324 Ipv6Proto::Proto(IpProto::Tcp) => Some(Self::Tcp(
1325 TcpSegment::parse_mut(body, TcpParseArgs::new(src_ip, dst_ip)).ok()?,
1326 )),
1327 Ipv6Proto::Icmpv6 => Some(Self::Icmp(Icmpv6PacketRaw::parse_mut(body, ()).ok()?)),
1328 Ipv6Proto::Proto(IpProto::Reserved) | Ipv6Proto::NoNextHeader | Ipv6Proto::Other(_) => {
1329 None
1330 }
1331 }
1332 }
1333}
1334
1335impl<'a, I: IpExt> ParsedTransportHeaderMut<'a, I> {
1336 fn parse_in_ip_packet<BV: BufferViewMut<&'a mut [u8]>>(
1337 src_ip: I::Addr,
1338 dst_ip: I::Addr,
1339 proto: I::Proto,
1340 body: BV,
1341 ) -> Option<Self> {
1342 I::map_ip(
1343 (src_ip, dst_ip, proto, IpInvariant(body)),
1344 |(src_ip, dst_ip, proto, IpInvariant(body))| {
1345 ParsedTransportHeaderMut::<'a, Ipv4>::parse_in_ipv4_packet(
1346 src_ip, dst_ip, proto, body,
1347 )
1348 },
1349 |(src_ip, dst_ip, proto, IpInvariant(body))| {
1350 ParsedTransportHeaderMut::<'a, Ipv6>::parse_in_ipv6_packet(
1351 src_ip, dst_ip, proto, body,
1352 )
1353 },
1354 )
1355 }
1356
1357 fn update_pseudo_header_address(&mut self, old: I::Addr, new: I::Addr) {
1358 match self {
1359 Self::Tcp(segment) => segment.update_checksum_pseudo_header_address(old, new),
1360 Self::Udp(packet) => {
1361 packet.update_checksum_pseudo_header_address(old, new);
1362 }
1363 Self::Icmp(packet) => {
1364 packet.update_checksum_pseudo_header_address(old, new);
1365 }
1366 }
1367 }
1368}
1369
1370trait IcmpMessageImplHelper<I: IpExt> {
1372 fn message_impl_mut(&mut self) -> &mut impl IcmpMessage<I>;
1373}
1374
1375impl<I: IpExt, B: SplitByteSliceMut, M: IcmpMessage<I>> IcmpMessageImplHelper<I>
1376 for IcmpPacketRaw<I, B, M>
1377{
1378 fn message_impl_mut(&mut self) -> &mut impl IcmpMessage<I> {
1379 self.message_mut()
1380 }
1381}
1382
1383impl<'a, I: IpExt> TransportPacketMut<I> for ParsedTransportHeaderMut<'a, I> {
1384 fn set_src_port(&mut self, port: NonZeroU16) {
1385 match self {
1386 ParsedTransportHeaderMut::Tcp(segment) => segment.set_src_port(port),
1387 ParsedTransportHeaderMut::Udp(packet) => packet.set_src_port(port.get()),
1388 ParsedTransportHeaderMut::Icmp(packet) => {
1389 I::map_ip::<_, ()>(
1390 packet,
1391 |packet| {
1392 packet_formats::icmpv4_dispatch!(
1393 packet: raw,
1394 p => {
1395 let old = p.message_impl_mut().update_icmp_id(port.get());
1396 p.update_checksum_header_field_u16(old, port.get())
1397 }
1398 );
1399 },
1400 |packet| {
1401 packet_formats::icmpv6_dispatch!(
1402 packet: raw,
1403 p => {
1404 let old = p.message_impl_mut().update_icmp_id(port.get());
1405 p.update_checksum_header_field_u16(old, port.get())
1406 }
1407 );
1408 },
1409 );
1410 }
1411 }
1412 }
1413
1414 fn set_dst_port(&mut self, port: NonZeroU16) {
1415 match self {
1416 ParsedTransportHeaderMut::Tcp(ref mut segment) => segment.set_dst_port(port),
1417 ParsedTransportHeaderMut::Udp(ref mut packet) => packet.set_dst_port(port),
1418 ParsedTransportHeaderMut::Icmp(packet) => {
1419 I::map_ip::<_, ()>(
1420 packet,
1421 |packet| {
1422 packet_formats::icmpv4_dispatch!(
1423 packet:raw,
1424 p => {
1425 let old = p.message_impl_mut().update_icmp_id(port.get());
1426 p.update_checksum_header_field_u16(old, port.get())
1427 }
1428 );
1429 },
1430 |packet| {
1431 packet_formats::icmpv6_dispatch!(
1432 packet:raw,
1433 p => {
1434 let old = p.message_impl_mut().update_icmp_id(port.get());
1435 p.update_checksum_header_field_u16(old, port.get())
1436 }
1437 );
1438 },
1439 );
1440 }
1441 }
1442 }
1443
1444 fn update_pseudo_header_src_addr(&mut self, old: I::Addr, new: I::Addr) {
1445 self.update_pseudo_header_address(old, new);
1446 }
1447
1448 fn update_pseudo_header_dst_addr(&mut self, old: I::Addr, new: I::Addr) {
1449 self.update_pseudo_header_address(old, new);
1450 }
1451}
1452
1453#[cfg(any(test, feature = "testutils"))]
1454pub mod testutil {
1455 use super::*;
1456
1457 impl<B: BufferMut> MaybeTransportPacket for Nested<B, ()> {
1465 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1466 unimplemented!()
1467 }
1468 }
1469
1470 impl<I: IpExt, B: BufferMut> MaybeTransportPacketMut<I> for Nested<B, ()> {
1471 type TransportPacketMut<'a>
1472 = Never
1473 where
1474 B: 'a;
1475
1476 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1477 unimplemented!()
1478 }
1479 }
1480
1481 impl MaybeTransportPacket for InnerSerializer<&[u8], EmptyBuf> {
1482 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1483 None
1484 }
1485 }
1486
1487 impl<I: IpExt> MaybeTransportPacketMut<I> for InnerSerializer<&[u8], EmptyBuf> {
1488 type TransportPacketMut<'a>
1489 = Never
1490 where
1491 Self: 'a;
1492
1493 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1494 None
1495 }
1496 }
1497
1498 #[cfg(test)]
1499 pub(crate) mod internal {
1500 use net_declare::{net_ip_v4, net_ip_v6, net_subnet_v4, net_subnet_v6};
1501 use net_types::ip::Subnet;
1502 use netstack3_base::{SeqNum, UnscaledWindowSize};
1503
1504 use super::*;
1505
1506 pub trait TestIpExt: IpExt {
1507 const SRC_IP: Self::Addr;
1508 const SRC_PORT: u16 = 1234;
1509 const DST_IP: Self::Addr;
1510 const DST_PORT: u16 = 9876;
1511 const SRC_IP_2: Self::Addr;
1512 const DST_IP_2: Self::Addr;
1513 const IP_OUTSIDE_SUBNET: Self::Addr;
1514 const SUBNET: Subnet<Self::Addr>;
1515 }
1516
1517 impl TestIpExt for Ipv4 {
1518 const SRC_IP: Self::Addr = net_ip_v4!("192.0.2.1");
1519 const DST_IP: Self::Addr = net_ip_v4!("192.0.2.2");
1520 const SRC_IP_2: Self::Addr = net_ip_v4!("192.0.2.3");
1521 const DST_IP_2: Self::Addr = net_ip_v4!("192.0.2.4");
1522 const IP_OUTSIDE_SUBNET: Self::Addr = net_ip_v4!("192.0.3.1");
1523 const SUBNET: Subnet<Self::Addr> = net_subnet_v4!("192.0.2.0/24");
1524 }
1525
1526 impl TestIpExt for Ipv6 {
1527 const SRC_IP: Self::Addr = net_ip_v6!("2001:db8::1");
1528 const DST_IP: Self::Addr = net_ip_v6!("2001:db8::2");
1529 const SRC_IP_2: Self::Addr = net_ip_v6!("2001:db8::3");
1530 const DST_IP_2: Self::Addr = net_ip_v6!("2001:db8::4");
1531 const IP_OUTSIDE_SUBNET: Self::Addr = net_ip_v6!("2001:db8:ffff::1");
1532 const SUBNET: Subnet<Self::Addr> = net_subnet_v6!("2001:db8::/64");
1533 }
1534
1535 #[derive(Clone, Debug, PartialEq)]
1536 pub struct FakeIpPacket<I: IpExt, T>
1537 where
1538 for<'a> &'a T: TransportPacketExt<I>,
1539 {
1540 pub src_ip: I::Addr,
1541 pub dst_ip: I::Addr,
1542 pub body: T,
1543 }
1544
1545 impl<I: IpExt> FakeIpPacket<I, FakeUdpPacket> {
1546 pub(crate) fn reply(&self) -> Self {
1547 Self { src_ip: self.dst_ip, dst_ip: self.src_ip, body: self.body.reply() }
1548 }
1549 }
1550
1551 pub trait TransportPacketExt<I: IpExt>: MaybeTransportPacket {
1552 fn proto() -> I::Proto;
1553 }
1554
1555 impl<I: IpExt, T> IpPacket<I> for FakeIpPacket<I, T>
1556 where
1557 for<'a> &'a T: TransportPacketExt<I>,
1558 for<'a> &'a mut T: MaybeTransportPacketMut<I>,
1559 {
1560 type TransportPacket<'a>
1561 = &'a T
1562 where
1563 T: 'a;
1564 type TransportPacketMut<'a>
1565 = &'a mut T
1566 where
1567 T: 'a;
1568
1569 fn src_addr(&self) -> I::Addr {
1570 self.src_ip
1571 }
1572
1573 fn set_src_addr(&mut self, addr: I::Addr) {
1574 self.src_ip = addr;
1575 }
1576
1577 fn dst_addr(&self) -> I::Addr {
1578 self.dst_ip
1579 }
1580
1581 fn set_dst_addr(&mut self, addr: I::Addr) {
1582 self.dst_ip = addr;
1583 }
1584
1585 fn protocol(&self) -> I::Proto {
1586 <&T>::proto()
1587 }
1588
1589 fn maybe_transport_packet(&self) -> Self::TransportPacket<'_> {
1590 &self.body
1591 }
1592
1593 fn transport_packet_mut(&mut self) -> Self::TransportPacketMut<'_> {
1594 &mut self.body
1595 }
1596 }
1597
1598 #[derive(Clone, Debug, PartialEq)]
1599 pub struct FakeTcpSegment {
1600 pub src_port: u16,
1601 pub dst_port: u16,
1602 pub segment: SegmentHeader,
1603 pub payload_len: usize,
1604 }
1605
1606 impl<I: IpExt> TransportPacketExt<I> for &FakeTcpSegment {
1607 fn proto() -> I::Proto {
1608 I::map_ip_out(
1609 (),
1610 |()| Ipv4Proto::Proto(IpProto::Tcp),
1611 |()| Ipv6Proto::Proto(IpProto::Tcp),
1612 )
1613 }
1614 }
1615
1616 impl MaybeTransportPacket for &FakeTcpSegment {
1617 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1618 Some(TransportPacketData::Tcp {
1619 src_port: self.src_port,
1620 dst_port: self.dst_port,
1621 segment: self.segment.clone(),
1622 payload_len: self.payload_len,
1623 })
1624 }
1625 }
1626
1627 impl<I: IpExt> MaybeTransportPacketMut<I> for FakeTcpSegment {
1628 type TransportPacketMut<'a> = &'a mut Self;
1629
1630 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1631 Some(self)
1632 }
1633 }
1634
1635 impl<I: IpExt> TransportPacketMut<I> for FakeTcpSegment {
1636 fn set_src_port(&mut self, port: NonZeroU16) {
1637 self.src_port = port.get();
1638 }
1639
1640 fn set_dst_port(&mut self, port: NonZeroU16) {
1641 self.dst_port = port.get();
1642 }
1643
1644 fn update_pseudo_header_src_addr(&mut self, _: I::Addr, _: I::Addr) {}
1645
1646 fn update_pseudo_header_dst_addr(&mut self, _: I::Addr, _: I::Addr) {}
1647 }
1648
1649 #[derive(Clone, Debug, PartialEq)]
1650 pub struct FakeUdpPacket {
1651 pub src_port: u16,
1652 pub dst_port: u16,
1653 }
1654
1655 impl FakeUdpPacket {
1656 fn reply(&self) -> Self {
1657 Self { src_port: self.dst_port, dst_port: self.src_port }
1658 }
1659 }
1660
1661 impl<I: IpExt> TransportPacketExt<I> for &FakeUdpPacket {
1662 fn proto() -> I::Proto {
1663 I::map_ip_out(
1664 (),
1665 |()| Ipv4Proto::Proto(IpProto::Udp),
1666 |()| Ipv6Proto::Proto(IpProto::Udp),
1667 )
1668 }
1669 }
1670
1671 impl MaybeTransportPacket for &FakeUdpPacket {
1672 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1673 Some(TransportPacketData::Generic {
1674 src_port: self.src_port,
1675 dst_port: self.dst_port,
1676 })
1677 }
1678 }
1679
1680 impl<I: IpExt> MaybeTransportPacketMut<I> for FakeUdpPacket {
1681 type TransportPacketMut<'a> = &'a mut Self;
1682
1683 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1684 Some(self)
1685 }
1686 }
1687
1688 impl<I: IpExt> TransportPacketMut<I> for FakeUdpPacket {
1689 fn set_src_port(&mut self, port: NonZeroU16) {
1690 self.src_port = port.get();
1691 }
1692
1693 fn set_dst_port(&mut self, port: NonZeroU16) {
1694 self.dst_port = port.get();
1695 }
1696
1697 fn update_pseudo_header_src_addr(&mut self, _: I::Addr, _: I::Addr) {}
1698
1699 fn update_pseudo_header_dst_addr(&mut self, _: I::Addr, _: I::Addr) {}
1700 }
1701
1702 pub struct FakeIcmpEchoRequest {
1703 pub id: u16,
1704 }
1705
1706 impl<I: IpExt> TransportPacketExt<I> for &FakeIcmpEchoRequest {
1707 fn proto() -> I::Proto {
1708 I::map_ip_out((), |()| Ipv4Proto::Icmp, |()| Ipv6Proto::Icmpv6)
1709 }
1710 }
1711
1712 impl MaybeTransportPacket for &FakeIcmpEchoRequest {
1713 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1714 Some(TransportPacketData::Generic { src_port: self.id, dst_port: 0 })
1715 }
1716 }
1717
1718 impl<I: IpExt> MaybeTransportPacketMut<I> for FakeIcmpEchoRequest {
1719 type TransportPacketMut<'a> = &'a mut Self;
1720
1721 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1722 Some(self)
1723 }
1724 }
1725
1726 impl<I: IpExt> TransportPacketMut<I> for FakeIcmpEchoRequest {
1727 fn set_src_port(&mut self, port: NonZeroU16) {
1728 self.id = port.get();
1729 }
1730
1731 fn set_dst_port(&mut self, _: NonZeroU16) {
1732 panic!("cannot set destination port for ICMP echo request")
1733 }
1734
1735 fn update_pseudo_header_src_addr(&mut self, _: I::Addr, _: I::Addr) {}
1736
1737 fn update_pseudo_header_dst_addr(&mut self, _: I::Addr, _: I::Addr) {}
1738 }
1739
1740 pub trait ArbitraryValue {
1741 fn arbitrary_value() -> Self;
1742 }
1743
1744 impl<I, T> ArbitraryValue for FakeIpPacket<I, T>
1745 where
1746 I: TestIpExt,
1747 T: ArbitraryValue,
1748 for<'a> &'a T: TransportPacketExt<I>,
1749 {
1750 fn arbitrary_value() -> Self {
1751 FakeIpPacket { src_ip: I::SRC_IP, dst_ip: I::DST_IP, body: T::arbitrary_value() }
1752 }
1753 }
1754
1755 impl ArbitraryValue for FakeTcpSegment {
1756 fn arbitrary_value() -> Self {
1757 FakeTcpSegment {
1758 src_port: 33333,
1759 dst_port: 44444,
1760 segment: SegmentHeader::arbitrary_value(),
1761 payload_len: 8888,
1762 }
1763 }
1764 }
1765
1766 impl ArbitraryValue for FakeUdpPacket {
1767 fn arbitrary_value() -> Self {
1768 FakeUdpPacket { src_port: 33333, dst_port: 44444 }
1769 }
1770 }
1771
1772 impl ArbitraryValue for FakeIcmpEchoRequest {
1773 fn arbitrary_value() -> Self {
1774 FakeIcmpEchoRequest { id: 1 }
1775 }
1776 }
1777
1778 impl ArbitraryValue for SegmentHeader {
1779 fn arbitrary_value() -> Self {
1780 SegmentHeader {
1781 seq: SeqNum::new(55555),
1782 wnd: UnscaledWindowSize::from(1234),
1783 ..Default::default()
1784 }
1785 }
1786 }
1787 }
1788}
1789
1790#[cfg(test)]
1791mod tests {
1792 use alloc::vec::Vec;
1793 use core::fmt::Debug;
1794 use netstack3_base::{SeqNum, UnscaledWindowSize};
1795
1796 use ip_test_macro::ip_test;
1797 use packet::InnerPacketBuilder as _;
1798 use packet_formats::icmp::IcmpZeroCode;
1799 use packet_formats::tcp::TcpSegmentBuilder;
1800 use test_case::test_case;
1801
1802 use super::testutil::internal::TestIpExt;
1803 use super::*;
1804
1805 const SRC_PORT: NonZeroU16 = NonZeroU16::new(11111).unwrap();
1806 const DST_PORT: NonZeroU16 = NonZeroU16::new(22222).unwrap();
1807 const SRC_PORT_2: NonZeroU16 = NonZeroU16::new(44444).unwrap();
1808 const DST_PORT_2: NonZeroU16 = NonZeroU16::new(55555).unwrap();
1809
1810 const SEQ_NUM: u32 = 1;
1811 const ACK_NUM: Option<u32> = Some(2);
1812 const WINDOW_SIZE: u16 = 3u16;
1813
1814 trait Protocol {
1815 type Serializer<'a, I: IpExt>: TransportPacketSerializer<I, Buffer: packet::ReusableBuffer>
1816 + MaybeTransportPacketMut<I>
1817 + Debug
1818 + PartialEq;
1819
1820 fn proto<I: IpExt>() -> I::Proto;
1821
1822 fn make_serializer_with_ports<'a, I: IpExt>(
1823 src_ip: I::Addr,
1824 dst_ip: I::Addr,
1825 src_port: NonZeroU16,
1826 dst_port: NonZeroU16,
1827 ) -> Self::Serializer<'a, I>;
1828
1829 fn make_serializer<'a, I: IpExt>(
1830 src_ip: I::Addr,
1831 dst_ip: I::Addr,
1832 ) -> Self::Serializer<'a, I> {
1833 Self::make_serializer_with_ports(src_ip, dst_ip, SRC_PORT, DST_PORT)
1834 }
1835
1836 fn make_packet<I: IpExt>(src_ip: I::Addr, dst_ip: I::Addr) -> Vec<u8> {
1837 Self::make_packet_with_ports::<I>(src_ip, dst_ip, SRC_PORT, DST_PORT)
1838 }
1839
1840 fn make_packet_with_ports<I: IpExt>(
1841 src_ip: I::Addr,
1842 dst_ip: I::Addr,
1843 src_port: NonZeroU16,
1844 dst_port: NonZeroU16,
1845 ) -> Vec<u8> {
1846 Self::make_serializer_with_ports::<I>(src_ip, dst_ip, src_port, dst_port)
1847 .serialize_vec_outer()
1848 .expect("serialize packet")
1849 .unwrap_b()
1850 .into_inner()
1851 }
1852 }
1853
1854 struct Udp;
1855
1856 impl Protocol for Udp {
1857 type Serializer<'a, I: IpExt> =
1858 Nested<InnerSerializer<&'a [u8], EmptyBuf>, UdpPacketBuilder<I::Addr>>;
1859
1860 fn proto<I: IpExt>() -> I::Proto {
1861 IpProto::Udp.into()
1862 }
1863
1864 fn make_serializer_with_ports<'a, I: IpExt>(
1865 src_ip: I::Addr,
1866 dst_ip: I::Addr,
1867 src_port: NonZeroU16,
1868 dst_port: NonZeroU16,
1869 ) -> Self::Serializer<'a, I> {
1870 [].into_serializer().encapsulate(UdpPacketBuilder::new(
1871 src_ip,
1872 dst_ip,
1873 Some(src_port),
1874 dst_port,
1875 ))
1876 }
1877 }
1878
1879 impl<A: IpAddress, Inner: PayloadLen> MaybeTransportPacket for Nested<Inner, TcpSegmentBuilder<A>> {
1887 fn transport_packet_data(&self) -> Option<TransportPacketData> {
1888 Some(TransportPacketData::Tcp {
1889 src_port: TcpSegmentBuilder::src_port(self.outer()).map_or(0, NonZeroU16::get),
1890 dst_port: TcpSegmentBuilder::dst_port(self.outer()).map_or(0, NonZeroU16::get),
1891 segment: self.outer().try_into().ok()?,
1892 payload_len: self.inner().len(),
1893 })
1894 }
1895 }
1896
1897 impl<I: IpExt, Inner> MaybeTransportPacketMut<I> for Nested<Inner, TcpSegmentBuilder<I::Addr>> {
1898 type TransportPacketMut<'a>
1899 = &'a mut Self
1900 where
1901 Self: 'a;
1902
1903 fn transport_packet_mut(&mut self) -> Option<Self::TransportPacketMut<'_>> {
1904 Some(self)
1905 }
1906 }
1907
1908 impl<I: IpExt, Inner> TransportPacketMut<I> for Nested<Inner, TcpSegmentBuilder<I::Addr>> {
1909 fn set_src_port(&mut self, port: NonZeroU16) {
1910 self.outer_mut().set_src_port(port);
1911 }
1912
1913 fn set_dst_port(&mut self, port: NonZeroU16) {
1914 self.outer_mut().set_dst_port(port);
1915 }
1916
1917 fn update_pseudo_header_src_addr(&mut self, _old: I::Addr, new: I::Addr) {
1918 self.outer_mut().set_src_ip(new);
1919 }
1920
1921 fn update_pseudo_header_dst_addr(&mut self, _old: I::Addr, new: I::Addr) {
1922 self.outer_mut().set_dst_ip(new);
1923 }
1924 }
1925
1926 struct Tcp;
1927
1928 impl Protocol for Tcp {
1929 type Serializer<'a, I: IpExt> =
1930 Nested<InnerSerializer<&'a [u8], EmptyBuf>, TcpSegmentBuilder<I::Addr>>;
1931
1932 fn proto<I: IpExt>() -> I::Proto {
1933 IpProto::Tcp.into()
1934 }
1935
1936 fn make_serializer_with_ports<'a, I: IpExt>(
1937 src_ip: I::Addr,
1938 dst_ip: I::Addr,
1939 src_port: NonZeroU16,
1940 dst_port: NonZeroU16,
1941 ) -> Self::Serializer<'a, I> {
1942 [1, 2, 3].into_serializer().encapsulate(TcpSegmentBuilder::new(
1943 src_ip,
1944 dst_ip,
1945 src_port,
1946 dst_port,
1947 SEQ_NUM,
1948 ACK_NUM,
1949 WINDOW_SIZE,
1950 ))
1951 }
1952 }
1953
1954 struct IcmpEchoRequest;
1955
1956 impl Protocol for IcmpEchoRequest {
1957 type Serializer<'a, I: IpExt> = Nested<
1958 InnerSerializer<&'a [u8], EmptyBuf>,
1959 IcmpPacketBuilder<I, icmp::IcmpEchoRequest>,
1960 >;
1961
1962 fn proto<I: IpExt>() -> I::Proto {
1963 I::map_ip((), |()| Ipv4Proto::Icmp, |()| Ipv6Proto::Icmpv6)
1964 }
1965
1966 fn make_serializer_with_ports<'a, I: IpExt>(
1967 src_ip: I::Addr,
1968 dst_ip: I::Addr,
1969 src_port: NonZeroU16,
1970 _dst_port: NonZeroU16,
1971 ) -> Self::Serializer<'a, I> {
1972 [].into_serializer().encapsulate(IcmpPacketBuilder::<I, _>::new(
1973 src_ip,
1974 dst_ip,
1975 IcmpZeroCode,
1976 icmp::IcmpEchoRequest::new(src_port.get(), 0),
1977 ))
1978 }
1979 }
1980
1981 struct IcmpEchoReply;
1982
1983 impl Protocol for IcmpEchoReply {
1984 type Serializer<'a, I: IpExt> =
1985 Nested<InnerSerializer<&'a [u8], EmptyBuf>, IcmpPacketBuilder<I, icmp::IcmpEchoReply>>;
1986
1987 fn proto<I: IpExt>() -> I::Proto {
1988 I::map_ip((), |()| Ipv4Proto::Icmp, |()| Ipv6Proto::Icmpv6)
1989 }
1990
1991 fn make_serializer_with_ports<'a, I: IpExt>(
1992 src_ip: I::Addr,
1993 dst_ip: I::Addr,
1994 _src_port: NonZeroU16,
1995 dst_port: NonZeroU16,
1996 ) -> Self::Serializer<'a, I> {
1997 [].into_serializer().encapsulate(IcmpPacketBuilder::<I, _>::new(
1998 src_ip,
1999 dst_ip,
2000 IcmpZeroCode,
2001 icmp::IcmpEchoReply::new(dst_port.get(), 0),
2002 ))
2003 }
2004 }
2005
2006 enum TransportPacketDataProtocol {
2007 Tcp,
2008 Udp,
2009 IcmpEchoRequest,
2010 }
2011
2012 impl TransportPacketDataProtocol {
2013 fn make_packet<I: TestIpExt>(&self, src_ip: I::Addr, dst_ip: I::Addr) -> Vec<u8> {
2014 match self {
2015 TransportPacketDataProtocol::Tcp => Tcp::make_packet::<I>(src_ip, dst_ip),
2016 TransportPacketDataProtocol::Udp => Udp::make_packet::<I>(src_ip, dst_ip),
2017 TransportPacketDataProtocol::IcmpEchoRequest => {
2018 IcmpEchoRequest::make_packet::<I>(src_ip, dst_ip)
2019 }
2020 }
2021 }
2022
2023 fn proto<I: TestIpExt>(&self) -> I::Proto {
2024 match self {
2025 TransportPacketDataProtocol::Tcp => Tcp::proto::<I>(),
2026 TransportPacketDataProtocol::Udp => Udp::proto::<I>(),
2027 TransportPacketDataProtocol::IcmpEchoRequest => IcmpEchoRequest::proto::<I>(),
2028 }
2029 }
2030 }
2031
2032 #[ip_test(I)]
2033 #[test_case(TransportPacketDataProtocol::Udp)]
2034 #[test_case(TransportPacketDataProtocol::Tcp)]
2035 #[test_case(TransportPacketDataProtocol::IcmpEchoRequest)]
2036 fn transport_packet_data_from_serialized<I: TestIpExt>(proto: TransportPacketDataProtocol) {
2037 let expected_data = match proto {
2038 TransportPacketDataProtocol::Tcp => TransportPacketData::Tcp {
2039 src_port: SRC_PORT.get(),
2040 dst_port: DST_PORT.get(),
2041 segment: SegmentHeader {
2042 seq: SeqNum::new(SEQ_NUM),
2043 ack: ACK_NUM.map(SeqNum::new),
2044 wnd: UnscaledWindowSize::from(WINDOW_SIZE),
2045 ..Default::default()
2046 },
2047 payload_len: 3,
2048 },
2049 TransportPacketDataProtocol::Udp => {
2050 TransportPacketData::Generic { src_port: SRC_PORT.get(), dst_port: DST_PORT.get() }
2051 }
2052 TransportPacketDataProtocol::IcmpEchoRequest => {
2053 TransportPacketData::Generic { src_port: SRC_PORT.get(), dst_port: SRC_PORT.get() }
2054 }
2055 };
2056
2057 let buf = proto.make_packet::<I>(I::SRC_IP, I::DST_IP);
2058 let parsed_data = TransportPacketData::parse_in_ip_packet::<I, _>(
2059 I::SRC_IP,
2060 I::DST_IP,
2061 proto.proto::<I>(),
2062 buf.as_slice(),
2063 )
2064 .expect("failed to parse transport packet data");
2065
2066 assert_eq!(parsed_data, expected_data);
2067 }
2068
2069 #[ip_test(I)]
2070 #[test_case(Udp)]
2071 #[test_case(Tcp)]
2072 #[test_case(IcmpEchoRequest)]
2073 fn update_pseudo_header_address_updates_checksum<I: TestIpExt, P: Protocol>(_proto: P) {
2074 let mut buf = P::make_packet::<I>(I::SRC_IP, I::DST_IP);
2075 let view = SliceBufViewMut::new(&mut buf);
2076
2077 let mut packet = ParsedTransportHeaderMut::<I>::parse_in_ip_packet(
2078 I::SRC_IP,
2079 I::DST_IP,
2080 P::proto::<I>(),
2081 view,
2082 )
2083 .expect("parse transport header");
2084 packet.update_pseudo_header_src_addr(I::SRC_IP, I::SRC_IP_2);
2085 packet.update_pseudo_header_dst_addr(I::DST_IP, I::DST_IP_2);
2086 drop(packet);
2089
2090 let equivalent = P::make_packet::<I>(I::SRC_IP_2, I::DST_IP_2);
2091
2092 assert_eq!(equivalent, buf);
2093 }
2094
2095 #[ip_test(I)]
2096 #[test_case(Udp, true, true)]
2097 #[test_case(Tcp, true, true)]
2098 #[test_case(IcmpEchoRequest, true, false)]
2099 #[test_case(IcmpEchoReply, false, true)]
2100 fn parsed_packet_update_src_dst_port_updates_checksum<I: TestIpExt, P: Protocol>(
2101 _proto: P,
2102 update_src_port: bool,
2103 update_dst_port: bool,
2104 ) {
2105 let mut buf = P::make_packet_with_ports::<I>(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT);
2106 let view = SliceBufViewMut::new(&mut buf);
2107
2108 let mut packet = ParsedTransportHeaderMut::<I>::parse_in_ip_packet(
2109 I::SRC_IP,
2110 I::DST_IP,
2111 P::proto::<I>(),
2112 view,
2113 )
2114 .expect("parse transport header");
2115 let expected_src_port = if update_src_port {
2116 packet.set_src_port(SRC_PORT_2);
2117 SRC_PORT_2
2118 } else {
2119 SRC_PORT
2120 };
2121 let expected_dst_port = if update_dst_port {
2122 packet.set_dst_port(DST_PORT_2);
2123 DST_PORT_2
2124 } else {
2125 DST_PORT
2126 };
2127 drop(packet);
2128
2129 let equivalent = P::make_packet_with_ports::<I>(
2130 I::SRC_IP,
2131 I::DST_IP,
2132 expected_src_port,
2133 expected_dst_port,
2134 );
2135
2136 assert_eq!(equivalent, buf);
2137 }
2138
2139 #[ip_test(I)]
2140 #[test_case(Udp)]
2141 #[test_case(Tcp)]
2142 fn serializer_update_src_dst_port_updates_checksum<I: TestIpExt, P: Protocol>(_proto: P) {
2143 let mut serializer =
2144 P::make_serializer_with_ports::<I>(I::SRC_IP, I::DST_IP, SRC_PORT, DST_PORT);
2145 let mut packet =
2146 serializer.transport_packet_mut().expect("packet should support rewriting");
2147 packet.set_src_port(SRC_PORT_2);
2148 packet.set_dst_port(DST_PORT_2);
2149 drop(packet);
2150
2151 let equivalent =
2152 P::make_serializer_with_ports::<I>(I::SRC_IP, I::DST_IP, SRC_PORT_2, DST_PORT_2);
2153
2154 assert_eq!(equivalent, serializer);
2155 }
2156
2157 #[ip_test(I)]
2158 fn icmp_echo_request_update_id_port_updates_checksum<I: TestIpExt>() {
2159 let mut serializer = [].into_serializer().encapsulate(IcmpPacketBuilder::<I, _>::new(
2160 I::SRC_IP,
2161 I::DST_IP,
2162 IcmpZeroCode,
2163 icmp::IcmpEchoRequest::new(SRC_PORT.get(), 0),
2164 ));
2165 serializer
2166 .transport_packet_mut()
2167 .expect("packet should support rewriting")
2168 .set_src_port(SRC_PORT_2);
2169
2170 let equivalent = [].into_serializer().encapsulate(IcmpPacketBuilder::<I, _>::new(
2171 I::SRC_IP,
2172 I::DST_IP,
2173 IcmpZeroCode,
2174 icmp::IcmpEchoRequest::new(SRC_PORT_2.get(), 0),
2175 ));
2176
2177 assert_eq!(equivalent, serializer);
2178 }
2179
2180 #[ip_test(I)]
2181 fn icmp_echo_reply_update_id_port_updates_checksum<I: TestIpExt>() {
2182 let mut serializer = [].into_serializer().encapsulate(IcmpPacketBuilder::<I, _>::new(
2183 I::SRC_IP,
2184 I::DST_IP,
2185 IcmpZeroCode,
2186 icmp::IcmpEchoReply::new(SRC_PORT.get(), 0),
2187 ));
2188 serializer
2189 .transport_packet_mut()
2190 .expect("packet should support rewriting")
2191 .set_dst_port(SRC_PORT_2);
2192
2193 let equivalent = [].into_serializer().encapsulate(IcmpPacketBuilder::<I, _>::new(
2194 I::SRC_IP,
2195 I::DST_IP,
2196 IcmpZeroCode,
2197 icmp::IcmpEchoReply::new(SRC_PORT_2.get(), 0),
2198 ));
2199
2200 assert_eq!(equivalent, serializer);
2201 }
2202
2203 #[test]
2204 #[should_panic]
2205 fn icmp_serializer_set_port_panics_on_unsupported_type() {
2206 let mut serializer = [].into_serializer().encapsulate(IcmpPacketBuilder::new(
2207 Ipv4::SRC_IP,
2208 Ipv4::DST_IP,
2209 IcmpZeroCode,
2210 icmp::Icmpv4TimestampRequest::new(
2211 0,
2212 SRC_PORT.get(),
2213 0,
2214 )
2215 .reply(0, 0),
2216 ));
2217 let Some(packet) = serializer.transport_packet_mut() else {
2218 return;
2222 };
2223 packet.set_src_port(SRC_PORT_2);
2224 }
2225
2226 fn ip_packet<I: IpExt, P: Protocol>(src: I::Addr, dst: I::Addr) -> Buf<Vec<u8>> {
2227 Buf::new(P::make_packet::<I>(src, dst), ..)
2228 .encapsulate(I::PacketBuilder::new(src, dst, u8::MAX, P::proto::<I>()))
2229 .serialize_vec_outer()
2230 .expect("serialize IP packet")
2231 .unwrap_b()
2232 }
2233
2234 #[ip_test(I)]
2235 #[test_case(Udp)]
2236 #[test_case(Tcp)]
2237 #[test_case(IcmpEchoRequest)]
2238 fn ip_packet_set_src_dst_addr_updates_checksums<I: TestIpExt, P: Protocol>(_proto: P)
2239 where
2240 for<'a> I::Packet<&'a mut [u8]>: IpPacket<I>,
2241 {
2242 let mut buf = ip_packet::<I, P>(I::SRC_IP, I::DST_IP).into_inner();
2243
2244 let mut packet =
2245 I::Packet::parse_mut(SliceBufViewMut::new(&mut buf), ()).expect("parse IP packet");
2246 packet.set_src_addr(I::SRC_IP_2);
2247 packet.set_dst_addr(I::DST_IP_2);
2248 drop(packet);
2249
2250 let equivalent = ip_packet::<I, P>(I::SRC_IP_2, I::DST_IP_2).into_inner();
2251
2252 assert_eq!(equivalent, buf);
2253 }
2254
2255 #[ip_test(I)]
2256 #[test_case(Udp)]
2257 #[test_case(Tcp)]
2258 #[test_case(IcmpEchoRequest)]
2259 fn forwarded_packet_set_src_dst_addr_updates_checksums<I: TestIpExt, P: Protocol>(_proto: P) {
2260 let mut buffer = ip_packet::<I, P>(I::SRC_IP, I::DST_IP);
2261 let meta = buffer.parse::<I::Packet<_>>().expect("parse IP packet").parse_metadata();
2262 let mut packet =
2263 ForwardedPacket::<I, _>::new(I::SRC_IP, I::DST_IP, P::proto::<I>(), meta, buffer);
2264 packet.set_src_addr(I::SRC_IP_2);
2265 packet.set_dst_addr(I::DST_IP_2);
2266
2267 let mut buffer = ip_packet::<I, P>(I::SRC_IP_2, I::DST_IP_2);
2268 let meta = buffer.parse::<I::Packet<_>>().expect("parse IP packet").parse_metadata();
2269 let equivalent =
2270 ForwardedPacket::<I, _>::new(I::SRC_IP_2, I::DST_IP_2, P::proto::<I>(), meta, buffer);
2271
2272 assert_eq!(equivalent, packet);
2273 }
2274
2275 #[ip_test(I)]
2276 #[test_case(Udp)]
2277 #[test_case(Tcp)]
2278 #[test_case(IcmpEchoRequest)]
2279 fn tx_packet_set_src_dst_addr_updates_checksums<I: TestIpExt, P: Protocol>(_proto: P) {
2280 let mut body = P::make_serializer::<I>(I::SRC_IP, I::DST_IP);
2281 let mut packet = TxPacket::<I, _>::new(I::SRC_IP, I::DST_IP, P::proto::<I>(), &mut body);
2282 packet.set_src_addr(I::SRC_IP_2);
2283 packet.set_dst_addr(I::DST_IP_2);
2284
2285 let mut equivalent_body = P::make_serializer::<I>(I::SRC_IP_2, I::DST_IP_2);
2286 let equivalent =
2287 TxPacket::new(I::SRC_IP_2, I::DST_IP_2, P::proto::<I>(), &mut equivalent_body);
2288
2289 assert_eq!(equivalent, packet);
2290 }
2291
2292 #[ip_test(I)]
2293 #[test_case(Udp)]
2294 #[test_case(Tcp)]
2295 #[test_case(IcmpEchoRequest)]
2296 fn nested_serializer_set_src_dst_addr_updates_checksums<I: TestIpExt, P: Protocol>(_proto: P) {
2297 let mut packet = P::make_serializer::<I>(I::SRC_IP, I::DST_IP).encapsulate(
2298 I::PacketBuilder::new(I::SRC_IP, I::DST_IP, u8::MAX, P::proto::<I>()),
2299 );
2300 packet.set_src_addr(I::SRC_IP_2);
2301 packet.set_dst_addr(I::DST_IP_2);
2302
2303 let equivalent =
2304 P::make_serializer::<I>(I::SRC_IP_2, I::DST_IP_2).encapsulate(I::PacketBuilder::new(
2305 I::SRC_IP_2,
2306 I::DST_IP_2,
2307 u8::MAX,
2308 P::proto::<I>(),
2309 ));
2310
2311 assert_eq!(equivalent, packet);
2312 }
2313}