1use alloc::vec::Vec;
12use core::borrow::Borrow;
13use core::convert::Infallible as Never;
14use core::fmt::{self, Debug, Formatter};
15use core::ops::Range;
16
17use internet_checksum::Checksum;
18use log::debug;
19use net_types::ip::{GenericOverIp, IpAddress, Ipv4, Ipv4Addr, Ipv4SourceAddr, Ipv6Addr};
20use packet::records::RecordsIter;
21use packet::records::options::{OptionSequenceBuilder, OptionsRaw};
22use packet::{
23 BufferProvider, BufferView, BufferViewMut, EmptyBuf, FragmentedBytesMut, FromRaw,
24 GrowBufferMut, InnerPacketBuilder, LayoutBufferAlloc, MaybeParsed, PacketBuilder,
25 PacketConstraints, ParsablePacket, ParseMetadata, PartialPacketBuilder, PartialSerializeResult,
26 PartialSerializer, SerializeError, SerializeTarget, Serializer,
27};
28use zerocopy::byteorder::network_endian::U16;
29use zerocopy::{
30 FromBytes, Immutable, IntoBytes, KnownLayout, Ref, SplitByteSlice, SplitByteSliceMut, Unaligned,
31};
32
33use crate::error::ParseError;
34use crate::ip::{
35 DscpAndEcn, FragmentOffset, IpExt, IpPacketBuilder, IpProto, Ipv4Proto, Ipv6Proto, Nat64Error,
36 Nat64TranslationResult,
37};
38use crate::ipv6::Ipv6PacketBuilder;
39use crate::tcp::{TcpParseArgs, TcpSegment};
40use crate::udp::{UdpPacket, UdpParseArgs};
41
42pub(crate) use self::inner::IPV4_MIN_HDR_LEN;
43use self::options::{Ipv4Option, Ipv4OptionsImpl};
44
45pub const HDR_PREFIX_LEN: usize = 20;
47
48pub const MAX_HDR_LEN: usize = 60;
50
51pub const MAX_OPTIONS_LEN: usize = MAX_HDR_LEN - HDR_PREFIX_LEN;
53
54const IPV4_FRAGMENT_DATA_BYTE_RANGE: Range<usize> = 4..8;
56
57#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
59#[allow(missing_docs)]
60pub enum Ipv4FragmentType {
61 InitialFragment,
62 NonInitialFragment,
63}
64
65#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned)]
68#[repr(C)]
69pub struct HeaderPrefix {
70 version_ihl: u8,
71 dscp_and_ecn: DscpAndEcn,
72 total_len: U16,
73 id: U16,
74 flags_frag_off: [u8; 2],
75 ttl: u8,
76 proto: u8,
77 hdr_checksum: [u8; 2],
78 src_ip: Ipv4Addr,
79 dst_ip: Ipv4Addr,
80}
81
82const IP_VERSION: u8 = 4;
83const VERSION_OFFSET: u8 = 4;
84const IHL_MASK: u8 = 0xF;
85const IHL_MAX: u8 = (1 << VERSION_OFFSET) - 1;
86const FLAGS_OFFSET: u8 = 13;
87const FLAGS_MAX: u8 = (1 << (16 - FLAGS_OFFSET)) - 1;
88const FRAG_OFF_MAX: u16 = (1 << FLAGS_OFFSET) - 1;
89
90impl HeaderPrefix {
91 #[allow(clippy::too_many_arguments)]
92 fn new(
93 ihl: u8,
94 dscp_and_ecn: DscpAndEcn,
95 total_len: u16,
96 id: u16,
97 flags: u8,
98 frag_off: u16,
99 ttl: u8,
100 proto: u8,
101 hdr_checksum: [u8; 2],
102 src_ip: Ipv4Addr,
103 dst_ip: Ipv4Addr,
104 ) -> HeaderPrefix {
105 debug_assert!(ihl <= IHL_MAX);
106 debug_assert!(flags <= FLAGS_MAX);
107 debug_assert!(frag_off <= FRAG_OFF_MAX);
108
109 HeaderPrefix {
110 version_ihl: (IP_VERSION << VERSION_OFFSET) | ihl,
111 dscp_and_ecn,
112 total_len: U16::new(total_len),
113 id: U16::new(id),
114 flags_frag_off: ((u16::from(flags) << FLAGS_OFFSET) | frag_off).to_be_bytes(),
115 ttl,
116 proto,
117 src_ip,
118 dst_ip,
119 hdr_checksum,
120 }
121 }
122
123 fn version(&self) -> u8 {
124 self.version_ihl >> VERSION_OFFSET
125 }
126
127 pub(crate) fn ihl(&self) -> u8 {
129 self.version_ihl & IHL_MASK
130 }
131
132 pub(crate) fn mf_flag(&self) -> bool {
134 self.flags_frag_off[0] & (1 << ((FLAGS_OFFSET - 8) + MF_FLAG_OFFSET)) > 0
139 }
140}
141
142pub trait Ipv4Header {
147 fn get_header_prefix(&self) -> &HeaderPrefix;
149
150 fn dscp_and_ecn(&self) -> DscpAndEcn {
152 self.get_header_prefix().dscp_and_ecn
153 }
154
155 fn id(&self) -> u16 {
157 self.get_header_prefix().id.get()
158 }
159
160 fn df_flag(&self) -> bool {
162 self.get_header_prefix().flags_frag_off[0] & (1 << (5 + DF_FLAG_OFFSET)) > 0
164 }
165
166 fn mf_flag(&self) -> bool {
168 self.get_header_prefix().mf_flag()
169 }
170
171 fn fragment_offset(&self) -> FragmentOffset {
173 FragmentOffset::new_with_lsb(U16::from_bytes(self.get_header_prefix().flags_frag_off).get())
174 }
175
176 fn fragment_type(&self) -> Ipv4FragmentType {
182 match self.fragment_offset().into_raw() {
183 0 => Ipv4FragmentType::InitialFragment,
184 _ => Ipv4FragmentType::NonInitialFragment,
185 }
186 }
187
188 fn ttl(&self) -> u8 {
190 self.get_header_prefix().ttl
191 }
192
193 fn proto(&self) -> Ipv4Proto {
197 Ipv4Proto::from(self.get_header_prefix().proto)
198 }
199
200 fn src_ip(&self) -> Ipv4Addr {
202 self.get_header_prefix().src_ip
203 }
204
205 fn dst_ip(&self) -> Ipv4Addr {
207 self.get_header_prefix().dst_ip
208 }
209
210 fn builder(&self) -> Ipv4PacketBuilder {
212 let mut s = Ipv4PacketBuilder {
213 id: self.id(),
214 dscp_and_ecn: self.dscp_and_ecn(),
215 flags: 0,
216 frag_off: self.fragment_offset().into_raw(),
217 ttl: self.ttl(),
218 proto: self.get_header_prefix().proto.into(),
219 src_ip: self.src_ip(),
220 dst_ip: self.dst_ip(),
221 };
222 s.df_flag(self.df_flag());
223 s.mf_flag(self.mf_flag());
224 s
225 }
226}
227
228impl Ipv4Header for HeaderPrefix {
229 fn get_header_prefix(&self) -> &HeaderPrefix {
230 self
231 }
232}
233
234pub struct Ipv4Packet<B> {
244 hdr_prefix: Ref<B, HeaderPrefix>,
245 options: Options<B>,
246 body: B,
247}
248
249impl<B: SplitByteSlice, I: IpExt> GenericOverIp<I> for Ipv4Packet<B> {
250 type Type = <I as IpExt>::Packet<B>;
251}
252
253impl<B: SplitByteSlice> Ipv4Header for Ipv4Packet<B> {
254 fn get_header_prefix(&self) -> &HeaderPrefix {
255 &self.hdr_prefix
256 }
257}
258
259impl<B: SplitByteSlice> PartialSerializer for Ipv4Packet<B> {
260 fn partial_serialize(
261 &self,
262 _outer: PacketConstraints,
263 mut buffer: &mut [u8],
264 ) -> Result<PartialSerializeResult, SerializeError<Never>> {
265 let hdr_prefix = Ref::bytes(&self.hdr_prefix);
266 let options = self.options.bytes();
267
268 let mut buffer = &mut buffer;
269 let bytes_written = buffer.write_bytes_front_allow_partial(hdr_prefix)
270 + buffer.write_bytes_front_allow_partial(options)
271 + buffer.write_bytes_front_allow_partial(&self.body);
272 let total_size = hdr_prefix.len() + options.len() + self.body.len();
273
274 Ok(PartialSerializeResult { bytes_written, total_size })
275 }
276}
277
278impl<B: SplitByteSlice> ParsablePacket<B, ()> for Ipv4Packet<B> {
279 type Error = ParseError;
280
281 fn parse_metadata(&self) -> ParseMetadata {
282 ParseMetadata::from_packet(self.header_len(), self.body.len(), 0)
283 }
284
285 fn parse<BV: BufferView<B>>(buffer: BV, _args: ()) -> Result<Self, ParseError> {
286 Ipv4PacketRaw::<B>::parse(buffer, ()).and_then(Ipv4Packet::try_from_raw)
287 }
288}
289
290impl<B: SplitByteSlice> FromRaw<Ipv4PacketRaw<B>, ()> for Ipv4Packet<B> {
291 type Error = ParseError;
292
293 fn try_from_raw_with(raw: Ipv4PacketRaw<B>, _args: ()) -> Result<Self, Self::Error> {
294 let hdr_prefix = raw.hdr_prefix;
297 let hdr_bytes = (hdr_prefix.ihl() * 4) as usize;
298
299 if hdr_bytes < HDR_PREFIX_LEN {
300 return debug_err!(Err(ParseError::Format), "invalid IHL: {}", hdr_prefix.ihl());
301 }
302
303 let options = match raw.options {
304 MaybeParsed::Incomplete(_) => {
305 return debug_err!(Err(ParseError::Format), "Incomplete options");
306 }
307 MaybeParsed::Complete(unchecked) => Options::try_from_raw(unchecked)
308 .map_err(|e| debug_err!(e, "malformed options: {:?}", e))?,
309 };
310
311 if hdr_prefix.version() != 4 {
312 return debug_err!(
313 Err(ParseError::Format),
314 "unexpected IP version: {}",
315 hdr_prefix.version()
316 );
317 }
318
319 let body = match raw.body {
320 MaybeParsed::Incomplete(_) => {
321 if hdr_prefix.mf_flag() {
322 return debug_err!(
323 Err(ParseError::NotSupported),
324 "fragmentation not supported"
325 );
326 } else {
327 return debug_err!(Err(ParseError::Format), "Incomplete body");
328 }
329 }
330 MaybeParsed::Complete(bytes) => bytes,
331 };
332
333 let packet = Ipv4Packet { hdr_prefix, options, body };
334 if packet.compute_header_checksum() != [0, 0] {
335 return debug_err!(Err(ParseError::Checksum), "invalid checksum");
336 }
337 Ok(packet)
338 }
339}
340
341fn compute_header_checksum(hdr_prefix: &[u8], options: &[u8]) -> [u8; 2] {
342 let mut c = Checksum::new();
343 c.add_bytes(hdr_prefix);
344 c.add_bytes(options);
345 c.checksum()
346}
347
348impl<B: SplitByteSlice> Ipv4Packet<B> {
349 pub fn iter_options(&self) -> impl Iterator<Item = Ipv4Option<'_>> {
351 self.options.iter()
352 }
353
354 fn compute_header_checksum(&self) -> [u8; 2] {
356 compute_header_checksum(Ref::bytes(&self.hdr_prefix), self.options.bytes())
357 }
358
359 pub fn body(&self) -> &[u8] {
361 &self.body
362 }
363
364 pub fn header_len(&self) -> usize {
366 Ref::bytes(&self.hdr_prefix).len() + self.options.bytes().len()
367 }
368
369 pub fn src_ipv4(&self) -> Option<Ipv4SourceAddr> {
374 Ipv4SourceAddr::new(self.src_ip())
375 }
376
377 pub fn copy_header_bytes_for_fragment(&self) -> Vec<u8> {
383 let expected_bytes_len = self.header_len();
384 let mut bytes = Vec::with_capacity(expected_bytes_len);
385
386 bytes.extend_from_slice(Ref::bytes(&self.hdr_prefix));
387 bytes.extend_from_slice(self.options.bytes());
388
389 assert_eq!(bytes.len(), expected_bytes_len);
391
392 bytes[IPV4_FRAGMENT_DATA_BYTE_RANGE].copy_from_slice(&[0; 4][..]);
394
395 bytes
396 }
397
398 pub fn nat64_translate(
424 &self,
425 v6_src_addr: Ipv6Addr,
426 v6_dst_addr: Ipv6Addr,
427 ) -> Nat64TranslationResult<impl Serializer<Buffer = EmptyBuf> + Debug + '_, Nat64Error> {
428 #[derive(Debug)]
431 enum Nat64Serializer<T, U, O> {
432 Tcp(T),
433 Udp(U),
434 Other(O),
435 }
436
437 impl<T, U, O> Serializer for Nat64Serializer<T, U, O>
438 where
439 T: Serializer<Buffer = EmptyBuf>,
440 U: Serializer<Buffer = EmptyBuf>,
441 O: Serializer<Buffer = EmptyBuf>,
442 {
443 type Buffer = EmptyBuf;
444 fn serialize<B, P>(
445 self,
446 outer: PacketConstraints,
447 provider: P,
448 ) -> Result<B, (SerializeError<P::Error>, Self)>
449 where
450 B: GrowBufferMut,
451 P: BufferProvider<Self::Buffer, B>,
452 {
453 match self {
454 Nat64Serializer::Tcp(serializer) => serializer
455 .serialize(outer, provider)
456 .map_err(|(err, ser)| (err, Nat64Serializer::Tcp(ser))),
457 Nat64Serializer::Udp(serializer) => serializer
458 .serialize(outer, provider)
459 .map_err(|(err, ser)| (err, Nat64Serializer::Udp(ser))),
460 Nat64Serializer::Other(serializer) => serializer
461 .serialize(outer, provider)
462 .map_err(|(err, ser)| (err, Nat64Serializer::Other(ser))),
463 }
464 }
465
466 fn serialize_new_buf<B: GrowBufferMut, A: LayoutBufferAlloc<B>>(
467 &self,
468 outer: PacketConstraints,
469 alloc: A,
470 ) -> Result<B, SerializeError<A::Error>> {
471 match self {
472 Nat64Serializer::Tcp(serializer) => serializer.serialize_new_buf(outer, alloc),
473 Nat64Serializer::Udp(serializer) => serializer.serialize_new_buf(outer, alloc),
474 Nat64Serializer::Other(serializer) => {
475 serializer.serialize_new_buf(outer, alloc)
476 }
477 }
478 }
479 }
480
481 let v6_builder = |v6_proto| {
482 let mut builder =
483 Ipv6PacketBuilder::new(v6_src_addr, v6_dst_addr, self.ttl(), v6_proto);
484 builder.dscp_and_ecn(self.dscp_and_ecn());
485 builder.flowlabel(0);
486 builder
487 };
488
489 match self.proto() {
490 Ipv4Proto::Igmp => {
491 Nat64TranslationResult::Drop
493 }
494
495 Ipv4Proto::Proto(IpProto::Tcp) => {
496 let v6_pkt_builder = v6_builder(Ipv6Proto::Proto(IpProto::Tcp));
497 let args = TcpParseArgs::new(self.src_ip(), self.dst_ip());
498 match TcpSegment::parse(&mut self.body.as_bytes(), args) {
499 Ok(tcp) => {
500 let tcp_serializer =
504 Nat64Serializer::Tcp(tcp.into_serializer(v6_src_addr, v6_dst_addr));
505 Nat64TranslationResult::Forward(v6_pkt_builder.wrap_body(tcp_serializer))
506 }
507 Err(msg) => {
508 debug!("Parsing of TCP segment failed: {:?}", msg);
509
510 let common_serializer =
516 Nat64Serializer::Other(self.body().into_serializer());
517 Nat64TranslationResult::Forward(v6_pkt_builder.wrap_body(common_serializer))
518 }
519 }
520 }
521
522 Ipv4Proto::Proto(IpProto::Udp) => {
523 let v6_pkt_builder = v6_builder(Ipv6Proto::Proto(IpProto::Udp));
524 let args = UdpParseArgs::new(self.src_ip(), self.dst_ip());
525 match UdpPacket::parse(&mut self.body.as_bytes(), args) {
526 Ok(udp) => {
527 let udp_serializer =
531 Nat64Serializer::Udp(udp.into_serializer(v6_src_addr, v6_dst_addr));
532 Nat64TranslationResult::Forward(v6_pkt_builder.wrap_body(udp_serializer))
533 }
534 Err(msg) => {
535 debug!("Parsing of UDP packet failed: {:?}", msg);
536
537 let common_serializer =
543 Nat64Serializer::Other(self.body().into_serializer());
544 Nat64TranslationResult::Forward(v6_pkt_builder.wrap_body(common_serializer))
545 }
546 }
547 }
548
549 Ipv4Proto::Icmp => Nat64TranslationResult::Err(Nat64Error::NotImplemented),
550
551 Ipv4Proto::Other(val) => {
556 let v6_pkt_builder = v6_builder(Ipv6Proto::Other(val));
557 let common_serializer = Nat64Serializer::Other(self.body().into_serializer());
558 Nat64TranslationResult::Forward(v6_pkt_builder.wrap_body(common_serializer))
559 }
560
561 Ipv4Proto::Proto(IpProto::Reserved) => Nat64TranslationResult::Drop,
564 }
565 }
566
567 pub fn to_vec(&self) -> Vec<u8> {
569 let Ipv4Packet { hdr_prefix, options, body } = self;
570 let mut buf = Vec::with_capacity(
571 Ref::bytes(&hdr_prefix).len() + options.bytes().len() + body.as_bytes().len(),
572 );
573 buf.extend(Ref::bytes(&hdr_prefix));
574 buf.extend(options.bytes());
575 buf.extend(body.as_bytes());
576 buf
577 }
578}
579
580impl<B: SplitByteSliceMut> Ipv4Packet<B> {
581 pub fn set_src_ip_and_update_checksum(&mut self, addr: Ipv4Addr) {
585 let old_bytes = self.hdr_prefix.src_ip.bytes();
586 self.hdr_prefix.hdr_checksum =
587 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, addr.bytes());
588 self.hdr_prefix.src_ip = addr;
589 }
590
591 pub fn set_dst_ip_and_update_checksum(&mut self, addr: Ipv4Addr) {
595 let old_bytes = self.hdr_prefix.dst_ip.bytes();
596 self.hdr_prefix.hdr_checksum =
597 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, addr.bytes());
598 self.hdr_prefix.dst_ip = addr;
599 }
600
601 pub fn set_ttl(&mut self, ttl: u8) {
605 let old_bytes = [self.hdr_prefix.ttl, self.hdr_prefix.proto];
609 let new_bytes = [ttl, self.hdr_prefix.proto];
610 self.hdr_prefix.hdr_checksum =
611 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, &new_bytes);
612 self.hdr_prefix.ttl = ttl;
613 }
614
615 pub fn body_mut(&mut self) -> &mut [u8] {
617 &mut self.body
618 }
619
620 pub fn parts_with_body_mut(&mut self) -> (&HeaderPrefix, &Options<B>, &mut [u8]) {
623 (&self.hdr_prefix, &self.options, &mut self.body)
624 }
625}
626
627impl<B> Debug for Ipv4Packet<B>
628where
629 B: SplitByteSlice,
630{
631 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
632 f.debug_struct("Ipv4Packet")
633 .field("src_ip", &self.src_ip())
634 .field("dst_ip", &self.dst_ip())
635 .field("id", &self.id())
636 .field("ttl", &self.ttl())
637 .field("proto", &self.proto())
638 .field("frag_off", &self.fragment_offset())
639 .field("dscp", &self.dscp_and_ecn().dscp())
640 .field("ecn", &self.dscp_and_ecn().ecn())
641 .field("mf_flag", &self.mf_flag())
642 .field("df_flag", &self.df_flag())
643 .field("body", &alloc::format!("<{} bytes>", self.body.len()))
644 .finish()
645 }
646}
647
648pub struct Ipv4PacketRaw<B> {
658 hdr_prefix: Ref<B, HeaderPrefix>,
659 options: MaybeParsed<OptionsRaw<B, Ipv4OptionsImpl>, B>,
660 body: MaybeParsed<B, B>,
661}
662
663impl<B> Ipv4PacketRaw<B> {
664 pub fn body_mut(&mut self) -> &mut B {
668 match &mut self.body {
669 MaybeParsed::Complete(b) => b,
670 MaybeParsed::Incomplete(b) => b,
671 }
672 }
673}
674
675impl<B: SplitByteSlice> Ipv4Header for Ipv4PacketRaw<B> {
676 fn get_header_prefix(&self) -> &HeaderPrefix {
677 &self.hdr_prefix
678 }
679}
680
681impl<B: SplitByteSlice> ParsablePacket<B, ()> for Ipv4PacketRaw<B> {
682 type Error = ParseError;
683
684 fn parse_metadata(&self) -> ParseMetadata {
685 let header_len = Ref::bytes(&self.hdr_prefix).len() + self.options.len();
686 ParseMetadata::from_packet(header_len, self.body.len(), 0)
687 }
688
689 fn parse<BV: BufferView<B>>(mut buffer: BV, _args: ()) -> Result<Self, ParseError> {
690 let hdr_prefix = buffer
691 .take_obj_front::<HeaderPrefix>()
692 .ok_or_else(debug_err_fn!(ParseError::Format, "too few bytes for header"))?;
693 let hdr_bytes = (hdr_prefix.ihl() * 4) as usize;
694
695 let options = MaybeParsed::take_from_buffer_with(
696 &mut buffer,
697 hdr_bytes.saturating_sub(HDR_PREFIX_LEN),
702 OptionsRaw::new,
703 );
704
705 let total_len: usize = hdr_prefix.total_len.get().into();
706 let body_len = total_len.saturating_sub(hdr_bytes);
707 if buffer.len() > body_len {
708 let _: B = buffer.take_back(buffer.len() - body_len).unwrap();
711 }
712
713 let body = MaybeParsed::new_with_min_len(buffer.into_rest(), body_len);
714
715 Ok(Self { hdr_prefix, options, body })
716 }
717}
718
719impl<B> Ipv4PacketRaw<B> {
720 pub fn options(&self) -> &MaybeParsed<OptionsRaw<B, Ipv4OptionsImpl>, B> {
722 &self.options
723 }
724}
725
726impl<B: SplitByteSlice> Ipv4PacketRaw<B> {
727 pub fn body(&self) -> MaybeParsed<&[u8], &[u8]> {
733 self.body.as_ref().map(|b| b.deref()).map_incomplete(|b| b.deref())
734 }
735
736 pub fn into_body(self) -> MaybeParsed<B, B> {
740 self.body
741 }
742}
743
744impl<B: SplitByteSliceMut> Ipv4PacketRaw<B> {
745 pub fn set_src_ip_and_update_checksum(&mut self, addr: Ipv4Addr) {
749 let old_bytes = self.hdr_prefix.src_ip.bytes();
750 self.hdr_prefix.hdr_checksum =
751 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, addr.bytes());
752 self.hdr_prefix.src_ip = addr;
753 }
754
755 pub fn set_dst_ip_and_update_checksum(&mut self, addr: Ipv4Addr) {
759 let old_bytes = self.hdr_prefix.dst_ip.bytes();
760 self.hdr_prefix.hdr_checksum =
761 internet_checksum::update(self.hdr_prefix.hdr_checksum, &old_bytes, addr.bytes());
762 self.hdr_prefix.dst_ip = addr;
763 }
764}
765
766pub type Options<B> = packet::records::options::Options<B, Ipv4OptionsImpl>;
772
773#[derive(Debug)]
776pub struct Ipv4OptionsTooLongError;
777
778#[derive(Debug, Clone)]
780pub struct Ipv4PacketBuilderWithOptions<'a, I> {
781 prefix_builder: Ipv4PacketBuilder,
782 options: OptionSequenceBuilder<Ipv4Option<'a>, I>,
783}
784
785impl<'a, I> Ipv4PacketBuilderWithOptions<'a, I>
786where
787 I: Iterator + Clone,
788 I::Item: Borrow<Ipv4Option<'a>>,
789{
790 pub fn new<T: IntoIterator<IntoIter = I>>(
796 prefix_builder: Ipv4PacketBuilder,
797 options: T,
798 ) -> Result<Ipv4PacketBuilderWithOptions<'a, I>, Ipv4OptionsTooLongError> {
799 let options = OptionSequenceBuilder::new(options.into_iter());
800 if options.serialized_len() > MAX_OPTIONS_LEN {
801 return Err(Ipv4OptionsTooLongError);
802 }
803 Ok(Ipv4PacketBuilderWithOptions { prefix_builder, options })
804 }
805
806 fn aligned_options_len(&self) -> usize {
807 crate::utils::round_to_next_multiple_of_four(self.options.serialized_len())
809 }
810
811 pub fn prefix_builder(&self) -> &Ipv4PacketBuilder {
813 &self.prefix_builder
814 }
815
816 pub fn prefix_builder_mut(&mut self) -> &mut Ipv4PacketBuilder {
818 &mut self.prefix_builder
819 }
820
821 pub fn options(&self) -> &I {
823 self.options.records()
824 }
825
826 pub fn with_fragment_options(
832 self,
833 first_fragment: bool,
834 ) -> Ipv4PacketBuilderWithOptions<'a, impl Iterator<Item: Borrow<Ipv4Option<'a>>> + Clone> {
835 let Self { prefix_builder, options } = self;
836 Ipv4PacketBuilderWithOptions {
837 prefix_builder,
838 options: OptionSequenceBuilder::new(
841 options
842 .records()
843 .clone()
844 .filter(move |opt| first_fragment || opt.borrow().copied()),
845 ),
846 }
847 }
848}
849
850impl<'a, B> Ipv4PacketBuilderWithOptions<'a, RecordsIter<'a, B, Ipv4OptionsImpl>> {
851 pub fn new_with_records_iter(
854 prefix_builder: Ipv4PacketBuilder,
855 iter: RecordsIter<'a, B, Ipv4OptionsImpl>,
856 ) -> Self {
857 Self { prefix_builder, options: OptionSequenceBuilder::new(iter) }
858 }
859}
860
861impl<'a, I> PacketBuilder for Ipv4PacketBuilderWithOptions<'a, I>
862where
863 I: Iterator + Clone,
864 I::Item: Borrow<Ipv4Option<'a>>,
865{
866 fn constraints(&self) -> PacketConstraints {
867 let header_len = IPV4_MIN_HDR_LEN + self.aligned_options_len();
868 assert_eq!(header_len % 4, 0);
869 PacketConstraints::new(header_len, 0, 0, (1 << 16) - 1 - header_len)
870 }
871
872 fn serialize(&self, target: &mut SerializeTarget<'_>, body: FragmentedBytesMut<'_, '_>) {
873 let opt_len = self.aligned_options_len();
874 let mut header = &mut &mut target.header[..];
880 let opts = header.take_back_zero(opt_len).expect("too few bytes for Ipv4 options");
881 let Ipv4PacketBuilderWithOptions { prefix_builder, options } = self;
882 options.serialize_into(opts);
883 prefix_builder.serialize(target, body);
884 }
885}
886
887impl<'a, I> PartialPacketBuilder for Ipv4PacketBuilderWithOptions<'a, I>
888where
889 I: Iterator + Clone,
890 I::Item: Borrow<Ipv4Option<'a>>,
891{
892 fn partial_serialize(&self, body_len: usize, header: &mut [u8]) {
893 let Ipv4PacketBuilderWithOptions { prefix_builder, options } = self;
894 prefix_builder.partial_serialize(body_len, header);
895 let options_slice = &mut header[IPV4_MIN_HDR_LEN..];
896 assert_eq!(options_slice.len(), self.aligned_options_len());
897 options.serialize_into(options_slice);
898 }
899}
900
901impl<'a, I> IpPacketBuilder<Ipv4> for Ipv4PacketBuilderWithOptions<'a, I>
902where
903 I: Default + Debug + Clone + Iterator<Item: Borrow<Ipv4Option<'a>>>,
904{
905 fn new(src_ip: Ipv4Addr, dst_ip: Ipv4Addr, ttl: u8, proto: Ipv4Proto) -> Self {
906 Ipv4PacketBuilderWithOptions::new(
907 Ipv4PacketBuilder::new(src_ip, dst_ip, ttl, proto),
908 I::default(),
909 )
910 .expect("packet builder with no options should be valid")
911 }
912
913 fn src_ip(&self) -> Ipv4Addr {
914 self.prefix_builder.src_ip
915 }
916
917 fn set_src_ip(&mut self, addr: Ipv4Addr) {
918 self.prefix_builder.set_src_ip(addr);
919 }
920
921 fn dst_ip(&self) -> Ipv4Addr {
922 self.prefix_builder.dst_ip
923 }
924
925 fn set_dst_ip(&mut self, addr: Ipv4Addr) {
926 self.prefix_builder.set_dst_ip(addr);
927 }
928
929 fn proto(&self) -> Ipv4Proto {
930 self.prefix_builder.proto
931 }
932
933 fn set_dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
934 self.prefix_builder.set_dscp_and_ecn(dscp_and_ecn)
935 }
936}
937
938#[derive(Debug, Clone, Eq, PartialEq)]
940pub struct Ipv4PacketBuilder {
941 id: u16,
942 dscp_and_ecn: DscpAndEcn,
943 flags: u8,
944 frag_off: u16,
945 ttl: u8,
946 proto: Ipv4Proto,
947 src_ip: Ipv4Addr,
948 dst_ip: Ipv4Addr,
949}
950
951impl Ipv4PacketBuilder {
952 pub fn new<S: Into<Ipv4Addr>, D: Into<Ipv4Addr>>(
954 src_ip: S,
955 dst_ip: D,
956 ttl: u8,
957 proto: Ipv4Proto,
958 ) -> Ipv4PacketBuilder {
959 Ipv4PacketBuilder {
960 id: 0,
961 dscp_and_ecn: DscpAndEcn::default(),
962 flags: 0,
963 frag_off: 0,
964 ttl,
965 proto: proto,
966 src_ip: src_ip.into(),
967 dst_ip: dst_ip.into(),
968 }
969 }
970
971 pub fn dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
973 self.dscp_and_ecn = dscp_and_ecn;
974 }
975
976 pub fn id(&mut self, id: u16) {
978 self.id = id
979 }
980
981 pub fn df_flag(&mut self, df: bool) {
983 if df {
984 self.flags |= 1 << DF_FLAG_OFFSET;
985 } else {
986 self.flags &= !(1 << DF_FLAG_OFFSET);
987 }
988 }
989
990 pub fn mf_flag(&mut self, mf: bool) {
992 if mf {
993 self.flags |= 1 << MF_FLAG_OFFSET;
994 } else {
995 self.flags &= !(1 << MF_FLAG_OFFSET);
996 }
997 }
998
999 pub fn fragment_offset(&mut self, fragment_offset: FragmentOffset) {
1001 self.frag_off = fragment_offset.into_raw();
1002 }
1003
1004 pub fn read_df_flag(&self) -> bool {
1006 (self.flags & (1 << DF_FLAG_OFFSET)) != 0
1007 }
1008
1009 fn get_header_prefix(&self, header_len: usize, total_len: usize) -> HeaderPrefix {
1010 assert_eq!(header_len % 4, 0);
1011 let ihl: u8 = u8::try_from(header_len / 4).expect("Header too large");
1012
1013 let id = if ((self.flags & (1 << DF_FLAG_OFFSET)) == 0)
1023 || ((self.flags & (1 << MF_FLAG_OFFSET)) == 1)
1024 || (self.frag_off > 0)
1025 {
1026 self.id
1027 } else {
1028 0
1029 };
1030
1031 HeaderPrefix::new(
1032 ihl,
1033 self.dscp_and_ecn,
1034 {
1035 debug_assert!(total_len <= core::u16::MAX as usize);
1041 total_len as u16
1042 },
1043 id,
1044 self.flags,
1045 self.frag_off,
1046 self.ttl,
1047 self.proto.into(),
1048 [0, 0], self.src_ip,
1050 self.dst_ip,
1051 )
1052 }
1053}
1054
1055impl PacketBuilder for Ipv4PacketBuilder {
1056 fn constraints(&self) -> PacketConstraints {
1057 PacketConstraints::new(IPV4_MIN_HDR_LEN, 0, 0, (1 << 16) - 1 - IPV4_MIN_HDR_LEN)
1058 }
1059
1060 fn serialize(&self, target: &mut SerializeTarget<'_>, body: FragmentedBytesMut<'_, '_>) {
1061 let header_len = target.header.len();
1062 let total_len = header_len + body.len();
1063 let mut hdr_prefix = self.get_header_prefix(header_len, total_len);
1064 let options = &target.header[HDR_PREFIX_LEN..];
1065 let checksum = compute_header_checksum(hdr_prefix.as_bytes(), options);
1066 hdr_prefix.hdr_checksum = checksum;
1067 let mut header = &mut target.header;
1068 header.write_obj_front(&hdr_prefix).expect("too few bytes for IPv4 header prefix");
1069 }
1070}
1071
1072impl PartialPacketBuilder for Ipv4PacketBuilder {
1073 fn partial_serialize(&self, body_len: usize, mut header: &mut [u8]) {
1074 let total_len = header.len() + body_len;
1075 let hdr_prefix = self.get_header_prefix(header.len(), total_len);
1076 (&mut header).write_obj_front(&hdr_prefix).expect("too few bytes for IPv4 header prefix");
1077 }
1078}
1079
1080impl IpPacketBuilder<Ipv4> for Ipv4PacketBuilder {
1081 fn new(src_ip: Ipv4Addr, dst_ip: Ipv4Addr, ttl: u8, proto: Ipv4Proto) -> Self {
1082 Ipv4PacketBuilder::new(src_ip, dst_ip, ttl, proto)
1083 }
1084
1085 fn src_ip(&self) -> Ipv4Addr {
1086 self.src_ip
1087 }
1088
1089 fn set_src_ip(&mut self, addr: Ipv4Addr) {
1090 self.src_ip = addr;
1091 }
1092
1093 fn dst_ip(&self) -> Ipv4Addr {
1094 self.dst_ip
1095 }
1096
1097 fn set_dst_ip(&mut self, addr: Ipv4Addr) {
1098 self.dst_ip = addr;
1099 }
1100
1101 fn proto(&self) -> Ipv4Proto {
1102 self.proto
1103 }
1104
1105 fn set_dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
1106 self.dscp_and_ecn = dscp_and_ecn;
1107 }
1108}
1109
1110const DF_FLAG_OFFSET: u8 = 1;
1112const MF_FLAG_OFFSET: u8 = 0;
1113
1114pub(crate) fn reassemble_fragmented_packet<
1116 B: SplitByteSliceMut,
1117 BV: BufferViewMut<B>,
1118 I: Iterator<Item = Vec<u8>>,
1119>(
1120 mut buffer: BV,
1121 header: Vec<u8>,
1122 body_fragments: I,
1123) -> Result<(), ParseError> {
1124 let bytes = buffer.as_mut();
1125
1126 bytes[0..header.len()].copy_from_slice(&header[..]);
1128 let mut byte_count = header.len();
1129
1130 for p in body_fragments {
1132 bytes[byte_count..byte_count + p.len()].copy_from_slice(&p[..]);
1133 byte_count += p.len();
1134 }
1135
1136 if byte_count > usize::from(core::u16::MAX) {
1141 return debug_err!(
1142 Err(ParseError::Format),
1143 "fragmented packet length of {} bytes is too large",
1144 byte_count
1145 );
1146 }
1147
1148 let mut header = Ref::<_, HeaderPrefix>::from_prefix(bytes).unwrap().0;
1151
1152 header.total_len.set(u16::try_from(byte_count).unwrap());
1154
1155 header.flags_frag_off = [0; 2];
1158
1159 header.hdr_checksum = [0; 2];
1161 header.hdr_checksum = compute_header_checksum(header.as_bytes(), &[]);
1162
1163 Ok(())
1164}
1165
1166pub mod options {
1168 use byteorder::{ByteOrder, NetworkEndian};
1169 use packet::BufferViewMut;
1170 use packet::records::options::{
1171 OptionBuilder, OptionLayout, OptionParseErr, OptionParseLayout, OptionsImpl,
1172 };
1173 use zerocopy::byteorder::network_endian::U16;
1174
1175 const OPTION_KIND_EOL: u8 = 0;
1176 const OPTION_KIND_NOP: u8 = 1;
1177 const OPTION_KIND_RTRALRT: u8 = 148;
1178
1179 const OPTION_RTRALRT_LEN: usize = 2;
1180
1181 #[derive(PartialEq, Eq, Debug, Clone)]
1188 #[allow(missing_docs)]
1189 pub enum Ipv4Option<'a> {
1190 RouterAlert { data: u16 },
1196
1197 Unrecognized { kind: u8, data: &'a [u8] },
1209 }
1210
1211 impl<'a> Ipv4Option<'a> {
1212 pub fn copied(&self) -> bool {
1214 match self {
1215 Ipv4Option::RouterAlert { .. } => true,
1219 Ipv4Option::Unrecognized { kind, .. } => *kind & (1 << 7) != 0,
1220 }
1221 }
1222 }
1223
1224 #[derive(Debug, Clone)]
1226 pub struct Ipv4OptionsImpl;
1227
1228 impl OptionLayout for Ipv4OptionsImpl {
1229 type KindLenField = u8;
1230 }
1231
1232 impl OptionParseLayout for Ipv4OptionsImpl {
1233 type Error = OptionParseErr;
1234 const END_OF_OPTIONS: Option<u8> = Some(0);
1235 const NOP: Option<u8> = Some(1);
1236 }
1237
1238 impl OptionsImpl for Ipv4OptionsImpl {
1239 type Option<'a> = Ipv4Option<'a>;
1240
1241 fn parse<'a>(kind: u8, data: &'a [u8]) -> Result<Option<Ipv4Option<'a>>, OptionParseErr> {
1242 match kind {
1243 self::OPTION_KIND_EOL | self::OPTION_KIND_NOP => {
1244 unreachable!("records::options::Options promises to handle EOL and NOP")
1245 }
1246 self::OPTION_KIND_RTRALRT => {
1247 if data.len() == OPTION_RTRALRT_LEN {
1248 Ok(Some(Ipv4Option::RouterAlert { data: NetworkEndian::read_u16(data) }))
1249 } else {
1250 Err(OptionParseErr)
1251 }
1252 }
1253 kind => {
1254 if data.len() > 38 {
1255 Err(OptionParseErr)
1256 } else {
1257 Ok(Some(Ipv4Option::Unrecognized { kind, data }))
1258 }
1259 }
1260 }
1261 }
1262 }
1263
1264 impl<'a> OptionBuilder for Ipv4Option<'a> {
1265 type Layout = Ipv4OptionsImpl;
1266
1267 fn serialized_len(&self) -> usize {
1268 match self {
1269 Ipv4Option::RouterAlert { .. } => OPTION_RTRALRT_LEN,
1270 Ipv4Option::Unrecognized { data, .. } => data.len(),
1271 }
1272 }
1273
1274 fn option_kind(&self) -> u8 {
1275 match self {
1276 Ipv4Option::RouterAlert { .. } => OPTION_KIND_RTRALRT,
1277 Ipv4Option::Unrecognized { kind, .. } => *kind,
1278 }
1279 }
1280
1281 fn serialize_into(&self, mut buffer: &mut [u8]) {
1282 match self {
1283 Ipv4Option::Unrecognized { data, .. } => buffer.copy_from_slice(data),
1284 Ipv4Option::RouterAlert { data } => {
1285 (&mut buffer).write_obj_front(&U16::new(*data)).unwrap()
1286 }
1287 };
1288 }
1289 }
1290
1291 #[cfg(test)]
1292 mod test {
1293 use packet::records::RecordBuilder;
1294 use packet::records::options::Options;
1295
1296 use super::*;
1297
1298 #[test]
1299 fn test_serialize_router_alert() {
1300 let mut buffer = [0u8; 4];
1301 let option = Ipv4Option::RouterAlert { data: 0 };
1302 <Ipv4Option<'_> as RecordBuilder>::serialize_into(&option, &mut buffer);
1303 assert_eq!(buffer[0], 148);
1304 assert_eq!(buffer[1], 4);
1305 assert_eq!(buffer[2], 0);
1306 assert_eq!(buffer[3], 0);
1307 }
1308
1309 #[test]
1310 fn test_parse_router_alert() {
1311 let mut buffer: Vec<u8> = vec![148, 4, 0, 0];
1312 let options = Options::<_, Ipv4OptionsImpl>::parse(buffer.as_mut()).unwrap();
1313 let rtralt = options.iter().next().unwrap();
1314 assert_eq!(rtralt, Ipv4Option::RouterAlert { data: 0 });
1315 }
1316 }
1317}
1318
1319mod inner {
1320 pub const IPV4_MIN_HDR_LEN: usize = super::HDR_PREFIX_LEN;
1322}
1323
1324pub mod testutil {
1326 pub use super::inner::IPV4_MIN_HDR_LEN;
1327
1328 pub const IPV4_TTL_OFFSET: usize = 8;
1330
1331 pub const IPV4_CHECKSUM_OFFSET: usize = 10;
1333}
1334
1335#[cfg(test)]
1336mod tests {
1337 use net_types::ethernet::Mac;
1338 use packet::{Buf, FragmentedBuffer, ParseBuffer};
1339
1340 use super::*;
1341 use crate::ethernet::{
1342 ETHERNET_MIN_BODY_LEN_NO_TAG, EtherType, EthernetFrame, EthernetFrameBuilder,
1343 EthernetFrameLengthCheck,
1344 };
1345 use crate::testutil::*;
1346
1347 const DEFAULT_SRC_MAC: Mac = Mac::new([1, 2, 3, 4, 5, 6]);
1348 const DEFAULT_DST_MAC: Mac = Mac::new([7, 8, 9, 0, 1, 2]);
1349 const DEFAULT_SRC_IP: Ipv4Addr = Ipv4Addr::new([1, 2, 3, 4]);
1350 const DEFAULT_DST_IP: Ipv4Addr = Ipv4Addr::new([5, 6, 7, 8]);
1351 const DEFAULT_V6_SRC_IP: Ipv6Addr = Ipv6Addr::new([0x2001, 0x0db8, 0, 0, 0, 0, 0, 1]);
1353 const DEFAULT_V6_DST_IP: Ipv6Addr = Ipv6Addr::new([0x2001, 0x0db8, 0, 0, 0, 0, 0, 2]);
1355
1356 #[test]
1357 fn test_parse_serialize_full_tcp() {
1358 use crate::testdata::tls_client_hello_v4::*;
1359
1360 let mut buf = ETHERNET_FRAME.bytes;
1361 let frame = buf.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1362 verify_ethernet_frame(&frame, ETHERNET_FRAME);
1363
1364 let mut body = frame.body();
1365 let packet = body.parse::<Ipv4Packet<_>>().unwrap();
1366 verify_ipv4_packet(&packet, IPV4_PACKET);
1367
1368 let buffer = packet
1370 .body()
1371 .into_serializer()
1372 .wrap_in(packet.builder())
1373 .wrap_in(frame.builder())
1374 .serialize_vec_outer()
1375 .unwrap();
1376 assert_eq!(buffer.as_ref(), ETHERNET_FRAME.bytes);
1377
1378 assert_eq!(&packet.to_vec()[..], IPV4_PACKET.bytes);
1380 }
1381
1382 #[test]
1383 fn test_parse_serialize_full_udp() {
1384 use crate::testdata::dns_request_v4::*;
1385
1386 let mut buf = ETHERNET_FRAME.bytes;
1387 let frame = buf.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1388 verify_ethernet_frame(&frame, ETHERNET_FRAME);
1389
1390 let mut body = frame.body();
1391 let packet = body.parse::<Ipv4Packet<_>>().unwrap();
1392 verify_ipv4_packet(&packet, IPV4_PACKET);
1393
1394 let buffer = packet
1396 .body()
1397 .into_serializer()
1398 .wrap_in(packet.builder())
1399 .wrap_in(frame.builder())
1400 .serialize_vec_outer()
1401 .unwrap();
1402 assert_eq!(buffer.as_ref(), ETHERNET_FRAME.bytes);
1403
1404 assert_eq!(&packet.to_vec()[..], IPV4_PACKET.bytes);
1406 }
1407
1408 #[test]
1409 fn test_parse_serialize_with_options() {
1410 use crate::testdata::igmpv2_membership::report::*;
1413
1414 let mut buf = IP_PACKET_BYTES;
1415 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1416 assert_eq!(packet.iter_options().count(), 1);
1417
1418 assert_eq!(&packet.to_vec()[..], IP_PACKET_BYTES);
1423 }
1424
1425 fn hdr_prefix_to_bytes(hdr_prefix: HeaderPrefix) -> [u8; 20] {
1426 zerocopy::transmute!(hdr_prefix)
1427 }
1428
1429 fn new_hdr_prefix() -> HeaderPrefix {
1432 HeaderPrefix::new(
1433 5,
1434 DscpAndEcn::default(),
1435 20,
1436 0x0102,
1437 0,
1438 0,
1439 0x03,
1440 IpProto::Tcp.into(),
1441 [0xa6, 0xcf],
1442 DEFAULT_SRC_IP,
1443 DEFAULT_DST_IP,
1444 )
1445 }
1446
1447 #[test]
1448 fn test_parse() {
1449 let mut bytes = &hdr_prefix_to_bytes(new_hdr_prefix())[..];
1450 let packet = bytes.parse::<Ipv4Packet<_>>().unwrap();
1451 assert_eq!(packet.id(), 0x0102);
1452 assert_eq!(packet.ttl(), 0x03);
1453 assert_eq!(packet.proto(), IpProto::Tcp.into());
1454 assert_eq!(packet.src_ip(), DEFAULT_SRC_IP);
1455 assert_eq!(packet.dst_ip(), DEFAULT_DST_IP);
1456 assert_eq!(packet.body(), []);
1457 }
1458
1459 #[test]
1460 fn test_parse_padding() {
1461 let mut buffer = Buf::new(Vec::new(), ..)
1463 .wrap_in(Ipv4PacketBuilder::new(DEFAULT_DST_IP, DEFAULT_DST_IP, 0, IpProto::Tcp.into()))
1464 .wrap_in(EthernetFrameBuilder::new(
1465 DEFAULT_SRC_MAC,
1466 DEFAULT_DST_MAC,
1467 EtherType::Ipv4,
1468 ETHERNET_MIN_BODY_LEN_NO_TAG,
1469 ))
1470 .serialize_vec_outer()
1471 .unwrap();
1472 let _: EthernetFrame<_> =
1473 buffer.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1474 assert_eq!(buffer.len(), 46);
1477 let packet = buffer.parse::<Ipv4Packet<_>>().unwrap();
1478 assert_eq!(packet.body().len(), 0);
1481 assert_eq!(buffer.len(), 0);
1485 }
1486
1487 #[test]
1488 fn test_parse_error() {
1489 let mut hdr_prefix = new_hdr_prefix();
1491 hdr_prefix.version_ihl = (5 << 4) | 5;
1492 assert_eq!(
1493 (&hdr_prefix_to_bytes(hdr_prefix)[..]).parse::<Ipv4Packet<_>>().unwrap_err(),
1494 ParseError::Format.into()
1495 );
1496
1497 let mut hdr_prefix = new_hdr_prefix();
1500 hdr_prefix.version_ihl = (4 << 4) | 4;
1501 assert_eq!(
1502 (&hdr_prefix_to_bytes(hdr_prefix)[..]).parse::<Ipv4Packet<_>>().unwrap_err(),
1503 ParseError::Format.into()
1504 );
1505
1506 let mut hdr_prefix = new_hdr_prefix();
1509 hdr_prefix.version_ihl = (4 << 4) | 6;
1510 assert_eq!(
1511 (&hdr_prefix_to_bytes(hdr_prefix)[..]).parse::<Ipv4Packet<_>>().unwrap_err(),
1512 ParseError::Format.into()
1513 );
1514 }
1515
1516 fn new_builder() -> Ipv4PacketBuilder {
1518 Ipv4PacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, 64, IpProto::Tcp.into())
1519 }
1520
1521 #[test]
1522 fn test_fragment_type() {
1523 fn test_fragment_type_helper(fragment_offset: u16, expect_fragment_type: Ipv4FragmentType) {
1524 let mut builder = new_builder();
1525 builder.fragment_offset(FragmentOffset::new(fragment_offset).unwrap());
1526
1527 let mut buf = [0; IPV4_MIN_HDR_LEN]
1528 .into_serializer()
1529 .wrap_in(builder)
1530 .serialize_vec_outer()
1531 .unwrap();
1532
1533 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1534 assert_eq!(packet.fragment_type(), expect_fragment_type);
1535 }
1536
1537 test_fragment_type_helper(0x0000, Ipv4FragmentType::InitialFragment);
1538 test_fragment_type_helper(0x0008, Ipv4FragmentType::NonInitialFragment);
1539 }
1540
1541 #[test]
1542 fn test_serialize() {
1543 let mut builder = new_builder();
1544 builder.dscp_and_ecn(DscpAndEcn::new(0x12, 3));
1545 builder.id(0x0405);
1546 builder.df_flag(true);
1547 builder.mf_flag(true);
1548 builder.fragment_offset(FragmentOffset::new(0x0607).unwrap());
1549
1550 let mut buf = (&[0, 1, 2, 3, 3, 4, 5, 7, 8, 9])
1551 .into_serializer()
1552 .wrap_in(builder)
1553 .serialize_vec_outer()
1554 .unwrap();
1555 assert_eq!(
1556 buf.as_ref(),
1557 [
1558 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,
1559 4, 5, 7, 8, 9
1560 ]
1561 );
1562 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1563 assert_eq!(packet.dscp_and_ecn().dscp(), 0x12);
1564 assert_eq!(packet.dscp_and_ecn().ecn(), 3);
1565 assert_eq!(packet.id(), 0x0405);
1566 assert!(packet.df_flag());
1567 assert!(packet.mf_flag());
1568 assert_eq!(packet.fragment_offset().into_raw(), 0x0607);
1569 assert_eq!(packet.fragment_type(), Ipv4FragmentType::NonInitialFragment);
1570 }
1571
1572 #[test]
1573 fn test_partial_serialize() {
1574 let mut builder = new_builder();
1575 builder.dscp_and_ecn(DscpAndEcn::new(0x12, 3));
1576 builder.id(0x0405);
1577 builder.df_flag(true);
1578 builder.mf_flag(true);
1579 builder.fragment_offset(FragmentOffset::new(0x0607).unwrap());
1580 let body = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
1581 let packet = (&body).into_serializer().wrap_in(builder);
1582 const HEADER_LEN: usize = 20;
1583
1584 const HEADER: [u8; HEADER_LEN] =
1587 [69, 75, 0, 30, 4, 5, 102, 7, 64, 6, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8];
1588 let mut expected_partial = HEADER.to_vec();
1589 expected_partial.resize(expected_partial.len() + body.len(), 0);
1590
1591 for i in 1..expected_partial.len() {
1592 let mut buf = vec![0u8; i];
1593 let result =
1594 packet.partial_serialize(PacketConstraints::UNCONSTRAINED, buf.as_mut_slice());
1595
1596 let bytes_written = if i >= HEADER_LEN { HEADER_LEN } else { 0 };
1599 assert_eq!(
1600 result,
1601 Ok(PartialSerializeResult { bytes_written, total_size: body.len() + HEADER_LEN })
1602 );
1603 if bytes_written > 0 {
1604 assert_eq!(buf, expected_partial[..i]);
1605 }
1606 }
1607 }
1608
1609 #[test]
1610 fn test_serialize_id_unset() {
1611 let mut builder = new_builder();
1612 builder.id(0x0405);
1613 builder.df_flag(true);
1614
1615 let mut buf = (&[0, 1, 2, 3, 3, 4, 5, 7, 8, 9])
1616 .into_serializer()
1617 .wrap_in(builder)
1618 .serialize_vec_outer()
1619 .unwrap();
1620 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1621 assert_eq!(packet.id(), 0);
1622 assert!(packet.df_flag());
1623 assert_eq!(packet.mf_flag(), false);
1624 assert_eq!(packet.fragment_offset().into_raw(), 0);
1625 assert_eq!(packet.fragment_type(), Ipv4FragmentType::InitialFragment);
1626 }
1627
1628 #[test]
1629 fn test_serialize_zeroes() {
1630 let mut buf_0 = [0; IPV4_MIN_HDR_LEN];
1633 let _: Buf<&mut [u8]> = Buf::new(&mut buf_0[..], IPV4_MIN_HDR_LEN..)
1634 .wrap_in(new_builder())
1635 .serialize_vec_outer()
1636 .unwrap()
1637 .unwrap_a();
1638 let mut buf_1 = [0xFF; IPV4_MIN_HDR_LEN];
1639 let _: Buf<&mut [u8]> = Buf::new(&mut buf_1[..], IPV4_MIN_HDR_LEN..)
1640 .wrap_in(new_builder())
1641 .serialize_vec_outer()
1642 .unwrap()
1643 .unwrap_a();
1644 assert_eq!(buf_0, buf_1);
1645 }
1646
1647 #[test]
1648 #[should_panic(expected = "(SizeLimitExceeded, Nested { inner: Buf { buf:")]
1649 fn test_serialize_panic_packet_length() {
1650 let _: Buf<&mut [u8]> = Buf::new(&mut [0; (1 << 16) - IPV4_MIN_HDR_LEN][..], ..)
1652 .wrap_in(new_builder())
1653 .serialize_vec_outer()
1654 .unwrap()
1655 .unwrap_a();
1656 }
1657
1658 #[test]
1659 fn test_copy_header_bytes_for_fragment() {
1660 let hdr_prefix = new_hdr_prefix();
1661 let mut bytes = hdr_prefix_to_bytes(hdr_prefix);
1662 let mut buf = &bytes[..];
1663 let packet = buf.parse::<Ipv4Packet<_>>().unwrap();
1664 let copied_bytes = packet.copy_header_bytes_for_fragment();
1665 bytes[IPV4_FRAGMENT_DATA_BYTE_RANGE].copy_from_slice(&[0; 4][..]);
1666 assert_eq!(&copied_bytes[..], &bytes[..]);
1667 }
1668
1669 #[test]
1670 fn test_partial_parsing() {
1671 use core::ops::Deref as _;
1672
1673 let mut hdr_prefix = new_hdr_prefix();
1676 hdr_prefix.total_len = U16::new(256);
1677 let mut bytes = hdr_prefix_to_bytes(hdr_prefix)[..].to_owned();
1678 const PAYLOAD: &[u8] = &[1, 2, 3, 4, 5];
1679 bytes.extend(PAYLOAD);
1680 let mut buf = &bytes[..];
1681 let packet = buf.parse::<Ipv4PacketRaw<_>>().unwrap();
1682 let Ipv4PacketRaw { hdr_prefix, options, body } = &packet;
1683 assert_eq!(Ref::bytes(&hdr_prefix), &bytes[0..20]);
1684 assert_eq!(options.as_ref().complete().unwrap().deref(), []);
1685 assert_eq!(body, &MaybeParsed::Incomplete(PAYLOAD));
1687 assert!(Ipv4Packet::try_from_raw(packet).is_err());
1689
1690 let mut hdr_prefix = new_hdr_prefix();
1692 hdr_prefix.version_ihl = (4 << 4) | 10;
1693 let bytes = hdr_prefix_to_bytes(hdr_prefix);
1694 let mut buf = &bytes[..];
1695 let packet = buf.parse::<Ipv4PacketRaw<_>>().unwrap();
1696 let Ipv4PacketRaw { hdr_prefix, options, body } = &packet;
1697 assert_eq!(Ref::bytes(&hdr_prefix), bytes);
1698 assert_eq!(options.as_ref().incomplete().unwrap(), &[]);
1699 assert_eq!(body.complete().unwrap(), []);
1700 assert!(Ipv4Packet::try_from_raw(packet).is_err());
1702
1703 let hdr_prefix = new_hdr_prefix();
1705 let bytes = &hdr_prefix_to_bytes(hdr_prefix);
1706 let mut buf = &bytes[0..10];
1707 assert!(buf.parse::<Ipv4PacketRaw<_>>().is_err());
1708 }
1709
1710 fn create_ipv4_and_ipv6_builders(
1711 proto_v4: Ipv4Proto,
1712 proto_v6: Ipv6Proto,
1713 ) -> (Ipv4PacketBuilder, Ipv6PacketBuilder) {
1714 const IP_DSCP_AND_ECN: DscpAndEcn = DscpAndEcn::new(0x12, 3);
1715 const IP_TTL: u8 = 64;
1716
1717 let mut ipv4_builder =
1718 Ipv4PacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, IP_TTL, proto_v4);
1719 ipv4_builder.dscp_and_ecn(IP_DSCP_AND_ECN);
1720 ipv4_builder.id(0x0405);
1721 ipv4_builder.df_flag(true);
1722 ipv4_builder.mf_flag(false);
1723 ipv4_builder.fragment_offset(FragmentOffset::ZERO);
1724
1725 let mut ipv6_builder =
1726 Ipv6PacketBuilder::new(DEFAULT_V6_SRC_IP, DEFAULT_V6_DST_IP, IP_TTL, proto_v6);
1727 ipv6_builder.dscp_and_ecn(IP_DSCP_AND_ECN);
1728 ipv6_builder.flowlabel(0);
1729
1730 (ipv4_builder, ipv6_builder)
1731 }
1732
1733 fn create_tcp_ipv4_and_ipv6_pkt()
1734 -> (packet::Either<EmptyBuf, Buf<Vec<u8>>>, packet::Either<EmptyBuf, Buf<Vec<u8>>>) {
1735 use crate::tcp::TcpSegmentBuilder;
1736 use core::num::NonZeroU16;
1737
1738 let tcp_src_port: NonZeroU16 = NonZeroU16::new(20).unwrap();
1739 let tcp_dst_port: NonZeroU16 = NonZeroU16::new(30).unwrap();
1740 const TCP_SEQ_NUM: u32 = 4321;
1741 const TCP_ACK_NUM: Option<u32> = Some(1234);
1742 const TCP_WINDOW_SIZE: u16 = 12345;
1743 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
1744
1745 let (ipv4_builder, ipv6_builder) =
1746 create_ipv4_and_ipv6_builders(IpProto::Tcp.into(), IpProto::Tcp.into());
1747
1748 let tcp_builder = TcpSegmentBuilder::new(
1749 DEFAULT_SRC_IP,
1750 DEFAULT_DST_IP,
1751 tcp_src_port,
1752 tcp_dst_port,
1753 TCP_SEQ_NUM,
1754 TCP_ACK_NUM,
1755 TCP_WINDOW_SIZE,
1756 );
1757
1758 let v4_pkt_buf = (&PAYLOAD)
1759 .into_serializer()
1760 .wrap_in(tcp_builder)
1761 .wrap_in(ipv4_builder)
1762 .serialize_vec_outer()
1763 .unwrap();
1764
1765 let v6_tcp_builder = TcpSegmentBuilder::new(
1766 DEFAULT_V6_SRC_IP,
1767 DEFAULT_V6_DST_IP,
1768 tcp_src_port,
1769 tcp_dst_port,
1770 TCP_SEQ_NUM,
1771 TCP_ACK_NUM,
1772 TCP_WINDOW_SIZE,
1773 );
1774
1775 let v6_pkt_buf = (&PAYLOAD)
1776 .into_serializer()
1777 .wrap_in(v6_tcp_builder)
1778 .wrap_in(ipv6_builder)
1779 .serialize_vec_outer()
1780 .unwrap();
1781
1782 (v4_pkt_buf, v6_pkt_buf)
1783 }
1784
1785 #[test]
1786 fn test_nat64_translate_tcp() {
1787 let (mut v4_pkt_buf, expected_v6_pkt_buf) = create_tcp_ipv4_and_ipv6_pkt();
1788
1789 let parsed_v4_packet = v4_pkt_buf.parse::<Ipv4Packet<_>>().unwrap();
1790 let nat64_translation_result =
1791 parsed_v4_packet.nat64_translate(DEFAULT_V6_SRC_IP, DEFAULT_V6_DST_IP);
1792
1793 let serializable_pkt = match nat64_translation_result {
1794 Nat64TranslationResult::Forward(s) => s,
1795 _ => panic!("Nat64TranslationResult not of Forward type!"),
1796 };
1797
1798 let translated_v6_pkt_buf = serializable_pkt.serialize_vec_outer().unwrap();
1799
1800 assert_eq!(
1801 expected_v6_pkt_buf.to_flattened_vec(),
1802 translated_v6_pkt_buf.to_flattened_vec()
1803 );
1804 }
1805
1806 fn create_udp_ipv4_and_ipv6_pkt()
1807 -> (packet::Either<EmptyBuf, Buf<Vec<u8>>>, packet::Either<EmptyBuf, Buf<Vec<u8>>>) {
1808 use crate::udp::UdpPacketBuilder;
1809 use core::num::NonZeroU16;
1810
1811 let udp_src_port: NonZeroU16 = NonZeroU16::new(35000).unwrap();
1812 let udp_dst_port: NonZeroU16 = NonZeroU16::new(53).unwrap();
1813 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
1814
1815 let (ipv4_builder, ipv6_builder) =
1816 create_ipv4_and_ipv6_builders(IpProto::Udp.into(), IpProto::Udp.into());
1817
1818 let udp_builder =
1819 UdpPacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, Some(udp_src_port), udp_dst_port);
1820
1821 let v4_pkt_buf = (&PAYLOAD)
1822 .into_serializer()
1823 .wrap_in(udp_builder)
1824 .wrap_in(ipv4_builder)
1825 .serialize_vec_outer()
1826 .unwrap();
1827
1828 let v6_udp_builder = UdpPacketBuilder::new(
1829 DEFAULT_V6_SRC_IP,
1830 DEFAULT_V6_DST_IP,
1831 Some(udp_src_port),
1832 udp_dst_port,
1833 );
1834
1835 let v6_pkt_buf = (&PAYLOAD)
1836 .into_serializer()
1837 .wrap_in(v6_udp_builder)
1838 .wrap_in(ipv6_builder)
1839 .serialize_vec_outer()
1840 .unwrap();
1841
1842 (v4_pkt_buf, v6_pkt_buf)
1843 }
1844
1845 #[test]
1846 fn test_nat64_translate_udp() {
1847 let (mut v4_pkt_buf, expected_v6_pkt_buf) = create_udp_ipv4_and_ipv6_pkt();
1848
1849 let parsed_v4_packet = v4_pkt_buf.parse::<Ipv4Packet<_>>().unwrap();
1850 let nat64_translation_result =
1851 parsed_v4_packet.nat64_translate(DEFAULT_V6_SRC_IP, DEFAULT_V6_DST_IP);
1852
1853 let serializable_pkt = match nat64_translation_result {
1854 Nat64TranslationResult::Forward(s) => s,
1855 _ => panic!(
1856 "Nat64TranslationResult not of Forward type: {:?} ",
1857 nat64_translation_result
1858 ),
1859 };
1860
1861 let translated_v6_pkt_buf = serializable_pkt.serialize_vec_outer().unwrap();
1862
1863 assert_eq!(
1864 expected_v6_pkt_buf.to_flattened_vec(),
1865 translated_v6_pkt_buf.to_flattened_vec()
1866 );
1867 }
1868
1869 #[test]
1870 fn test_nat64_translate_non_tcp_udp_icmp() {
1871 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
1872
1873 let (ipv4_builder, ipv6_builder) =
1874 create_ipv4_and_ipv6_builders(Ipv4Proto::Other(50), Ipv6Proto::Other(50));
1875
1876 let mut v4_pkt_buf =
1877 (&PAYLOAD).into_serializer().wrap_in(ipv4_builder).serialize_vec_outer().unwrap();
1878
1879 let expected_v6_pkt_buf =
1880 (&PAYLOAD).into_serializer().wrap_in(ipv6_builder).serialize_vec_outer().unwrap();
1881
1882 let translated_v6_pkt_buf = {
1883 let parsed_v4_packet = v4_pkt_buf.parse::<Ipv4Packet<_>>().unwrap();
1884
1885 let nat64_translation_result =
1886 parsed_v4_packet.nat64_translate(DEFAULT_V6_SRC_IP, DEFAULT_V6_DST_IP);
1887
1888 let serializable_pkt = match nat64_translation_result {
1889 Nat64TranslationResult::Forward(s) => s,
1890 _ => panic!(
1891 "Nat64TranslationResult not of Forward type: {:?} ",
1892 nat64_translation_result
1893 ),
1894 };
1895
1896 let translated_buf = serializable_pkt.serialize_vec_outer().unwrap();
1897
1898 translated_buf
1899 };
1900
1901 assert_eq!(
1902 expected_v6_pkt_buf.to_flattened_vec(),
1903 translated_v6_pkt_buf.to_flattened_vec()
1904 );
1905 }
1906
1907 #[test]
1908 fn test_partial_serialize_parsed() {
1909 let packet_bytes = [
1910 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, 4,
1911 5, 7, 8, 9,
1912 ];
1913 let packet_len = packet_bytes.len();
1914 let mut packet_bytes_copy = packet_bytes;
1915 let mut packet_bytes_ref: &mut [u8] = &mut packet_bytes_copy[..];
1916 let packet = packet_bytes_ref.parse::<Ipv4Packet<_>>().unwrap();
1917
1918 for i in 1..(packet_len + 1) {
1919 let mut buf = vec![0u8; i];
1920 let result =
1921 packet.partial_serialize(PacketConstraints::UNCONSTRAINED, buf.as_mut_slice());
1922
1923 let bytes_written = if i >= packet_len { packet_len } else { i };
1924 assert_eq!(
1925 result,
1926 Ok(PartialSerializeResult { bytes_written, total_size: packet_len })
1927 );
1928 assert_eq!(buf[..bytes_written], packet_bytes[..bytes_written]);
1929 }
1930 }
1931}