1use alloc::vec::Vec;
12use core::borrow::Borrow;
13use core::fmt::{self, Debug, Formatter};
14use core::ops::Range;
15
16use internet_checksum::Checksum;
17use log::debug;
18use net_types::ip::{GenericOverIp, IpAddress, Ipv4, Ipv4Addr, Ipv6Addr};
19use packet::records::options::{OptionSequenceBuilder, OptionsRaw};
20use packet::records::RecordsIter;
21use packet::{
22 BufferAlloc, BufferProvider, BufferView, BufferViewMut, EmptyBuf, FragmentedBytesMut, FromRaw,
23 GrowBufferMut, InnerPacketBuilder, MaybeParsed, PacketBuilder, PacketConstraints,
24 ParsablePacket, ParseMetadata, ReusableBuffer, SerializeError, SerializeTarget, Serializer,
25};
26use zerocopy::byteorder::network_endian::U16;
27use zerocopy::{
28 FromBytes, Immutable, IntoBytes, KnownLayout, Ref, SplitByteSlice, SplitByteSliceMut, Unaligned,
29};
30
31use crate::error::{IpParseError, IpParseResult, ParseError};
32use crate::ip::{
33 DscpAndEcn, FragmentOffset, IpExt, IpPacketBuilder, IpProto, Ipv4Proto, Ipv6Proto, Nat64Error,
34 Nat64TranslationResult,
35};
36use crate::ipv6::Ipv6PacketBuilder;
37use crate::tcp::{TcpParseArgs, TcpSegment};
38use crate::udp::{UdpPacket, UdpParseArgs};
39
40pub(crate) use self::inner::IPV4_MIN_HDR_LEN;
41use self::options::{Ipv4Option, Ipv4OptionsImpl};
42
43pub const HDR_PREFIX_LEN: usize = 20;
45
46pub const MAX_HDR_LEN: usize = 60;
48
49pub const MAX_OPTIONS_LEN: usize = MAX_HDR_LEN - HDR_PREFIX_LEN;
51
52const IPV4_FRAGMENT_DATA_BYTE_RANGE: Range<usize> = 4..8;
54
55#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
57#[allow(missing_docs)]
58pub enum Ipv4FragmentType {
59 InitialFragment,
60 NonInitialFragment,
61}
62
63#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned)]
66#[repr(C)]
67pub struct HeaderPrefix {
68 version_ihl: u8,
69 dscp_and_ecn: DscpAndEcn,
70 total_len: U16,
71 id: U16,
72 flags_frag_off: [u8; 2],
73 ttl: u8,
74 proto: u8,
75 hdr_checksum: [u8; 2],
76 src_ip: Ipv4Addr,
77 dst_ip: Ipv4Addr,
78}
79
80const IP_VERSION: u8 = 4;
81const VERSION_OFFSET: u8 = 4;
82const IHL_MASK: u8 = 0xF;
83const IHL_MAX: u8 = (1 << VERSION_OFFSET) - 1;
84const FLAGS_OFFSET: u8 = 13;
85const FLAGS_MAX: u8 = (1 << (16 - FLAGS_OFFSET)) - 1;
86const FRAG_OFF_MAX: u16 = (1 << FLAGS_OFFSET) - 1;
87
88impl HeaderPrefix {
89 #[allow(clippy::too_many_arguments)]
90 fn new(
91 ihl: u8,
92 dscp_and_ecn: DscpAndEcn,
93 total_len: u16,
94 id: u16,
95 flags: u8,
96 frag_off: u16,
97 ttl: u8,
98 proto: u8,
99 hdr_checksum: [u8; 2],
100 src_ip: Ipv4Addr,
101 dst_ip: Ipv4Addr,
102 ) -> HeaderPrefix {
103 debug_assert!(ihl <= IHL_MAX);
104 debug_assert!(flags <= FLAGS_MAX);
105 debug_assert!(frag_off <= FRAG_OFF_MAX);
106
107 HeaderPrefix {
108 version_ihl: (IP_VERSION << VERSION_OFFSET) | ihl,
109 dscp_and_ecn,
110 total_len: U16::new(total_len),
111 id: U16::new(id),
112 flags_frag_off: ((u16::from(flags) << FLAGS_OFFSET) | frag_off).to_be_bytes(),
113 ttl,
114 proto,
115 src_ip,
116 dst_ip,
117 hdr_checksum,
118 }
119 }
120
121 fn version(&self) -> u8 {
122 self.version_ihl >> VERSION_OFFSET
123 }
124
125 pub(crate) fn ihl(&self) -> u8 {
127 self.version_ihl & IHL_MASK
128 }
129
130 pub(crate) fn mf_flag(&self) -> bool {
132 self.flags_frag_off[0] & (1 << ((FLAGS_OFFSET - 8) + MF_FLAG_OFFSET)) > 0
137 }
138}
139
140pub trait Ipv4Header {
145 fn get_header_prefix(&self) -> &HeaderPrefix;
147
148 fn dscp_and_ecn(&self) -> DscpAndEcn {
150 self.get_header_prefix().dscp_and_ecn
151 }
152
153 fn id(&self) -> u16 {
155 self.get_header_prefix().id.get()
156 }
157
158 fn df_flag(&self) -> bool {
160 self.get_header_prefix().flags_frag_off[0] & (1 << (5 + DF_FLAG_OFFSET)) > 0
162 }
163
164 fn mf_flag(&self) -> bool {
166 self.get_header_prefix().mf_flag()
167 }
168
169 fn fragment_offset(&self) -> FragmentOffset {
171 FragmentOffset::new_with_lsb(U16::from_bytes(self.get_header_prefix().flags_frag_off).get())
172 }
173
174 fn fragment_type(&self) -> Ipv4FragmentType {
180 match self.fragment_offset().into_raw() {
181 0 => Ipv4FragmentType::InitialFragment,
182 _ => Ipv4FragmentType::NonInitialFragment,
183 }
184 }
185
186 fn ttl(&self) -> u8 {
188 self.get_header_prefix().ttl
189 }
190
191 fn proto(&self) -> Ipv4Proto {
195 Ipv4Proto::from(self.get_header_prefix().proto)
196 }
197
198 fn src_ip(&self) -> Ipv4Addr {
200 self.get_header_prefix().src_ip
201 }
202
203 fn dst_ip(&self) -> Ipv4Addr {
205 self.get_header_prefix().dst_ip
206 }
207
208 fn builder(&self) -> Ipv4PacketBuilder {
210 let mut s = Ipv4PacketBuilder {
211 id: self.id(),
212 dscp_and_ecn: self.dscp_and_ecn(),
213 flags: 0,
214 frag_off: self.fragment_offset().into_raw(),
215 ttl: self.ttl(),
216 proto: self.get_header_prefix().proto.into(),
217 src_ip: self.src_ip(),
218 dst_ip: self.dst_ip(),
219 };
220 s.df_flag(self.df_flag());
221 s.mf_flag(self.mf_flag());
222 s
223 }
224}
225
226impl Ipv4Header for HeaderPrefix {
227 fn get_header_prefix(&self) -> &HeaderPrefix {
228 self
229 }
230}
231
232pub struct Ipv4OnlyMeta {
234 pub id: u16,
236 pub fragment_type: Ipv4FragmentType,
238}
239
240pub struct Ipv4Packet<B> {
250 hdr_prefix: Ref<B, HeaderPrefix>,
251 options: Options<B>,
252 body: B,
253}
254
255impl<B: SplitByteSlice, I: IpExt> GenericOverIp<I> for Ipv4Packet<B> {
256 type Type = <I as IpExt>::Packet<B>;
257}
258
259impl<B: SplitByteSlice> Ipv4Header for Ipv4Packet<B> {
260 fn get_header_prefix(&self) -> &HeaderPrefix {
261 &self.hdr_prefix
262 }
263}
264
265impl<B: SplitByteSlice> ParsablePacket<B, ()> for Ipv4Packet<B> {
266 type Error = IpParseError<Ipv4>;
267
268 fn parse_metadata(&self) -> ParseMetadata {
269 let header_len = Ref::bytes(&self.hdr_prefix).len() + self.options.bytes().len();
270 ParseMetadata::from_packet(header_len, self.body.len(), 0)
271 }
272
273 fn parse<BV: BufferView<B>>(buffer: BV, _args: ()) -> IpParseResult<Ipv4, Self> {
274 Ipv4PacketRaw::<B>::parse(buffer, ()).and_then(Ipv4Packet::try_from_raw)
275 }
276}
277
278impl<B: SplitByteSlice> FromRaw<Ipv4PacketRaw<B>, ()> for Ipv4Packet<B> {
279 type Error = IpParseError<Ipv4>;
280
281 fn try_from_raw_with(raw: Ipv4PacketRaw<B>, _args: ()) -> Result<Self, Self::Error> {
282 let hdr_prefix = raw.hdr_prefix;
285 let hdr_bytes = (hdr_prefix.ihl() * 4) as usize;
286
287 if hdr_bytes < HDR_PREFIX_LEN {
288 return debug_err!(Err(ParseError::Format.into()), "invalid IHL: {}", hdr_prefix.ihl());
289 }
290
291 let options = match raw.options {
292 MaybeParsed::Incomplete(_) => {
293 return debug_err!(Err(ParseError::Format.into()), "Incomplete options");
294 }
295 MaybeParsed::Complete(unchecked) => Options::try_from_raw(unchecked)
296 .map_err(|e| debug_err!(e, "malformed options: {:?}", e))?,
297 };
298
299 if hdr_prefix.version() != 4 {
300 return debug_err!(
301 Err(ParseError::Format.into()),
302 "unexpected IP version: {}",
303 hdr_prefix.version()
304 );
305 }
306
307 let body = match raw.body {
308 MaybeParsed::Incomplete(_) => {
309 if hdr_prefix.mf_flag() {
310 return debug_err!(
311 Err(ParseError::NotSupported.into()),
312 "fragmentation not supported"
313 );
314 } else {
315 return debug_err!(Err(ParseError::Format.into()), "Incomplete body");
316 }
317 }
318 MaybeParsed::Complete(bytes) => bytes,
319 };
320
321 let packet = Ipv4Packet { hdr_prefix, options, body };
322 if packet.compute_header_checksum() != [0, 0] {
323 return debug_err!(Err(ParseError::Checksum.into()), "invalid checksum");
324 }
325 Ok(packet)
326 }
327}
328
329fn compute_header_checksum(hdr_prefix: &[u8], options: &[u8]) -> [u8; 2] {
330 let mut c = Checksum::new();
331 c.add_bytes(hdr_prefix);
332 c.add_bytes(options);
333 c.checksum()
334}
335
336impl<B: SplitByteSlice> Ipv4Packet<B> {
337 pub fn iter_options(&self) -> impl Iterator<Item = Ipv4Option<'_>> {
339 self.options.iter()
340 }
341
342 fn compute_header_checksum(&self) -> [u8; 2] {
344 compute_header_checksum(Ref::bytes(&self.hdr_prefix), self.options.bytes())
345 }
346
347 pub fn body(&self) -> &[u8] {
349 &self.body
350 }
351
352 pub fn header_len(&self) -> usize {
354 Ref::bytes(&self.hdr_prefix).len() + self.options.bytes().len()
355 }
356
357 pub fn copy_header_bytes_for_fragment(&self) -> Vec<u8> {
363 let expected_bytes_len = self.header_len();
364 let mut bytes = Vec::with_capacity(expected_bytes_len);
365
366 bytes.extend_from_slice(Ref::bytes(&self.hdr_prefix));
367 bytes.extend_from_slice(self.options.bytes());
368
369 assert_eq!(bytes.len(), expected_bytes_len);
371
372 bytes[IPV4_FRAGMENT_DATA_BYTE_RANGE].copy_from_slice(&[0; 4][..]);
374
375 bytes
376 }
377
378 pub fn nat64_translate(
404 &self,
405 v6_src_addr: Ipv6Addr,
406 v6_dst_addr: Ipv6Addr,
407 ) -> Nat64TranslationResult<impl Serializer<Buffer = EmptyBuf> + Debug + '_, Nat64Error> {
408 #[derive(Debug)]
411 enum Nat64Serializer<T, U, O> {
412 Tcp(T),
413 Udp(U),
414 Other(O),
415 }
416
417 impl<T, U, O> Serializer for Nat64Serializer<T, U, O>
418 where
419 T: Serializer<Buffer = EmptyBuf>,
420 U: Serializer<Buffer = EmptyBuf>,
421 O: Serializer<Buffer = EmptyBuf>,
422 {
423 type Buffer = EmptyBuf;
424 fn serialize<B, P>(
425 self,
426 outer: PacketConstraints,
427 provider: P,
428 ) -> Result<B, (SerializeError<P::Error>, Self)>
429 where
430 B: GrowBufferMut,
431 P: BufferProvider<Self::Buffer, B>,
432 {
433 match self {
434 Nat64Serializer::Tcp(serializer) => serializer
435 .serialize(outer, provider)
436 .map_err(|(err, ser)| (err, Nat64Serializer::Tcp(ser))),
437 Nat64Serializer::Udp(serializer) => serializer
438 .serialize(outer, provider)
439 .map_err(|(err, ser)| (err, Nat64Serializer::Udp(ser))),
440 Nat64Serializer::Other(serializer) => serializer
441 .serialize(outer, provider)
442 .map_err(|(err, ser)| (err, Nat64Serializer::Other(ser))),
443 }
444 }
445
446 fn serialize_new_buf<B: ReusableBuffer, A: BufferAlloc<B>>(
447 &self,
448 outer: PacketConstraints,
449 alloc: A,
450 ) -> Result<B, SerializeError<A::Error>> {
451 match self {
452 Nat64Serializer::Tcp(serializer) => serializer.serialize_new_buf(outer, alloc),
453 Nat64Serializer::Udp(serializer) => serializer.serialize_new_buf(outer, alloc),
454 Nat64Serializer::Other(serializer) => {
455 serializer.serialize_new_buf(outer, alloc)
456 }
457 }
458 }
459 }
460
461 let v6_builder = |v6_proto| {
462 let mut builder =
463 Ipv6PacketBuilder::new(v6_src_addr, v6_dst_addr, self.ttl(), v6_proto);
464 builder.dscp_and_ecn(self.dscp_and_ecn());
465 builder.flowlabel(0);
466 builder
467 };
468
469 match self.proto() {
470 Ipv4Proto::Igmp => {
471 Nat64TranslationResult::Drop
473 }
474
475 Ipv4Proto::Proto(IpProto::Tcp) => {
476 let v6_pkt_builder = v6_builder(Ipv6Proto::Proto(IpProto::Tcp));
477 let args = TcpParseArgs::new(self.src_ip(), self.dst_ip());
478 match TcpSegment::parse(&mut self.body.as_bytes(), args) {
479 Ok(tcp) => {
480 let tcp_serializer =
484 Nat64Serializer::Tcp(tcp.into_serializer(v6_src_addr, v6_dst_addr));
485 Nat64TranslationResult::Forward(tcp_serializer.encapsulate(v6_pkt_builder))
486 }
487 Err(msg) => {
488 debug!("Parsing of TCP segment failed: {:?}", msg);
489
490 let common_serializer =
496 Nat64Serializer::Other(self.body().into_serializer());
497 Nat64TranslationResult::Forward(
498 common_serializer.encapsulate(v6_pkt_builder),
499 )
500 }
501 }
502 }
503
504 Ipv4Proto::Proto(IpProto::Udp) => {
505 let v6_pkt_builder = v6_builder(Ipv6Proto::Proto(IpProto::Udp));
506 let args = UdpParseArgs::new(self.src_ip(), self.dst_ip());
507 match UdpPacket::parse(&mut self.body.as_bytes(), args) {
508 Ok(udp) => {
509 let udp_serializer =
513 Nat64Serializer::Udp(udp.into_serializer(v6_src_addr, v6_dst_addr));
514 Nat64TranslationResult::Forward(udp_serializer.encapsulate(v6_pkt_builder))
515 }
516 Err(msg) => {
517 debug!("Parsing of UDP packet failed: {:?}", msg);
518
519 let common_serializer =
525 Nat64Serializer::Other(self.body().into_serializer());
526 Nat64TranslationResult::Forward(
527 common_serializer.encapsulate(v6_pkt_builder),
528 )
529 }
530 }
531 }
532
533 Ipv4Proto::Icmp => Nat64TranslationResult::Err(Nat64Error::NotImplemented),
534
535 Ipv4Proto::Other(val) => {
540 let v6_pkt_builder = v6_builder(Ipv6Proto::Other(val));
541 let common_serializer = Nat64Serializer::Other(self.body().into_serializer());
542 Nat64TranslationResult::Forward(common_serializer.encapsulate(v6_pkt_builder))
543 }
544
545 Ipv4Proto::Proto(IpProto::Reserved) => Nat64TranslationResult::Drop,
548 }
549 }
550
551 pub fn to_vec(&self) -> Vec<u8> {
553 let Ipv4Packet { hdr_prefix, options, body } = self;
554 let mut buf = Vec::with_capacity(
555 Ref::bytes(&hdr_prefix).len() + options.bytes().len() + body.as_bytes().len(),
556 );
557 buf.extend(Ref::bytes(&hdr_prefix));
558 buf.extend(options.bytes());
559 buf.extend(body.as_bytes());
560 buf
561 }
562}
563
564impl<B: SplitByteSliceMut> Ipv4Packet<B> {
565 pub fn set_src_ip_and_update_checksum(&mut self, addr: Ipv4Addr) {
569 let old_bytes = self.hdr_prefix.src_ip.bytes();
570 self.hdr_prefix.hdr_checksum =
571 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, addr.bytes());
572 self.hdr_prefix.src_ip = addr;
573 }
574
575 pub fn set_dst_ip_and_update_checksum(&mut self, addr: Ipv4Addr) {
579 let old_bytes = self.hdr_prefix.dst_ip.bytes();
580 self.hdr_prefix.hdr_checksum =
581 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, addr.bytes());
582 self.hdr_prefix.dst_ip = addr;
583 }
584
585 pub fn set_ttl(&mut self, ttl: u8) {
589 let old_bytes = [self.hdr_prefix.ttl, self.hdr_prefix.proto];
593 let new_bytes = [ttl, self.hdr_prefix.proto];
594 self.hdr_prefix.hdr_checksum =
595 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, &new_bytes);
596 self.hdr_prefix.ttl = ttl;
597 }
598
599 pub fn body_mut(&mut self) -> &mut [u8] {
601 &mut self.body
602 }
603
604 pub fn parts_with_body_mut(&mut self) -> (&HeaderPrefix, &Options<B>, &mut [u8]) {
607 (&self.hdr_prefix, &self.options, &mut self.body)
608 }
609}
610
611impl<B> Debug for Ipv4Packet<B>
612where
613 B: SplitByteSlice,
614{
615 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
616 f.debug_struct("Ipv4Packet")
617 .field("src_ip", &self.src_ip())
618 .field("dst_ip", &self.dst_ip())
619 .field("id", &self.id())
620 .field("ttl", &self.ttl())
621 .field("proto", &self.proto())
622 .field("frag_off", &self.fragment_offset())
623 .field("dscp", &self.dscp_and_ecn().dscp())
624 .field("ecn", &self.dscp_and_ecn().ecn())
625 .field("mf_flag", &self.mf_flag())
626 .field("df_flag", &self.df_flag())
627 .field("body", &alloc::format!("<{} bytes>", self.body.len()))
628 .finish()
629 }
630}
631
632pub struct Ipv4PacketRaw<B> {
642 hdr_prefix: Ref<B, HeaderPrefix>,
643 options: MaybeParsed<OptionsRaw<B, Ipv4OptionsImpl>, B>,
644 body: MaybeParsed<B, B>,
645}
646
647impl<B: SplitByteSlice> Ipv4Header for Ipv4PacketRaw<B> {
648 fn get_header_prefix(&self) -> &HeaderPrefix {
649 &self.hdr_prefix
650 }
651}
652
653impl<B: SplitByteSlice> ParsablePacket<B, ()> for Ipv4PacketRaw<B> {
654 type Error = IpParseError<Ipv4>;
655
656 fn parse_metadata(&self) -> ParseMetadata {
657 let header_len = Ref::bytes(&self.hdr_prefix).len() + self.options.len();
658 ParseMetadata::from_packet(header_len, self.body.len(), 0)
659 }
660
661 fn parse<BV: BufferView<B>>(mut buffer: BV, _args: ()) -> IpParseResult<Ipv4, Self> {
662 let hdr_prefix = buffer
663 .take_obj_front::<HeaderPrefix>()
664 .ok_or_else(debug_err_fn!(ParseError::Format, "too few bytes for header"))?;
665 let hdr_bytes = (hdr_prefix.ihl() * 4) as usize;
666
667 let options = MaybeParsed::take_from_buffer_with(
668 &mut buffer,
669 hdr_bytes.saturating_sub(HDR_PREFIX_LEN),
674 OptionsRaw::new,
675 );
676
677 let total_len: usize = hdr_prefix.total_len.get().into();
678 let body_len = total_len.saturating_sub(hdr_bytes);
679 if buffer.len() > body_len {
680 let _: B = buffer.take_back(buffer.len() - body_len).unwrap();
683 }
684
685 let body = MaybeParsed::new_with_min_len(buffer.into_rest(), body_len);
686
687 Ok(Self { hdr_prefix, options, body })
688 }
689}
690
691impl<B> Ipv4PacketRaw<B> {
692 pub fn options(&self) -> &MaybeParsed<OptionsRaw<B, Ipv4OptionsImpl>, B> {
694 &self.options
695 }
696}
697
698impl<B: SplitByteSlice> Ipv4PacketRaw<B> {
699 pub fn body(&self) -> MaybeParsed<&[u8], &[u8]> {
705 self.body.as_ref().map(|b| b.deref()).map_incomplete(|b| b.deref())
706 }
707
708 pub fn into_body(self) -> MaybeParsed<B, B> {
712 self.body
713 }
714}
715
716impl<B: SplitByteSliceMut> Ipv4PacketRaw<B> {
717 pub fn set_src_ip_and_update_checksum(&mut self, addr: Ipv4Addr) {
721 let old_bytes = self.hdr_prefix.src_ip.bytes();
722 self.hdr_prefix.hdr_checksum =
723 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, addr.bytes());
724 self.hdr_prefix.src_ip = addr;
725 }
726
727 pub fn set_dst_ip_and_update_checksum(&mut self, addr: Ipv4Addr) {
731 let old_bytes = self.hdr_prefix.dst_ip.bytes();
732 self.hdr_prefix.hdr_checksum =
733 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, addr.bytes());
734 self.hdr_prefix.dst_ip = addr;
735 }
736}
737
738pub type Options<B> = packet::records::options::Options<B, Ipv4OptionsImpl>;
744
745#[derive(Debug)]
748pub struct Ipv4OptionsTooLongError;
749
750#[derive(Debug, Clone)]
752pub struct Ipv4PacketBuilderWithOptions<'a, I> {
753 prefix_builder: Ipv4PacketBuilder,
754 options: OptionSequenceBuilder<Ipv4Option<'a>, I>,
755}
756
757impl<'a, I> Ipv4PacketBuilderWithOptions<'a, I>
758where
759 I: Iterator + Clone,
760 I::Item: Borrow<Ipv4Option<'a>>,
761{
762 pub fn new<T: IntoIterator<IntoIter = I>>(
768 prefix_builder: Ipv4PacketBuilder,
769 options: T,
770 ) -> Result<Ipv4PacketBuilderWithOptions<'a, I>, Ipv4OptionsTooLongError> {
771 let options = OptionSequenceBuilder::new(options.into_iter());
772 if options.serialized_len() > MAX_OPTIONS_LEN {
773 return Err(Ipv4OptionsTooLongError);
774 }
775 Ok(Ipv4PacketBuilderWithOptions { prefix_builder, options })
776 }
777
778 fn aligned_options_len(&self) -> usize {
779 crate::utils::round_to_next_multiple_of_four(self.options.serialized_len())
781 }
782
783 pub fn prefix_builder(&self) -> &Ipv4PacketBuilder {
785 &self.prefix_builder
786 }
787
788 pub fn prefix_builder_mut(&mut self) -> &mut Ipv4PacketBuilder {
790 &mut self.prefix_builder
791 }
792
793 pub fn options(&self) -> &I {
795 self.options.records()
796 }
797
798 pub fn with_fragment_options(
804 self,
805 first_fragment: bool,
806 ) -> Ipv4PacketBuilderWithOptions<'a, impl Iterator<Item: Borrow<Ipv4Option<'a>>> + Clone> {
807 let Self { prefix_builder, options } = self;
808 Ipv4PacketBuilderWithOptions {
809 prefix_builder,
810 options: OptionSequenceBuilder::new(
813 options
814 .records()
815 .clone()
816 .filter(move |opt| first_fragment || opt.borrow().copied()),
817 ),
818 }
819 }
820}
821
822impl<'a, B> Ipv4PacketBuilderWithOptions<'a, RecordsIter<'a, B, Ipv4OptionsImpl>> {
823 pub fn new_with_records_iter(
826 prefix_builder: Ipv4PacketBuilder,
827 iter: RecordsIter<'a, B, Ipv4OptionsImpl>,
828 ) -> Self {
829 Self { prefix_builder, options: OptionSequenceBuilder::new(iter) }
830 }
831}
832
833impl<'a, I> PacketBuilder for Ipv4PacketBuilderWithOptions<'a, I>
834where
835 I: Iterator + Clone,
836 I::Item: Borrow<Ipv4Option<'a>>,
837{
838 fn constraints(&self) -> PacketConstraints {
839 let header_len = IPV4_MIN_HDR_LEN + self.aligned_options_len();
840 assert_eq!(header_len % 4, 0);
841 PacketConstraints::new(header_len, 0, 0, (1 << 16) - 1 - header_len)
842 }
843
844 fn serialize(&self, target: &mut SerializeTarget<'_>, body: FragmentedBytesMut<'_, '_>) {
845 let opt_len = self.aligned_options_len();
846 let mut header = &mut &mut target.header[..];
852 let opts = header.take_back_zero(opt_len).expect("too few bytes for Ipv4 options");
853 let Ipv4PacketBuilderWithOptions { prefix_builder, options } = self;
854 options.serialize_into(opts);
855 prefix_builder.serialize(target, body);
856 }
857}
858
859impl<'a, I> IpPacketBuilder<Ipv4> for Ipv4PacketBuilderWithOptions<'a, I>
860where
861 I: Default + Debug + Clone + Iterator<Item: Borrow<Ipv4Option<'a>>>,
862{
863 fn new(src_ip: Ipv4Addr, dst_ip: Ipv4Addr, ttl: u8, proto: Ipv4Proto) -> Self {
864 Ipv4PacketBuilderWithOptions::new(
865 Ipv4PacketBuilder::new(src_ip, dst_ip, ttl, proto),
866 I::default(),
867 )
868 .expect("packet builder with no options should be valid")
869 }
870
871 fn src_ip(&self) -> Ipv4Addr {
872 self.prefix_builder.src_ip
873 }
874
875 fn set_src_ip(&mut self, addr: Ipv4Addr) {
876 self.prefix_builder.set_src_ip(addr);
877 }
878
879 fn dst_ip(&self) -> Ipv4Addr {
880 self.prefix_builder.dst_ip
881 }
882
883 fn set_dst_ip(&mut self, addr: Ipv4Addr) {
884 self.prefix_builder.set_dst_ip(addr);
885 }
886
887 fn proto(&self) -> Ipv4Proto {
888 self.prefix_builder.proto
889 }
890
891 fn set_dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
892 self.prefix_builder.set_dscp_and_ecn(dscp_and_ecn)
893 }
894}
895
896#[derive(Debug, Clone, Eq, PartialEq)]
898pub struct Ipv4PacketBuilder {
899 id: u16,
900 dscp_and_ecn: DscpAndEcn,
901 flags: u8,
902 frag_off: u16,
903 ttl: u8,
904 proto: Ipv4Proto,
905 src_ip: Ipv4Addr,
906 dst_ip: Ipv4Addr,
907}
908
909impl Ipv4PacketBuilder {
910 pub fn new<S: Into<Ipv4Addr>, D: Into<Ipv4Addr>>(
912 src_ip: S,
913 dst_ip: D,
914 ttl: u8,
915 proto: Ipv4Proto,
916 ) -> Ipv4PacketBuilder {
917 Ipv4PacketBuilder {
918 id: 0,
919 dscp_and_ecn: DscpAndEcn::default(),
920 flags: 0,
921 frag_off: 0,
922 ttl,
923 proto: proto,
924 src_ip: src_ip.into(),
925 dst_ip: dst_ip.into(),
926 }
927 }
928
929 pub fn dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
931 self.dscp_and_ecn = dscp_and_ecn;
932 }
933
934 pub fn id(&mut self, id: u16) {
936 self.id = id
937 }
938
939 pub fn df_flag(&mut self, df: bool) {
941 if df {
942 self.flags |= 1 << DF_FLAG_OFFSET;
943 } else {
944 self.flags &= !(1 << DF_FLAG_OFFSET);
945 }
946 }
947
948 pub fn mf_flag(&mut self, mf: bool) {
950 if mf {
951 self.flags |= 1 << MF_FLAG_OFFSET;
952 } else {
953 self.flags &= !(1 << MF_FLAG_OFFSET);
954 }
955 }
956
957 pub fn fragment_offset(&mut self, fragment_offset: FragmentOffset) {
959 self.frag_off = fragment_offset.into_raw();
960 }
961
962 pub fn read_df_flag(&self) -> bool {
964 (self.flags & (1 << DF_FLAG_OFFSET)) != 0
965 }
966}
967
968impl PacketBuilder for Ipv4PacketBuilder {
969 fn constraints(&self) -> PacketConstraints {
970 PacketConstraints::new(IPV4_MIN_HDR_LEN, 0, 0, (1 << 16) - 1 - IPV4_MIN_HDR_LEN)
971 }
972
973 fn serialize(&self, target: &mut SerializeTarget<'_>, body: FragmentedBytesMut<'_, '_>) {
974 let total_len = target.header.len() + body.len();
975 assert_eq!(target.header.len() % 4, 0);
976 let ihl: u8 = u8::try_from(target.header.len() / 4).expect("Header too large");
977
978 let id = if ((self.flags & (1 << DF_FLAG_OFFSET)) == 0)
988 || ((self.flags & (1 << MF_FLAG_OFFSET)) == 1)
989 || (self.frag_off > 0)
990 {
991 self.id
992 } else {
993 0
994 };
995
996 let mut hdr_prefix = HeaderPrefix::new(
997 ihl,
998 self.dscp_and_ecn,
999 {
1000 debug_assert!(total_len <= core::u16::MAX as usize);
1006 total_len as u16
1007 },
1008 id,
1009 self.flags,
1010 self.frag_off,
1011 self.ttl,
1012 self.proto.into(),
1013 [0, 0], self.src_ip,
1015 self.dst_ip,
1016 );
1017
1018 let options = &target.header[HDR_PREFIX_LEN..];
1019 let checksum = compute_header_checksum(hdr_prefix.as_bytes(), options);
1020 hdr_prefix.hdr_checksum = checksum;
1021 let mut header = &mut target.header;
1022 header.write_obj_front(&hdr_prefix).expect("too few bytes for IPv4 header prefix");
1023 }
1024}
1025
1026impl IpPacketBuilder<Ipv4> for Ipv4PacketBuilder {
1027 fn new(src_ip: Ipv4Addr, dst_ip: Ipv4Addr, ttl: u8, proto: Ipv4Proto) -> Self {
1028 Ipv4PacketBuilder::new(src_ip, dst_ip, ttl, proto)
1029 }
1030
1031 fn src_ip(&self) -> Ipv4Addr {
1032 self.src_ip
1033 }
1034
1035 fn set_src_ip(&mut self, addr: Ipv4Addr) {
1036 self.src_ip = addr;
1037 }
1038
1039 fn dst_ip(&self) -> Ipv4Addr {
1040 self.dst_ip
1041 }
1042
1043 fn set_dst_ip(&mut self, addr: Ipv4Addr) {
1044 self.dst_ip = addr;
1045 }
1046
1047 fn proto(&self) -> Ipv4Proto {
1048 self.proto
1049 }
1050
1051 fn set_dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
1052 self.dscp_and_ecn = dscp_and_ecn;
1053 }
1054}
1055
1056const DF_FLAG_OFFSET: u8 = 1;
1058const MF_FLAG_OFFSET: u8 = 0;
1059
1060pub(crate) fn reassemble_fragmented_packet<
1062 B: SplitByteSliceMut,
1063 BV: BufferViewMut<B>,
1064 I: Iterator<Item = Vec<u8>>,
1065>(
1066 mut buffer: BV,
1067 header: Vec<u8>,
1068 body_fragments: I,
1069) -> IpParseResult<Ipv4, ()> {
1070 let bytes = buffer.as_mut();
1071
1072 bytes[0..header.len()].copy_from_slice(&header[..]);
1074 let mut byte_count = header.len();
1075
1076 for p in body_fragments {
1078 bytes[byte_count..byte_count + p.len()].copy_from_slice(&p[..]);
1079 byte_count += p.len();
1080 }
1081
1082 if byte_count > usize::from(core::u16::MAX) {
1087 return debug_err!(
1088 Err(ParseError::Format.into()),
1089 "fragmented packet length of {} bytes is too large",
1090 byte_count
1091 );
1092 }
1093
1094 let mut header = Ref::<_, HeaderPrefix>::from_prefix(bytes).unwrap().0;
1097
1098 header.total_len.set(u16::try_from(byte_count).unwrap());
1100
1101 header.flags_frag_off = [0; 2];
1104
1105 header.hdr_checksum = [0; 2];
1107 header.hdr_checksum = compute_header_checksum(header.as_bytes(), &[]);
1108
1109 Ok(())
1110}
1111
1112pub mod options {
1114 use byteorder::{ByteOrder, NetworkEndian};
1115 use packet::records::options::{
1116 OptionBuilder, OptionLayout, OptionParseErr, OptionParseLayout, OptionsImpl,
1117 };
1118 use packet::BufferViewMut;
1119 use zerocopy::byteorder::network_endian::U16;
1120
1121 const OPTION_KIND_EOL: u8 = 0;
1122 const OPTION_KIND_NOP: u8 = 1;
1123 const OPTION_KIND_RTRALRT: u8 = 148;
1124
1125 const OPTION_RTRALRT_LEN: usize = 2;
1126
1127 #[derive(PartialEq, Eq, Debug, Clone)]
1134 #[allow(missing_docs)]
1135 pub enum Ipv4Option<'a> {
1136 RouterAlert { data: u16 },
1142
1143 Unrecognized { kind: u8, data: &'a [u8] },
1155 }
1156
1157 impl<'a> Ipv4Option<'a> {
1158 pub fn copied(&self) -> bool {
1160 match self {
1161 Ipv4Option::RouterAlert { .. } => true,
1165 Ipv4Option::Unrecognized { kind, .. } => *kind & (1 << 7) != 0,
1166 }
1167 }
1168 }
1169
1170 #[derive(Debug, Clone)]
1172 pub struct Ipv4OptionsImpl;
1173
1174 impl OptionLayout for Ipv4OptionsImpl {
1175 type KindLenField = u8;
1176 }
1177
1178 impl OptionParseLayout for Ipv4OptionsImpl {
1179 type Error = OptionParseErr;
1180 const END_OF_OPTIONS: Option<u8> = Some(0);
1181 const NOP: Option<u8> = Some(1);
1182 }
1183
1184 impl OptionsImpl for Ipv4OptionsImpl {
1185 type Option<'a> = Ipv4Option<'a>;
1186
1187 fn parse<'a>(kind: u8, data: &'a [u8]) -> Result<Option<Ipv4Option<'a>>, OptionParseErr> {
1188 match kind {
1189 self::OPTION_KIND_EOL | self::OPTION_KIND_NOP => {
1190 unreachable!("records::options::Options promises to handle EOL and NOP")
1191 }
1192 self::OPTION_KIND_RTRALRT => {
1193 if data.len() == OPTION_RTRALRT_LEN {
1194 Ok(Some(Ipv4Option::RouterAlert { data: NetworkEndian::read_u16(data) }))
1195 } else {
1196 Err(OptionParseErr)
1197 }
1198 }
1199 kind => {
1200 if data.len() > 38 {
1201 Err(OptionParseErr)
1202 } else {
1203 Ok(Some(Ipv4Option::Unrecognized { kind, data }))
1204 }
1205 }
1206 }
1207 }
1208 }
1209
1210 impl<'a> OptionBuilder for Ipv4Option<'a> {
1211 type Layout = Ipv4OptionsImpl;
1212
1213 fn serialized_len(&self) -> usize {
1214 match self {
1215 Ipv4Option::RouterAlert { .. } => OPTION_RTRALRT_LEN,
1216 Ipv4Option::Unrecognized { data, .. } => data.len(),
1217 }
1218 }
1219
1220 fn option_kind(&self) -> u8 {
1221 match self {
1222 Ipv4Option::RouterAlert { .. } => OPTION_KIND_RTRALRT,
1223 Ipv4Option::Unrecognized { kind, .. } => *kind,
1224 }
1225 }
1226
1227 fn serialize_into(&self, mut buffer: &mut [u8]) {
1228 match self {
1229 Ipv4Option::Unrecognized { data, .. } => buffer.copy_from_slice(data),
1230 Ipv4Option::RouterAlert { data } => {
1231 (&mut buffer).write_obj_front(&U16::new(*data)).unwrap()
1232 }
1233 };
1234 }
1235 }
1236
1237 #[cfg(test)]
1238 mod test {
1239 use packet::records::options::Options;
1240 use packet::records::RecordBuilder;
1241
1242 use super::*;
1243
1244 #[test]
1245 fn test_serialize_router_alert() {
1246 let mut buffer = [0u8; 4];
1247 let option = Ipv4Option::RouterAlert { data: 0 };
1248 <Ipv4Option<'_> as RecordBuilder>::serialize_into(&option, &mut buffer);
1249 assert_eq!(buffer[0], 148);
1250 assert_eq!(buffer[1], 4);
1251 assert_eq!(buffer[2], 0);
1252 assert_eq!(buffer[3], 0);
1253 }
1254
1255 #[test]
1256 fn test_parse_router_alert() {
1257 let mut buffer: Vec<u8> = vec![148, 4, 0, 0];
1258 let options = Options::<_, Ipv4OptionsImpl>::parse(buffer.as_mut()).unwrap();
1259 let rtralt = options.iter().next().unwrap();
1260 assert_eq!(rtralt, Ipv4Option::RouterAlert { data: 0 });
1261 }
1262 }
1263}
1264
1265mod inner {
1266 pub const IPV4_MIN_HDR_LEN: usize = super::HDR_PREFIX_LEN;
1268}
1269
1270pub mod testutil {
1272 pub use super::inner::IPV4_MIN_HDR_LEN;
1273
1274 pub const IPV4_TTL_OFFSET: usize = 8;
1276
1277 pub const IPV4_CHECKSUM_OFFSET: usize = 10;
1279}
1280
1281#[cfg(test)]
1282mod tests {
1283 use net_types::ethernet::Mac;
1284 use packet::{Buf, FragmentedBuffer, ParseBuffer};
1285
1286 use super::*;
1287 use crate::ethernet::{
1288 EtherType, EthernetFrame, EthernetFrameBuilder, EthernetFrameLengthCheck,
1289 ETHERNET_MIN_BODY_LEN_NO_TAG,
1290 };
1291 use crate::testutil::*;
1292
1293 const DEFAULT_SRC_MAC: Mac = Mac::new([1, 2, 3, 4, 5, 6]);
1294 const DEFAULT_DST_MAC: Mac = Mac::new([7, 8, 9, 0, 1, 2]);
1295 const DEFAULT_SRC_IP: Ipv4Addr = Ipv4Addr::new([1, 2, 3, 4]);
1296 const DEFAULT_DST_IP: Ipv4Addr = Ipv4Addr::new([5, 6, 7, 8]);
1297 const DEFAULT_V6_SRC_IP: Ipv6Addr = Ipv6Addr::new([0x2001, 0x0db8, 0, 0, 0, 0, 0, 1]);
1299 const DEFAULT_V6_DST_IP: Ipv6Addr = Ipv6Addr::new([0x2001, 0x0db8, 0, 0, 0, 0, 0, 2]);
1301
1302 #[test]
1303 fn test_parse_serialize_full_tcp() {
1304 use crate::testdata::tls_client_hello_v4::*;
1305
1306 let mut buf = ETHERNET_FRAME.bytes;
1307 let frame = buf.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1308 verify_ethernet_frame(&frame, ETHERNET_FRAME);
1309
1310 let mut body = frame.body();
1311 let packet = body.parse::<Ipv4Packet<_>>().unwrap();
1312 verify_ipv4_packet(&packet, IPV4_PACKET);
1313
1314 let buffer = packet
1316 .body()
1317 .into_serializer()
1318 .encapsulate(packet.builder())
1319 .encapsulate(frame.builder())
1320 .serialize_vec_outer()
1321 .unwrap();
1322 assert_eq!(buffer.as_ref(), ETHERNET_FRAME.bytes);
1323
1324 assert_eq!(&packet.to_vec()[..], IPV4_PACKET.bytes);
1326 }
1327
1328 #[test]
1329 fn test_parse_serialize_full_udp() {
1330 use crate::testdata::dns_request_v4::*;
1331
1332 let mut buf = ETHERNET_FRAME.bytes;
1333 let frame = buf.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1334 verify_ethernet_frame(&frame, ETHERNET_FRAME);
1335
1336 let mut body = frame.body();
1337 let packet = body.parse::<Ipv4Packet<_>>().unwrap();
1338 verify_ipv4_packet(&packet, IPV4_PACKET);
1339
1340 let buffer = packet
1342 .body()
1343 .into_serializer()
1344 .encapsulate(packet.builder())
1345 .encapsulate(frame.builder())
1346 .serialize_vec_outer()
1347 .unwrap();
1348 assert_eq!(buffer.as_ref(), ETHERNET_FRAME.bytes);
1349
1350 assert_eq!(&packet.to_vec()[..], IPV4_PACKET.bytes);
1352 }
1353
1354 #[test]
1355 fn test_parse_serialize_with_options() {
1356 use crate::testdata::igmpv2_membership::report::*;
1359
1360 let mut buf = IP_PACKET_BYTES;
1361 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1362 assert_eq!(packet.iter_options().count(), 1);
1363
1364 assert_eq!(&packet.to_vec()[..], IP_PACKET_BYTES);
1369 }
1370
1371 fn hdr_prefix_to_bytes(hdr_prefix: HeaderPrefix) -> [u8; 20] {
1372 zerocopy::transmute!(hdr_prefix)
1373 }
1374
1375 fn new_hdr_prefix() -> HeaderPrefix {
1378 HeaderPrefix::new(
1379 5,
1380 DscpAndEcn::default(),
1381 20,
1382 0x0102,
1383 0,
1384 0,
1385 0x03,
1386 IpProto::Tcp.into(),
1387 [0xa6, 0xcf],
1388 DEFAULT_SRC_IP,
1389 DEFAULT_DST_IP,
1390 )
1391 }
1392
1393 #[test]
1394 fn test_parse() {
1395 let mut bytes = &hdr_prefix_to_bytes(new_hdr_prefix())[..];
1396 let packet = bytes.parse::<Ipv4Packet<_>>().unwrap();
1397 assert_eq!(packet.id(), 0x0102);
1398 assert_eq!(packet.ttl(), 0x03);
1399 assert_eq!(packet.proto(), IpProto::Tcp.into());
1400 assert_eq!(packet.src_ip(), DEFAULT_SRC_IP);
1401 assert_eq!(packet.dst_ip(), DEFAULT_DST_IP);
1402 assert_eq!(packet.body(), []);
1403 }
1404
1405 #[test]
1406 fn test_parse_padding() {
1407 let mut buffer = Buf::new(Vec::new(), ..)
1409 .encapsulate(Ipv4PacketBuilder::new(
1410 DEFAULT_DST_IP,
1411 DEFAULT_DST_IP,
1412 0,
1413 IpProto::Tcp.into(),
1414 ))
1415 .encapsulate(EthernetFrameBuilder::new(
1416 DEFAULT_SRC_MAC,
1417 DEFAULT_DST_MAC,
1418 EtherType::Ipv4,
1419 ETHERNET_MIN_BODY_LEN_NO_TAG,
1420 ))
1421 .serialize_vec_outer()
1422 .unwrap();
1423 let _: EthernetFrame<_> =
1424 buffer.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1425 assert_eq!(buffer.len(), 46);
1428 let packet = buffer.parse::<Ipv4Packet<_>>().unwrap();
1429 assert_eq!(packet.body().len(), 0);
1432 assert_eq!(buffer.len(), 0);
1436 }
1437
1438 #[test]
1439 fn test_parse_error() {
1440 let mut hdr_prefix = new_hdr_prefix();
1442 hdr_prefix.version_ihl = (5 << 4) | 5;
1443 assert_eq!(
1444 (&hdr_prefix_to_bytes(hdr_prefix)[..]).parse::<Ipv4Packet<_>>().unwrap_err(),
1445 ParseError::Format.into()
1446 );
1447
1448 let mut hdr_prefix = new_hdr_prefix();
1451 hdr_prefix.version_ihl = (4 << 4) | 4;
1452 assert_eq!(
1453 (&hdr_prefix_to_bytes(hdr_prefix)[..]).parse::<Ipv4Packet<_>>().unwrap_err(),
1454 ParseError::Format.into()
1455 );
1456
1457 let mut hdr_prefix = new_hdr_prefix();
1460 hdr_prefix.version_ihl = (4 << 4) | 6;
1461 assert_eq!(
1462 (&hdr_prefix_to_bytes(hdr_prefix)[..]).parse::<Ipv4Packet<_>>().unwrap_err(),
1463 ParseError::Format.into()
1464 );
1465 }
1466
1467 fn new_builder() -> Ipv4PacketBuilder {
1469 Ipv4PacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, 64, IpProto::Tcp.into())
1470 }
1471
1472 #[test]
1473 fn test_fragment_type() {
1474 fn test_fragment_type_helper(fragment_offset: u16, expect_fragment_type: Ipv4FragmentType) {
1475 let mut builder = new_builder();
1476 builder.fragment_offset(FragmentOffset::new(fragment_offset).unwrap());
1477
1478 let mut buf = [0; IPV4_MIN_HDR_LEN]
1479 .into_serializer()
1480 .encapsulate(builder)
1481 .serialize_vec_outer()
1482 .unwrap();
1483
1484 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1485 assert_eq!(packet.fragment_type(), expect_fragment_type);
1486 }
1487
1488 test_fragment_type_helper(0x0000, Ipv4FragmentType::InitialFragment);
1489 test_fragment_type_helper(0x0008, Ipv4FragmentType::NonInitialFragment);
1490 }
1491
1492 #[test]
1493 fn test_serialize() {
1494 let mut builder = new_builder();
1495 builder.dscp_and_ecn(DscpAndEcn::new(0x12, 3));
1496 builder.id(0x0405);
1497 builder.df_flag(true);
1498 builder.mf_flag(true);
1499 builder.fragment_offset(FragmentOffset::new(0x0607).unwrap());
1500
1501 let mut buf = (&[0, 1, 2, 3, 3, 4, 5, 7, 8, 9])
1502 .into_serializer()
1503 .encapsulate(builder)
1504 .serialize_vec_outer()
1505 .unwrap();
1506 assert_eq!(
1507 buf.as_ref(),
1508 [
1509 69, 75, 0, 30, 4, 5, 102, 7, 64, 6, 0, 112, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 3,
1510 4, 5, 7, 8, 9
1511 ]
1512 );
1513 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1514 assert_eq!(packet.dscp_and_ecn().dscp(), 0x12);
1515 assert_eq!(packet.dscp_and_ecn().ecn(), 3);
1516 assert_eq!(packet.id(), 0x0405);
1517 assert!(packet.df_flag());
1518 assert!(packet.mf_flag());
1519 assert_eq!(packet.fragment_offset().into_raw(), 0x0607);
1520 assert_eq!(packet.fragment_type(), Ipv4FragmentType::NonInitialFragment);
1521 }
1522
1523 #[test]
1524 fn test_serialize_id_unset() {
1525 let mut builder = new_builder();
1526 builder.id(0x0405);
1527 builder.df_flag(true);
1528
1529 let mut buf = (&[0, 1, 2, 3, 3, 4, 5, 7, 8, 9])
1530 .into_serializer()
1531 .encapsulate(builder)
1532 .serialize_vec_outer()
1533 .unwrap();
1534 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1535 assert_eq!(packet.id(), 0);
1536 assert!(packet.df_flag());
1537 assert_eq!(packet.mf_flag(), false);
1538 assert_eq!(packet.fragment_offset().into_raw(), 0);
1539 assert_eq!(packet.fragment_type(), Ipv4FragmentType::InitialFragment);
1540 }
1541
1542 #[test]
1543 fn test_serialize_zeroes() {
1544 let mut buf_0 = [0; IPV4_MIN_HDR_LEN];
1547 let _: Buf<&mut [u8]> = Buf::new(&mut buf_0[..], IPV4_MIN_HDR_LEN..)
1548 .encapsulate(new_builder())
1549 .serialize_vec_outer()
1550 .unwrap()
1551 .unwrap_a();
1552 let mut buf_1 = [0xFF; IPV4_MIN_HDR_LEN];
1553 let _: Buf<&mut [u8]> = Buf::new(&mut buf_1[..], IPV4_MIN_HDR_LEN..)
1554 .encapsulate(new_builder())
1555 .serialize_vec_outer()
1556 .unwrap()
1557 .unwrap_a();
1558 assert_eq!(buf_0, buf_1);
1559 }
1560
1561 #[test]
1562 #[should_panic(expected = "(SizeLimitExceeded, Nested { inner: Buf { buf:")]
1563 fn test_serialize_panic_packet_length() {
1564 let _: Buf<&mut [u8]> = Buf::new(&mut [0; (1 << 16) - IPV4_MIN_HDR_LEN][..], ..)
1566 .encapsulate(new_builder())
1567 .serialize_vec_outer()
1568 .unwrap()
1569 .unwrap_a();
1570 }
1571
1572 #[test]
1573 fn test_copy_header_bytes_for_fragment() {
1574 let hdr_prefix = new_hdr_prefix();
1575 let mut bytes = hdr_prefix_to_bytes(hdr_prefix);
1576 let mut buf = &bytes[..];
1577 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1578 let copied_bytes = packet.copy_header_bytes_for_fragment();
1579 bytes[IPV4_FRAGMENT_DATA_BYTE_RANGE].copy_from_slice(&[0; 4][..]);
1580 assert_eq!(&copied_bytes[..], &bytes[..]);
1581 }
1582
1583 #[test]
1584 fn test_partial_parsing() {
1585 use core::ops::Deref as _;
1586
1587 let mut hdr_prefix = new_hdr_prefix();
1590 hdr_prefix.total_len = U16::new(256);
1591 let mut bytes = hdr_prefix_to_bytes(hdr_prefix)[..].to_owned();
1592 const PAYLOAD: &[u8] = &[1, 2, 3, 4, 5];
1593 bytes.extend(PAYLOAD);
1594 let mut buf = &bytes[..];
1595 let packet = buf.parse::<Ipv4PacketRaw<_>>().unwrap();
1596 let Ipv4PacketRaw { hdr_prefix, options, body } = &packet;
1597 assert_eq!(Ref::bytes(&hdr_prefix), &bytes[0..20]);
1598 assert_eq!(options.as_ref().complete().unwrap().deref(), []);
1599 assert_eq!(body, &MaybeParsed::Incomplete(PAYLOAD));
1601 assert!(Ipv4Packet::try_from_raw(packet).is_err());
1603
1604 let mut hdr_prefix = new_hdr_prefix();
1606 hdr_prefix.version_ihl = (4 << 4) | 10;
1607 let bytes = hdr_prefix_to_bytes(hdr_prefix);
1608 let mut buf = &bytes[..];
1609 let packet = buf.parse::<Ipv4PacketRaw<_>>().unwrap();
1610 let Ipv4PacketRaw { hdr_prefix, options, body } = &packet;
1611 assert_eq!(Ref::bytes(&hdr_prefix), bytes);
1612 assert_eq!(options.as_ref().incomplete().unwrap(), &[]);
1613 assert_eq!(body.complete().unwrap(), []);
1614 assert!(Ipv4Packet::try_from_raw(packet).is_err());
1616
1617 let hdr_prefix = new_hdr_prefix();
1619 let bytes = &hdr_prefix_to_bytes(hdr_prefix);
1620 let mut buf = &bytes[0..10];
1621 assert!(buf.parse::<Ipv4PacketRaw<_>>().is_err());
1622 }
1623
1624 fn create_ipv4_and_ipv6_builders(
1625 proto_v4: Ipv4Proto,
1626 proto_v6: Ipv6Proto,
1627 ) -> (Ipv4PacketBuilder, Ipv6PacketBuilder) {
1628 const IP_DSCP_AND_ECN: DscpAndEcn = DscpAndEcn::new(0x12, 3);
1629 const IP_TTL: u8 = 64;
1630
1631 let mut ipv4_builder =
1632 Ipv4PacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, IP_TTL, proto_v4);
1633 ipv4_builder.dscp_and_ecn(IP_DSCP_AND_ECN);
1634 ipv4_builder.id(0x0405);
1635 ipv4_builder.df_flag(true);
1636 ipv4_builder.mf_flag(false);
1637 ipv4_builder.fragment_offset(FragmentOffset::ZERO);
1638
1639 let mut ipv6_builder =
1640 Ipv6PacketBuilder::new(DEFAULT_V6_SRC_IP, DEFAULT_V6_DST_IP, IP_TTL, proto_v6);
1641 ipv6_builder.dscp_and_ecn(IP_DSCP_AND_ECN);
1642 ipv6_builder.flowlabel(0);
1643
1644 (ipv4_builder, ipv6_builder)
1645 }
1646
1647 fn create_tcp_ipv4_and_ipv6_pkt(
1648 ) -> (packet::Either<EmptyBuf, Buf<Vec<u8>>>, packet::Either<EmptyBuf, Buf<Vec<u8>>>) {
1649 use crate::tcp::TcpSegmentBuilder;
1650 use core::num::NonZeroU16;
1651
1652 let tcp_src_port: NonZeroU16 = NonZeroU16::new(20).unwrap();
1653 let tcp_dst_port: NonZeroU16 = NonZeroU16::new(30).unwrap();
1654 const TCP_SEQ_NUM: u32 = 4321;
1655 const TCP_ACK_NUM: Option<u32> = Some(1234);
1656 const TCP_WINDOW_SIZE: u16 = 12345;
1657 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
1658
1659 let (ipv4_builder, ipv6_builder) =
1660 create_ipv4_and_ipv6_builders(IpProto::Tcp.into(), IpProto::Tcp.into());
1661
1662 let tcp_builder = TcpSegmentBuilder::new(
1663 DEFAULT_SRC_IP,
1664 DEFAULT_DST_IP,
1665 tcp_src_port,
1666 tcp_dst_port,
1667 TCP_SEQ_NUM,
1668 TCP_ACK_NUM,
1669 TCP_WINDOW_SIZE,
1670 );
1671
1672 let v4_pkt_buf = (&PAYLOAD)
1673 .into_serializer()
1674 .encapsulate(tcp_builder)
1675 .encapsulate(ipv4_builder)
1676 .serialize_vec_outer()
1677 .unwrap();
1678
1679 let v6_tcp_builder = TcpSegmentBuilder::new(
1680 DEFAULT_V6_SRC_IP,
1681 DEFAULT_V6_DST_IP,
1682 tcp_src_port,
1683 tcp_dst_port,
1684 TCP_SEQ_NUM,
1685 TCP_ACK_NUM,
1686 TCP_WINDOW_SIZE,
1687 );
1688
1689 let v6_pkt_buf = (&PAYLOAD)
1690 .into_serializer()
1691 .encapsulate(v6_tcp_builder)
1692 .encapsulate(ipv6_builder)
1693 .serialize_vec_outer()
1694 .unwrap();
1695
1696 (v4_pkt_buf, v6_pkt_buf)
1697 }
1698
1699 #[test]
1700 fn test_nat64_translate_tcp() {
1701 let (mut v4_pkt_buf, expected_v6_pkt_buf) = create_tcp_ipv4_and_ipv6_pkt();
1702
1703 let parsed_v4_packet = v4_pkt_buf.parse::<Ipv4Packet<_>>().unwrap();
1704 let nat64_translation_result =
1705 parsed_v4_packet.nat64_translate(DEFAULT_V6_SRC_IP, DEFAULT_V6_DST_IP);
1706
1707 let serializable_pkt = match nat64_translation_result {
1708 Nat64TranslationResult::Forward(s) => s,
1709 _ => panic!("Nat64TranslationResult not of Forward type!"),
1710 };
1711
1712 let translated_v6_pkt_buf = serializable_pkt.serialize_vec_outer().unwrap();
1713
1714 assert_eq!(
1715 expected_v6_pkt_buf.to_flattened_vec(),
1716 translated_v6_pkt_buf.to_flattened_vec()
1717 );
1718 }
1719
1720 fn create_udp_ipv4_and_ipv6_pkt(
1721 ) -> (packet::Either<EmptyBuf, Buf<Vec<u8>>>, packet::Either<EmptyBuf, Buf<Vec<u8>>>) {
1722 use crate::udp::UdpPacketBuilder;
1723 use core::num::NonZeroU16;
1724
1725 let udp_src_port: NonZeroU16 = NonZeroU16::new(35000).unwrap();
1726 let udp_dst_port: NonZeroU16 = NonZeroU16::new(53).unwrap();
1727 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
1728
1729 let (ipv4_builder, ipv6_builder) =
1730 create_ipv4_and_ipv6_builders(IpProto::Udp.into(), IpProto::Udp.into());
1731
1732 let udp_builder =
1733 UdpPacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, Some(udp_src_port), udp_dst_port);
1734
1735 let v4_pkt_buf = (&PAYLOAD)
1736 .into_serializer()
1737 .encapsulate(udp_builder)
1738 .encapsulate(ipv4_builder)
1739 .serialize_vec_outer()
1740 .unwrap();
1741
1742 let v6_udp_builder = UdpPacketBuilder::new(
1743 DEFAULT_V6_SRC_IP,
1744 DEFAULT_V6_DST_IP,
1745 Some(udp_src_port),
1746 udp_dst_port,
1747 );
1748
1749 let v6_pkt_buf = (&PAYLOAD)
1750 .into_serializer()
1751 .encapsulate(v6_udp_builder)
1752 .encapsulate(ipv6_builder)
1753 .serialize_vec_outer()
1754 .unwrap();
1755
1756 (v4_pkt_buf, v6_pkt_buf)
1757 }
1758
1759 #[test]
1760 fn test_nat64_translate_udp() {
1761 let (mut v4_pkt_buf, expected_v6_pkt_buf) = create_udp_ipv4_and_ipv6_pkt();
1762
1763 let parsed_v4_packet = v4_pkt_buf.parse::<Ipv4Packet<_>>().unwrap();
1764 let nat64_translation_result =
1765 parsed_v4_packet.nat64_translate(DEFAULT_V6_SRC_IP, DEFAULT_V6_DST_IP);
1766
1767 let serializable_pkt = match nat64_translation_result {
1768 Nat64TranslationResult::Forward(s) => s,
1769 _ => panic!(
1770 "Nat64TranslationResult not of Forward type: {:?} ",
1771 nat64_translation_result
1772 ),
1773 };
1774
1775 let translated_v6_pkt_buf = serializable_pkt.serialize_vec_outer().unwrap();
1776
1777 assert_eq!(
1778 expected_v6_pkt_buf.to_flattened_vec(),
1779 translated_v6_pkt_buf.to_flattened_vec()
1780 );
1781 }
1782
1783 #[test]
1784 fn test_nat64_translate_non_tcp_udp_icmp() {
1785 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
1786
1787 let (ipv4_builder, ipv6_builder) =
1788 create_ipv4_and_ipv6_builders(Ipv4Proto::Other(50), Ipv6Proto::Other(50));
1789
1790 let mut v4_pkt_buf =
1791 (&PAYLOAD).into_serializer().encapsulate(ipv4_builder).serialize_vec_outer().unwrap();
1792
1793 let expected_v6_pkt_buf =
1794 (&PAYLOAD).into_serializer().encapsulate(ipv6_builder).serialize_vec_outer().unwrap();
1795
1796 let translated_v6_pkt_buf = {
1797 let parsed_v4_packet = v4_pkt_buf.parse::<Ipv4Packet<_>>().unwrap();
1798
1799 let nat64_translation_result =
1800 parsed_v4_packet.nat64_translate(DEFAULT_V6_SRC_IP, DEFAULT_V6_DST_IP);
1801
1802 let serializable_pkt = match nat64_translation_result {
1803 Nat64TranslationResult::Forward(s) => s,
1804 _ => panic!(
1805 "Nat64TranslationResult not of Forward type: {:?} ",
1806 nat64_translation_result
1807 ),
1808 };
1809
1810 let translated_buf = serializable_pkt.serialize_vec_outer().unwrap();
1811
1812 translated_buf
1813 };
1814
1815 assert_eq!(
1816 expected_v6_pkt_buf.to_flattened_vec(),
1817 translated_v6_pkt_buf.to_flattened_vec()
1818 );
1819 }
1820}