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, PartialPacketBuilder, ReusableBuffer, SerializeError,
25 SerializeTarget, Serializer,
26};
27use zerocopy::byteorder::network_endian::U16;
28use zerocopy::{
29 FromBytes, Immutable, IntoBytes, KnownLayout, Ref, SplitByteSlice, SplitByteSliceMut, Unaligned,
30};
31
32use crate::error::{IpParseError, IpParseResult, ParseError};
33use crate::ip::{
34 DscpAndEcn, FragmentOffset, IpExt, IpPacketBuilder, IpProto, Ipv4Proto, Ipv6Proto, Nat64Error,
35 Nat64TranslationResult,
36};
37use crate::ipv6::Ipv6PacketBuilder;
38use crate::tcp::{TcpParseArgs, TcpSegment};
39use crate::udp::{UdpPacket, UdpParseArgs};
40
41pub(crate) use self::inner::IPV4_MIN_HDR_LEN;
42use self::options::{Ipv4Option, Ipv4OptionsImpl};
43
44pub const HDR_PREFIX_LEN: usize = 20;
46
47pub const MAX_HDR_LEN: usize = 60;
49
50pub const MAX_OPTIONS_LEN: usize = MAX_HDR_LEN - HDR_PREFIX_LEN;
52
53const IPV4_FRAGMENT_DATA_BYTE_RANGE: Range<usize> = 4..8;
55
56#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
58#[allow(missing_docs)]
59pub enum Ipv4FragmentType {
60 InitialFragment,
61 NonInitialFragment,
62}
63
64#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned)]
67#[repr(C)]
68pub struct HeaderPrefix {
69 version_ihl: u8,
70 dscp_and_ecn: DscpAndEcn,
71 total_len: U16,
72 id: U16,
73 flags_frag_off: [u8; 2],
74 ttl: u8,
75 proto: u8,
76 hdr_checksum: [u8; 2],
77 src_ip: Ipv4Addr,
78 dst_ip: Ipv4Addr,
79}
80
81const IP_VERSION: u8 = 4;
82const VERSION_OFFSET: u8 = 4;
83const IHL_MASK: u8 = 0xF;
84const IHL_MAX: u8 = (1 << VERSION_OFFSET) - 1;
85const FLAGS_OFFSET: u8 = 13;
86const FLAGS_MAX: u8 = (1 << (16 - FLAGS_OFFSET)) - 1;
87const FRAG_OFF_MAX: u16 = (1 << FLAGS_OFFSET) - 1;
88
89impl HeaderPrefix {
90 #[allow(clippy::too_many_arguments)]
91 fn new(
92 ihl: u8,
93 dscp_and_ecn: DscpAndEcn,
94 total_len: u16,
95 id: u16,
96 flags: u8,
97 frag_off: u16,
98 ttl: u8,
99 proto: u8,
100 hdr_checksum: [u8; 2],
101 src_ip: Ipv4Addr,
102 dst_ip: Ipv4Addr,
103 ) -> HeaderPrefix {
104 debug_assert!(ihl <= IHL_MAX);
105 debug_assert!(flags <= FLAGS_MAX);
106 debug_assert!(frag_off <= FRAG_OFF_MAX);
107
108 HeaderPrefix {
109 version_ihl: (IP_VERSION << VERSION_OFFSET) | ihl,
110 dscp_and_ecn,
111 total_len: U16::new(total_len),
112 id: U16::new(id),
113 flags_frag_off: ((u16::from(flags) << FLAGS_OFFSET) | frag_off).to_be_bytes(),
114 ttl,
115 proto,
116 src_ip,
117 dst_ip,
118 hdr_checksum,
119 }
120 }
121
122 fn version(&self) -> u8 {
123 self.version_ihl >> VERSION_OFFSET
124 }
125
126 pub(crate) fn ihl(&self) -> u8 {
128 self.version_ihl & IHL_MASK
129 }
130
131 pub(crate) fn mf_flag(&self) -> bool {
133 self.flags_frag_off[0] & (1 << ((FLAGS_OFFSET - 8) + MF_FLAG_OFFSET)) > 0
138 }
139}
140
141pub trait Ipv4Header {
146 fn get_header_prefix(&self) -> &HeaderPrefix;
148
149 fn dscp_and_ecn(&self) -> DscpAndEcn {
151 self.get_header_prefix().dscp_and_ecn
152 }
153
154 fn id(&self) -> u16 {
156 self.get_header_prefix().id.get()
157 }
158
159 fn df_flag(&self) -> bool {
161 self.get_header_prefix().flags_frag_off[0] & (1 << (5 + DF_FLAG_OFFSET)) > 0
163 }
164
165 fn mf_flag(&self) -> bool {
167 self.get_header_prefix().mf_flag()
168 }
169
170 fn fragment_offset(&self) -> FragmentOffset {
172 FragmentOffset::new_with_lsb(U16::from_bytes(self.get_header_prefix().flags_frag_off).get())
173 }
174
175 fn fragment_type(&self) -> Ipv4FragmentType {
181 match self.fragment_offset().into_raw() {
182 0 => Ipv4FragmentType::InitialFragment,
183 _ => Ipv4FragmentType::NonInitialFragment,
184 }
185 }
186
187 fn ttl(&self) -> u8 {
189 self.get_header_prefix().ttl
190 }
191
192 fn proto(&self) -> Ipv4Proto {
196 Ipv4Proto::from(self.get_header_prefix().proto)
197 }
198
199 fn src_ip(&self) -> Ipv4Addr {
201 self.get_header_prefix().src_ip
202 }
203
204 fn dst_ip(&self) -> Ipv4Addr {
206 self.get_header_prefix().dst_ip
207 }
208
209 fn builder(&self) -> Ipv4PacketBuilder {
211 let mut s = Ipv4PacketBuilder {
212 id: self.id(),
213 dscp_and_ecn: self.dscp_and_ecn(),
214 flags: 0,
215 frag_off: self.fragment_offset().into_raw(),
216 ttl: self.ttl(),
217 proto: self.get_header_prefix().proto.into(),
218 src_ip: self.src_ip(),
219 dst_ip: self.dst_ip(),
220 };
221 s.df_flag(self.df_flag());
222 s.mf_flag(self.mf_flag());
223 s
224 }
225}
226
227impl Ipv4Header for HeaderPrefix {
228 fn get_header_prefix(&self) -> &HeaderPrefix {
229 self
230 }
231}
232
233pub struct Ipv4OnlyMeta {
235 pub id: u16,
237 pub fragment_type: Ipv4FragmentType,
239}
240
241pub struct Ipv4Packet<B> {
251 hdr_prefix: Ref<B, HeaderPrefix>,
252 options: Options<B>,
253 body: B,
254}
255
256impl<B: SplitByteSlice, I: IpExt> GenericOverIp<I> for Ipv4Packet<B> {
257 type Type = <I as IpExt>::Packet<B>;
258}
259
260impl<B: SplitByteSlice> Ipv4Header for Ipv4Packet<B> {
261 fn get_header_prefix(&self) -> &HeaderPrefix {
262 &self.hdr_prefix
263 }
264}
265
266impl<B: SplitByteSlice> ParsablePacket<B, ()> for Ipv4Packet<B> {
267 type Error = IpParseError<Ipv4>;
268
269 fn parse_metadata(&self) -> ParseMetadata {
270 let header_len = Ref::bytes(&self.hdr_prefix).len() + self.options.bytes().len();
271 ParseMetadata::from_packet(header_len, self.body.len(), 0)
272 }
273
274 fn parse<BV: BufferView<B>>(buffer: BV, _args: ()) -> IpParseResult<Ipv4, Self> {
275 Ipv4PacketRaw::<B>::parse(buffer, ()).and_then(Ipv4Packet::try_from_raw)
276 }
277}
278
279impl<B: SplitByteSlice> FromRaw<Ipv4PacketRaw<B>, ()> for Ipv4Packet<B> {
280 type Error = IpParseError<Ipv4>;
281
282 fn try_from_raw_with(raw: Ipv4PacketRaw<B>, _args: ()) -> Result<Self, Self::Error> {
283 let hdr_prefix = raw.hdr_prefix;
286 let hdr_bytes = (hdr_prefix.ihl() * 4) as usize;
287
288 if hdr_bytes < HDR_PREFIX_LEN {
289 return debug_err!(Err(ParseError::Format.into()), "invalid IHL: {}", hdr_prefix.ihl());
290 }
291
292 let options = match raw.options {
293 MaybeParsed::Incomplete(_) => {
294 return debug_err!(Err(ParseError::Format.into()), "Incomplete options");
295 }
296 MaybeParsed::Complete(unchecked) => Options::try_from_raw(unchecked)
297 .map_err(|e| debug_err!(e, "malformed options: {:?}", e))?,
298 };
299
300 if hdr_prefix.version() != 4 {
301 return debug_err!(
302 Err(ParseError::Format.into()),
303 "unexpected IP version: {}",
304 hdr_prefix.version()
305 );
306 }
307
308 let body = match raw.body {
309 MaybeParsed::Incomplete(_) => {
310 if hdr_prefix.mf_flag() {
311 return debug_err!(
312 Err(ParseError::NotSupported.into()),
313 "fragmentation not supported"
314 );
315 } else {
316 return debug_err!(Err(ParseError::Format.into()), "Incomplete body");
317 }
318 }
319 MaybeParsed::Complete(bytes) => bytes,
320 };
321
322 let packet = Ipv4Packet { hdr_prefix, options, body };
323 if packet.compute_header_checksum() != [0, 0] {
324 return debug_err!(Err(ParseError::Checksum.into()), "invalid checksum");
325 }
326 Ok(packet)
327 }
328}
329
330fn compute_header_checksum(hdr_prefix: &[u8], options: &[u8]) -> [u8; 2] {
331 let mut c = Checksum::new();
332 c.add_bytes(hdr_prefix);
333 c.add_bytes(options);
334 c.checksum()
335}
336
337impl<B: SplitByteSlice> Ipv4Packet<B> {
338 pub fn iter_options(&self) -> impl Iterator<Item = Ipv4Option<'_>> {
340 self.options.iter()
341 }
342
343 fn compute_header_checksum(&self) -> [u8; 2] {
345 compute_header_checksum(Ref::bytes(&self.hdr_prefix), self.options.bytes())
346 }
347
348 pub fn body(&self) -> &[u8] {
350 &self.body
351 }
352
353 pub fn header_len(&self) -> usize {
355 Ref::bytes(&self.hdr_prefix).len() + self.options.bytes().len()
356 }
357
358 pub fn src_ipv4(&self) -> Option<Ipv4SourceAddr> {
363 Ipv4SourceAddr::new(self.src_ip())
364 }
365
366 pub fn copy_header_bytes_for_fragment(&self) -> Vec<u8> {
372 let expected_bytes_len = self.header_len();
373 let mut bytes = Vec::with_capacity(expected_bytes_len);
374
375 bytes.extend_from_slice(Ref::bytes(&self.hdr_prefix));
376 bytes.extend_from_slice(self.options.bytes());
377
378 assert_eq!(bytes.len(), expected_bytes_len);
380
381 bytes[IPV4_FRAGMENT_DATA_BYTE_RANGE].copy_from_slice(&[0; 4][..]);
383
384 bytes
385 }
386
387 pub fn nat64_translate(
413 &self,
414 v6_src_addr: Ipv6Addr,
415 v6_dst_addr: Ipv6Addr,
416 ) -> Nat64TranslationResult<impl Serializer<Buffer = EmptyBuf> + Debug + '_, Nat64Error> {
417 #[derive(Debug)]
420 enum Nat64Serializer<T, U, O> {
421 Tcp(T),
422 Udp(U),
423 Other(O),
424 }
425
426 impl<T, U, O> Serializer for Nat64Serializer<T, U, O>
427 where
428 T: Serializer<Buffer = EmptyBuf>,
429 U: Serializer<Buffer = EmptyBuf>,
430 O: Serializer<Buffer = EmptyBuf>,
431 {
432 type Buffer = EmptyBuf;
433 fn serialize<B, P>(
434 self,
435 outer: PacketConstraints,
436 provider: P,
437 ) -> Result<B, (SerializeError<P::Error>, Self)>
438 where
439 B: GrowBufferMut,
440 P: BufferProvider<Self::Buffer, B>,
441 {
442 match self {
443 Nat64Serializer::Tcp(serializer) => serializer
444 .serialize(outer, provider)
445 .map_err(|(err, ser)| (err, Nat64Serializer::Tcp(ser))),
446 Nat64Serializer::Udp(serializer) => serializer
447 .serialize(outer, provider)
448 .map_err(|(err, ser)| (err, Nat64Serializer::Udp(ser))),
449 Nat64Serializer::Other(serializer) => serializer
450 .serialize(outer, provider)
451 .map_err(|(err, ser)| (err, Nat64Serializer::Other(ser))),
452 }
453 }
454
455 fn serialize_new_buf<B: ReusableBuffer, A: BufferAlloc<B>>(
456 &self,
457 outer: PacketConstraints,
458 alloc: A,
459 ) -> Result<B, SerializeError<A::Error>> {
460 match self {
461 Nat64Serializer::Tcp(serializer) => serializer.serialize_new_buf(outer, alloc),
462 Nat64Serializer::Udp(serializer) => serializer.serialize_new_buf(outer, alloc),
463 Nat64Serializer::Other(serializer) => {
464 serializer.serialize_new_buf(outer, alloc)
465 }
466 }
467 }
468 }
469
470 let v6_builder = |v6_proto| {
471 let mut builder =
472 Ipv6PacketBuilder::new(v6_src_addr, v6_dst_addr, self.ttl(), v6_proto);
473 builder.dscp_and_ecn(self.dscp_and_ecn());
474 builder.flowlabel(0);
475 builder
476 };
477
478 match self.proto() {
479 Ipv4Proto::Igmp => {
480 Nat64TranslationResult::Drop
482 }
483
484 Ipv4Proto::Proto(IpProto::Tcp) => {
485 let v6_pkt_builder = v6_builder(Ipv6Proto::Proto(IpProto::Tcp));
486 let args = TcpParseArgs::new(self.src_ip(), self.dst_ip());
487 match TcpSegment::parse(&mut self.body.as_bytes(), args) {
488 Ok(tcp) => {
489 let tcp_serializer =
493 Nat64Serializer::Tcp(tcp.into_serializer(v6_src_addr, v6_dst_addr));
494 Nat64TranslationResult::Forward(v6_pkt_builder.wrap_body(tcp_serializer))
495 }
496 Err(msg) => {
497 debug!("Parsing of TCP segment failed: {:?}", msg);
498
499 let common_serializer =
505 Nat64Serializer::Other(self.body().into_serializer());
506 Nat64TranslationResult::Forward(v6_pkt_builder.wrap_body(common_serializer))
507 }
508 }
509 }
510
511 Ipv4Proto::Proto(IpProto::Udp) => {
512 let v6_pkt_builder = v6_builder(Ipv6Proto::Proto(IpProto::Udp));
513 let args = UdpParseArgs::new(self.src_ip(), self.dst_ip());
514 match UdpPacket::parse(&mut self.body.as_bytes(), args) {
515 Ok(udp) => {
516 let udp_serializer =
520 Nat64Serializer::Udp(udp.into_serializer(v6_src_addr, v6_dst_addr));
521 Nat64TranslationResult::Forward(v6_pkt_builder.wrap_body(udp_serializer))
522 }
523 Err(msg) => {
524 debug!("Parsing of UDP packet failed: {:?}", msg);
525
526 let common_serializer =
532 Nat64Serializer::Other(self.body().into_serializer());
533 Nat64TranslationResult::Forward(v6_pkt_builder.wrap_body(common_serializer))
534 }
535 }
536 }
537
538 Ipv4Proto::Icmp => Nat64TranslationResult::Err(Nat64Error::NotImplemented),
539
540 Ipv4Proto::Other(val) => {
545 let v6_pkt_builder = v6_builder(Ipv6Proto::Other(val));
546 let common_serializer = Nat64Serializer::Other(self.body().into_serializer());
547 Nat64TranslationResult::Forward(v6_pkt_builder.wrap_body(common_serializer))
548 }
549
550 Ipv4Proto::Proto(IpProto::Reserved) => Nat64TranslationResult::Drop,
553 }
554 }
555
556 pub fn to_vec(&self) -> Vec<u8> {
558 let Ipv4Packet { hdr_prefix, options, body } = self;
559 let mut buf = Vec::with_capacity(
560 Ref::bytes(&hdr_prefix).len() + options.bytes().len() + body.as_bytes().len(),
561 );
562 buf.extend(Ref::bytes(&hdr_prefix));
563 buf.extend(options.bytes());
564 buf.extend(body.as_bytes());
565 buf
566 }
567}
568
569impl<B: SplitByteSliceMut> Ipv4Packet<B> {
570 pub fn set_src_ip_and_update_checksum(&mut self, addr: Ipv4Addr) {
574 let old_bytes = self.hdr_prefix.src_ip.bytes();
575 self.hdr_prefix.hdr_checksum =
576 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, addr.bytes());
577 self.hdr_prefix.src_ip = addr;
578 }
579
580 pub fn set_dst_ip_and_update_checksum(&mut self, addr: Ipv4Addr) {
584 let old_bytes = self.hdr_prefix.dst_ip.bytes();
585 self.hdr_prefix.hdr_checksum =
586 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, addr.bytes());
587 self.hdr_prefix.dst_ip = addr;
588 }
589
590 pub fn set_ttl(&mut self, ttl: u8) {
594 let old_bytes = [self.hdr_prefix.ttl, self.hdr_prefix.proto];
598 let new_bytes = [ttl, self.hdr_prefix.proto];
599 self.hdr_prefix.hdr_checksum =
600 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, &new_bytes);
601 self.hdr_prefix.ttl = ttl;
602 }
603
604 pub fn body_mut(&mut self) -> &mut [u8] {
606 &mut self.body
607 }
608
609 pub fn parts_with_body_mut(&mut self) -> (&HeaderPrefix, &Options<B>, &mut [u8]) {
612 (&self.hdr_prefix, &self.options, &mut self.body)
613 }
614}
615
616impl<B> Debug for Ipv4Packet<B>
617where
618 B: SplitByteSlice,
619{
620 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
621 f.debug_struct("Ipv4Packet")
622 .field("src_ip", &self.src_ip())
623 .field("dst_ip", &self.dst_ip())
624 .field("id", &self.id())
625 .field("ttl", &self.ttl())
626 .field("proto", &self.proto())
627 .field("frag_off", &self.fragment_offset())
628 .field("dscp", &self.dscp_and_ecn().dscp())
629 .field("ecn", &self.dscp_and_ecn().ecn())
630 .field("mf_flag", &self.mf_flag())
631 .field("df_flag", &self.df_flag())
632 .field("body", &alloc::format!("<{} bytes>", self.body.len()))
633 .finish()
634 }
635}
636
637pub struct Ipv4PacketRaw<B> {
647 hdr_prefix: Ref<B, HeaderPrefix>,
648 options: MaybeParsed<OptionsRaw<B, Ipv4OptionsImpl>, B>,
649 body: MaybeParsed<B, B>,
650}
651
652impl<B> Ipv4PacketRaw<B> {
653 pub fn body_mut(&mut self) -> &mut B {
657 match &mut self.body {
658 MaybeParsed::Complete(b) => b,
659 MaybeParsed::Incomplete(b) => b,
660 }
661 }
662}
663
664impl<B: SplitByteSlice> Ipv4Header for Ipv4PacketRaw<B> {
665 fn get_header_prefix(&self) -> &HeaderPrefix {
666 &self.hdr_prefix
667 }
668}
669
670impl<B: SplitByteSlice> ParsablePacket<B, ()> for Ipv4PacketRaw<B> {
671 type Error = IpParseError<Ipv4>;
672
673 fn parse_metadata(&self) -> ParseMetadata {
674 let header_len = Ref::bytes(&self.hdr_prefix).len() + self.options.len();
675 ParseMetadata::from_packet(header_len, self.body.len(), 0)
676 }
677
678 fn parse<BV: BufferView<B>>(mut buffer: BV, _args: ()) -> IpParseResult<Ipv4, Self> {
679 let hdr_prefix = buffer
680 .take_obj_front::<HeaderPrefix>()
681 .ok_or_else(debug_err_fn!(ParseError::Format, "too few bytes for header"))?;
682 let hdr_bytes = (hdr_prefix.ihl() * 4) as usize;
683
684 let options = MaybeParsed::take_from_buffer_with(
685 &mut buffer,
686 hdr_bytes.saturating_sub(HDR_PREFIX_LEN),
691 OptionsRaw::new,
692 );
693
694 let total_len: usize = hdr_prefix.total_len.get().into();
695 let body_len = total_len.saturating_sub(hdr_bytes);
696 if buffer.len() > body_len {
697 let _: B = buffer.take_back(buffer.len() - body_len).unwrap();
700 }
701
702 let body = MaybeParsed::new_with_min_len(buffer.into_rest(), body_len);
703
704 Ok(Self { hdr_prefix, options, body })
705 }
706}
707
708impl<B> Ipv4PacketRaw<B> {
709 pub fn options(&self) -> &MaybeParsed<OptionsRaw<B, Ipv4OptionsImpl>, B> {
711 &self.options
712 }
713}
714
715impl<B: SplitByteSlice> Ipv4PacketRaw<B> {
716 pub fn body(&self) -> MaybeParsed<&[u8], &[u8]> {
722 self.body.as_ref().map(|b| b.deref()).map_incomplete(|b| b.deref())
723 }
724
725 pub fn into_body(self) -> MaybeParsed<B, B> {
729 self.body
730 }
731}
732
733impl<B: SplitByteSliceMut> Ipv4PacketRaw<B> {
734 pub fn set_src_ip_and_update_checksum(&mut self, addr: Ipv4Addr) {
738 let old_bytes = self.hdr_prefix.src_ip.bytes();
739 self.hdr_prefix.hdr_checksum =
740 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, addr.bytes());
741 self.hdr_prefix.src_ip = addr;
742 }
743
744 pub fn set_dst_ip_and_update_checksum(&mut self, addr: Ipv4Addr) {
748 let old_bytes = self.hdr_prefix.dst_ip.bytes();
749 self.hdr_prefix.hdr_checksum =
750 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, addr.bytes());
751 self.hdr_prefix.dst_ip = addr;
752 }
753}
754
755pub type Options<B> = packet::records::options::Options<B, Ipv4OptionsImpl>;
761
762#[derive(Debug)]
765pub struct Ipv4OptionsTooLongError;
766
767#[derive(Debug, Clone)]
769pub struct Ipv4PacketBuilderWithOptions<'a, I> {
770 prefix_builder: Ipv4PacketBuilder,
771 options: OptionSequenceBuilder<Ipv4Option<'a>, I>,
772}
773
774impl<'a, I> Ipv4PacketBuilderWithOptions<'a, I>
775where
776 I: Iterator + Clone,
777 I::Item: Borrow<Ipv4Option<'a>>,
778{
779 pub fn new<T: IntoIterator<IntoIter = I>>(
785 prefix_builder: Ipv4PacketBuilder,
786 options: T,
787 ) -> Result<Ipv4PacketBuilderWithOptions<'a, I>, Ipv4OptionsTooLongError> {
788 let options = OptionSequenceBuilder::new(options.into_iter());
789 if options.serialized_len() > MAX_OPTIONS_LEN {
790 return Err(Ipv4OptionsTooLongError);
791 }
792 Ok(Ipv4PacketBuilderWithOptions { prefix_builder, options })
793 }
794
795 fn aligned_options_len(&self) -> usize {
796 crate::utils::round_to_next_multiple_of_four(self.options.serialized_len())
798 }
799
800 pub fn prefix_builder(&self) -> &Ipv4PacketBuilder {
802 &self.prefix_builder
803 }
804
805 pub fn prefix_builder_mut(&mut self) -> &mut Ipv4PacketBuilder {
807 &mut self.prefix_builder
808 }
809
810 pub fn options(&self) -> &I {
812 self.options.records()
813 }
814
815 pub fn with_fragment_options(
821 self,
822 first_fragment: bool,
823 ) -> Ipv4PacketBuilderWithOptions<'a, impl Iterator<Item: Borrow<Ipv4Option<'a>>> + Clone> {
824 let Self { prefix_builder, options } = self;
825 Ipv4PacketBuilderWithOptions {
826 prefix_builder,
827 options: OptionSequenceBuilder::new(
830 options
831 .records()
832 .clone()
833 .filter(move |opt| first_fragment || opt.borrow().copied()),
834 ),
835 }
836 }
837}
838
839impl<'a, B> Ipv4PacketBuilderWithOptions<'a, RecordsIter<'a, B, Ipv4OptionsImpl>> {
840 pub fn new_with_records_iter(
843 prefix_builder: Ipv4PacketBuilder,
844 iter: RecordsIter<'a, B, Ipv4OptionsImpl>,
845 ) -> Self {
846 Self { prefix_builder, options: OptionSequenceBuilder::new(iter) }
847 }
848}
849
850impl<'a, I> PacketBuilder for Ipv4PacketBuilderWithOptions<'a, I>
851where
852 I: Iterator + Clone,
853 I::Item: Borrow<Ipv4Option<'a>>,
854{
855 fn constraints(&self) -> PacketConstraints {
856 let header_len = IPV4_MIN_HDR_LEN + self.aligned_options_len();
857 assert_eq!(header_len % 4, 0);
858 PacketConstraints::new(header_len, 0, 0, (1 << 16) - 1 - header_len)
859 }
860
861 fn serialize(&self, target: &mut SerializeTarget<'_>, body: FragmentedBytesMut<'_, '_>) {
862 let opt_len = self.aligned_options_len();
863 let mut header = &mut &mut target.header[..];
869 let opts = header.take_back_zero(opt_len).expect("too few bytes for Ipv4 options");
870 let Ipv4PacketBuilderWithOptions { prefix_builder, options } = self;
871 options.serialize_into(opts);
872 prefix_builder.serialize(target, body);
873 }
874}
875
876impl<'a, I> PartialPacketBuilder for Ipv4PacketBuilderWithOptions<'a, I>
877where
878 I: Iterator + Clone,
879 I::Item: Borrow<Ipv4Option<'a>>,
880{
881 fn partial_serialize(&self, body_len: usize, header: &mut [u8]) {
882 let Ipv4PacketBuilderWithOptions { prefix_builder, options } = self;
883 prefix_builder.partial_serialize(body_len, header);
884 let options_slice = &mut header[IPV4_MIN_HDR_LEN..];
885 assert_eq!(options_slice.len(), self.aligned_options_len());
886 options.serialize_into(options_slice);
887 }
888}
889
890impl<'a, I> IpPacketBuilder<Ipv4> for Ipv4PacketBuilderWithOptions<'a, I>
891where
892 I: Default + Debug + Clone + Iterator<Item: Borrow<Ipv4Option<'a>>>,
893{
894 fn new(src_ip: Ipv4Addr, dst_ip: Ipv4Addr, ttl: u8, proto: Ipv4Proto) -> Self {
895 Ipv4PacketBuilderWithOptions::new(
896 Ipv4PacketBuilder::new(src_ip, dst_ip, ttl, proto),
897 I::default(),
898 )
899 .expect("packet builder with no options should be valid")
900 }
901
902 fn src_ip(&self) -> Ipv4Addr {
903 self.prefix_builder.src_ip
904 }
905
906 fn set_src_ip(&mut self, addr: Ipv4Addr) {
907 self.prefix_builder.set_src_ip(addr);
908 }
909
910 fn dst_ip(&self) -> Ipv4Addr {
911 self.prefix_builder.dst_ip
912 }
913
914 fn set_dst_ip(&mut self, addr: Ipv4Addr) {
915 self.prefix_builder.set_dst_ip(addr);
916 }
917
918 fn proto(&self) -> Ipv4Proto {
919 self.prefix_builder.proto
920 }
921
922 fn set_dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
923 self.prefix_builder.set_dscp_and_ecn(dscp_and_ecn)
924 }
925}
926
927#[derive(Debug, Clone, Eq, PartialEq)]
929pub struct Ipv4PacketBuilder {
930 id: u16,
931 dscp_and_ecn: DscpAndEcn,
932 flags: u8,
933 frag_off: u16,
934 ttl: u8,
935 proto: Ipv4Proto,
936 src_ip: Ipv4Addr,
937 dst_ip: Ipv4Addr,
938}
939
940impl Ipv4PacketBuilder {
941 pub fn new<S: Into<Ipv4Addr>, D: Into<Ipv4Addr>>(
943 src_ip: S,
944 dst_ip: D,
945 ttl: u8,
946 proto: Ipv4Proto,
947 ) -> Ipv4PacketBuilder {
948 Ipv4PacketBuilder {
949 id: 0,
950 dscp_and_ecn: DscpAndEcn::default(),
951 flags: 0,
952 frag_off: 0,
953 ttl,
954 proto: proto,
955 src_ip: src_ip.into(),
956 dst_ip: dst_ip.into(),
957 }
958 }
959
960 pub fn dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
962 self.dscp_and_ecn = dscp_and_ecn;
963 }
964
965 pub fn id(&mut self, id: u16) {
967 self.id = id
968 }
969
970 pub fn df_flag(&mut self, df: bool) {
972 if df {
973 self.flags |= 1 << DF_FLAG_OFFSET;
974 } else {
975 self.flags &= !(1 << DF_FLAG_OFFSET);
976 }
977 }
978
979 pub fn mf_flag(&mut self, mf: bool) {
981 if mf {
982 self.flags |= 1 << MF_FLAG_OFFSET;
983 } else {
984 self.flags &= !(1 << MF_FLAG_OFFSET);
985 }
986 }
987
988 pub fn fragment_offset(&mut self, fragment_offset: FragmentOffset) {
990 self.frag_off = fragment_offset.into_raw();
991 }
992
993 pub fn read_df_flag(&self) -> bool {
995 (self.flags & (1 << DF_FLAG_OFFSET)) != 0
996 }
997
998 fn get_header_prefix(&self, header_len: usize, total_len: usize) -> HeaderPrefix {
999 assert_eq!(header_len % 4, 0);
1000 let ihl: u8 = u8::try_from(header_len / 4).expect("Header too large");
1001
1002 let id = if ((self.flags & (1 << DF_FLAG_OFFSET)) == 0)
1012 || ((self.flags & (1 << MF_FLAG_OFFSET)) == 1)
1013 || (self.frag_off > 0)
1014 {
1015 self.id
1016 } else {
1017 0
1018 };
1019
1020 HeaderPrefix::new(
1021 ihl,
1022 self.dscp_and_ecn,
1023 {
1024 debug_assert!(total_len <= core::u16::MAX as usize);
1030 total_len as u16
1031 },
1032 id,
1033 self.flags,
1034 self.frag_off,
1035 self.ttl,
1036 self.proto.into(),
1037 [0, 0], self.src_ip,
1039 self.dst_ip,
1040 )
1041 }
1042}
1043
1044impl PacketBuilder for Ipv4PacketBuilder {
1045 fn constraints(&self) -> PacketConstraints {
1046 PacketConstraints::new(IPV4_MIN_HDR_LEN, 0, 0, (1 << 16) - 1 - IPV4_MIN_HDR_LEN)
1047 }
1048
1049 fn serialize(&self, target: &mut SerializeTarget<'_>, body: FragmentedBytesMut<'_, '_>) {
1050 let header_len = target.header.len();
1051 let total_len = header_len + body.len();
1052 let mut hdr_prefix = self.get_header_prefix(header_len, total_len);
1053 let options = &target.header[HDR_PREFIX_LEN..];
1054 let checksum = compute_header_checksum(hdr_prefix.as_bytes(), options);
1055 hdr_prefix.hdr_checksum = checksum;
1056 let mut header = &mut target.header;
1057 header.write_obj_front(&hdr_prefix).expect("too few bytes for IPv4 header prefix");
1058 }
1059}
1060
1061impl PartialPacketBuilder for Ipv4PacketBuilder {
1062 fn partial_serialize(&self, body_len: usize, mut header: &mut [u8]) {
1063 let total_len = header.len() + body_len;
1064 let hdr_prefix = self.get_header_prefix(header.len(), total_len);
1065 (&mut header).write_obj_front(&hdr_prefix).expect("too few bytes for IPv4 header prefix");
1066 }
1067}
1068
1069impl IpPacketBuilder<Ipv4> for Ipv4PacketBuilder {
1070 fn new(src_ip: Ipv4Addr, dst_ip: Ipv4Addr, ttl: u8, proto: Ipv4Proto) -> Self {
1071 Ipv4PacketBuilder::new(src_ip, dst_ip, ttl, proto)
1072 }
1073
1074 fn src_ip(&self) -> Ipv4Addr {
1075 self.src_ip
1076 }
1077
1078 fn set_src_ip(&mut self, addr: Ipv4Addr) {
1079 self.src_ip = addr;
1080 }
1081
1082 fn dst_ip(&self) -> Ipv4Addr {
1083 self.dst_ip
1084 }
1085
1086 fn set_dst_ip(&mut self, addr: Ipv4Addr) {
1087 self.dst_ip = addr;
1088 }
1089
1090 fn proto(&self) -> Ipv4Proto {
1091 self.proto
1092 }
1093
1094 fn set_dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
1095 self.dscp_and_ecn = dscp_and_ecn;
1096 }
1097}
1098
1099const DF_FLAG_OFFSET: u8 = 1;
1101const MF_FLAG_OFFSET: u8 = 0;
1102
1103pub(crate) fn reassemble_fragmented_packet<
1105 B: SplitByteSliceMut,
1106 BV: BufferViewMut<B>,
1107 I: Iterator<Item = Vec<u8>>,
1108>(
1109 mut buffer: BV,
1110 header: Vec<u8>,
1111 body_fragments: I,
1112) -> IpParseResult<Ipv4, ()> {
1113 let bytes = buffer.as_mut();
1114
1115 bytes[0..header.len()].copy_from_slice(&header[..]);
1117 let mut byte_count = header.len();
1118
1119 for p in body_fragments {
1121 bytes[byte_count..byte_count + p.len()].copy_from_slice(&p[..]);
1122 byte_count += p.len();
1123 }
1124
1125 if byte_count > usize::from(core::u16::MAX) {
1130 return debug_err!(
1131 Err(ParseError::Format.into()),
1132 "fragmented packet length of {} bytes is too large",
1133 byte_count
1134 );
1135 }
1136
1137 let mut header = Ref::<_, HeaderPrefix>::from_prefix(bytes).unwrap().0;
1140
1141 header.total_len.set(u16::try_from(byte_count).unwrap());
1143
1144 header.flags_frag_off = [0; 2];
1147
1148 header.hdr_checksum = [0; 2];
1150 header.hdr_checksum = compute_header_checksum(header.as_bytes(), &[]);
1151
1152 Ok(())
1153}
1154
1155pub mod options {
1157 use byteorder::{ByteOrder, NetworkEndian};
1158 use packet::records::options::{
1159 OptionBuilder, OptionLayout, OptionParseErr, OptionParseLayout, OptionsImpl,
1160 };
1161 use packet::BufferViewMut;
1162 use zerocopy::byteorder::network_endian::U16;
1163
1164 const OPTION_KIND_EOL: u8 = 0;
1165 const OPTION_KIND_NOP: u8 = 1;
1166 const OPTION_KIND_RTRALRT: u8 = 148;
1167
1168 const OPTION_RTRALRT_LEN: usize = 2;
1169
1170 #[derive(PartialEq, Eq, Debug, Clone)]
1177 #[allow(missing_docs)]
1178 pub enum Ipv4Option<'a> {
1179 RouterAlert { data: u16 },
1185
1186 Unrecognized { kind: u8, data: &'a [u8] },
1198 }
1199
1200 impl<'a> Ipv4Option<'a> {
1201 pub fn copied(&self) -> bool {
1203 match self {
1204 Ipv4Option::RouterAlert { .. } => true,
1208 Ipv4Option::Unrecognized { kind, .. } => *kind & (1 << 7) != 0,
1209 }
1210 }
1211 }
1212
1213 #[derive(Debug, Clone)]
1215 pub struct Ipv4OptionsImpl;
1216
1217 impl OptionLayout for Ipv4OptionsImpl {
1218 type KindLenField = u8;
1219 }
1220
1221 impl OptionParseLayout for Ipv4OptionsImpl {
1222 type Error = OptionParseErr;
1223 const END_OF_OPTIONS: Option<u8> = Some(0);
1224 const NOP: Option<u8> = Some(1);
1225 }
1226
1227 impl OptionsImpl for Ipv4OptionsImpl {
1228 type Option<'a> = Ipv4Option<'a>;
1229
1230 fn parse<'a>(kind: u8, data: &'a [u8]) -> Result<Option<Ipv4Option<'a>>, OptionParseErr> {
1231 match kind {
1232 self::OPTION_KIND_EOL | self::OPTION_KIND_NOP => {
1233 unreachable!("records::options::Options promises to handle EOL and NOP")
1234 }
1235 self::OPTION_KIND_RTRALRT => {
1236 if data.len() == OPTION_RTRALRT_LEN {
1237 Ok(Some(Ipv4Option::RouterAlert { data: NetworkEndian::read_u16(data) }))
1238 } else {
1239 Err(OptionParseErr)
1240 }
1241 }
1242 kind => {
1243 if data.len() > 38 {
1244 Err(OptionParseErr)
1245 } else {
1246 Ok(Some(Ipv4Option::Unrecognized { kind, data }))
1247 }
1248 }
1249 }
1250 }
1251 }
1252
1253 impl<'a> OptionBuilder for Ipv4Option<'a> {
1254 type Layout = Ipv4OptionsImpl;
1255
1256 fn serialized_len(&self) -> usize {
1257 match self {
1258 Ipv4Option::RouterAlert { .. } => OPTION_RTRALRT_LEN,
1259 Ipv4Option::Unrecognized { data, .. } => data.len(),
1260 }
1261 }
1262
1263 fn option_kind(&self) -> u8 {
1264 match self {
1265 Ipv4Option::RouterAlert { .. } => OPTION_KIND_RTRALRT,
1266 Ipv4Option::Unrecognized { kind, .. } => *kind,
1267 }
1268 }
1269
1270 fn serialize_into(&self, mut buffer: &mut [u8]) {
1271 match self {
1272 Ipv4Option::Unrecognized { data, .. } => buffer.copy_from_slice(data),
1273 Ipv4Option::RouterAlert { data } => {
1274 (&mut buffer).write_obj_front(&U16::new(*data)).unwrap()
1275 }
1276 };
1277 }
1278 }
1279
1280 #[cfg(test)]
1281 mod test {
1282 use packet::records::options::Options;
1283 use packet::records::RecordBuilder;
1284
1285 use super::*;
1286
1287 #[test]
1288 fn test_serialize_router_alert() {
1289 let mut buffer = [0u8; 4];
1290 let option = Ipv4Option::RouterAlert { data: 0 };
1291 <Ipv4Option<'_> as RecordBuilder>::serialize_into(&option, &mut buffer);
1292 assert_eq!(buffer[0], 148);
1293 assert_eq!(buffer[1], 4);
1294 assert_eq!(buffer[2], 0);
1295 assert_eq!(buffer[3], 0);
1296 }
1297
1298 #[test]
1299 fn test_parse_router_alert() {
1300 let mut buffer: Vec<u8> = vec![148, 4, 0, 0];
1301 let options = Options::<_, Ipv4OptionsImpl>::parse(buffer.as_mut()).unwrap();
1302 let rtralt = options.iter().next().unwrap();
1303 assert_eq!(rtralt, Ipv4Option::RouterAlert { data: 0 });
1304 }
1305 }
1306}
1307
1308mod inner {
1309 pub const IPV4_MIN_HDR_LEN: usize = super::HDR_PREFIX_LEN;
1311}
1312
1313pub mod testutil {
1315 pub use super::inner::IPV4_MIN_HDR_LEN;
1316
1317 pub const IPV4_TTL_OFFSET: usize = 8;
1319
1320 pub const IPV4_CHECKSUM_OFFSET: usize = 10;
1322}
1323
1324#[cfg(test)]
1325mod tests {
1326 use net_types::ethernet::Mac;
1327 use packet::{Buf, FragmentedBuffer, ParseBuffer};
1328
1329 use super::*;
1330 use crate::ethernet::{
1331 EtherType, EthernetFrame, EthernetFrameBuilder, EthernetFrameLengthCheck,
1332 ETHERNET_MIN_BODY_LEN_NO_TAG,
1333 };
1334 use crate::testutil::*;
1335
1336 const DEFAULT_SRC_MAC: Mac = Mac::new([1, 2, 3, 4, 5, 6]);
1337 const DEFAULT_DST_MAC: Mac = Mac::new([7, 8, 9, 0, 1, 2]);
1338 const DEFAULT_SRC_IP: Ipv4Addr = Ipv4Addr::new([1, 2, 3, 4]);
1339 const DEFAULT_DST_IP: Ipv4Addr = Ipv4Addr::new([5, 6, 7, 8]);
1340 const DEFAULT_V6_SRC_IP: Ipv6Addr = Ipv6Addr::new([0x2001, 0x0db8, 0, 0, 0, 0, 0, 1]);
1342 const DEFAULT_V6_DST_IP: Ipv6Addr = Ipv6Addr::new([0x2001, 0x0db8, 0, 0, 0, 0, 0, 2]);
1344
1345 #[test]
1346 fn test_parse_serialize_full_tcp() {
1347 use crate::testdata::tls_client_hello_v4::*;
1348
1349 let mut buf = ETHERNET_FRAME.bytes;
1350 let frame = buf.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1351 verify_ethernet_frame(&frame, ETHERNET_FRAME);
1352
1353 let mut body = frame.body();
1354 let packet = body.parse::<Ipv4Packet<_>>().unwrap();
1355 verify_ipv4_packet(&packet, IPV4_PACKET);
1356
1357 let buffer = packet
1359 .body()
1360 .into_serializer()
1361 .wrap_in(packet.builder())
1362 .wrap_in(frame.builder())
1363 .serialize_vec_outer()
1364 .unwrap();
1365 assert_eq!(buffer.as_ref(), ETHERNET_FRAME.bytes);
1366
1367 assert_eq!(&packet.to_vec()[..], IPV4_PACKET.bytes);
1369 }
1370
1371 #[test]
1372 fn test_parse_serialize_full_udp() {
1373 use crate::testdata::dns_request_v4::*;
1374
1375 let mut buf = ETHERNET_FRAME.bytes;
1376 let frame = buf.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1377 verify_ethernet_frame(&frame, ETHERNET_FRAME);
1378
1379 let mut body = frame.body();
1380 let packet = body.parse::<Ipv4Packet<_>>().unwrap();
1381 verify_ipv4_packet(&packet, IPV4_PACKET);
1382
1383 let buffer = packet
1385 .body()
1386 .into_serializer()
1387 .wrap_in(packet.builder())
1388 .wrap_in(frame.builder())
1389 .serialize_vec_outer()
1390 .unwrap();
1391 assert_eq!(buffer.as_ref(), ETHERNET_FRAME.bytes);
1392
1393 assert_eq!(&packet.to_vec()[..], IPV4_PACKET.bytes);
1395 }
1396
1397 #[test]
1398 fn test_parse_serialize_with_options() {
1399 use crate::testdata::igmpv2_membership::report::*;
1402
1403 let mut buf = IP_PACKET_BYTES;
1404 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1405 assert_eq!(packet.iter_options().count(), 1);
1406
1407 assert_eq!(&packet.to_vec()[..], IP_PACKET_BYTES);
1412 }
1413
1414 fn hdr_prefix_to_bytes(hdr_prefix: HeaderPrefix) -> [u8; 20] {
1415 zerocopy::transmute!(hdr_prefix)
1416 }
1417
1418 fn new_hdr_prefix() -> HeaderPrefix {
1421 HeaderPrefix::new(
1422 5,
1423 DscpAndEcn::default(),
1424 20,
1425 0x0102,
1426 0,
1427 0,
1428 0x03,
1429 IpProto::Tcp.into(),
1430 [0xa6, 0xcf],
1431 DEFAULT_SRC_IP,
1432 DEFAULT_DST_IP,
1433 )
1434 }
1435
1436 #[test]
1437 fn test_parse() {
1438 let mut bytes = &hdr_prefix_to_bytes(new_hdr_prefix())[..];
1439 let packet = bytes.parse::<Ipv4Packet<_>>().unwrap();
1440 assert_eq!(packet.id(), 0x0102);
1441 assert_eq!(packet.ttl(), 0x03);
1442 assert_eq!(packet.proto(), IpProto::Tcp.into());
1443 assert_eq!(packet.src_ip(), DEFAULT_SRC_IP);
1444 assert_eq!(packet.dst_ip(), DEFAULT_DST_IP);
1445 assert_eq!(packet.body(), []);
1446 }
1447
1448 #[test]
1449 fn test_parse_padding() {
1450 let mut buffer = Buf::new(Vec::new(), ..)
1452 .wrap_in(Ipv4PacketBuilder::new(DEFAULT_DST_IP, DEFAULT_DST_IP, 0, IpProto::Tcp.into()))
1453 .wrap_in(EthernetFrameBuilder::new(
1454 DEFAULT_SRC_MAC,
1455 DEFAULT_DST_MAC,
1456 EtherType::Ipv4,
1457 ETHERNET_MIN_BODY_LEN_NO_TAG,
1458 ))
1459 .serialize_vec_outer()
1460 .unwrap();
1461 let _: EthernetFrame<_> =
1462 buffer.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1463 assert_eq!(buffer.len(), 46);
1466 let packet = buffer.parse::<Ipv4Packet<_>>().unwrap();
1467 assert_eq!(packet.body().len(), 0);
1470 assert_eq!(buffer.len(), 0);
1474 }
1475
1476 #[test]
1477 fn test_parse_error() {
1478 let mut hdr_prefix = new_hdr_prefix();
1480 hdr_prefix.version_ihl = (5 << 4) | 5;
1481 assert_eq!(
1482 (&hdr_prefix_to_bytes(hdr_prefix)[..]).parse::<Ipv4Packet<_>>().unwrap_err(),
1483 ParseError::Format.into()
1484 );
1485
1486 let mut hdr_prefix = new_hdr_prefix();
1489 hdr_prefix.version_ihl = (4 << 4) | 4;
1490 assert_eq!(
1491 (&hdr_prefix_to_bytes(hdr_prefix)[..]).parse::<Ipv4Packet<_>>().unwrap_err(),
1492 ParseError::Format.into()
1493 );
1494
1495 let mut hdr_prefix = new_hdr_prefix();
1498 hdr_prefix.version_ihl = (4 << 4) | 6;
1499 assert_eq!(
1500 (&hdr_prefix_to_bytes(hdr_prefix)[..]).parse::<Ipv4Packet<_>>().unwrap_err(),
1501 ParseError::Format.into()
1502 );
1503 }
1504
1505 fn new_builder() -> Ipv4PacketBuilder {
1507 Ipv4PacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, 64, IpProto::Tcp.into())
1508 }
1509
1510 #[test]
1511 fn test_fragment_type() {
1512 fn test_fragment_type_helper(fragment_offset: u16, expect_fragment_type: Ipv4FragmentType) {
1513 let mut builder = new_builder();
1514 builder.fragment_offset(FragmentOffset::new(fragment_offset).unwrap());
1515
1516 let mut buf = [0; IPV4_MIN_HDR_LEN]
1517 .into_serializer()
1518 .wrap_in(builder)
1519 .serialize_vec_outer()
1520 .unwrap();
1521
1522 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1523 assert_eq!(packet.fragment_type(), expect_fragment_type);
1524 }
1525
1526 test_fragment_type_helper(0x0000, Ipv4FragmentType::InitialFragment);
1527 test_fragment_type_helper(0x0008, Ipv4FragmentType::NonInitialFragment);
1528 }
1529
1530 #[test]
1531 fn test_serialize() {
1532 let mut builder = new_builder();
1533 builder.dscp_and_ecn(DscpAndEcn::new(0x12, 3));
1534 builder.id(0x0405);
1535 builder.df_flag(true);
1536 builder.mf_flag(true);
1537 builder.fragment_offset(FragmentOffset::new(0x0607).unwrap());
1538
1539 let mut buf = (&[0, 1, 2, 3, 3, 4, 5, 7, 8, 9])
1540 .into_serializer()
1541 .wrap_in(builder)
1542 .serialize_vec_outer()
1543 .unwrap();
1544 assert_eq!(
1545 buf.as_ref(),
1546 [
1547 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,
1548 4, 5, 7, 8, 9
1549 ]
1550 );
1551 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1552 assert_eq!(packet.dscp_and_ecn().dscp(), 0x12);
1553 assert_eq!(packet.dscp_and_ecn().ecn(), 3);
1554 assert_eq!(packet.id(), 0x0405);
1555 assert!(packet.df_flag());
1556 assert!(packet.mf_flag());
1557 assert_eq!(packet.fragment_offset().into_raw(), 0x0607);
1558 assert_eq!(packet.fragment_type(), Ipv4FragmentType::NonInitialFragment);
1559 }
1560
1561 #[test]
1562 fn test_serialize_id_unset() {
1563 let mut builder = new_builder();
1564 builder.id(0x0405);
1565 builder.df_flag(true);
1566
1567 let mut buf = (&[0, 1, 2, 3, 3, 4, 5, 7, 8, 9])
1568 .into_serializer()
1569 .wrap_in(builder)
1570 .serialize_vec_outer()
1571 .unwrap();
1572 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1573 assert_eq!(packet.id(), 0);
1574 assert!(packet.df_flag());
1575 assert_eq!(packet.mf_flag(), false);
1576 assert_eq!(packet.fragment_offset().into_raw(), 0);
1577 assert_eq!(packet.fragment_type(), Ipv4FragmentType::InitialFragment);
1578 }
1579
1580 #[test]
1581 fn test_serialize_zeroes() {
1582 let mut buf_0 = [0; IPV4_MIN_HDR_LEN];
1585 let _: Buf<&mut [u8]> = Buf::new(&mut buf_0[..], IPV4_MIN_HDR_LEN..)
1586 .wrap_in(new_builder())
1587 .serialize_vec_outer()
1588 .unwrap()
1589 .unwrap_a();
1590 let mut buf_1 = [0xFF; IPV4_MIN_HDR_LEN];
1591 let _: Buf<&mut [u8]> = Buf::new(&mut buf_1[..], IPV4_MIN_HDR_LEN..)
1592 .wrap_in(new_builder())
1593 .serialize_vec_outer()
1594 .unwrap()
1595 .unwrap_a();
1596 assert_eq!(buf_0, buf_1);
1597 }
1598
1599 #[test]
1600 #[should_panic(expected = "(SizeLimitExceeded, Nested { inner: Buf { buf:")]
1601 fn test_serialize_panic_packet_length() {
1602 let _: Buf<&mut [u8]> = Buf::new(&mut [0; (1 << 16) - IPV4_MIN_HDR_LEN][..], ..)
1604 .wrap_in(new_builder())
1605 .serialize_vec_outer()
1606 .unwrap()
1607 .unwrap_a();
1608 }
1609
1610 #[test]
1611 fn test_copy_header_bytes_for_fragment() {
1612 let hdr_prefix = new_hdr_prefix();
1613 let mut bytes = hdr_prefix_to_bytes(hdr_prefix);
1614 let mut buf = &bytes[..];
1615 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1616 let copied_bytes = packet.copy_header_bytes_for_fragment();
1617 bytes[IPV4_FRAGMENT_DATA_BYTE_RANGE].copy_from_slice(&[0; 4][..]);
1618 assert_eq!(&copied_bytes[..], &bytes[..]);
1619 }
1620
1621 #[test]
1622 fn test_partial_parsing() {
1623 use core::ops::Deref as _;
1624
1625 let mut hdr_prefix = new_hdr_prefix();
1628 hdr_prefix.total_len = U16::new(256);
1629 let mut bytes = hdr_prefix_to_bytes(hdr_prefix)[..].to_owned();
1630 const PAYLOAD: &[u8] = &[1, 2, 3, 4, 5];
1631 bytes.extend(PAYLOAD);
1632 let mut buf = &bytes[..];
1633 let packet = buf.parse::<Ipv4PacketRaw<_>>().unwrap();
1634 let Ipv4PacketRaw { hdr_prefix, options, body } = &packet;
1635 assert_eq!(Ref::bytes(&hdr_prefix), &bytes[0..20]);
1636 assert_eq!(options.as_ref().complete().unwrap().deref(), []);
1637 assert_eq!(body, &MaybeParsed::Incomplete(PAYLOAD));
1639 assert!(Ipv4Packet::try_from_raw(packet).is_err());
1641
1642 let mut hdr_prefix = new_hdr_prefix();
1644 hdr_prefix.version_ihl = (4 << 4) | 10;
1645 let bytes = hdr_prefix_to_bytes(hdr_prefix);
1646 let mut buf = &bytes[..];
1647 let packet = buf.parse::<Ipv4PacketRaw<_>>().unwrap();
1648 let Ipv4PacketRaw { hdr_prefix, options, body } = &packet;
1649 assert_eq!(Ref::bytes(&hdr_prefix), bytes);
1650 assert_eq!(options.as_ref().incomplete().unwrap(), &[]);
1651 assert_eq!(body.complete().unwrap(), []);
1652 assert!(Ipv4Packet::try_from_raw(packet).is_err());
1654
1655 let hdr_prefix = new_hdr_prefix();
1657 let bytes = &hdr_prefix_to_bytes(hdr_prefix);
1658 let mut buf = &bytes[0..10];
1659 assert!(buf.parse::<Ipv4PacketRaw<_>>().is_err());
1660 }
1661
1662 fn create_ipv4_and_ipv6_builders(
1663 proto_v4: Ipv4Proto,
1664 proto_v6: Ipv6Proto,
1665 ) -> (Ipv4PacketBuilder, Ipv6PacketBuilder) {
1666 const IP_DSCP_AND_ECN: DscpAndEcn = DscpAndEcn::new(0x12, 3);
1667 const IP_TTL: u8 = 64;
1668
1669 let mut ipv4_builder =
1670 Ipv4PacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, IP_TTL, proto_v4);
1671 ipv4_builder.dscp_and_ecn(IP_DSCP_AND_ECN);
1672 ipv4_builder.id(0x0405);
1673 ipv4_builder.df_flag(true);
1674 ipv4_builder.mf_flag(false);
1675 ipv4_builder.fragment_offset(FragmentOffset::ZERO);
1676
1677 let mut ipv6_builder =
1678 Ipv6PacketBuilder::new(DEFAULT_V6_SRC_IP, DEFAULT_V6_DST_IP, IP_TTL, proto_v6);
1679 ipv6_builder.dscp_and_ecn(IP_DSCP_AND_ECN);
1680 ipv6_builder.flowlabel(0);
1681
1682 (ipv4_builder, ipv6_builder)
1683 }
1684
1685 fn create_tcp_ipv4_and_ipv6_pkt(
1686 ) -> (packet::Either<EmptyBuf, Buf<Vec<u8>>>, packet::Either<EmptyBuf, Buf<Vec<u8>>>) {
1687 use crate::tcp::TcpSegmentBuilder;
1688 use core::num::NonZeroU16;
1689
1690 let tcp_src_port: NonZeroU16 = NonZeroU16::new(20).unwrap();
1691 let tcp_dst_port: NonZeroU16 = NonZeroU16::new(30).unwrap();
1692 const TCP_SEQ_NUM: u32 = 4321;
1693 const TCP_ACK_NUM: Option<u32> = Some(1234);
1694 const TCP_WINDOW_SIZE: u16 = 12345;
1695 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
1696
1697 let (ipv4_builder, ipv6_builder) =
1698 create_ipv4_and_ipv6_builders(IpProto::Tcp.into(), IpProto::Tcp.into());
1699
1700 let tcp_builder = TcpSegmentBuilder::new(
1701 DEFAULT_SRC_IP,
1702 DEFAULT_DST_IP,
1703 tcp_src_port,
1704 tcp_dst_port,
1705 TCP_SEQ_NUM,
1706 TCP_ACK_NUM,
1707 TCP_WINDOW_SIZE,
1708 );
1709
1710 let v4_pkt_buf = (&PAYLOAD)
1711 .into_serializer()
1712 .wrap_in(tcp_builder)
1713 .wrap_in(ipv4_builder)
1714 .serialize_vec_outer()
1715 .unwrap();
1716
1717 let v6_tcp_builder = TcpSegmentBuilder::new(
1718 DEFAULT_V6_SRC_IP,
1719 DEFAULT_V6_DST_IP,
1720 tcp_src_port,
1721 tcp_dst_port,
1722 TCP_SEQ_NUM,
1723 TCP_ACK_NUM,
1724 TCP_WINDOW_SIZE,
1725 );
1726
1727 let v6_pkt_buf = (&PAYLOAD)
1728 .into_serializer()
1729 .wrap_in(v6_tcp_builder)
1730 .wrap_in(ipv6_builder)
1731 .serialize_vec_outer()
1732 .unwrap();
1733
1734 (v4_pkt_buf, v6_pkt_buf)
1735 }
1736
1737 #[test]
1738 fn test_nat64_translate_tcp() {
1739 let (mut v4_pkt_buf, expected_v6_pkt_buf) = create_tcp_ipv4_and_ipv6_pkt();
1740
1741 let parsed_v4_packet = v4_pkt_buf.parse::<Ipv4Packet<_>>().unwrap();
1742 let nat64_translation_result =
1743 parsed_v4_packet.nat64_translate(DEFAULT_V6_SRC_IP, DEFAULT_V6_DST_IP);
1744
1745 let serializable_pkt = match nat64_translation_result {
1746 Nat64TranslationResult::Forward(s) => s,
1747 _ => panic!("Nat64TranslationResult not of Forward type!"),
1748 };
1749
1750 let translated_v6_pkt_buf = serializable_pkt.serialize_vec_outer().unwrap();
1751
1752 assert_eq!(
1753 expected_v6_pkt_buf.to_flattened_vec(),
1754 translated_v6_pkt_buf.to_flattened_vec()
1755 );
1756 }
1757
1758 fn create_udp_ipv4_and_ipv6_pkt(
1759 ) -> (packet::Either<EmptyBuf, Buf<Vec<u8>>>, packet::Either<EmptyBuf, Buf<Vec<u8>>>) {
1760 use crate::udp::UdpPacketBuilder;
1761 use core::num::NonZeroU16;
1762
1763 let udp_src_port: NonZeroU16 = NonZeroU16::new(35000).unwrap();
1764 let udp_dst_port: NonZeroU16 = NonZeroU16::new(53).unwrap();
1765 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
1766
1767 let (ipv4_builder, ipv6_builder) =
1768 create_ipv4_and_ipv6_builders(IpProto::Udp.into(), IpProto::Udp.into());
1769
1770 let udp_builder =
1771 UdpPacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, Some(udp_src_port), udp_dst_port);
1772
1773 let v4_pkt_buf = (&PAYLOAD)
1774 .into_serializer()
1775 .wrap_in(udp_builder)
1776 .wrap_in(ipv4_builder)
1777 .serialize_vec_outer()
1778 .unwrap();
1779
1780 let v6_udp_builder = UdpPacketBuilder::new(
1781 DEFAULT_V6_SRC_IP,
1782 DEFAULT_V6_DST_IP,
1783 Some(udp_src_port),
1784 udp_dst_port,
1785 );
1786
1787 let v6_pkt_buf = (&PAYLOAD)
1788 .into_serializer()
1789 .wrap_in(v6_udp_builder)
1790 .wrap_in(ipv6_builder)
1791 .serialize_vec_outer()
1792 .unwrap();
1793
1794 (v4_pkt_buf, v6_pkt_buf)
1795 }
1796
1797 #[test]
1798 fn test_nat64_translate_udp() {
1799 let (mut v4_pkt_buf, expected_v6_pkt_buf) = create_udp_ipv4_and_ipv6_pkt();
1800
1801 let parsed_v4_packet = v4_pkt_buf.parse::<Ipv4Packet<_>>().unwrap();
1802 let nat64_translation_result =
1803 parsed_v4_packet.nat64_translate(DEFAULT_V6_SRC_IP, DEFAULT_V6_DST_IP);
1804
1805 let serializable_pkt = match nat64_translation_result {
1806 Nat64TranslationResult::Forward(s) => s,
1807 _ => panic!(
1808 "Nat64TranslationResult not of Forward type: {:?} ",
1809 nat64_translation_result
1810 ),
1811 };
1812
1813 let translated_v6_pkt_buf = serializable_pkt.serialize_vec_outer().unwrap();
1814
1815 assert_eq!(
1816 expected_v6_pkt_buf.to_flattened_vec(),
1817 translated_v6_pkt_buf.to_flattened_vec()
1818 );
1819 }
1820
1821 #[test]
1822 fn test_nat64_translate_non_tcp_udp_icmp() {
1823 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
1824
1825 let (ipv4_builder, ipv6_builder) =
1826 create_ipv4_and_ipv6_builders(Ipv4Proto::Other(50), Ipv6Proto::Other(50));
1827
1828 let mut v4_pkt_buf =
1829 (&PAYLOAD).into_serializer().wrap_in(ipv4_builder).serialize_vec_outer().unwrap();
1830
1831 let expected_v6_pkt_buf =
1832 (&PAYLOAD).into_serializer().wrap_in(ipv6_builder).serialize_vec_outer().unwrap();
1833
1834 let translated_v6_pkt_buf = {
1835 let parsed_v4_packet = v4_pkt_buf.parse::<Ipv4Packet<_>>().unwrap();
1836
1837 let nat64_translation_result =
1838 parsed_v4_packet.nat64_translate(DEFAULT_V6_SRC_IP, DEFAULT_V6_DST_IP);
1839
1840 let serializable_pkt = match nat64_translation_result {
1841 Nat64TranslationResult::Forward(s) => s,
1842 _ => panic!(
1843 "Nat64TranslationResult not of Forward type: {:?} ",
1844 nat64_translation_result
1845 ),
1846 };
1847
1848 let translated_buf = serializable_pkt.serialize_vec_outer().unwrap();
1849
1850 translated_buf
1851 };
1852
1853 assert_eq!(
1854 expected_v6_pkt_buf.to_flattened_vec(),
1855 translated_v6_pkt_buf.to_flattened_vec()
1856 );
1857 }
1858}