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, Ipv4SourceAddr, 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 src_ipv4(&self) -> Option<Ipv4SourceAddr> {
362 Ipv4SourceAddr::new(self.src_ip())
363 }
364
365 pub fn copy_header_bytes_for_fragment(&self) -> Vec<u8> {
371 let expected_bytes_len = self.header_len();
372 let mut bytes = Vec::with_capacity(expected_bytes_len);
373
374 bytes.extend_from_slice(Ref::bytes(&self.hdr_prefix));
375 bytes.extend_from_slice(self.options.bytes());
376
377 assert_eq!(bytes.len(), expected_bytes_len);
379
380 bytes[IPV4_FRAGMENT_DATA_BYTE_RANGE].copy_from_slice(&[0; 4][..]);
382
383 bytes
384 }
385
386 pub fn nat64_translate(
412 &self,
413 v6_src_addr: Ipv6Addr,
414 v6_dst_addr: Ipv6Addr,
415 ) -> Nat64TranslationResult<impl Serializer<Buffer = EmptyBuf> + Debug + '_, Nat64Error> {
416 #[derive(Debug)]
419 enum Nat64Serializer<T, U, O> {
420 Tcp(T),
421 Udp(U),
422 Other(O),
423 }
424
425 impl<T, U, O> Serializer for Nat64Serializer<T, U, O>
426 where
427 T: Serializer<Buffer = EmptyBuf>,
428 U: Serializer<Buffer = EmptyBuf>,
429 O: Serializer<Buffer = EmptyBuf>,
430 {
431 type Buffer = EmptyBuf;
432 fn serialize<B, P>(
433 self,
434 outer: PacketConstraints,
435 provider: P,
436 ) -> Result<B, (SerializeError<P::Error>, Self)>
437 where
438 B: GrowBufferMut,
439 P: BufferProvider<Self::Buffer, B>,
440 {
441 match self {
442 Nat64Serializer::Tcp(serializer) => serializer
443 .serialize(outer, provider)
444 .map_err(|(err, ser)| (err, Nat64Serializer::Tcp(ser))),
445 Nat64Serializer::Udp(serializer) => serializer
446 .serialize(outer, provider)
447 .map_err(|(err, ser)| (err, Nat64Serializer::Udp(ser))),
448 Nat64Serializer::Other(serializer) => serializer
449 .serialize(outer, provider)
450 .map_err(|(err, ser)| (err, Nat64Serializer::Other(ser))),
451 }
452 }
453
454 fn serialize_new_buf<B: ReusableBuffer, A: BufferAlloc<B>>(
455 &self,
456 outer: PacketConstraints,
457 alloc: A,
458 ) -> Result<B, SerializeError<A::Error>> {
459 match self {
460 Nat64Serializer::Tcp(serializer) => serializer.serialize_new_buf(outer, alloc),
461 Nat64Serializer::Udp(serializer) => serializer.serialize_new_buf(outer, alloc),
462 Nat64Serializer::Other(serializer) => {
463 serializer.serialize_new_buf(outer, alloc)
464 }
465 }
466 }
467 }
468
469 let v6_builder = |v6_proto| {
470 let mut builder =
471 Ipv6PacketBuilder::new(v6_src_addr, v6_dst_addr, self.ttl(), v6_proto);
472 builder.dscp_and_ecn(self.dscp_and_ecn());
473 builder.flowlabel(0);
474 builder
475 };
476
477 match self.proto() {
478 Ipv4Proto::Igmp => {
479 Nat64TranslationResult::Drop
481 }
482
483 Ipv4Proto::Proto(IpProto::Tcp) => {
484 let v6_pkt_builder = v6_builder(Ipv6Proto::Proto(IpProto::Tcp));
485 let args = TcpParseArgs::new(self.src_ip(), self.dst_ip());
486 match TcpSegment::parse(&mut self.body.as_bytes(), args) {
487 Ok(tcp) => {
488 let tcp_serializer =
492 Nat64Serializer::Tcp(tcp.into_serializer(v6_src_addr, v6_dst_addr));
493 Nat64TranslationResult::Forward(tcp_serializer.encapsulate(v6_pkt_builder))
494 }
495 Err(msg) => {
496 debug!("Parsing of TCP segment failed: {:?}", msg);
497
498 let common_serializer =
504 Nat64Serializer::Other(self.body().into_serializer());
505 Nat64TranslationResult::Forward(
506 common_serializer.encapsulate(v6_pkt_builder),
507 )
508 }
509 }
510 }
511
512 Ipv4Proto::Proto(IpProto::Udp) => {
513 let v6_pkt_builder = v6_builder(Ipv6Proto::Proto(IpProto::Udp));
514 let args = UdpParseArgs::new(self.src_ip(), self.dst_ip());
515 match UdpPacket::parse(&mut self.body.as_bytes(), args) {
516 Ok(udp) => {
517 let udp_serializer =
521 Nat64Serializer::Udp(udp.into_serializer(v6_src_addr, v6_dst_addr));
522 Nat64TranslationResult::Forward(udp_serializer.encapsulate(v6_pkt_builder))
523 }
524 Err(msg) => {
525 debug!("Parsing of UDP packet failed: {:?}", msg);
526
527 let common_serializer =
533 Nat64Serializer::Other(self.body().into_serializer());
534 Nat64TranslationResult::Forward(
535 common_serializer.encapsulate(v6_pkt_builder),
536 )
537 }
538 }
539 }
540
541 Ipv4Proto::Icmp => Nat64TranslationResult::Err(Nat64Error::NotImplemented),
542
543 Ipv4Proto::Other(val) => {
548 let v6_pkt_builder = v6_builder(Ipv6Proto::Other(val));
549 let common_serializer = Nat64Serializer::Other(self.body().into_serializer());
550 Nat64TranslationResult::Forward(common_serializer.encapsulate(v6_pkt_builder))
551 }
552
553 Ipv4Proto::Proto(IpProto::Reserved) => Nat64TranslationResult::Drop,
556 }
557 }
558
559 pub fn to_vec(&self) -> Vec<u8> {
561 let Ipv4Packet { hdr_prefix, options, body } = self;
562 let mut buf = Vec::with_capacity(
563 Ref::bytes(&hdr_prefix).len() + options.bytes().len() + body.as_bytes().len(),
564 );
565 buf.extend(Ref::bytes(&hdr_prefix));
566 buf.extend(options.bytes());
567 buf.extend(body.as_bytes());
568 buf
569 }
570}
571
572impl<B: SplitByteSliceMut> Ipv4Packet<B> {
573 pub fn set_src_ip_and_update_checksum(&mut self, addr: Ipv4Addr) {
577 let old_bytes = self.hdr_prefix.src_ip.bytes();
578 self.hdr_prefix.hdr_checksum =
579 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, addr.bytes());
580 self.hdr_prefix.src_ip = addr;
581 }
582
583 pub fn set_dst_ip_and_update_checksum(&mut self, addr: Ipv4Addr) {
587 let old_bytes = self.hdr_prefix.dst_ip.bytes();
588 self.hdr_prefix.hdr_checksum =
589 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, addr.bytes());
590 self.hdr_prefix.dst_ip = addr;
591 }
592
593 pub fn set_ttl(&mut self, ttl: u8) {
597 let old_bytes = [self.hdr_prefix.ttl, self.hdr_prefix.proto];
601 let new_bytes = [ttl, self.hdr_prefix.proto];
602 self.hdr_prefix.hdr_checksum =
603 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, &new_bytes);
604 self.hdr_prefix.ttl = ttl;
605 }
606
607 pub fn body_mut(&mut self) -> &mut [u8] {
609 &mut self.body
610 }
611
612 pub fn parts_with_body_mut(&mut self) -> (&HeaderPrefix, &Options<B>, &mut [u8]) {
615 (&self.hdr_prefix, &self.options, &mut self.body)
616 }
617}
618
619impl<B> Debug for Ipv4Packet<B>
620where
621 B: SplitByteSlice,
622{
623 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
624 f.debug_struct("Ipv4Packet")
625 .field("src_ip", &self.src_ip())
626 .field("dst_ip", &self.dst_ip())
627 .field("id", &self.id())
628 .field("ttl", &self.ttl())
629 .field("proto", &self.proto())
630 .field("frag_off", &self.fragment_offset())
631 .field("dscp", &self.dscp_and_ecn().dscp())
632 .field("ecn", &self.dscp_and_ecn().ecn())
633 .field("mf_flag", &self.mf_flag())
634 .field("df_flag", &self.df_flag())
635 .field("body", &alloc::format!("<{} bytes>", self.body.len()))
636 .finish()
637 }
638}
639
640pub struct Ipv4PacketRaw<B> {
650 hdr_prefix: Ref<B, HeaderPrefix>,
651 options: MaybeParsed<OptionsRaw<B, Ipv4OptionsImpl>, B>,
652 body: MaybeParsed<B, B>,
653}
654
655impl<B> Ipv4PacketRaw<B> {
656 pub fn body_mut(&mut self) -> &mut B {
660 match &mut self.body {
661 MaybeParsed::Complete(b) => b,
662 MaybeParsed::Incomplete(b) => b,
663 }
664 }
665}
666
667impl<B: SplitByteSlice> Ipv4Header for Ipv4PacketRaw<B> {
668 fn get_header_prefix(&self) -> &HeaderPrefix {
669 &self.hdr_prefix
670 }
671}
672
673impl<B: SplitByteSlice> ParsablePacket<B, ()> for Ipv4PacketRaw<B> {
674 type Error = IpParseError<Ipv4>;
675
676 fn parse_metadata(&self) -> ParseMetadata {
677 let header_len = Ref::bytes(&self.hdr_prefix).len() + self.options.len();
678 ParseMetadata::from_packet(header_len, self.body.len(), 0)
679 }
680
681 fn parse<BV: BufferView<B>>(mut buffer: BV, _args: ()) -> IpParseResult<Ipv4, Self> {
682 let hdr_prefix = buffer
683 .take_obj_front::<HeaderPrefix>()
684 .ok_or_else(debug_err_fn!(ParseError::Format, "too few bytes for header"))?;
685 let hdr_bytes = (hdr_prefix.ihl() * 4) as usize;
686
687 let options = MaybeParsed::take_from_buffer_with(
688 &mut buffer,
689 hdr_bytes.saturating_sub(HDR_PREFIX_LEN),
694 OptionsRaw::new,
695 );
696
697 let total_len: usize = hdr_prefix.total_len.get().into();
698 let body_len = total_len.saturating_sub(hdr_bytes);
699 if buffer.len() > body_len {
700 let _: B = buffer.take_back(buffer.len() - body_len).unwrap();
703 }
704
705 let body = MaybeParsed::new_with_min_len(buffer.into_rest(), body_len);
706
707 Ok(Self { hdr_prefix, options, body })
708 }
709}
710
711impl<B> Ipv4PacketRaw<B> {
712 pub fn options(&self) -> &MaybeParsed<OptionsRaw<B, Ipv4OptionsImpl>, B> {
714 &self.options
715 }
716}
717
718impl<B: SplitByteSlice> Ipv4PacketRaw<B> {
719 pub fn body(&self) -> MaybeParsed<&[u8], &[u8]> {
725 self.body.as_ref().map(|b| b.deref()).map_incomplete(|b| b.deref())
726 }
727
728 pub fn into_body(self) -> MaybeParsed<B, B> {
732 self.body
733 }
734}
735
736impl<B: SplitByteSliceMut> Ipv4PacketRaw<B> {
737 pub fn set_src_ip_and_update_checksum(&mut self, addr: Ipv4Addr) {
741 let old_bytes = self.hdr_prefix.src_ip.bytes();
742 self.hdr_prefix.hdr_checksum =
743 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, addr.bytes());
744 self.hdr_prefix.src_ip = addr;
745 }
746
747 pub fn set_dst_ip_and_update_checksum(&mut self, addr: Ipv4Addr) {
751 let old_bytes = self.hdr_prefix.dst_ip.bytes();
752 self.hdr_prefix.hdr_checksum =
753 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, addr.bytes());
754 self.hdr_prefix.dst_ip = addr;
755 }
756}
757
758pub type Options<B> = packet::records::options::Options<B, Ipv4OptionsImpl>;
764
765#[derive(Debug)]
768pub struct Ipv4OptionsTooLongError;
769
770#[derive(Debug, Clone)]
772pub struct Ipv4PacketBuilderWithOptions<'a, I> {
773 prefix_builder: Ipv4PacketBuilder,
774 options: OptionSequenceBuilder<Ipv4Option<'a>, I>,
775}
776
777impl<'a, I> Ipv4PacketBuilderWithOptions<'a, I>
778where
779 I: Iterator + Clone,
780 I::Item: Borrow<Ipv4Option<'a>>,
781{
782 pub fn new<T: IntoIterator<IntoIter = I>>(
788 prefix_builder: Ipv4PacketBuilder,
789 options: T,
790 ) -> Result<Ipv4PacketBuilderWithOptions<'a, I>, Ipv4OptionsTooLongError> {
791 let options = OptionSequenceBuilder::new(options.into_iter());
792 if options.serialized_len() > MAX_OPTIONS_LEN {
793 return Err(Ipv4OptionsTooLongError);
794 }
795 Ok(Ipv4PacketBuilderWithOptions { prefix_builder, options })
796 }
797
798 fn aligned_options_len(&self) -> usize {
799 crate::utils::round_to_next_multiple_of_four(self.options.serialized_len())
801 }
802
803 pub fn prefix_builder(&self) -> &Ipv4PacketBuilder {
805 &self.prefix_builder
806 }
807
808 pub fn prefix_builder_mut(&mut self) -> &mut Ipv4PacketBuilder {
810 &mut self.prefix_builder
811 }
812
813 pub fn options(&self) -> &I {
815 self.options.records()
816 }
817
818 pub fn with_fragment_options(
824 self,
825 first_fragment: bool,
826 ) -> Ipv4PacketBuilderWithOptions<'a, impl Iterator<Item: Borrow<Ipv4Option<'a>>> + Clone> {
827 let Self { prefix_builder, options } = self;
828 Ipv4PacketBuilderWithOptions {
829 prefix_builder,
830 options: OptionSequenceBuilder::new(
833 options
834 .records()
835 .clone()
836 .filter(move |opt| first_fragment || opt.borrow().copied()),
837 ),
838 }
839 }
840}
841
842impl<'a, B> Ipv4PacketBuilderWithOptions<'a, RecordsIter<'a, B, Ipv4OptionsImpl>> {
843 pub fn new_with_records_iter(
846 prefix_builder: Ipv4PacketBuilder,
847 iter: RecordsIter<'a, B, Ipv4OptionsImpl>,
848 ) -> Self {
849 Self { prefix_builder, options: OptionSequenceBuilder::new(iter) }
850 }
851}
852
853impl<'a, I> PacketBuilder for Ipv4PacketBuilderWithOptions<'a, I>
854where
855 I: Iterator + Clone,
856 I::Item: Borrow<Ipv4Option<'a>>,
857{
858 fn constraints(&self) -> PacketConstraints {
859 let header_len = IPV4_MIN_HDR_LEN + self.aligned_options_len();
860 assert_eq!(header_len % 4, 0);
861 PacketConstraints::new(header_len, 0, 0, (1 << 16) - 1 - header_len)
862 }
863
864 fn serialize(&self, target: &mut SerializeTarget<'_>, body: FragmentedBytesMut<'_, '_>) {
865 let opt_len = self.aligned_options_len();
866 let mut header = &mut &mut target.header[..];
872 let opts = header.take_back_zero(opt_len).expect("too few bytes for Ipv4 options");
873 let Ipv4PacketBuilderWithOptions { prefix_builder, options } = self;
874 options.serialize_into(opts);
875 prefix_builder.serialize(target, body);
876 }
877}
878
879impl<'a, I> IpPacketBuilder<Ipv4> for Ipv4PacketBuilderWithOptions<'a, I>
880where
881 I: Default + Debug + Clone + Iterator<Item: Borrow<Ipv4Option<'a>>>,
882{
883 fn new(src_ip: Ipv4Addr, dst_ip: Ipv4Addr, ttl: u8, proto: Ipv4Proto) -> Self {
884 Ipv4PacketBuilderWithOptions::new(
885 Ipv4PacketBuilder::new(src_ip, dst_ip, ttl, proto),
886 I::default(),
887 )
888 .expect("packet builder with no options should be valid")
889 }
890
891 fn src_ip(&self) -> Ipv4Addr {
892 self.prefix_builder.src_ip
893 }
894
895 fn set_src_ip(&mut self, addr: Ipv4Addr) {
896 self.prefix_builder.set_src_ip(addr);
897 }
898
899 fn dst_ip(&self) -> Ipv4Addr {
900 self.prefix_builder.dst_ip
901 }
902
903 fn set_dst_ip(&mut self, addr: Ipv4Addr) {
904 self.prefix_builder.set_dst_ip(addr);
905 }
906
907 fn proto(&self) -> Ipv4Proto {
908 self.prefix_builder.proto
909 }
910
911 fn set_dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
912 self.prefix_builder.set_dscp_and_ecn(dscp_and_ecn)
913 }
914}
915
916#[derive(Debug, Clone, Eq, PartialEq)]
918pub struct Ipv4PacketBuilder {
919 id: u16,
920 dscp_and_ecn: DscpAndEcn,
921 flags: u8,
922 frag_off: u16,
923 ttl: u8,
924 proto: Ipv4Proto,
925 src_ip: Ipv4Addr,
926 dst_ip: Ipv4Addr,
927}
928
929impl Ipv4PacketBuilder {
930 pub fn new<S: Into<Ipv4Addr>, D: Into<Ipv4Addr>>(
932 src_ip: S,
933 dst_ip: D,
934 ttl: u8,
935 proto: Ipv4Proto,
936 ) -> Ipv4PacketBuilder {
937 Ipv4PacketBuilder {
938 id: 0,
939 dscp_and_ecn: DscpAndEcn::default(),
940 flags: 0,
941 frag_off: 0,
942 ttl,
943 proto: proto,
944 src_ip: src_ip.into(),
945 dst_ip: dst_ip.into(),
946 }
947 }
948
949 pub fn dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
951 self.dscp_and_ecn = dscp_and_ecn;
952 }
953
954 pub fn id(&mut self, id: u16) {
956 self.id = id
957 }
958
959 pub fn df_flag(&mut self, df: bool) {
961 if df {
962 self.flags |= 1 << DF_FLAG_OFFSET;
963 } else {
964 self.flags &= !(1 << DF_FLAG_OFFSET);
965 }
966 }
967
968 pub fn mf_flag(&mut self, mf: bool) {
970 if mf {
971 self.flags |= 1 << MF_FLAG_OFFSET;
972 } else {
973 self.flags &= !(1 << MF_FLAG_OFFSET);
974 }
975 }
976
977 pub fn fragment_offset(&mut self, fragment_offset: FragmentOffset) {
979 self.frag_off = fragment_offset.into_raw();
980 }
981
982 pub fn read_df_flag(&self) -> bool {
984 (self.flags & (1 << DF_FLAG_OFFSET)) != 0
985 }
986}
987
988impl PacketBuilder for Ipv4PacketBuilder {
989 fn constraints(&self) -> PacketConstraints {
990 PacketConstraints::new(IPV4_MIN_HDR_LEN, 0, 0, (1 << 16) - 1 - IPV4_MIN_HDR_LEN)
991 }
992
993 fn serialize(&self, target: &mut SerializeTarget<'_>, body: FragmentedBytesMut<'_, '_>) {
994 let total_len = target.header.len() + body.len();
995 assert_eq!(target.header.len() % 4, 0);
996 let ihl: u8 = u8::try_from(target.header.len() / 4).expect("Header too large");
997
998 let id = if ((self.flags & (1 << DF_FLAG_OFFSET)) == 0)
1008 || ((self.flags & (1 << MF_FLAG_OFFSET)) == 1)
1009 || (self.frag_off > 0)
1010 {
1011 self.id
1012 } else {
1013 0
1014 };
1015
1016 let mut hdr_prefix = HeaderPrefix::new(
1017 ihl,
1018 self.dscp_and_ecn,
1019 {
1020 debug_assert!(total_len <= core::u16::MAX as usize);
1026 total_len as u16
1027 },
1028 id,
1029 self.flags,
1030 self.frag_off,
1031 self.ttl,
1032 self.proto.into(),
1033 [0, 0], self.src_ip,
1035 self.dst_ip,
1036 );
1037
1038 let options = &target.header[HDR_PREFIX_LEN..];
1039 let checksum = compute_header_checksum(hdr_prefix.as_bytes(), options);
1040 hdr_prefix.hdr_checksum = checksum;
1041 let mut header = &mut target.header;
1042 header.write_obj_front(&hdr_prefix).expect("too few bytes for IPv4 header prefix");
1043 }
1044}
1045
1046impl IpPacketBuilder<Ipv4> for Ipv4PacketBuilder {
1047 fn new(src_ip: Ipv4Addr, dst_ip: Ipv4Addr, ttl: u8, proto: Ipv4Proto) -> Self {
1048 Ipv4PacketBuilder::new(src_ip, dst_ip, ttl, proto)
1049 }
1050
1051 fn src_ip(&self) -> Ipv4Addr {
1052 self.src_ip
1053 }
1054
1055 fn set_src_ip(&mut self, addr: Ipv4Addr) {
1056 self.src_ip = addr;
1057 }
1058
1059 fn dst_ip(&self) -> Ipv4Addr {
1060 self.dst_ip
1061 }
1062
1063 fn set_dst_ip(&mut self, addr: Ipv4Addr) {
1064 self.dst_ip = addr;
1065 }
1066
1067 fn proto(&self) -> Ipv4Proto {
1068 self.proto
1069 }
1070
1071 fn set_dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
1072 self.dscp_and_ecn = dscp_and_ecn;
1073 }
1074}
1075
1076const DF_FLAG_OFFSET: u8 = 1;
1078const MF_FLAG_OFFSET: u8 = 0;
1079
1080pub(crate) fn reassemble_fragmented_packet<
1082 B: SplitByteSliceMut,
1083 BV: BufferViewMut<B>,
1084 I: Iterator<Item = Vec<u8>>,
1085>(
1086 mut buffer: BV,
1087 header: Vec<u8>,
1088 body_fragments: I,
1089) -> IpParseResult<Ipv4, ()> {
1090 let bytes = buffer.as_mut();
1091
1092 bytes[0..header.len()].copy_from_slice(&header[..]);
1094 let mut byte_count = header.len();
1095
1096 for p in body_fragments {
1098 bytes[byte_count..byte_count + p.len()].copy_from_slice(&p[..]);
1099 byte_count += p.len();
1100 }
1101
1102 if byte_count > usize::from(core::u16::MAX) {
1107 return debug_err!(
1108 Err(ParseError::Format.into()),
1109 "fragmented packet length of {} bytes is too large",
1110 byte_count
1111 );
1112 }
1113
1114 let mut header = Ref::<_, HeaderPrefix>::from_prefix(bytes).unwrap().0;
1117
1118 header.total_len.set(u16::try_from(byte_count).unwrap());
1120
1121 header.flags_frag_off = [0; 2];
1124
1125 header.hdr_checksum = [0; 2];
1127 header.hdr_checksum = compute_header_checksum(header.as_bytes(), &[]);
1128
1129 Ok(())
1130}
1131
1132pub mod options {
1134 use byteorder::{ByteOrder, NetworkEndian};
1135 use packet::records::options::{
1136 OptionBuilder, OptionLayout, OptionParseErr, OptionParseLayout, OptionsImpl,
1137 };
1138 use packet::BufferViewMut;
1139 use zerocopy::byteorder::network_endian::U16;
1140
1141 const OPTION_KIND_EOL: u8 = 0;
1142 const OPTION_KIND_NOP: u8 = 1;
1143 const OPTION_KIND_RTRALRT: u8 = 148;
1144
1145 const OPTION_RTRALRT_LEN: usize = 2;
1146
1147 #[derive(PartialEq, Eq, Debug, Clone)]
1154 #[allow(missing_docs)]
1155 pub enum Ipv4Option<'a> {
1156 RouterAlert { data: u16 },
1162
1163 Unrecognized { kind: u8, data: &'a [u8] },
1175 }
1176
1177 impl<'a> Ipv4Option<'a> {
1178 pub fn copied(&self) -> bool {
1180 match self {
1181 Ipv4Option::RouterAlert { .. } => true,
1185 Ipv4Option::Unrecognized { kind, .. } => *kind & (1 << 7) != 0,
1186 }
1187 }
1188 }
1189
1190 #[derive(Debug, Clone)]
1192 pub struct Ipv4OptionsImpl;
1193
1194 impl OptionLayout for Ipv4OptionsImpl {
1195 type KindLenField = u8;
1196 }
1197
1198 impl OptionParseLayout for Ipv4OptionsImpl {
1199 type Error = OptionParseErr;
1200 const END_OF_OPTIONS: Option<u8> = Some(0);
1201 const NOP: Option<u8> = Some(1);
1202 }
1203
1204 impl OptionsImpl for Ipv4OptionsImpl {
1205 type Option<'a> = Ipv4Option<'a>;
1206
1207 fn parse<'a>(kind: u8, data: &'a [u8]) -> Result<Option<Ipv4Option<'a>>, OptionParseErr> {
1208 match kind {
1209 self::OPTION_KIND_EOL | self::OPTION_KIND_NOP => {
1210 unreachable!("records::options::Options promises to handle EOL and NOP")
1211 }
1212 self::OPTION_KIND_RTRALRT => {
1213 if data.len() == OPTION_RTRALRT_LEN {
1214 Ok(Some(Ipv4Option::RouterAlert { data: NetworkEndian::read_u16(data) }))
1215 } else {
1216 Err(OptionParseErr)
1217 }
1218 }
1219 kind => {
1220 if data.len() > 38 {
1221 Err(OptionParseErr)
1222 } else {
1223 Ok(Some(Ipv4Option::Unrecognized { kind, data }))
1224 }
1225 }
1226 }
1227 }
1228 }
1229
1230 impl<'a> OptionBuilder for Ipv4Option<'a> {
1231 type Layout = Ipv4OptionsImpl;
1232
1233 fn serialized_len(&self) -> usize {
1234 match self {
1235 Ipv4Option::RouterAlert { .. } => OPTION_RTRALRT_LEN,
1236 Ipv4Option::Unrecognized { data, .. } => data.len(),
1237 }
1238 }
1239
1240 fn option_kind(&self) -> u8 {
1241 match self {
1242 Ipv4Option::RouterAlert { .. } => OPTION_KIND_RTRALRT,
1243 Ipv4Option::Unrecognized { kind, .. } => *kind,
1244 }
1245 }
1246
1247 fn serialize_into(&self, mut buffer: &mut [u8]) {
1248 match self {
1249 Ipv4Option::Unrecognized { data, .. } => buffer.copy_from_slice(data),
1250 Ipv4Option::RouterAlert { data } => {
1251 (&mut buffer).write_obj_front(&U16::new(*data)).unwrap()
1252 }
1253 };
1254 }
1255 }
1256
1257 #[cfg(test)]
1258 mod test {
1259 use packet::records::options::Options;
1260 use packet::records::RecordBuilder;
1261
1262 use super::*;
1263
1264 #[test]
1265 fn test_serialize_router_alert() {
1266 let mut buffer = [0u8; 4];
1267 let option = Ipv4Option::RouterAlert { data: 0 };
1268 <Ipv4Option<'_> as RecordBuilder>::serialize_into(&option, &mut buffer);
1269 assert_eq!(buffer[0], 148);
1270 assert_eq!(buffer[1], 4);
1271 assert_eq!(buffer[2], 0);
1272 assert_eq!(buffer[3], 0);
1273 }
1274
1275 #[test]
1276 fn test_parse_router_alert() {
1277 let mut buffer: Vec<u8> = vec![148, 4, 0, 0];
1278 let options = Options::<_, Ipv4OptionsImpl>::parse(buffer.as_mut()).unwrap();
1279 let rtralt = options.iter().next().unwrap();
1280 assert_eq!(rtralt, Ipv4Option::RouterAlert { data: 0 });
1281 }
1282 }
1283}
1284
1285mod inner {
1286 pub const IPV4_MIN_HDR_LEN: usize = super::HDR_PREFIX_LEN;
1288}
1289
1290pub mod testutil {
1292 pub use super::inner::IPV4_MIN_HDR_LEN;
1293
1294 pub const IPV4_TTL_OFFSET: usize = 8;
1296
1297 pub const IPV4_CHECKSUM_OFFSET: usize = 10;
1299}
1300
1301#[cfg(test)]
1302mod tests {
1303 use net_types::ethernet::Mac;
1304 use packet::{Buf, FragmentedBuffer, ParseBuffer};
1305
1306 use super::*;
1307 use crate::ethernet::{
1308 EtherType, EthernetFrame, EthernetFrameBuilder, EthernetFrameLengthCheck,
1309 ETHERNET_MIN_BODY_LEN_NO_TAG,
1310 };
1311 use crate::testutil::*;
1312
1313 const DEFAULT_SRC_MAC: Mac = Mac::new([1, 2, 3, 4, 5, 6]);
1314 const DEFAULT_DST_MAC: Mac = Mac::new([7, 8, 9, 0, 1, 2]);
1315 const DEFAULT_SRC_IP: Ipv4Addr = Ipv4Addr::new([1, 2, 3, 4]);
1316 const DEFAULT_DST_IP: Ipv4Addr = Ipv4Addr::new([5, 6, 7, 8]);
1317 const DEFAULT_V6_SRC_IP: Ipv6Addr = Ipv6Addr::new([0x2001, 0x0db8, 0, 0, 0, 0, 0, 1]);
1319 const DEFAULT_V6_DST_IP: Ipv6Addr = Ipv6Addr::new([0x2001, 0x0db8, 0, 0, 0, 0, 0, 2]);
1321
1322 #[test]
1323 fn test_parse_serialize_full_tcp() {
1324 use crate::testdata::tls_client_hello_v4::*;
1325
1326 let mut buf = ETHERNET_FRAME.bytes;
1327 let frame = buf.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1328 verify_ethernet_frame(&frame, ETHERNET_FRAME);
1329
1330 let mut body = frame.body();
1331 let packet = body.parse::<Ipv4Packet<_>>().unwrap();
1332 verify_ipv4_packet(&packet, IPV4_PACKET);
1333
1334 let buffer = packet
1336 .body()
1337 .into_serializer()
1338 .encapsulate(packet.builder())
1339 .encapsulate(frame.builder())
1340 .serialize_vec_outer()
1341 .unwrap();
1342 assert_eq!(buffer.as_ref(), ETHERNET_FRAME.bytes);
1343
1344 assert_eq!(&packet.to_vec()[..], IPV4_PACKET.bytes);
1346 }
1347
1348 #[test]
1349 fn test_parse_serialize_full_udp() {
1350 use crate::testdata::dns_request_v4::*;
1351
1352 let mut buf = ETHERNET_FRAME.bytes;
1353 let frame = buf.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1354 verify_ethernet_frame(&frame, ETHERNET_FRAME);
1355
1356 let mut body = frame.body();
1357 let packet = body.parse::<Ipv4Packet<_>>().unwrap();
1358 verify_ipv4_packet(&packet, IPV4_PACKET);
1359
1360 let buffer = packet
1362 .body()
1363 .into_serializer()
1364 .encapsulate(packet.builder())
1365 .encapsulate(frame.builder())
1366 .serialize_vec_outer()
1367 .unwrap();
1368 assert_eq!(buffer.as_ref(), ETHERNET_FRAME.bytes);
1369
1370 assert_eq!(&packet.to_vec()[..], IPV4_PACKET.bytes);
1372 }
1373
1374 #[test]
1375 fn test_parse_serialize_with_options() {
1376 use crate::testdata::igmpv2_membership::report::*;
1379
1380 let mut buf = IP_PACKET_BYTES;
1381 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1382 assert_eq!(packet.iter_options().count(), 1);
1383
1384 assert_eq!(&packet.to_vec()[..], IP_PACKET_BYTES);
1389 }
1390
1391 fn hdr_prefix_to_bytes(hdr_prefix: HeaderPrefix) -> [u8; 20] {
1392 zerocopy::transmute!(hdr_prefix)
1393 }
1394
1395 fn new_hdr_prefix() -> HeaderPrefix {
1398 HeaderPrefix::new(
1399 5,
1400 DscpAndEcn::default(),
1401 20,
1402 0x0102,
1403 0,
1404 0,
1405 0x03,
1406 IpProto::Tcp.into(),
1407 [0xa6, 0xcf],
1408 DEFAULT_SRC_IP,
1409 DEFAULT_DST_IP,
1410 )
1411 }
1412
1413 #[test]
1414 fn test_parse() {
1415 let mut bytes = &hdr_prefix_to_bytes(new_hdr_prefix())[..];
1416 let packet = bytes.parse::<Ipv4Packet<_>>().unwrap();
1417 assert_eq!(packet.id(), 0x0102);
1418 assert_eq!(packet.ttl(), 0x03);
1419 assert_eq!(packet.proto(), IpProto::Tcp.into());
1420 assert_eq!(packet.src_ip(), DEFAULT_SRC_IP);
1421 assert_eq!(packet.dst_ip(), DEFAULT_DST_IP);
1422 assert_eq!(packet.body(), []);
1423 }
1424
1425 #[test]
1426 fn test_parse_padding() {
1427 let mut buffer = Buf::new(Vec::new(), ..)
1429 .encapsulate(Ipv4PacketBuilder::new(
1430 DEFAULT_DST_IP,
1431 DEFAULT_DST_IP,
1432 0,
1433 IpProto::Tcp.into(),
1434 ))
1435 .encapsulate(EthernetFrameBuilder::new(
1436 DEFAULT_SRC_MAC,
1437 DEFAULT_DST_MAC,
1438 EtherType::Ipv4,
1439 ETHERNET_MIN_BODY_LEN_NO_TAG,
1440 ))
1441 .serialize_vec_outer()
1442 .unwrap();
1443 let _: EthernetFrame<_> =
1444 buffer.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1445 assert_eq!(buffer.len(), 46);
1448 let packet = buffer.parse::<Ipv4Packet<_>>().unwrap();
1449 assert_eq!(packet.body().len(), 0);
1452 assert_eq!(buffer.len(), 0);
1456 }
1457
1458 #[test]
1459 fn test_parse_error() {
1460 let mut hdr_prefix = new_hdr_prefix();
1462 hdr_prefix.version_ihl = (5 << 4) | 5;
1463 assert_eq!(
1464 (&hdr_prefix_to_bytes(hdr_prefix)[..]).parse::<Ipv4Packet<_>>().unwrap_err(),
1465 ParseError::Format.into()
1466 );
1467
1468 let mut hdr_prefix = new_hdr_prefix();
1471 hdr_prefix.version_ihl = (4 << 4) | 4;
1472 assert_eq!(
1473 (&hdr_prefix_to_bytes(hdr_prefix)[..]).parse::<Ipv4Packet<_>>().unwrap_err(),
1474 ParseError::Format.into()
1475 );
1476
1477 let mut hdr_prefix = new_hdr_prefix();
1480 hdr_prefix.version_ihl = (4 << 4) | 6;
1481 assert_eq!(
1482 (&hdr_prefix_to_bytes(hdr_prefix)[..]).parse::<Ipv4Packet<_>>().unwrap_err(),
1483 ParseError::Format.into()
1484 );
1485 }
1486
1487 fn new_builder() -> Ipv4PacketBuilder {
1489 Ipv4PacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, 64, IpProto::Tcp.into())
1490 }
1491
1492 #[test]
1493 fn test_fragment_type() {
1494 fn test_fragment_type_helper(fragment_offset: u16, expect_fragment_type: Ipv4FragmentType) {
1495 let mut builder = new_builder();
1496 builder.fragment_offset(FragmentOffset::new(fragment_offset).unwrap());
1497
1498 let mut buf = [0; IPV4_MIN_HDR_LEN]
1499 .into_serializer()
1500 .encapsulate(builder)
1501 .serialize_vec_outer()
1502 .unwrap();
1503
1504 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1505 assert_eq!(packet.fragment_type(), expect_fragment_type);
1506 }
1507
1508 test_fragment_type_helper(0x0000, Ipv4FragmentType::InitialFragment);
1509 test_fragment_type_helper(0x0008, Ipv4FragmentType::NonInitialFragment);
1510 }
1511
1512 #[test]
1513 fn test_serialize() {
1514 let mut builder = new_builder();
1515 builder.dscp_and_ecn(DscpAndEcn::new(0x12, 3));
1516 builder.id(0x0405);
1517 builder.df_flag(true);
1518 builder.mf_flag(true);
1519 builder.fragment_offset(FragmentOffset::new(0x0607).unwrap());
1520
1521 let mut buf = (&[0, 1, 2, 3, 3, 4, 5, 7, 8, 9])
1522 .into_serializer()
1523 .encapsulate(builder)
1524 .serialize_vec_outer()
1525 .unwrap();
1526 assert_eq!(
1527 buf.as_ref(),
1528 [
1529 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,
1530 4, 5, 7, 8, 9
1531 ]
1532 );
1533 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1534 assert_eq!(packet.dscp_and_ecn().dscp(), 0x12);
1535 assert_eq!(packet.dscp_and_ecn().ecn(), 3);
1536 assert_eq!(packet.id(), 0x0405);
1537 assert!(packet.df_flag());
1538 assert!(packet.mf_flag());
1539 assert_eq!(packet.fragment_offset().into_raw(), 0x0607);
1540 assert_eq!(packet.fragment_type(), Ipv4FragmentType::NonInitialFragment);
1541 }
1542
1543 #[test]
1544 fn test_serialize_id_unset() {
1545 let mut builder = new_builder();
1546 builder.id(0x0405);
1547 builder.df_flag(true);
1548
1549 let mut buf = (&[0, 1, 2, 3, 3, 4, 5, 7, 8, 9])
1550 .into_serializer()
1551 .encapsulate(builder)
1552 .serialize_vec_outer()
1553 .unwrap();
1554 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1555 assert_eq!(packet.id(), 0);
1556 assert!(packet.df_flag());
1557 assert_eq!(packet.mf_flag(), false);
1558 assert_eq!(packet.fragment_offset().into_raw(), 0);
1559 assert_eq!(packet.fragment_type(), Ipv4FragmentType::InitialFragment);
1560 }
1561
1562 #[test]
1563 fn test_serialize_zeroes() {
1564 let mut buf_0 = [0; IPV4_MIN_HDR_LEN];
1567 let _: Buf<&mut [u8]> = Buf::new(&mut buf_0[..], IPV4_MIN_HDR_LEN..)
1568 .encapsulate(new_builder())
1569 .serialize_vec_outer()
1570 .unwrap()
1571 .unwrap_a();
1572 let mut buf_1 = [0xFF; IPV4_MIN_HDR_LEN];
1573 let _: Buf<&mut [u8]> = Buf::new(&mut buf_1[..], IPV4_MIN_HDR_LEN..)
1574 .encapsulate(new_builder())
1575 .serialize_vec_outer()
1576 .unwrap()
1577 .unwrap_a();
1578 assert_eq!(buf_0, buf_1);
1579 }
1580
1581 #[test]
1582 #[should_panic(expected = "(SizeLimitExceeded, Nested { inner: Buf { buf:")]
1583 fn test_serialize_panic_packet_length() {
1584 let _: Buf<&mut [u8]> = Buf::new(&mut [0; (1 << 16) - IPV4_MIN_HDR_LEN][..], ..)
1586 .encapsulate(new_builder())
1587 .serialize_vec_outer()
1588 .unwrap()
1589 .unwrap_a();
1590 }
1591
1592 #[test]
1593 fn test_copy_header_bytes_for_fragment() {
1594 let hdr_prefix = new_hdr_prefix();
1595 let mut bytes = hdr_prefix_to_bytes(hdr_prefix);
1596 let mut buf = &bytes[..];
1597 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1598 let copied_bytes = packet.copy_header_bytes_for_fragment();
1599 bytes[IPV4_FRAGMENT_DATA_BYTE_RANGE].copy_from_slice(&[0; 4][..]);
1600 assert_eq!(&copied_bytes[..], &bytes[..]);
1601 }
1602
1603 #[test]
1604 fn test_partial_parsing() {
1605 use core::ops::Deref as _;
1606
1607 let mut hdr_prefix = new_hdr_prefix();
1610 hdr_prefix.total_len = U16::new(256);
1611 let mut bytes = hdr_prefix_to_bytes(hdr_prefix)[..].to_owned();
1612 const PAYLOAD: &[u8] = &[1, 2, 3, 4, 5];
1613 bytes.extend(PAYLOAD);
1614 let mut buf = &bytes[..];
1615 let packet = buf.parse::<Ipv4PacketRaw<_>>().unwrap();
1616 let Ipv4PacketRaw { hdr_prefix, options, body } = &packet;
1617 assert_eq!(Ref::bytes(&hdr_prefix), &bytes[0..20]);
1618 assert_eq!(options.as_ref().complete().unwrap().deref(), []);
1619 assert_eq!(body, &MaybeParsed::Incomplete(PAYLOAD));
1621 assert!(Ipv4Packet::try_from_raw(packet).is_err());
1623
1624 let mut hdr_prefix = new_hdr_prefix();
1626 hdr_prefix.version_ihl = (4 << 4) | 10;
1627 let bytes = hdr_prefix_to_bytes(hdr_prefix);
1628 let mut buf = &bytes[..];
1629 let packet = buf.parse::<Ipv4PacketRaw<_>>().unwrap();
1630 let Ipv4PacketRaw { hdr_prefix, options, body } = &packet;
1631 assert_eq!(Ref::bytes(&hdr_prefix), bytes);
1632 assert_eq!(options.as_ref().incomplete().unwrap(), &[]);
1633 assert_eq!(body.complete().unwrap(), []);
1634 assert!(Ipv4Packet::try_from_raw(packet).is_err());
1636
1637 let hdr_prefix = new_hdr_prefix();
1639 let bytes = &hdr_prefix_to_bytes(hdr_prefix);
1640 let mut buf = &bytes[0..10];
1641 assert!(buf.parse::<Ipv4PacketRaw<_>>().is_err());
1642 }
1643
1644 fn create_ipv4_and_ipv6_builders(
1645 proto_v4: Ipv4Proto,
1646 proto_v6: Ipv6Proto,
1647 ) -> (Ipv4PacketBuilder, Ipv6PacketBuilder) {
1648 const IP_DSCP_AND_ECN: DscpAndEcn = DscpAndEcn::new(0x12, 3);
1649 const IP_TTL: u8 = 64;
1650
1651 let mut ipv4_builder =
1652 Ipv4PacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, IP_TTL, proto_v4);
1653 ipv4_builder.dscp_and_ecn(IP_DSCP_AND_ECN);
1654 ipv4_builder.id(0x0405);
1655 ipv4_builder.df_flag(true);
1656 ipv4_builder.mf_flag(false);
1657 ipv4_builder.fragment_offset(FragmentOffset::ZERO);
1658
1659 let mut ipv6_builder =
1660 Ipv6PacketBuilder::new(DEFAULT_V6_SRC_IP, DEFAULT_V6_DST_IP, IP_TTL, proto_v6);
1661 ipv6_builder.dscp_and_ecn(IP_DSCP_AND_ECN);
1662 ipv6_builder.flowlabel(0);
1663
1664 (ipv4_builder, ipv6_builder)
1665 }
1666
1667 fn create_tcp_ipv4_and_ipv6_pkt(
1668 ) -> (packet::Either<EmptyBuf, Buf<Vec<u8>>>, packet::Either<EmptyBuf, Buf<Vec<u8>>>) {
1669 use crate::tcp::TcpSegmentBuilder;
1670 use core::num::NonZeroU16;
1671
1672 let tcp_src_port: NonZeroU16 = NonZeroU16::new(20).unwrap();
1673 let tcp_dst_port: NonZeroU16 = NonZeroU16::new(30).unwrap();
1674 const TCP_SEQ_NUM: u32 = 4321;
1675 const TCP_ACK_NUM: Option<u32> = Some(1234);
1676 const TCP_WINDOW_SIZE: u16 = 12345;
1677 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
1678
1679 let (ipv4_builder, ipv6_builder) =
1680 create_ipv4_and_ipv6_builders(IpProto::Tcp.into(), IpProto::Tcp.into());
1681
1682 let tcp_builder = TcpSegmentBuilder::new(
1683 DEFAULT_SRC_IP,
1684 DEFAULT_DST_IP,
1685 tcp_src_port,
1686 tcp_dst_port,
1687 TCP_SEQ_NUM,
1688 TCP_ACK_NUM,
1689 TCP_WINDOW_SIZE,
1690 );
1691
1692 let v4_pkt_buf = (&PAYLOAD)
1693 .into_serializer()
1694 .encapsulate(tcp_builder)
1695 .encapsulate(ipv4_builder)
1696 .serialize_vec_outer()
1697 .unwrap();
1698
1699 let v6_tcp_builder = TcpSegmentBuilder::new(
1700 DEFAULT_V6_SRC_IP,
1701 DEFAULT_V6_DST_IP,
1702 tcp_src_port,
1703 tcp_dst_port,
1704 TCP_SEQ_NUM,
1705 TCP_ACK_NUM,
1706 TCP_WINDOW_SIZE,
1707 );
1708
1709 let v6_pkt_buf = (&PAYLOAD)
1710 .into_serializer()
1711 .encapsulate(v6_tcp_builder)
1712 .encapsulate(ipv6_builder)
1713 .serialize_vec_outer()
1714 .unwrap();
1715
1716 (v4_pkt_buf, v6_pkt_buf)
1717 }
1718
1719 #[test]
1720 fn test_nat64_translate_tcp() {
1721 let (mut v4_pkt_buf, expected_v6_pkt_buf) = create_tcp_ipv4_and_ipv6_pkt();
1722
1723 let parsed_v4_packet = v4_pkt_buf.parse::<Ipv4Packet<_>>().unwrap();
1724 let nat64_translation_result =
1725 parsed_v4_packet.nat64_translate(DEFAULT_V6_SRC_IP, DEFAULT_V6_DST_IP);
1726
1727 let serializable_pkt = match nat64_translation_result {
1728 Nat64TranslationResult::Forward(s) => s,
1729 _ => panic!("Nat64TranslationResult not of Forward type!"),
1730 };
1731
1732 let translated_v6_pkt_buf = serializable_pkt.serialize_vec_outer().unwrap();
1733
1734 assert_eq!(
1735 expected_v6_pkt_buf.to_flattened_vec(),
1736 translated_v6_pkt_buf.to_flattened_vec()
1737 );
1738 }
1739
1740 fn create_udp_ipv4_and_ipv6_pkt(
1741 ) -> (packet::Either<EmptyBuf, Buf<Vec<u8>>>, packet::Either<EmptyBuf, Buf<Vec<u8>>>) {
1742 use crate::udp::UdpPacketBuilder;
1743 use core::num::NonZeroU16;
1744
1745 let udp_src_port: NonZeroU16 = NonZeroU16::new(35000).unwrap();
1746 let udp_dst_port: NonZeroU16 = NonZeroU16::new(53).unwrap();
1747 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
1748
1749 let (ipv4_builder, ipv6_builder) =
1750 create_ipv4_and_ipv6_builders(IpProto::Udp.into(), IpProto::Udp.into());
1751
1752 let udp_builder =
1753 UdpPacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, Some(udp_src_port), udp_dst_port);
1754
1755 let v4_pkt_buf = (&PAYLOAD)
1756 .into_serializer()
1757 .encapsulate(udp_builder)
1758 .encapsulate(ipv4_builder)
1759 .serialize_vec_outer()
1760 .unwrap();
1761
1762 let v6_udp_builder = UdpPacketBuilder::new(
1763 DEFAULT_V6_SRC_IP,
1764 DEFAULT_V6_DST_IP,
1765 Some(udp_src_port),
1766 udp_dst_port,
1767 );
1768
1769 let v6_pkt_buf = (&PAYLOAD)
1770 .into_serializer()
1771 .encapsulate(v6_udp_builder)
1772 .encapsulate(ipv6_builder)
1773 .serialize_vec_outer()
1774 .unwrap();
1775
1776 (v4_pkt_buf, v6_pkt_buf)
1777 }
1778
1779 #[test]
1780 fn test_nat64_translate_udp() {
1781 let (mut v4_pkt_buf, expected_v6_pkt_buf) = create_udp_ipv4_and_ipv6_pkt();
1782
1783 let parsed_v4_packet = v4_pkt_buf.parse::<Ipv4Packet<_>>().unwrap();
1784 let nat64_translation_result =
1785 parsed_v4_packet.nat64_translate(DEFAULT_V6_SRC_IP, DEFAULT_V6_DST_IP);
1786
1787 let serializable_pkt = match nat64_translation_result {
1788 Nat64TranslationResult::Forward(s) => s,
1789 _ => panic!(
1790 "Nat64TranslationResult not of Forward type: {:?} ",
1791 nat64_translation_result
1792 ),
1793 };
1794
1795 let translated_v6_pkt_buf = serializable_pkt.serialize_vec_outer().unwrap();
1796
1797 assert_eq!(
1798 expected_v6_pkt_buf.to_flattened_vec(),
1799 translated_v6_pkt_buf.to_flattened_vec()
1800 );
1801 }
1802
1803 #[test]
1804 fn test_nat64_translate_non_tcp_udp_icmp() {
1805 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
1806
1807 let (ipv4_builder, ipv6_builder) =
1808 create_ipv4_and_ipv6_builders(Ipv4Proto::Other(50), Ipv6Proto::Other(50));
1809
1810 let mut v4_pkt_buf =
1811 (&PAYLOAD).into_serializer().encapsulate(ipv4_builder).serialize_vec_outer().unwrap();
1812
1813 let expected_v6_pkt_buf =
1814 (&PAYLOAD).into_serializer().encapsulate(ipv6_builder).serialize_vec_outer().unwrap();
1815
1816 let translated_v6_pkt_buf = {
1817 let parsed_v4_packet = v4_pkt_buf.parse::<Ipv4Packet<_>>().unwrap();
1818
1819 let nat64_translation_result =
1820 parsed_v4_packet.nat64_translate(DEFAULT_V6_SRC_IP, DEFAULT_V6_DST_IP);
1821
1822 let serializable_pkt = match nat64_translation_result {
1823 Nat64TranslationResult::Forward(s) => s,
1824 _ => panic!(
1825 "Nat64TranslationResult not of Forward type: {:?} ",
1826 nat64_translation_result
1827 ),
1828 };
1829
1830 let translated_buf = serializable_pkt.serialize_vec_outer().unwrap();
1831
1832 translated_buf
1833 };
1834
1835 assert_eq!(
1836 expected_v6_pkt_buf.to_flattened_vec(),
1837 translated_v6_pkt_buf.to_flattened_vec()
1838 );
1839 }
1840}