1pub mod ext_hdrs;
12
13use alloc::vec::Vec;
14use core::borrow::Borrow;
15use core::convert::Infallible as Never;
16use core::fmt::{self, Debug, Formatter};
17use core::ops::Range;
18
19use log::debug;
20use net_types::ip::{GenericOverIp, Ipv4Addr, Ipv6, Ipv6Addr, Ipv6SourceAddr};
21use packet::records::{AlignedRecordSequenceBuilder, Records, RecordsRaw};
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, U32};
29use zerocopy::{
30 FromBytes, Immutable, IntoBytes, KnownLayout, Ref, SplitByteSlice, SplitByteSliceMut, Unaligned,
31};
32
33use crate::error::{IpParseError, IpParseErrorAction, IpParseResult, ParseError};
34use crate::icmp::Icmpv6ParameterProblemCode;
35use crate::ip::{
36 DscpAndEcn, FragmentOffset, IpExt, IpPacketBuilder, IpProto, Ipv4Proto, Ipv6ExtHdrType,
37 Ipv6Proto, Nat64Error, Nat64TranslationResult,
38};
39use crate::ipv4::{HDR_PREFIX_LEN, Ipv4PacketBuilder};
40use crate::tcp::{TcpParseArgs, TcpSegment};
41use crate::udp::{UdpPacket, UdpParseArgs};
42
43use ext_hdrs::{
44 ExtensionHeaderOptionAction, HopByHopOption, HopByHopOptionData, IPV6_FRAGMENT_EXT_HDR_LEN,
45 Ipv6ExtensionHeader, Ipv6ExtensionHeaderData, Ipv6ExtensionHeaderImpl,
46 Ipv6ExtensionHeaderParsingContext, Ipv6ExtensionHeaderParsingError, is_valid_next_header,
47 is_valid_next_header_upper_layer,
48};
49
50pub const IPV6_FIXED_HDR_LEN: usize = 40;
52
53pub const IPV6_PAYLOAD_LEN_BYTE_RANGE: Range<usize> = 4..6;
56
57const NEXT_HEADER_OFFSET: u8 = 6;
59
60const IPV6_HBH_OPTIONS_MAX_LEN: usize = (core::u8::MAX as usize) * 8 + 8;
64
65const IPV6_MAX_PAYLOAD_LENGTH: usize = core::u16::MAX as usize;
72
73fn ext_hdr_err_fn(hdr: &FixedHeader, err: Ipv6ExtensionHeaderParsingError) -> IpParseError<Ipv6> {
76 match err {
95 Ipv6ExtensionHeaderParsingError::ErroneousHeaderField {
96 pointer,
97 must_send_icmp,
98 header_len: _,
99 } => {
100 let (pointer, action) = match pointer.checked_add(IPV6_FIXED_HDR_LEN as u32) {
101 None => (0, IpParseErrorAction::DiscardPacket),
105 Some(p) => (p, IpParseErrorAction::DiscardPacketSendIcmpNoMulticast),
109 };
110
111 IpParseError::ParameterProblem {
112 src_ip: hdr.src_ip,
113 dst_ip: hdr.dst_ip,
114 code: Icmpv6ParameterProblemCode::ErroneousHeaderField,
115 pointer,
116 must_send_icmp,
117 header_len: (),
118 action,
119 }
120 }
121 Ipv6ExtensionHeaderParsingError::UnrecognizedNextHeader {
122 pointer,
123 must_send_icmp,
124 header_len: _,
125 } => {
126 let (pointer, action) = match pointer.checked_add(IPV6_FIXED_HDR_LEN as u32) {
127 None => (0, IpParseErrorAction::DiscardPacket),
128 Some(p) => (p, IpParseErrorAction::DiscardPacketSendIcmpNoMulticast),
129 };
130
131 IpParseError::ParameterProblem {
132 src_ip: hdr.src_ip,
133 dst_ip: hdr.dst_ip,
134 code: Icmpv6ParameterProblemCode::UnrecognizedNextHeaderType,
135 pointer,
136 must_send_icmp,
137 header_len: (),
138 action,
139 }
140 }
141 Ipv6ExtensionHeaderParsingError::UnrecognizedOption {
142 pointer,
143 must_send_icmp,
144 header_len: _,
145 action,
146 } => {
147 let (pointer, action) = match pointer.checked_add(IPV6_FIXED_HDR_LEN as u32) {
148 None => (0, IpParseErrorAction::DiscardPacket),
149 Some(p) => {
150 let action = match action {
151 ExtensionHeaderOptionAction::SkipAndContinue => unreachable!(
152 "Should never end up here because this action should never result in an error"
153 ),
154 ExtensionHeaderOptionAction::DiscardPacket => {
155 IpParseErrorAction::DiscardPacket
156 }
157 ExtensionHeaderOptionAction::DiscardPacketSendIcmp => {
158 IpParseErrorAction::DiscardPacketSendIcmp
159 }
160 ExtensionHeaderOptionAction::DiscardPacketSendIcmpNoMulticast => {
161 IpParseErrorAction::DiscardPacketSendIcmpNoMulticast
162 }
163 };
164
165 (p, action)
166 }
167 };
168
169 IpParseError::ParameterProblem {
170 src_ip: hdr.src_ip,
171 dst_ip: hdr.dst_ip,
172 code: Icmpv6ParameterProblemCode::UnrecognizedIpv6Option,
173 pointer,
174 must_send_icmp,
175 header_len: (),
176 action,
177 }
178 }
179 Ipv6ExtensionHeaderParsingError::BufferExhausted
180 | Ipv6ExtensionHeaderParsingError::MalformedData => {
181 IpParseError::Parse { error: ParseError::Format }
184 }
185 }
186}
187
188#[derive(Debug, Default, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, PartialEq)]
190#[repr(C)]
191pub struct FixedHeader {
192 version_tc_flowlabel: [u8; 4],
193 payload_len: U16,
194 next_hdr: u8,
195 hop_limit: u8,
196 src_ip: Ipv6Addr,
197 dst_ip: Ipv6Addr,
198}
199
200const IP_VERSION: u8 = 6;
201const VERSION_OFFSET: u8 = 4;
202const FLOW_LABEL_MAX: u32 = (1 << 20) - 1;
203
204impl FixedHeader {
205 #[allow(clippy::too_many_arguments)]
206 fn new(
207 dscp_and_ecn: DscpAndEcn,
208 flow_label: u32,
209 payload_len: u16,
210 next_hdr: u8,
211 hop_limit: u8,
212 src_ip: Ipv6Addr,
213 dst_ip: Ipv6Addr,
214 ) -> FixedHeader {
215 debug_assert!(flow_label <= FLOW_LABEL_MAX);
216
217 let traffic_class = dscp_and_ecn.raw();
218 FixedHeader {
219 version_tc_flowlabel: [
220 IP_VERSION << VERSION_OFFSET | traffic_class >> 4,
221 (traffic_class << 4) | ((flow_label >> 16) as u8),
222 (flow_label >> 8) as u8,
223 flow_label as u8,
224 ],
225 payload_len: U16::new(payload_len),
226 next_hdr,
227 hop_limit,
228 src_ip,
229 dst_ip,
230 }
231 }
232
233 fn version(&self) -> u8 {
234 self.version_tc_flowlabel[0] >> 4
235 }
236
237 fn dscp_and_ecn(&self) -> DscpAndEcn {
238 ((self.version_tc_flowlabel[0] & 0xF) << 4 | self.version_tc_flowlabel[1] >> 4).into()
239 }
240
241 fn flowlabel(&self) -> u32 {
242 (u32::from(self.version_tc_flowlabel[1]) & 0xF) << 16
243 | u32::from(self.version_tc_flowlabel[2]) << 8
244 | u32::from(self.version_tc_flowlabel[3])
245 }
246}
247
248pub trait Ipv6Header {
253 fn get_fixed_header(&self) -> &FixedHeader;
255
256 fn hop_limit(&self) -> u8 {
258 self.get_fixed_header().hop_limit
259 }
260
261 fn next_header(&self) -> u8 {
263 self.get_fixed_header().next_hdr
264 }
265
266 fn src_ip(&self) -> Ipv6Addr {
268 self.get_fixed_header().src_ip
269 }
270
271 fn dst_ip(&self) -> Ipv6Addr {
273 self.get_fixed_header().dst_ip
274 }
275
276 fn dscp_and_ecn(&self) -> DscpAndEcn {
279 self.get_fixed_header().dscp_and_ecn()
280 }
281}
282
283impl Ipv6Header for FixedHeader {
284 fn get_fixed_header(&self) -> &FixedHeader {
285 self
286 }
287}
288
289pub struct Ipv6Packet<B> {
295 fixed_hdr: Ref<B, FixedHeader>,
296 extension_hdrs: Records<B, Ipv6ExtensionHeaderImpl>,
297 body: B,
298 proto: Ipv6Proto,
299}
300
301impl<B: SplitByteSlice, I: IpExt> GenericOverIp<I> for Ipv6Packet<B> {
302 type Type = <I as IpExt>::Packet<B>;
303}
304
305impl<B: SplitByteSlice> Ipv6Header for Ipv6Packet<B> {
306 fn get_fixed_header(&self) -> &FixedHeader {
307 &self.fixed_hdr
308 }
309}
310
311impl<B: SplitByteSlice> ParsablePacket<B, ()> for Ipv6Packet<B> {
312 type Error = IpParseError<Ipv6>;
313
314 fn parse_metadata(&self) -> ParseMetadata {
315 let header_len = Ref::bytes(&self.fixed_hdr).len() + self.extension_hdrs.bytes().len();
316 ParseMetadata::from_packet(header_len, self.body.len(), 0)
317 }
318
319 fn parse<BV: BufferView<B>>(buffer: BV, _args: ()) -> IpParseResult<Ipv6, Self> {
320 Ipv6PacketRaw::parse(buffer, ()).and_then(Ipv6Packet::try_from_raw)
321 }
322}
323
324impl<B: SplitByteSlice> FromRaw<Ipv6PacketRaw<B>, ()> for Ipv6Packet<B> {
325 type Error = IpParseError<Ipv6>;
326
327 fn try_from_raw_with(raw: Ipv6PacketRaw<B>, _args: ()) -> Result<Self, Self::Error> {
328 let fixed_hdr = raw.fixed_hdr;
329
330 if !is_valid_next_header(fixed_hdr.next_hdr, true) {
333 return debug_err!(
334 Err(IpParseError::ParameterProblem {
335 src_ip: fixed_hdr.src_ip,
336 dst_ip: fixed_hdr.dst_ip,
337 code: Icmpv6ParameterProblemCode::UnrecognizedNextHeaderType,
338 pointer: u32::from(NEXT_HEADER_OFFSET),
339 must_send_icmp: false,
340 header_len: (),
341 action: IpParseErrorAction::DiscardPacketSendIcmpNoMulticast,
342 }),
343 "Unrecognized next header value"
344 );
345 }
346
347 let extension_hdrs = match raw.extension_hdrs {
348 MaybeParsed::Complete(v) => {
349 Records::try_from_raw(v).map_err(|e| ext_hdr_err_fn(&fixed_hdr, e))?
350 }
351 MaybeParsed::Incomplete(_) => {
352 return debug_err!(
353 Err(ParseError::Format.into()),
354 "Incomplete IPv6 extension headers"
355 );
356 }
357 };
358
359 let (body, proto) =
363 raw.body_proto.expect("Unable to retrieve Ipv6Proto or MaybeParsed body from raw");
364 debug_assert!(is_valid_next_header_upper_layer(proto.into()));
365
366 let body = match body {
367 MaybeParsed::Complete(b) => b,
368 MaybeParsed::Incomplete(_b) => {
369 return debug_err!(Err(ParseError::Format.into()), "IPv6 body unretrievable.");
370 }
371 };
372
373 if extension_hdrs.bytes().len() + body.len() != usize::from(fixed_hdr.payload_len.get()) {
378 return debug_err!(
379 Err(ParseError::Format.into()),
380 "Payload len does not match body and extension headers"
381 );
382 }
383
384 if fixed_hdr.version() != 6 {
386 return debug_err!(
387 Err(ParseError::Format.into()),
388 "unexpected IP version: {}",
389 fixed_hdr.version()
390 );
391 }
392
393 Ok(Ipv6Packet { fixed_hdr, extension_hdrs, body, proto })
394 }
395}
396
397impl<B: SplitByteSlice> PartialSerializer for Ipv6Packet<B> {
398 fn partial_serialize(
399 &self,
400 _outer: PacketConstraints,
401 mut buffer: &mut [u8],
402 ) -> Result<PartialSerializeResult, SerializeError<Never>> {
403 let fixed_hdr = Ref::bytes(&self.fixed_hdr);
404 let extension_hdrs = self.extension_hdrs.bytes();
405
406 let mut buffer = &mut buffer;
407 let bytes_written = buffer.write_bytes_front_allow_partial(Ref::bytes(&self.fixed_hdr))
408 + buffer.write_bytes_front_allow_partial(self.extension_hdrs.bytes())
409 + buffer.write_bytes_front_allow_partial(&self.body);
410 let total_size = fixed_hdr.len() + extension_hdrs.len() + self.body.len();
411
412 Ok(PartialSerializeResult { bytes_written, total_size })
413 }
414}
415
416impl<B: SplitByteSlice> Ipv6Packet<B> {
417 pub fn iter_extension_hdrs(&self) -> impl Iterator<Item = Ipv6ExtensionHeader<'_>> {
419 self.extension_hdrs.iter()
420 }
421
422 pub fn body(&self) -> &[u8] {
424 &self.body
425 }
426
427 pub fn dscp_and_ecn(&self) -> DscpAndEcn {
430 self.fixed_hdr.dscp_and_ecn()
431 }
432
433 pub fn flowlabel(&self) -> u32 {
435 self.fixed_hdr.flowlabel()
436 }
437
438 pub fn proto(&self) -> Ipv6Proto {
444 self.proto
445 }
446
447 pub fn src_ipv6(&self) -> Option<Ipv6SourceAddr> {
454 Ipv6SourceAddr::new(self.fixed_hdr.src_ip)
455 }
456
457 pub fn copy_header_bytes_for_fragment(&self) -> Vec<u8> {
468 let expected_bytes_len = self.header_len() - IPV6_FRAGMENT_EXT_HDR_LEN;
471 let mut bytes = Vec::with_capacity(expected_bytes_len);
472
473 bytes.extend_from_slice(Ref::bytes(&self.fixed_hdr));
474
475 let mut iter = self.extension_hdrs.iter();
479
480 let ext_hdr = iter.next().expect("packet must have at least one extension header");
484
485 if self.fixed_hdr.next_hdr == Ipv6ExtHdrType::Fragment.into() {
486 bytes[6] = ext_hdr.next_header;
492
493 bytes.extend_from_slice(&self.extension_hdrs.bytes()[IPV6_FRAGMENT_EXT_HDR_LEN..]);
495 } else {
496 let mut ext_hdr = ext_hdr;
497 let mut ext_hdr_start = 0;
498 let mut ext_hdr_end = iter.context().bytes_parsed;
499
500 loop {
506 let next_ext_hdr = iter
512 .next()
513 .expect("exhausted all extension headers without finding fragment header");
514
515 if let Ipv6ExtensionHeaderData::Fragment { .. } = next_ext_hdr.data() {
516 let fragment_hdr_end = ext_hdr_end + IPV6_FRAGMENT_EXT_HDR_LEN;
523 assert_eq!(fragment_hdr_end, iter.context().bytes_parsed);
524
525 let extension_hdr_bytes = self.extension_hdrs.bytes();
526
527 bytes.extend_from_slice(&extension_hdr_bytes[..ext_hdr_end]);
529
530 bytes.extend_from_slice(&extension_hdr_bytes[fragment_hdr_end..]);
532
533 match ext_hdr.data() {
536 Ipv6ExtensionHeaderData::HopByHopOptions { .. }
539 | Ipv6ExtensionHeaderData::DestinationOptions { .. } => {
540 bytes[IPV6_FIXED_HDR_LEN + ext_hdr_start] = next_ext_hdr.next_header;
541 }
542 Ipv6ExtensionHeaderData::Fragment { .. } => unreachable!(
543 "If we had a fragment header before `ext_hdr`, we should have used that instead"
544 ),
545 }
546
547 break;
548 }
549
550 ext_hdr = next_ext_hdr;
551 ext_hdr_start = ext_hdr_end;
552 ext_hdr_end = iter.context().bytes_parsed;
553 }
554 }
555
556 assert_eq!(bytes.len(), expected_bytes_len);
558 bytes
559 }
560
561 fn header_len(&self) -> usize {
562 Ref::bytes(&self.fixed_hdr).len() + self.extension_hdrs.bytes().len()
563 }
564
565 fn fragment_header_present(&self) -> bool {
566 for ext_hdr in self.extension_hdrs.iter() {
567 if matches!(ext_hdr.data(), Ipv6ExtensionHeaderData::Fragment { .. }) {
568 return true;
569 }
570 }
571 false
572 }
573
574 pub fn builder(&self) -> Ipv6PacketBuilder {
576 Ipv6PacketBuilder {
577 dscp_and_ecn: self.dscp_and_ecn(),
578 flowlabel: self.flowlabel(),
579 hop_limit: self.hop_limit(),
580 proto: self.proto(),
581 src_ip: self.src_ip(),
582 dst_ip: self.dst_ip(),
583 }
584 }
585
586 pub fn nat64_translate(
612 &self,
613 v4_src_addr: Ipv4Addr,
614 v4_dst_addr: Ipv4Addr,
615 ) -> Nat64TranslationResult<impl Serializer<Buffer = EmptyBuf> + Debug + '_, Nat64Error> {
616 #[derive(Debug)]
619 enum Nat64Serializer<T, U, O> {
620 Tcp(T),
621 Udp(U),
622 Other(O),
623 }
624
625 impl<T, U, O> Serializer for Nat64Serializer<T, U, O>
626 where
627 T: Serializer<Buffer = EmptyBuf>,
628 U: Serializer<Buffer = EmptyBuf>,
629 O: Serializer<Buffer = EmptyBuf>,
630 {
631 type Buffer = EmptyBuf;
632 fn serialize<B, P>(
633 self,
634 outer: PacketConstraints,
635 provider: P,
636 ) -> Result<B, (SerializeError<P::Error>, Self)>
637 where
638 B: GrowBufferMut,
639 P: BufferProvider<Self::Buffer, B>,
640 {
641 match self {
642 Nat64Serializer::Tcp(serializer) => serializer
643 .serialize(outer, provider)
644 .map_err(|(err, ser)| (err, Nat64Serializer::Tcp(ser))),
645 Nat64Serializer::Udp(serializer) => serializer
646 .serialize(outer, provider)
647 .map_err(|(err, ser)| (err, Nat64Serializer::Udp(ser))),
648 Nat64Serializer::Other(serializer) => serializer
649 .serialize(outer, provider)
650 .map_err(|(err, ser)| (err, Nat64Serializer::Other(ser))),
651 }
652 }
653
654 fn serialize_new_buf<B: GrowBufferMut, A: LayoutBufferAlloc<B>>(
655 &self,
656 outer: PacketConstraints,
657 alloc: A,
658 ) -> Result<B, SerializeError<A::Error>> {
659 match self {
660 Nat64Serializer::Tcp(serializer) => serializer.serialize_new_buf(outer, alloc),
661 Nat64Serializer::Udp(serializer) => serializer.serialize_new_buf(outer, alloc),
662 Nat64Serializer::Other(serializer) => {
663 serializer.serialize_new_buf(outer, alloc)
664 }
665 }
666 }
667 }
668
669 if self.fragment_header_present() {
672 return Nat64TranslationResult::Err(Nat64Error::NotImplemented);
673 }
674
675 let v4_builder = |v4_proto| {
676 let mut builder =
677 Ipv4PacketBuilder::new(v4_src_addr, v4_dst_addr, self.hop_limit(), v4_proto);
678 builder.dscp_and_ecn(self.dscp_and_ecn());
679
680 const IPV4_HEADER_LEN_BYTES: usize = HDR_PREFIX_LEN;
685
686 builder.df_flag(self.body().len() + IPV4_HEADER_LEN_BYTES > 1260);
692
693 builder.fragment_offset(FragmentOffset::ZERO);
696 builder.mf_flag(false);
697
698 builder
699 };
700
701 match self.proto() {
702 Ipv6Proto::Proto(IpProto::Tcp) => {
703 let v4_pkt_builder = v4_builder(Ipv4Proto::Proto(IpProto::Tcp));
704 let args = TcpParseArgs::new(self.src_ip(), self.dst_ip());
705 match TcpSegment::parse(&mut self.body.as_bytes(), args) {
710 Ok(tcp) => {
711 let tcp_serializer =
715 Nat64Serializer::Tcp(tcp.into_serializer(v4_src_addr, v4_dst_addr));
716 Nat64TranslationResult::Forward(v4_pkt_builder.wrap_body(tcp_serializer))
717 }
718 Err(msg) => {
719 debug!("Parsing of TCP segment failed: {:?}", msg);
720
721 let common_serializer =
730 Nat64Serializer::Other(self.body().into_serializer());
731 Nat64TranslationResult::Forward(v4_pkt_builder.wrap_body(common_serializer))
732 }
733 }
734 }
735
736 Ipv6Proto::Proto(IpProto::Udp) => {
741 let v4_pkt_builder = v4_builder(Ipv4Proto::Proto(IpProto::Udp));
742 let args = UdpParseArgs::new(self.src_ip(), self.dst_ip());
743 match UdpPacket::parse(&mut self.body.as_bytes(), args) {
744 Ok(udp) => {
745 let udp_serializer =
749 Nat64Serializer::Udp(udp.into_serializer(v4_src_addr, v4_dst_addr));
750 Nat64TranslationResult::Forward(v4_pkt_builder.wrap_body(udp_serializer))
751 }
752 Err(msg) => {
753 debug!("Parsing of UDP packet failed: {:?}", msg);
754
755 let common_serializer =
765 Nat64Serializer::Other(self.body().into_serializer());
766 Nat64TranslationResult::Forward(v4_pkt_builder.wrap_body(common_serializer))
767 }
768 }
769 }
770
771 Ipv6Proto::Icmpv6 => Nat64TranslationResult::Err(Nat64Error::NotImplemented),
774
775 Ipv6Proto::Other(val) => {
795 let v4_pkt_builder = v4_builder(Ipv4Proto::Other(val));
796 let common_serializer = Nat64Serializer::Other(self.body().into_serializer());
797 Nat64TranslationResult::Forward(v4_pkt_builder.wrap_body(common_serializer))
798 }
799
800 Ipv6Proto::NoNextHeader => {
801 let v4_pkt_builder = v4_builder(Ipv4Proto::Other(Ipv6Proto::NoNextHeader.into()));
802 let common_serializer = Nat64Serializer::Other(self.body().into_serializer());
803 Nat64TranslationResult::Forward(v4_pkt_builder.wrap_body(common_serializer))
804 }
805
806 Ipv6Proto::Proto(IpProto::Reserved) => Nat64TranslationResult::Drop,
809 }
810 }
811
812 pub fn to_vec(&self) -> Vec<u8> {
814 let Ipv6Packet { fixed_hdr, extension_hdrs, body, proto: _ } = self;
815 let mut buf = Vec::with_capacity(
816 Ref::bytes(&fixed_hdr).len() + extension_hdrs.bytes().len() + body.as_bytes().len(),
817 );
818 buf.extend(Ref::bytes(&fixed_hdr));
819 buf.extend(extension_hdrs.bytes());
820 buf.extend(body.as_bytes());
821 buf
822 }
823}
824
825impl<B: SplitByteSliceMut> Ipv6Packet<B> {
826 pub fn set_src_ip(&mut self, addr: Ipv6Addr) {
828 self.fixed_hdr.src_ip = addr;
829 }
830
831 pub fn set_dst_ip(&mut self, addr: Ipv6Addr) {
833 self.fixed_hdr.dst_ip = addr;
834 }
835
836 pub fn set_hop_limit(&mut self, hlim: u8) {
838 self.fixed_hdr.hop_limit = hlim;
839 }
840
841 pub fn body_mut(&mut self) -> &mut [u8] {
843 &mut self.body
844 }
845
846 pub fn parts_with_body_mut(&mut self) -> (&FixedHeader, ExtensionHeaders<'_>, &mut [u8]) {
849 (&self.fixed_hdr, ExtensionHeaders(self.extension_hdrs.as_ref()), &mut self.body)
850 }
851}
852
853impl<B: SplitByteSlice> Debug for Ipv6Packet<B> {
854 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
855 f.debug_struct("Ipv6Packet")
856 .field("src_ip", &self.src_ip())
857 .field("dst_ip", &self.dst_ip())
858 .field("hop_limit", &self.hop_limit())
859 .field("proto", &self.proto())
860 .field("dscp", &self.dscp_and_ecn().dscp())
861 .field("ecn", &self.dscp_and_ecn().ecn())
862 .field("flowlabel", &self.flowlabel())
863 .field("extension headers", &"TODO")
864 .field("body", &alloc::format!("<{} bytes>", self.body.len()))
865 .finish()
866 }
867}
868
869pub struct ExtensionHeaders<'a>(Records<&'a [u8], Ipv6ExtensionHeaderImpl>);
871
872impl<'a> ExtensionHeaders<'a> {
873 pub fn iter(&self) -> impl Iterator<Item = Ipv6ExtensionHeader<'_>> {
875 self.0.iter()
876 }
877
878 pub fn bytes(&self) -> &[u8] {
880 self.0.bytes()
881 }
882}
883
884#[derive(Copy, Clone, Debug, Eq, PartialEq)]
890pub struct ExtHdrParseError;
891
892pub struct Ipv6PacketRaw<B> {
902 fixed_hdr: Ref<B, FixedHeader>,
904 extension_hdrs: MaybeParsed<RecordsRaw<B, Ipv6ExtensionHeaderImpl>, B>,
910 body_proto: Result<(MaybeParsed<B, B>, Ipv6Proto), ExtHdrParseError>,
923}
924
925impl<B> Ipv6PacketRaw<B> {
926 pub fn body_mut(&mut self) -> Option<&mut B> {
930 match self.body_proto {
931 Ok(ref mut b) => match b {
932 (MaybeParsed::Complete(b), _) => Some(b),
933 (MaybeParsed::Incomplete(b), _) => Some(b),
934 },
935 Err(_) => None,
936 }
937 }
938}
939
940impl<B: SplitByteSlice> Ipv6Header for Ipv6PacketRaw<B> {
941 fn get_fixed_header(&self) -> &FixedHeader {
942 &self.fixed_hdr
943 }
944}
945
946impl<B: SplitByteSlice> ParsablePacket<B, ()> for Ipv6PacketRaw<B> {
947 type Error = IpParseError<Ipv6>;
948
949 fn parse<BV: BufferView<B>>(mut buffer: BV, _args: ()) -> Result<Self, Self::Error> {
950 let fixed_hdr = buffer
951 .take_obj_front::<FixedHeader>()
952 .ok_or_else(debug_err_fn!(ParseError::Format, "too few bytes for header"))?;
953 let payload_len = fixed_hdr.payload_len.get().into();
954 let _: Option<B> = buffer.len().checked_sub(payload_len).map(|padding| {
956 buffer.take_back(padding).unwrap_or_else(|| {
957 panic!("buffer.len()={} padding={}", buffer.len(), padding);
958 })
959 });
960
961 let mut extension_hdr_context = Ipv6ExtensionHeaderParsingContext::new(fixed_hdr.next_hdr);
962
963 let extension_hdrs =
964 RecordsRaw::parse_raw_with_mut_context(&mut buffer, &mut extension_hdr_context)
965 .map_incomplete(|(b, _)| b);
966
967 let body_proto = match &extension_hdrs {
968 MaybeParsed::Complete(r) => {
969 let _: &RecordsRaw<B, _> = r;
970 assert!(is_valid_next_header_upper_layer(extension_hdr_context.next_header));
991 let proto = Ipv6Proto::from(extension_hdr_context.next_header);
992 let body = MaybeParsed::new_with_min_len(
993 buffer.into_rest(),
994 payload_len.saturating_sub(extension_hdrs.len()),
995 );
996 Ok((body, proto))
997 }
998 MaybeParsed::Incomplete(b) => {
999 let _: &B = b;
1000 Err(ExtHdrParseError)
1001 }
1002 };
1003
1004 Ok(Ipv6PacketRaw { fixed_hdr, extension_hdrs, body_proto })
1005 }
1006
1007 fn parse_metadata(&self) -> ParseMetadata {
1008 let header_len = Ref::bytes(&self.fixed_hdr).len() + self.extension_hdrs.len();
1009 let body_len = self.body_proto.as_ref().map(|(b, _p)| b.len()).unwrap_or(0);
1010 ParseMetadata::from_packet(header_len, body_len, 0)
1011 }
1012}
1013
1014impl<B: SplitByteSlice> Ipv6PacketRaw<B> {
1015 pub fn body_proto(&self) -> Result<(MaybeParsed<&[u8], &[u8]>, Ipv6Proto), ExtHdrParseError> {
1028 self.body_proto
1029 .as_ref()
1030 .map(|(mp, proto)| {
1031 (mp.as_ref().map(|b| b.deref()).map_incomplete(|b| b.deref()), *proto)
1032 })
1033 .map_err(|e| *e)
1034 }
1035
1036 pub fn body(&self) -> Result<MaybeParsed<&[u8], &[u8]>, ExtHdrParseError> {
1047 self.body_proto().map(|(body, _proto)| body)
1048 }
1049
1050 pub fn proto(&self) -> Result<Ipv6Proto, ExtHdrParseError> {
1057 self.body_proto().map(|(_body, proto)| proto)
1058 }
1059}
1060
1061impl<B: SplitByteSliceMut> Ipv6PacketRaw<B> {
1062 pub fn set_src_ip(&mut self, addr: Ipv6Addr) {
1064 self.fixed_hdr.src_ip = addr;
1065 }
1066
1067 pub fn set_dst_ip(&mut self, addr: Ipv6Addr) {
1069 self.fixed_hdr.dst_ip = addr;
1070 }
1071}
1072
1073pub enum NextHeader {
1076 NextLayer(Ipv6Proto),
1078 Extension(Ipv6ExtHdrType),
1080}
1081
1082impl From<NextHeader> for u8 {
1083 fn from(next_hdr: NextHeader) -> Self {
1084 match next_hdr {
1085 NextHeader::NextLayer(n) => n.into(),
1086 NextHeader::Extension(e) => e.into(),
1087 }
1088 }
1089}
1090
1091mod sealed {
1092 use super::*;
1093 pub trait Ipv6HeaderBefore<T> {}
1101
1102 impl<'a, O, T> Ipv6HeaderBefore<T> for &'a O where O: Ipv6HeaderBefore<T> {}
1103
1104 pub trait Ipv6HeaderBuilder {
1106 fn fixed_header(&self) -> &Ipv6PacketBuilder;
1108
1109 fn extension_headers_len(&self) -> usize;
1112
1113 fn serialize_header<B: SplitByteSliceMut, BV: BufferViewMut<B>>(
1118 &self,
1119 buffer: &mut BV,
1120 next_header: NextHeader,
1121 payload_len: usize,
1122 );
1123 }
1124}
1125use sealed::{Ipv6HeaderBefore, Ipv6HeaderBuilder};
1126
1127impl<'a, O> Ipv6HeaderBuilder for &'a O
1128where
1129 O: Ipv6HeaderBuilder,
1130{
1131 fn fixed_header(&self) -> &Ipv6PacketBuilder {
1132 O::fixed_header(self)
1133 }
1134
1135 fn extension_headers_len(&self) -> usize {
1136 O::extension_headers_len(self)
1137 }
1138
1139 fn serialize_header<B: SplitByteSliceMut, BV: BufferViewMut<B>>(
1140 &self,
1141 buffer: &mut BV,
1142 next_header: NextHeader,
1143 payload_len: usize,
1144 ) {
1145 O::serialize_header(self, buffer, next_header, payload_len)
1146 }
1147}
1148
1149macro_rules! impl_packet_builder {
1154 {} => {
1155 fn constraints(&self) -> PacketConstraints {
1156 let ext_headers = self.extension_headers_len();
1157 let header_len = IPV6_FIXED_HDR_LEN + ext_headers;
1158 let footer_len = 0;
1159 let min_body_len = 0;
1160 let max_body_len = IPV6_MAX_PAYLOAD_LENGTH - ext_headers;
1163 PacketConstraints::new(header_len, footer_len, min_body_len, max_body_len)
1164 }
1165
1166 fn serialize(&self, target: &mut SerializeTarget<'_>, body: FragmentedBytesMut<'_, '_>) {
1167 let mut bv = &mut target.header;
1168 self.serialize_header(
1169 &mut bv,
1170 NextHeader::NextLayer(self.fixed_header().proto()),
1171 body.len(),
1172 );
1173 }
1174 }
1175}
1176
1177macro_rules! impl_partial_packet_builder {
1178 {} => {
1179 fn partial_serialize(&self, body_len: usize, mut buffer: &mut [u8]) {
1180 self.serialize_header(
1181 &mut &mut buffer,
1182 NextHeader::NextLayer(self.fixed_header().proto()),
1183 body_len,
1184 );
1185 }
1186 }
1187}
1188#[derive(Debug, Clone, Eq, PartialEq)]
1190pub struct Ipv6PacketBuilder {
1191 dscp_and_ecn: DscpAndEcn,
1192 flowlabel: u32,
1193 hop_limit: u8,
1194 proto: Ipv6Proto,
1197 src_ip: Ipv6Addr,
1198 dst_ip: Ipv6Addr,
1199}
1200
1201impl Ipv6PacketBuilder {
1202 pub fn new<S: Into<Ipv6Addr>, D: Into<Ipv6Addr>>(
1208 src_ip: S,
1209 dst_ip: D,
1210 hop_limit: u8,
1211 proto: Ipv6Proto,
1212 ) -> Ipv6PacketBuilder {
1213 Ipv6PacketBuilder {
1214 dscp_and_ecn: DscpAndEcn::default(),
1215 flowlabel: 0,
1216 hop_limit,
1217 proto,
1218 src_ip: src_ip.into(),
1219 dst_ip: dst_ip.into(),
1220 }
1221 }
1222
1223 pub fn dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
1226 self.dscp_and_ecn = dscp_and_ecn;
1227 }
1228
1229 pub fn flowlabel(&mut self, flowlabel: u32) {
1235 assert!(flowlabel <= 1 << 20, "invalid flowlabel: {:x}", flowlabel);
1236 self.flowlabel = flowlabel;
1237 }
1238}
1239
1240impl Ipv6HeaderBuilder for Ipv6PacketBuilder {
1241 fn fixed_header(&self) -> &Ipv6PacketBuilder {
1242 self
1243 }
1244
1245 fn extension_headers_len(&self) -> usize {
1246 0
1247 }
1248
1249 fn serialize_header<B: SplitByteSliceMut, BV: BufferViewMut<B>>(
1250 &self,
1251 buffer: &mut BV,
1252 next_header: NextHeader,
1253 payload_len: usize,
1254 ) {
1255 buffer
1256 .write_obj_front(&FixedHeader::new(
1257 self.dscp_and_ecn,
1258 self.flowlabel,
1259 {
1260 debug_assert!(payload_len <= core::u16::MAX as usize);
1267 payload_len as u16
1268 },
1269 next_header.into(),
1270 self.hop_limit,
1271 self.src_ip,
1272 self.dst_ip,
1273 ))
1274 .expect("not enough bytes for IPv6 fixed header");
1275 }
1276}
1277
1278impl PacketBuilder for Ipv6PacketBuilder {
1279 impl_packet_builder! {}
1280}
1281
1282impl PartialPacketBuilder for Ipv6PacketBuilder {
1283 impl_partial_packet_builder! {}
1284}
1285
1286#[derive(Debug, Clone)]
1288pub struct Ipv6PacketBuilderWithHbhOptions<'a, I> {
1289 prefix_builder: Ipv6PacketBuilder,
1290 hbh_options: AlignedRecordSequenceBuilder<HopByHopOption<'a>, I>,
1291}
1292
1293impl<'a, I> Ipv6PacketBuilderWithHbhOptions<'a, I>
1294where
1295 I: Iterator + Clone,
1296 I::Item: Borrow<HopByHopOption<'a>>,
1297{
1298 pub fn new<T: IntoIterator<Item = I::Item, IntoIter = I>>(
1300 prefix_builder: Ipv6PacketBuilder,
1301 options: T,
1302 ) -> Option<Ipv6PacketBuilderWithHbhOptions<'a, I>> {
1303 let iter = options.into_iter();
1304 if iter
1307 .clone()
1308 .filter(|r| matches!(r.borrow().data, HopByHopOptionData::RouterAlert { .. }))
1309 .count()
1310 > 1
1311 {
1312 return None;
1313 }
1314 let hbh_options = AlignedRecordSequenceBuilder::new(2, iter);
1315 if next_multiple_of_eight(2 + hbh_options.serialized_len()) > IPV6_HBH_OPTIONS_MAX_LEN {
1317 return None;
1318 }
1319 Some(Ipv6PacketBuilderWithHbhOptions { prefix_builder, hbh_options })
1320 }
1321
1322 fn aligned_hbh_len(&self) -> usize {
1323 let opt_len = self.hbh_options.serialized_len();
1324 let hbh_len = opt_len + 2;
1325 next_multiple_of_eight(hbh_len)
1326 }
1327}
1328
1329fn next_multiple_of_eight(x: usize) -> usize {
1330 (x + 7) & (!7)
1331}
1332
1333impl IpPacketBuilder<Ipv6> for Ipv6PacketBuilder {
1334 fn new(src_ip: Ipv6Addr, dst_ip: Ipv6Addr, ttl: u8, proto: Ipv6Proto) -> Self {
1335 Ipv6PacketBuilder::new(src_ip, dst_ip, ttl, proto)
1336 }
1337
1338 fn src_ip(&self) -> Ipv6Addr {
1339 self.src_ip
1340 }
1341
1342 fn set_src_ip(&mut self, addr: Ipv6Addr) {
1343 self.src_ip = addr;
1344 }
1345
1346 fn dst_ip(&self) -> Ipv6Addr {
1347 self.dst_ip
1348 }
1349
1350 fn set_dst_ip(&mut self, addr: Ipv6Addr) {
1351 self.dst_ip = addr;
1352 }
1353
1354 fn proto(&self) -> Ipv6Proto {
1355 self.proto
1356 }
1357
1358 fn set_dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
1359 self.dscp_and_ecn = dscp_and_ecn;
1360 }
1361}
1362
1363impl<'a, I> Ipv6HeaderBuilder for Ipv6PacketBuilderWithHbhOptions<'a, I>
1364where
1365 I: Iterator + Clone,
1366 I::Item: Borrow<HopByHopOption<'a>>,
1367{
1368 fn fixed_header(&self) -> &Ipv6PacketBuilder {
1369 &self.prefix_builder
1370 }
1371
1372 fn extension_headers_len(&self) -> usize {
1373 self.prefix_builder.extension_headers_len() + self.aligned_hbh_len()
1374 }
1375
1376 fn serialize_header<B: SplitByteSliceMut, BV: BufferViewMut<B>>(
1377 &self,
1378 buffer: &mut BV,
1379 next_header: NextHeader,
1380 payload_len: usize,
1381 ) {
1382 let aligned_hbh_len = self.aligned_hbh_len();
1383 self.prefix_builder.serialize_header(
1385 buffer,
1386 NextHeader::Extension(Ipv6ExtHdrType::HopByHopOptions),
1387 payload_len + aligned_hbh_len,
1388 );
1389 let mut hbh_header = buffer.take_front(aligned_hbh_len).unwrap();
1391 let hbh_header = hbh_header.as_mut();
1392 hbh_header[0] = next_header.into();
1393 hbh_header[1] = u8::try_from((aligned_hbh_len - 8) / 8).expect("extension header too big");
1394 self.hbh_options.serialize_into(&mut hbh_header[2..]);
1395 }
1396}
1397
1398impl<'a, I> PacketBuilder for Ipv6PacketBuilderWithHbhOptions<'a, I>
1399where
1400 I: Iterator + Clone,
1401 I::Item: Borrow<HopByHopOption<'a>>,
1402{
1403 impl_packet_builder! {}
1404}
1405
1406impl<'a, I> PartialPacketBuilder for Ipv6PacketBuilderWithHbhOptions<'a, I>
1407where
1408 I: Iterator + Clone,
1409 I::Item: Borrow<HopByHopOption<'a>>,
1410{
1411 impl_partial_packet_builder! {}
1412}
1413
1414impl<'a, I> IpPacketBuilder<Ipv6> for Ipv6PacketBuilderWithHbhOptions<'a, I>
1415where
1416 I: Iterator<Item: Borrow<HopByHopOption<'a>>> + Debug + Default + Clone,
1417{
1418 fn new(src_ip: Ipv6Addr, dst_ip: Ipv6Addr, ttl: u8, proto: Ipv6Proto) -> Self {
1419 Ipv6PacketBuilderWithHbhOptions::new(
1420 Ipv6PacketBuilder::new(src_ip, dst_ip, ttl, proto),
1421 I::default(),
1422 )
1423 .expect("packet builder with no options should be valid")
1424 }
1425
1426 fn src_ip(&self) -> Ipv6Addr {
1427 self.prefix_builder.src_ip
1428 }
1429
1430 fn set_src_ip(&mut self, addr: Ipv6Addr) {
1431 self.prefix_builder.src_ip = addr;
1432 }
1433
1434 fn dst_ip(&self) -> Ipv6Addr {
1435 self.prefix_builder.dst_ip
1436 }
1437
1438 fn set_dst_ip(&mut self, addr: Ipv6Addr) {
1439 self.prefix_builder.dst_ip = addr;
1440 }
1441
1442 fn proto(&self) -> Ipv6Proto {
1443 self.prefix_builder.proto
1444 }
1445
1446 fn set_dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
1447 self.prefix_builder.set_dscp_and_ecn(dscp_and_ecn)
1448 }
1449}
1450
1451#[derive(Debug, Eq, PartialEq)]
1460pub struct Ipv6PacketBuilderWithFragmentHeader<B> {
1461 header_builder: B,
1462 fragment_offset: FragmentOffset,
1463 more_fragments: bool,
1464 identification: u32,
1465}
1466
1467impl<B: Ipv6HeaderBefore<Self>> Ipv6PacketBuilderWithFragmentHeader<B> {
1468 pub fn new(
1470 header_builder: B,
1471 fragment_offset: FragmentOffset,
1472 more_fragments: bool,
1473 identification: u32,
1474 ) -> Self {
1475 Self { header_builder, fragment_offset, more_fragments, identification }
1476 }
1477}
1478
1479impl<B> Ipv6HeaderBefore<Ipv6PacketBuilderWithFragmentHeader<B>> for Ipv6PacketBuilder {}
1480impl<B, I> Ipv6HeaderBefore<Ipv6PacketBuilderWithFragmentHeader<B>>
1481 for Ipv6PacketBuilderWithHbhOptions<'_, I>
1482{
1483}
1484
1485pub trait Ipv6PacketBuilderBeforeFragment:
1488 Ipv6HeaderBefore<Ipv6PacketBuilderWithFragmentHeader<Self>> + Ipv6HeaderBuilder + Sized
1489{
1490}
1491impl<B> Ipv6PacketBuilderBeforeFragment for B where
1492 B: Ipv6HeaderBefore<Ipv6PacketBuilderWithFragmentHeader<Self>> + Ipv6HeaderBuilder + Sized
1493{
1494}
1495
1496impl<B: Ipv6HeaderBuilder> Ipv6HeaderBuilder for Ipv6PacketBuilderWithFragmentHeader<B> {
1497 fn fixed_header(&self) -> &Ipv6PacketBuilder {
1498 self.header_builder.fixed_header()
1499 }
1500
1501 fn extension_headers_len(&self) -> usize {
1502 self.header_builder.extension_headers_len() + IPV6_FRAGMENT_EXT_HDR_LEN
1503 }
1504
1505 fn serialize_header<BB: SplitByteSliceMut, BV: BufferViewMut<BB>>(
1506 &self,
1507 buffer: &mut BV,
1508 next_header: NextHeader,
1509 payload_len: usize,
1510 ) {
1511 let Self { header_builder, fragment_offset, more_fragments, identification } = self;
1512 let payload_len = payload_len + IPV6_FRAGMENT_EXT_HDR_LEN;
1513 header_builder.serialize_header(
1514 buffer,
1515 NextHeader::Extension(Ipv6ExtHdrType::Fragment),
1516 payload_len,
1517 );
1518 buffer.write_obj_front(&u8::from(next_header)).unwrap();
1519 let _: BB = buffer.take_front_zero(1).unwrap();
1521 let more_fragments = u16::from(*more_fragments);
1522 buffer
1523 .write_obj_front(&U16::new(fragment_offset.into_raw() << 3 | more_fragments))
1524 .unwrap();
1525 buffer.write_obj_front(&U32::new(*identification)).unwrap();
1526 }
1527}
1528
1529impl<B: Ipv6HeaderBuilder> PacketBuilder for Ipv6PacketBuilderWithFragmentHeader<B> {
1530 impl_packet_builder! {}
1531}
1532
1533impl<B: Ipv6HeaderBuilder> PartialPacketBuilder for Ipv6PacketBuilderWithFragmentHeader<B> {
1534 impl_partial_packet_builder! {}
1535}
1536
1537pub(crate) fn reassemble_fragmented_packet<
1539 B: SplitByteSliceMut,
1540 BV: BufferViewMut<B>,
1541 I: Iterator<Item = Vec<u8>>,
1542>(
1543 mut buffer: BV,
1544 header: Vec<u8>,
1545 body_fragments: I,
1546) -> IpParseResult<Ipv6, ()> {
1547 let bytes = buffer.as_mut();
1548
1549 bytes[0..header.len()].copy_from_slice(&header[..]);
1551 let mut byte_count = header.len();
1552
1553 for p in body_fragments {
1555 bytes[byte_count..byte_count + p.len()].copy_from_slice(&p[..]);
1556 byte_count += p.len();
1557 }
1558
1559 let payload_length = byte_count - IPV6_FIXED_HDR_LEN;
1571
1572 if payload_length > usize::from(core::u16::MAX) {
1575 return debug_err!(
1576 Err(ParseError::Format.into()),
1577 "fragmented packet payload length of {} bytes is too large",
1578 payload_length
1579 );
1580 }
1581
1582 let mut header = Ref::<_, FixedHeader>::from_prefix(bytes).unwrap().0;
1585
1586 header.payload_len.set(u16::try_from(payload_length).unwrap());
1588
1589 Ok(())
1590}
1591
1592#[cfg(test)]
1593mod tests {
1594 use assert_matches::assert_matches;
1595 use packet::{Buf, FragmentedBuffer, ParseBuffer};
1596 use test_case::test_case;
1597
1598 use crate::ethernet::{EthernetFrame, EthernetFrameLengthCheck};
1599 use crate::testutil::*;
1600
1601 use super::ext_hdrs::*;
1602 use super::*;
1603
1604 const DEFAULT_SRC_IP: Ipv6Addr =
1605 Ipv6Addr::from_bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
1606 const DEFAULT_DST_IP: Ipv6Addr =
1607 Ipv6Addr::from_bytes([17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]);
1608
1609 const DEFAULT_V4_SRC_IP: Ipv4Addr = Ipv4Addr::new([1, 2, 3, 4]);
1610 const DEFAULT_V4_DST_IP: Ipv4Addr = Ipv4Addr::new([5, 6, 7, 8]);
1611
1612 #[test]
1613 fn test_parse_serialize_full_tcp() {
1614 use crate::testdata::syn_v6::*;
1615
1616 let mut buf = ETHERNET_FRAME.bytes;
1617 let frame = buf.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1618 verify_ethernet_frame(&frame, ETHERNET_FRAME);
1619
1620 let mut body = frame.body();
1621 let packet = body.parse::<Ipv6Packet<_>>().unwrap();
1622 verify_ipv6_packet(&packet, IPV6_PACKET);
1623
1624 let buffer = packet
1626 .body()
1627 .into_serializer()
1628 .wrap_in(packet.builder())
1629 .wrap_in(frame.builder())
1630 .serialize_vec_outer()
1631 .unwrap();
1632 assert_eq!(buffer.as_ref(), ETHERNET_FRAME.bytes);
1633
1634 assert_eq!(&packet.to_vec()[..], IPV6_PACKET.bytes);
1636 }
1637
1638 #[test]
1639 fn test_parse_serialize_full_udp() {
1640 use crate::testdata::dns_request_v6::*;
1641
1642 let mut buf = ETHERNET_FRAME.bytes;
1643 let frame = buf.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1644 verify_ethernet_frame(&frame, ETHERNET_FRAME);
1645
1646 let mut body = frame.body();
1647 let packet = body.parse::<Ipv6Packet<_>>().unwrap();
1648 verify_ipv6_packet(&packet, IPV6_PACKET);
1649
1650 let buffer = packet
1652 .body()
1653 .into_serializer()
1654 .wrap_in(packet.builder())
1655 .wrap_in(frame.builder())
1656 .serialize_vec_outer()
1657 .unwrap();
1658 assert_eq!(buffer.as_ref(), ETHERNET_FRAME.bytes);
1659
1660 assert_eq!(&packet.to_vec()[..], IPV6_PACKET.bytes);
1662 }
1663
1664 #[test]
1665 fn test_parse_serialize_with_extension_headers() {
1666 use crate::testdata::mld_router_report::*;
1669
1670 let mut buf = REPORT;
1671 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
1672 assert_eq!(packet.iter_extension_hdrs().count(), 1);
1673
1674 assert_eq!(&packet.to_vec()[..], REPORT);
1679 }
1680
1681 fn fixed_hdr_to_bytes(fixed_hdr: FixedHeader) -> [u8; IPV6_FIXED_HDR_LEN] {
1682 zerocopy::transmute!(fixed_hdr)
1683 }
1684
1685 fn new_fixed_hdr() -> FixedHeader {
1687 FixedHeader::new(
1688 DscpAndEcn::new(0, 2),
1689 0x77,
1690 0,
1691 IpProto::Tcp.into(),
1692 64,
1693 DEFAULT_SRC_IP,
1694 DEFAULT_DST_IP,
1695 )
1696 }
1697
1698 #[test]
1699 fn test_parse() {
1700 let mut buf = &fixed_hdr_to_bytes(new_fixed_hdr())[..];
1701 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
1702 assert_eq!(packet.dscp_and_ecn().dscp(), 0);
1703 assert_eq!(packet.dscp_and_ecn().ecn(), 2);
1704 assert_eq!(packet.flowlabel(), 0x77);
1705 assert_eq!(packet.hop_limit(), 64);
1706 assert_eq!(packet.fixed_hdr.next_hdr, IpProto::Tcp.into());
1707 assert_eq!(packet.proto(), IpProto::Tcp.into());
1708 assert_eq!(packet.src_ip(), DEFAULT_SRC_IP);
1709 assert_eq!(packet.dst_ip(), DEFAULT_DST_IP);
1710 assert_eq!(packet.body(), []);
1711 }
1712
1713 #[test]
1714 fn test_parse_with_ext_hdrs() {
1715 #[rustfmt::skip]
1716 let mut buf = [
1717 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1719 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1720
1721 Ipv6ExtHdrType::Routing.into(), 0, 0, 1, 0, 1, 1, 0, Ipv6ExtHdrType::DestinationOptions.into(), 4, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1736 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1737
1738 IpProto::Tcp.into(), 1, 0, 1, 0, 1, 1, 0, 1, 6, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5,
1748 ];
1749 let mut fixed_hdr = new_fixed_hdr();
1750 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
1751 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
1752 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
1753 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
1754 let mut buf = &buf[..];
1755 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
1756 assert_eq!(packet.dscp_and_ecn().dscp(), 0);
1757 assert_eq!(packet.dscp_and_ecn().ecn(), 2);
1758 assert_eq!(packet.flowlabel(), 0x77);
1759 assert_eq!(packet.hop_limit(), 64);
1760 assert_eq!(packet.fixed_hdr.next_hdr, Ipv6ExtHdrType::HopByHopOptions.into());
1761 assert_eq!(packet.proto(), IpProto::Tcp.into());
1762 assert_eq!(packet.src_ip(), DEFAULT_SRC_IP);
1763 assert_eq!(packet.dst_ip(), DEFAULT_DST_IP);
1764 assert_eq!(packet.body(), [1, 2, 3, 4, 5]);
1765 let ext_hdrs: Vec<Ipv6ExtensionHeader<'_>> = packet.iter_extension_hdrs().collect();
1766 assert_eq!(ext_hdrs.len(), 2);
1767 assert_eq!(ext_hdrs[0].next_header, Ipv6ExtHdrType::Routing.into());
1769 if let Ipv6ExtensionHeaderData::HopByHopOptions { options } = ext_hdrs[0].data() {
1770 assert_eq!(options.iter().count(), 0);
1772 } else {
1773 panic!("Should have matched HopByHopOptions!");
1774 }
1775
1776 assert_eq!(ext_hdrs[1].next_header, IpProto::Tcp.into());
1781 if let Ipv6ExtensionHeaderData::DestinationOptions { options } = ext_hdrs[1].data() {
1782 assert_eq!(options.iter().count(), 0);
1784 } else {
1785 panic!("Should have matched DestinationOptions!");
1786 }
1787
1788 #[rustfmt::skip]
1790 let mut buf = [
1791 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1793 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1794
1795 Ipv6Proto::NoNextHeader.into(), 0, 0, 1, 0, 1, 1, 0, 1, 2, 3, 4, 5,
1804 ];
1805 let mut fixed_hdr = new_fixed_hdr();
1806 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
1807 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
1808 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
1809 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
1810 let mut buf = &buf[..];
1811 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
1812 assert_eq!(packet.dscp_and_ecn().dscp(), 0);
1813 assert_eq!(packet.dscp_and_ecn().ecn(), 2);
1814 assert_eq!(packet.flowlabel(), 0x77);
1815 assert_eq!(packet.hop_limit(), 64);
1816 assert_eq!(packet.fixed_hdr.next_hdr, Ipv6ExtHdrType::HopByHopOptions.into());
1817 assert_eq!(packet.proto(), Ipv6Proto::NoNextHeader);
1818 assert_eq!(packet.src_ip(), DEFAULT_SRC_IP);
1819 assert_eq!(packet.dst_ip(), DEFAULT_DST_IP);
1820 assert_eq!(packet.body(), [1, 2, 3, 4, 5]);
1821 let ext_hdrs: Vec<Ipv6ExtensionHeader<'_>> = packet.iter_extension_hdrs().collect();
1822 assert_eq!(ext_hdrs.len(), 1);
1823 assert_eq!(ext_hdrs[0].next_header, Ipv6Proto::NoNextHeader.into());
1825 if let Ipv6ExtensionHeaderData::HopByHopOptions { options } = ext_hdrs[0].data() {
1826 assert_eq!(options.iter().count(), 0);
1828 } else {
1829 panic!("Should have matched HopByHopOptions!");
1830 }
1831 }
1832
1833 #[test]
1834 fn test_parse_error() {
1835 let mut fixed_hdr = new_fixed_hdr();
1837 fixed_hdr.version_tc_flowlabel[0] = 0x50;
1838 assert_eq!(
1839 (&fixed_hdr_to_bytes(fixed_hdr)[..]).parse::<Ipv6Packet<_>>().unwrap_err(),
1840 ParseError::Format.into()
1841 );
1842
1843 let mut fixed_hdr = new_fixed_hdr();
1845 fixed_hdr.payload_len = U16::new(2);
1846 assert_eq!(
1847 (&fixed_hdr_to_bytes(fixed_hdr)[..]).parse::<Ipv6Packet<_>>().unwrap_err(),
1848 ParseError::Format.into()
1849 );
1850
1851 let mut fixed_hdr = new_fixed_hdr();
1853 fixed_hdr.next_hdr = 255;
1854 assert_eq!(
1855 (&fixed_hdr_to_bytes(fixed_hdr)[..]).parse::<Ipv6Packet<_>>().unwrap_err(),
1856 IpParseError::ParameterProblem {
1857 src_ip: DEFAULT_SRC_IP,
1858 dst_ip: DEFAULT_DST_IP,
1859 code: Icmpv6ParameterProblemCode::UnrecognizedNextHeaderType,
1860 pointer: u32::from(NEXT_HEADER_OFFSET),
1861 must_send_icmp: false,
1862 header_len: (),
1863 action: IpParseErrorAction::DiscardPacketSendIcmpNoMulticast,
1864 }
1865 );
1866
1867 let mut fixed_hdr = new_fixed_hdr();
1869 fixed_hdr.next_hdr = Ipv4Proto::Icmp.into();
1870 assert_eq!(
1871 (&fixed_hdr_to_bytes(fixed_hdr)[..]).parse::<Ipv6Packet<_>>().unwrap_err(),
1872 IpParseError::ParameterProblem {
1873 src_ip: DEFAULT_SRC_IP,
1874 dst_ip: DEFAULT_DST_IP,
1875 code: Icmpv6ParameterProblemCode::UnrecognizedNextHeaderType,
1876 pointer: u32::from(NEXT_HEADER_OFFSET),
1877 must_send_icmp: false,
1878 header_len: (),
1879 action: IpParseErrorAction::DiscardPacketSendIcmpNoMulticast,
1880 }
1881 );
1882
1883 #[rustfmt::skip]
1885 let mut buf = [
1886 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1888 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1889
1890 Ipv6ExtHdrType::HopByHopOptions.into(), 4, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1898 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1899
1900 IpProto::Tcp.into(), 0, 0, 1, 0, 1, 1, 0, 1, 2, 3, 4, 5,
1909 ];
1910 let mut fixed_hdr = new_fixed_hdr();
1911 fixed_hdr.next_hdr = Ipv6ExtHdrType::Routing.into();
1912 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
1913 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
1914 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
1915 let mut buf = &buf[..];
1916 assert_eq!(
1917 buf.parse::<Ipv6Packet<_>>().unwrap_err(),
1918 IpParseError::ParameterProblem {
1919 src_ip: DEFAULT_SRC_IP,
1920 dst_ip: DEFAULT_DST_IP,
1921 code: Icmpv6ParameterProblemCode::UnrecognizedNextHeaderType,
1922 pointer: IPV6_FIXED_HDR_LEN as u32,
1923 must_send_icmp: false,
1924 header_len: (),
1925 action: IpParseErrorAction::DiscardPacketSendIcmpNoMulticast,
1926 }
1927 );
1928
1929 #[rustfmt::skip]
1931 let mut buf = [
1932 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1934 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1935
1936 IpProto::Tcp.into(), 4, 255, 1, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1944 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1945
1946 1, 2, 3, 4, 5,
1948 ];
1949 let mut fixed_hdr = new_fixed_hdr();
1950 fixed_hdr.next_hdr = Ipv6ExtHdrType::Routing.into();
1951 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
1952 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
1953 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
1954 let mut buf = &buf[..];
1955 assert_eq!(
1956 buf.parse::<Ipv6Packet<_>>().unwrap_err(),
1957 IpParseError::ParameterProblem {
1958 src_ip: DEFAULT_SRC_IP,
1959 dst_ip: DEFAULT_DST_IP,
1960 code: Icmpv6ParameterProblemCode::ErroneousHeaderField,
1961 pointer: (IPV6_FIXED_HDR_LEN as u32) + 2,
1962 must_send_icmp: true,
1963 header_len: (),
1964 action: IpParseErrorAction::DiscardPacketSendIcmpNoMulticast,
1965 }
1966 );
1967 }
1968
1969 #[test]
1970 fn test_parse_all_next_header_values() {
1971 let mut buf = [
1977 0x81, 0x13, 0x27, 0xeb, 0x75, 0x92, 0x33, 0x89, 0x01, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
1978 0x03, 0x70, 0x00, 0x22, 0xf7, 0x30, 0x2c, 0x06, 0xfe, 0xc9, 0x00, 0x2d, 0x3b, 0xeb,
1979 0xad, 0x3e, 0x5c, 0x41, 0xc8, 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x11, 0x00,
1980 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x4f, 0x4f, 0x6f, 0x4f, 0x4f, 0x4f, 0x4f,
1981 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x19, 0x19,
1982 0x19, 0x19, 0x19, 0x4f, 0x4f, 0x4f, 0x4f, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1983 0x00, 0x4f, 0x4f, 0x5a, 0x5a, 0x5a, 0xc9, 0x5a, 0x46, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
1984 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0xe4, 0x5a, 0x5a, 0x5a, 0x5a,
1985 ];
1986
1987 assert_matches!(
1990 (&buf[..]).parse::<Ipv6Packet<_>>(),
1991 Err(IpParseError::ParameterProblem {
1992 src_ip: _,
1993 dst_ip: _,
1994 code: Icmpv6ParameterProblemCode::UnrecognizedNextHeaderType,
1995 pointer: 0,
1996 must_send_icmp: false,
1997 header_len: (),
1998 action: IpParseErrorAction::DiscardPacket,
1999 })
2000 );
2001
2002 for b in 0u8..=255 {
2005 buf[6] = b;
2007 let _: Result<_, _> = (&buf[..]).parse::<Ipv6Packet<_>>();
2008 }
2009 }
2010
2011 #[test]
2012 fn test_partial_parse() {
2013 use core::convert::TryInto as _;
2014 use core::ops::Deref as _;
2015
2016 #[rustfmt::skip]
2018 let mut buf = [
2019 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2021 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2022
2023 IpProto::Tcp.into(), 0, 0, 1, 0, 1, 1, 0, 1, 2, 3, 4, 5,
2032 ];
2033 let len = buf.len() - IPV6_FIXED_HDR_LEN;
2034 let len = len.try_into().unwrap();
2035 let make_fixed_hdr = || {
2036 let mut fixed_hdr = new_fixed_hdr();
2037 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2038 fixed_hdr.payload_len = U16::new(len);
2039 fixed_hdr
2040 };
2041 const MALFORMED_BYTE: u8 = 10;
2043 buf[IPV6_FIXED_HDR_LEN + 1] = MALFORMED_BYTE;
2044 let fixed_hdr = fixed_hdr_to_bytes(make_fixed_hdr());
2045 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr);
2046 let mut buf = &buf[..];
2047 let partial = buf.parse::<Ipv6PacketRaw<_>>().unwrap();
2048 let Ipv6PacketRaw { fixed_hdr, extension_hdrs, body_proto } = &partial;
2049 assert_eq!(fixed_hdr.deref(), &make_fixed_hdr());
2050 assert_eq!(
2051 *extension_hdrs.as_ref().incomplete().unwrap(),
2052 [IpProto::Tcp.into(), MALFORMED_BYTE]
2053 );
2054 assert_eq!(body_proto, &Err(ExtHdrParseError));
2055 assert!(Ipv6Packet::try_from_raw(partial).is_err());
2056
2057 let mut buf = [
2059 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2061 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5,
2063 ];
2064 let make_fixed_hdr = || {
2065 let mut fixed_hdr = new_fixed_hdr();
2066 fixed_hdr.next_hdr = IpProto::Tcp.into();
2067 fixed_hdr.payload_len = U16::new(10);
2068 fixed_hdr
2069 };
2070 let fixed_hdr = fixed_hdr_to_bytes(make_fixed_hdr());
2071 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr);
2072 let mut parsebuff = &buf[..];
2073 let partial = parsebuff.parse::<Ipv6PacketRaw<_>>().unwrap();
2074 let Ipv6PacketRaw { fixed_hdr, extension_hdrs, body_proto } = &partial;
2075 assert_eq!(fixed_hdr.deref(), &make_fixed_hdr());
2076 assert_eq!(extension_hdrs.as_ref().complete().unwrap().deref(), []);
2077 let (body, proto) = body_proto.unwrap();
2078 assert_eq!(body.incomplete().unwrap(), &buf[IPV6_FIXED_HDR_LEN..]);
2079 assert_eq!(proto, IpProto::Tcp.into());
2080 assert!(Ipv6Packet::try_from_raw(partial).is_err());
2081 }
2082
2083 fn new_builder() -> Ipv6PacketBuilder {
2085 Ipv6PacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, 64, IpProto::Tcp.into())
2086 }
2087
2088 #[test]
2089 fn test_serialize() {
2090 let mut builder = new_builder();
2091 builder.dscp_and_ecn(DscpAndEcn::new(0x12, 3));
2092 builder.flowlabel(0x10405);
2093 let mut buf = (&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
2094 .into_serializer()
2095 .wrap_in(builder)
2096 .serialize_vec_outer()
2097 .unwrap();
2098 assert_eq!(
2100 buf.as_ref(),
2101 &[
2102 100, 177, 4, 5, 0, 10, 6, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
2103 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 1, 2, 3, 4,
2104 5, 6, 7, 8, 9
2105 ][..],
2106 );
2107
2108 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2109 assert_eq!(packet.dscp_and_ecn().dscp(), 0x12);
2112 assert_eq!(packet.dscp_and_ecn().ecn(), 3);
2113 assert_eq!(packet.flowlabel(), 0x10405);
2114 }
2115
2116 #[test]
2117 fn test_partial_serialize() {
2118 let mut builder = new_builder();
2119 builder.dscp_and_ecn(DscpAndEcn::new(0x12, 3));
2120 builder.flowlabel(0x10405);
2121 let body = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
2122 let packet = (&body).into_serializer().wrap_in(builder);
2123
2124 const HEADER_LEN: usize = 40;
2127 const HEADER: [u8; HEADER_LEN] = [
2128 100, 177, 4, 5, 0, 10, 6, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
2129 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
2130 ];
2131 let mut expected_partial = HEADER.to_vec();
2132 expected_partial.resize(expected_partial.len() + body.len(), 0);
2133
2134 for i in 1..expected_partial.len() {
2135 let mut buf = vec![0u8; i];
2136 let result =
2137 packet.partial_serialize(PacketConstraints::UNCONSTRAINED, buf.as_mut_slice());
2138
2139 let bytes_written = if i >= HEADER_LEN { HEADER_LEN } else { 0 };
2142 assert_eq!(
2143 result,
2144 Ok(PartialSerializeResult { bytes_written, total_size: body.len() + HEADER_LEN })
2145 );
2146 if bytes_written > 0 {
2147 assert_eq!(buf, expected_partial[..i]);
2148 }
2149 }
2150 }
2151
2152 #[test]
2153 fn test_serialize_zeroes() {
2154 let mut buf_0 = [0; IPV6_FIXED_HDR_LEN];
2157 let _: Buf<&mut [u8]> = Buf::new(&mut buf_0[..], IPV6_FIXED_HDR_LEN..)
2158 .wrap_in(new_builder())
2159 .serialize_vec_outer()
2160 .unwrap()
2161 .unwrap_a();
2162 let mut buf_1 = [0xFF; IPV6_FIXED_HDR_LEN];
2163 let _: Buf<&mut [u8]> = Buf::new(&mut buf_1[..], IPV6_FIXED_HDR_LEN..)
2164 .wrap_in(new_builder())
2165 .serialize_vec_outer()
2166 .unwrap()
2167 .unwrap_a();
2168 assert_eq!(&buf_0[..], &buf_1[..]);
2169 }
2170
2171 #[test]
2172 fn test_packet_builder_proto_not_next_header() {
2173 let mut buf = (&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
2177 .into_serializer()
2178 .wrap_in(
2179 Ipv6PacketBuilderWithHbhOptions::new(
2180 new_builder(),
2181 &[HopByHopOption {
2182 action: ExtensionHeaderOptionAction::SkipAndContinue,
2183 mutable: false,
2184 data: HopByHopOptionData::RouterAlert { data: 0 },
2185 }],
2186 )
2187 .unwrap(),
2188 )
2189 .serialize_vec_outer()
2190 .unwrap();
2191 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2192 assert_eq!(packet.proto(), IpProto::Tcp.into());
2193 assert_eq!(packet.next_header(), Ipv6ExtHdrType::HopByHopOptions.into());
2194 }
2195
2196 #[test]
2197 #[should_panic(expected = "SizeLimitExceeded, Nested { inner: Buf { buf:")]
2198 fn test_serialize_panic_packet_length() {
2199 let _: Buf<&mut [u8]> = Buf::new(&mut [0; 1 << 16][..], ..)
2202 .wrap_in(new_builder())
2203 .serialize_vec_outer()
2204 .unwrap()
2205 .unwrap_a();
2206 }
2207
2208 #[test]
2209 #[should_panic(expected = "packet must have at least one extension header")]
2210 fn test_copy_header_bytes_for_fragment_without_ext_hdrs() {
2211 let mut buf = &fixed_hdr_to_bytes(new_fixed_hdr())[..];
2212 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2213 let _: Vec<_> = packet.copy_header_bytes_for_fragment();
2214 }
2215
2216 #[test]
2217 #[should_panic(expected = "exhausted all extension headers without finding fragment header")]
2218 fn test_copy_header_bytes_for_fragment_with_1_ext_hdr_no_fragment() {
2219 #[rustfmt::skip]
2220 let mut buf = [
2221 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2223 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2224
2225 IpProto::Tcp.into(), 0, 0, 1, 0, 1, 1, 0, 1, 2, 3, 4, 5,
2234 ];
2235 let mut fixed_hdr = new_fixed_hdr();
2236 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2237 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
2238 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2239 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2240 let mut buf = &buf[..];
2241 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2242 let _: Vec<_> = packet.copy_header_bytes_for_fragment();
2243 }
2244
2245 #[test]
2246 #[should_panic(expected = "exhausted all extension headers without finding fragment header")]
2247 fn test_copy_header_bytes_for_fragment_with_2_ext_hdr_no_fragment() {
2248 #[rustfmt::skip]
2249 let mut buf = [
2250 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2252 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2253
2254 Ipv6ExtHdrType::DestinationOptions.into(), 0, 0, 1, 0, 1, 1, 0, IpProto::Tcp.into(), 1, 0, 1, 0, 1, 1, 0, 1, 6, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5,
2271 ];
2272 let mut fixed_hdr = new_fixed_hdr();
2273 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2274 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
2275 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2276 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2277 let mut buf = &buf[..];
2278 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2279 let _: Vec<_> = packet.copy_header_bytes_for_fragment();
2280 }
2281
2282 #[test]
2283 fn test_copy_header_bytes_for_fragment() {
2284 #[rustfmt::skip]
2289 let mut bytes = [
2290 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2292 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2293
2294 IpProto::Tcp.into(), 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5,
2302 ];
2303 let mut fixed_hdr = new_fixed_hdr();
2304 fixed_hdr.next_hdr = Ipv6ExtHdrType::Fragment.into();
2305 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2306 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2307 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2308 let mut buf = &bytes[..];
2309 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2310 let copied_bytes = packet.copy_header_bytes_for_fragment();
2311 bytes[6] = IpProto::Tcp.into();
2312 assert_eq!(&copied_bytes[..], &bytes[..IPV6_FIXED_HDR_LEN]);
2313
2314 #[rustfmt::skip]
2319 let mut bytes = [
2320 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2322 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2323
2324 Ipv6ExtHdrType::Fragment.into(), 0, 0, 1, 0, 1, 1, 0, IpProto::Tcp.into(), 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5,
2339 ];
2340 let mut fixed_hdr = new_fixed_hdr();
2341 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2342 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2343 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2344 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2345 let mut buf = &bytes[..];
2346 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2347 let copied_bytes = packet.copy_header_bytes_for_fragment();
2348 bytes[IPV6_FIXED_HDR_LEN] = IpProto::Tcp.into();
2349 assert_eq!(&copied_bytes[..], &bytes[..IPV6_FIXED_HDR_LEN + 8]);
2350
2351 #[rustfmt::skip]
2356 let mut bytes = [
2357 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2359 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2360
2361 Ipv6ExtHdrType::DestinationOptions.into(), 0, 0, 1, 0, 1, 1, 0, Ipv6ExtHdrType::Fragment.into(), 1, 0, 1, 0, 1, 1, 0, 1, 6, 0, 0, 0, 0, 0, 0, IpProto::Tcp.into(), 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5,
2384 ];
2385 let mut fixed_hdr = new_fixed_hdr();
2386 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2387 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2388 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2389 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2390 let mut buf = &bytes[..];
2391 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2392 let copied_bytes = packet.copy_header_bytes_for_fragment();
2393 bytes[IPV6_FIXED_HDR_LEN + 8] = IpProto::Tcp.into();
2394 assert_eq!(&copied_bytes[..], &bytes[..IPV6_FIXED_HDR_LEN + 24]);
2395
2396 #[rustfmt::skip]
2401 let mut bytes = [
2402 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2404 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2405
2406 Ipv6ExtHdrType::DestinationOptions.into(), 0, 0, 0, 1, 1, 1, 1, IpProto::Tcp.into(), 1, 0, 1, 0, 1, 1, 0, 1, 6, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5,
2422 ];
2423 let mut fixed_hdr = new_fixed_hdr();
2424 fixed_hdr.next_hdr = Ipv6ExtHdrType::Fragment.into();
2425 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2426 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2427 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2428 let mut buf = &bytes[..];
2429 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2430 let copied_bytes = packet.copy_header_bytes_for_fragment();
2431 let mut expected_bytes = Vec::new();
2432 expected_bytes.extend_from_slice(&bytes[..IPV6_FIXED_HDR_LEN]);
2433 expected_bytes.extend_from_slice(&bytes[IPV6_FIXED_HDR_LEN + 8..bytes.len() - 5]);
2434 expected_bytes[6] = Ipv6ExtHdrType::DestinationOptions.into();
2435 assert_eq!(&copied_bytes[..], &expected_bytes[..]);
2436
2437 #[rustfmt::skip]
2442 let mut bytes = [
2443 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2445 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2446
2447 Ipv6ExtHdrType::DestinationOptions.into(), 0, 0, 0, 1, 1, 1, 1, Ipv6ExtHdrType::Routing.into(), 1, 0, 1, 0, 1, 1, 0, 1, 6, 0, 0, 0, 0, 0, 0, IpProto::Tcp.into(), 4, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
2469 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
2470
2471 1, 2, 3, 4, 5,
2473 ];
2474 let mut fixed_hdr = new_fixed_hdr();
2475 fixed_hdr.next_hdr = Ipv6ExtHdrType::Fragment.into();
2476 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2477 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2478 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2479 let mut buf = &bytes[..];
2480 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2481 let copied_bytes = packet.copy_header_bytes_for_fragment();
2482 let mut expected_bytes = Vec::new();
2483 expected_bytes.extend_from_slice(&bytes[..IPV6_FIXED_HDR_LEN]);
2484 expected_bytes.extend_from_slice(&bytes[IPV6_FIXED_HDR_LEN + 8..bytes.len() - 5]);
2485 expected_bytes[6] = Ipv6ExtHdrType::DestinationOptions.into();
2486 assert_eq!(&copied_bytes[..], &expected_bytes[..]);
2487
2488 #[rustfmt::skip]
2493 let mut bytes = [
2494 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2496 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2497
2498 Ipv6ExtHdrType::Fragment.into(), 0, 0, 1, 0, 1, 1, 0, Ipv6ExtHdrType::DestinationOptions.into(), 0, 0, 0, 1, 1, 1, 1, IpProto::Tcp.into(), 1, 0, 1, 0, 1, 1, 0, 1, 6, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5,
2521 ];
2522 let mut fixed_hdr = new_fixed_hdr();
2523 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2524 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2525 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2526 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2527 let mut buf = &bytes[..];
2528 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2529 let copied_bytes = packet.copy_header_bytes_for_fragment();
2530 let mut expected_bytes = Vec::new();
2531 expected_bytes.extend_from_slice(&bytes[..IPV6_FIXED_HDR_LEN + 8]);
2532 expected_bytes.extend_from_slice(&bytes[IPV6_FIXED_HDR_LEN + 16..bytes.len() - 5]);
2533 expected_bytes[IPV6_FIXED_HDR_LEN] = Ipv6ExtHdrType::DestinationOptions.into();
2534 assert_eq!(&copied_bytes[..], &expected_bytes[..]);
2535
2536 #[rustfmt::skip]
2541 let mut bytes = [
2542 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2544 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2545
2546 Ipv6ExtHdrType::Fragment.into(), 0, 0, 0, 1, 1, 1, 1, IpProto::Tcp.into(), 0, 0, 0, 2, 2, 2, 2, 1, 2, 3, 4, 5,
2560 ];
2561 let mut fixed_hdr = new_fixed_hdr();
2562 fixed_hdr.next_hdr = Ipv6ExtHdrType::Fragment.into();
2563 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2564 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2565 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2566 let mut buf = &bytes[..];
2567 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2568 let copied_bytes = packet.copy_header_bytes_for_fragment();
2569 let mut expected_bytes = Vec::new();
2570 expected_bytes.extend_from_slice(&bytes[..IPV6_FIXED_HDR_LEN]);
2571 expected_bytes.extend_from_slice(&bytes[IPV6_FIXED_HDR_LEN + 8..bytes.len() - 5]);
2572 assert_eq!(&copied_bytes[..], &expected_bytes[..]);
2573 }
2574
2575 #[test]
2576 fn test_next_multiple_of_eight() {
2577 for x in 0usize..=IPV6_HBH_OPTIONS_MAX_LEN {
2578 let y = next_multiple_of_eight(x);
2579 assert_eq!(y % 8, 0);
2580 assert!(y >= x);
2581 if x % 8 == 0 {
2582 assert_eq!(x, y);
2583 } else {
2584 assert_eq!(x + (8 - x % 8), y);
2585 }
2586 }
2587 }
2588
2589 fn create_ipv4_and_ipv6_builders(
2590 proto_v4: Ipv4Proto,
2591 proto_v6: Ipv6Proto,
2592 ) -> (Ipv4PacketBuilder, Ipv6PacketBuilder) {
2593 const IP_DSCP_AND_ECN: DscpAndEcn = DscpAndEcn::new(0x12, 3);
2594 const IP_TTL: u8 = 64;
2595
2596 let mut ipv4_builder =
2597 Ipv4PacketBuilder::new(DEFAULT_V4_SRC_IP, DEFAULT_V4_DST_IP, IP_TTL, proto_v4);
2598 ipv4_builder.dscp_and_ecn(IP_DSCP_AND_ECN);
2599 ipv4_builder.df_flag(false);
2600 ipv4_builder.mf_flag(false);
2601 ipv4_builder.fragment_offset(FragmentOffset::ZERO);
2602
2603 let mut ipv6_builder =
2604 Ipv6PacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, IP_TTL, proto_v6);
2605 ipv6_builder.dscp_and_ecn(IP_DSCP_AND_ECN);
2606 ipv6_builder.flowlabel(0x456);
2607
2608 (ipv4_builder, ipv6_builder)
2609 }
2610
2611 fn create_tcp_ipv4_and_ipv6_pkt()
2612 -> (packet::Either<EmptyBuf, Buf<Vec<u8>>>, packet::Either<EmptyBuf, Buf<Vec<u8>>>) {
2613 use crate::tcp::TcpSegmentBuilder;
2614 use core::num::NonZeroU16;
2615
2616 let tcp_src_port: NonZeroU16 = NonZeroU16::new(20).unwrap();
2617 let tcp_dst_port: NonZeroU16 = NonZeroU16::new(30).unwrap();
2618 const TCP_SEQ_NUM: u32 = 4321;
2619 const TCP_ACK_NUM: Option<u32> = Some(1234);
2620 const TCP_WINDOW_SIZE: u16 = 12345;
2621 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
2622
2623 let (ipv4_builder, ipv6_builder) =
2624 create_ipv4_and_ipv6_builders(IpProto::Tcp.into(), IpProto::Tcp.into());
2625
2626 let tcp_builder = TcpSegmentBuilder::new(
2627 DEFAULT_V4_SRC_IP,
2628 DEFAULT_V4_DST_IP,
2629 tcp_src_port,
2630 tcp_dst_port,
2631 TCP_SEQ_NUM,
2632 TCP_ACK_NUM,
2633 TCP_WINDOW_SIZE,
2634 );
2635
2636 let v4_pkt_buf = (&PAYLOAD)
2637 .into_serializer()
2638 .wrap_in(tcp_builder)
2639 .wrap_in(ipv4_builder)
2640 .serialize_vec_outer()
2641 .expect("Failed to serialize to v4_pkt_buf");
2642
2643 let v6_tcp_builder = TcpSegmentBuilder::new(
2644 DEFAULT_SRC_IP,
2645 DEFAULT_DST_IP,
2646 tcp_src_port,
2647 tcp_dst_port,
2648 TCP_SEQ_NUM,
2649 TCP_ACK_NUM,
2650 TCP_WINDOW_SIZE,
2651 );
2652
2653 let v6_pkt_buf = (&PAYLOAD)
2654 .into_serializer()
2655 .wrap_in(v6_tcp_builder)
2656 .wrap_in(ipv6_builder)
2657 .serialize_vec_outer()
2658 .expect("Failed to serialize to v4_pkt_buf");
2659
2660 (v4_pkt_buf, v6_pkt_buf)
2661 }
2662
2663 #[test]
2664 fn test_nat64_translate_tcp() {
2665 let (expected_v4_pkt_buf, mut v6_pkt_buf) = create_tcp_ipv4_and_ipv6_pkt();
2666
2667 let parsed_v6_packet =
2668 v6_pkt_buf.parse::<Ipv6Packet<_>>().expect("Failed to parse v6_pkt_buf");
2669 let nat64_translation_result =
2670 parsed_v6_packet.nat64_translate(DEFAULT_V4_SRC_IP, DEFAULT_V4_DST_IP);
2671
2672 let serializable_pkt =
2673 assert_matches!(nat64_translation_result, Nat64TranslationResult::Forward(s) => s);
2674
2675 let translated_v4_pkt_buf = serializable_pkt
2676 .serialize_vec_outer()
2677 .expect("Failed to serialize to translated_v4_pkt_buf");
2678
2679 assert_eq!(
2680 expected_v4_pkt_buf.to_flattened_vec(),
2681 translated_v4_pkt_buf.to_flattened_vec()
2682 );
2683 }
2684
2685 fn create_udp_ipv4_and_ipv6_pkt()
2686 -> (packet::Either<EmptyBuf, Buf<Vec<u8>>>, packet::Either<EmptyBuf, Buf<Vec<u8>>>) {
2687 use crate::udp::UdpPacketBuilder;
2688 use core::num::NonZeroU16;
2689
2690 let udp_src_port: NonZeroU16 = NonZeroU16::new(35000).unwrap();
2691 let udp_dst_port: NonZeroU16 = NonZeroU16::new(53).unwrap();
2692 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
2693
2694 let (ipv4_builder, ipv6_builder) =
2695 create_ipv4_and_ipv6_builders(IpProto::Udp.into(), IpProto::Udp.into());
2696
2697 let v4_udp_builder = UdpPacketBuilder::new(
2698 DEFAULT_V4_SRC_IP,
2699 DEFAULT_V4_DST_IP,
2700 Some(udp_src_port),
2701 udp_dst_port,
2702 );
2703
2704 let v4_pkt_buf = (&PAYLOAD)
2705 .into_serializer()
2706 .wrap_in(v4_udp_builder)
2707 .wrap_in(ipv4_builder)
2708 .serialize_vec_outer()
2709 .expect("Unable to serialize to v4_pkt_buf");
2710
2711 let v6_udp_builder =
2712 UdpPacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, Some(udp_src_port), udp_dst_port);
2713
2714 let v6_pkt_buf = (&PAYLOAD)
2715 .into_serializer()
2716 .wrap_in(v6_udp_builder)
2717 .wrap_in(ipv6_builder)
2718 .serialize_vec_outer()
2719 .expect("Unable to serialize to v6_pkt_buf");
2720
2721 (v4_pkt_buf, v6_pkt_buf)
2722 }
2723
2724 #[test]
2725 fn test_nat64_translate_udp() {
2726 let (expected_v4_pkt_buf, mut v6_pkt_buf) = create_udp_ipv4_and_ipv6_pkt();
2727
2728 let parsed_v6_packet =
2729 v6_pkt_buf.parse::<Ipv6Packet<_>>().expect("Unable to parse Ipv6Packet");
2730 let nat64_translation_result =
2731 parsed_v6_packet.nat64_translate(DEFAULT_V4_SRC_IP, DEFAULT_V4_DST_IP);
2732
2733 let serializable_pkt = assert_matches!(nat64_translation_result,
2734 Nat64TranslationResult::Forward(s) => s);
2735
2736 let translated_v4_pkt_buf = serializable_pkt
2737 .serialize_vec_outer()
2738 .expect("Unable to serialize to translated_v4_pkt_buf");
2739
2740 assert_eq!(
2741 expected_v4_pkt_buf.to_flattened_vec(),
2742 translated_v4_pkt_buf.to_flattened_vec()
2743 );
2744 }
2745
2746 #[test]
2747 fn test_nat64_translate_non_tcp_udp_icmp() {
2748 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
2749
2750 let (ipv4_builder, ipv6_builder) =
2751 create_ipv4_and_ipv6_builders(Ipv4Proto::Other(59), Ipv6Proto::Other(59));
2752
2753 let expected_v4_pkt_buf = (&PAYLOAD)
2754 .into_serializer()
2755 .wrap_in(ipv4_builder)
2756 .serialize_vec_outer()
2757 .expect("Unable to serialize to expected_v4_pkt_buf");
2758
2759 let mut v6_pkt_buf = (&PAYLOAD)
2760 .into_serializer()
2761 .wrap_in(ipv6_builder)
2762 .serialize_vec_outer()
2763 .expect("Unable to serialize to v6_pkt_buf");
2764
2765 let translated_v4_pkt_buf = {
2766 let parsed_v6_packet = v6_pkt_buf
2767 .parse::<Ipv6Packet<_>>()
2768 .expect("Unable to serialize to translated_v4_pkt_buf");
2769
2770 let nat64_translation_result =
2771 parsed_v6_packet.nat64_translate(DEFAULT_V4_SRC_IP, DEFAULT_V4_DST_IP);
2772
2773 let serializable_pkt = assert_matches!(nat64_translation_result,
2774 Nat64TranslationResult::Forward(s) => s);
2775
2776 let translated_buf = serializable_pkt
2777 .serialize_vec_outer()
2778 .expect("Unable to serialize to translated_buf");
2779
2780 translated_buf
2781 };
2782
2783 assert_eq!(
2784 expected_v4_pkt_buf.to_flattened_vec(),
2785 translated_v4_pkt_buf.to_flattened_vec()
2786 );
2787 }
2788
2789 #[test_case(new_builder(), true; "fixed header more frags")]
2790 #[test_case(Ipv6PacketBuilderWithHbhOptions::new(
2791 new_builder(),
2792 &[HopByHopOption {
2793 action: ExtensionHeaderOptionAction::SkipAndContinue,
2794 mutable: false,
2795 data: HopByHopOptionData::RouterAlert { data: 0 },
2796 }]).unwrap(), false; "hbh last frag")]
2797 fn ipv6_packet_builder_with_fragment_header<
2798 B: Ipv6HeaderBuilder + Ipv6HeaderBefore<Ipv6PacketBuilderWithFragmentHeader<B>> + Debug,
2799 >(
2800 inner: B,
2801 more_fragments: bool,
2802 ) {
2803 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
2804 let fragment_offset = FragmentOffset::new(13).unwrap();
2805 let identification = 0xABCDABCD;
2806 let builder = Ipv6PacketBuilderWithFragmentHeader::new(
2807 inner,
2808 fragment_offset,
2809 more_fragments,
2810 identification,
2811 );
2812 let mut serialized =
2813 builder.wrap_body(PAYLOAD.into_serializer()).serialize_vec_outer().unwrap().unwrap_b();
2814 let packet = serialized.parse::<Ipv6Packet<_>>().unwrap();
2815 assert!(packet.fragment_header_present());
2816 assert_eq!(packet.proto(), Ipv6Proto::Proto(IpProto::Tcp));
2817 let fragment_data = packet
2818 .extension_hdrs
2819 .into_iter()
2820 .find_map(|ext_hdr| match ext_hdr.into_data() {
2821 Ipv6ExtensionHeaderData::Fragment { fragment_data } => Some(fragment_data),
2822 _ => None,
2823 })
2824 .unwrap();
2825 assert_eq!(fragment_data.fragment_offset(), fragment_offset);
2826 assert_eq!(fragment_data.identification(), identification);
2827 assert_eq!(fragment_data.m_flag(), more_fragments);
2828 }
2829
2830 #[test]
2833 fn extension_headers_take_from_max_body_size() {
2834 let builder = new_builder();
2835 assert_eq!(builder.constraints().max_body_len(), IPV6_MAX_PAYLOAD_LENGTH);
2836 let builder =
2837 Ipv6PacketBuilderWithFragmentHeader::new(builder, FragmentOffset::ZERO, false, 1234);
2838 assert_eq!(
2839 builder.constraints().max_body_len(),
2840 IPV6_MAX_PAYLOAD_LENGTH - IPV6_FRAGMENT_EXT_HDR_LEN
2841 );
2842 }
2843
2844 #[test]
2845 fn test_partial_serialize_parsed() {
2846 let packet_bytes = [
2847 100, 177, 4, 5, 0, 10, 6, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
2848 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 1, 2, 3, 4, 5, 6, 7,
2849 8, 9,
2850 ];
2851 let packet_len = packet_bytes.len();
2852 let mut packet_bytes_copy = packet_bytes;
2853 let mut packet_bytes_ref: &mut [u8] = &mut packet_bytes_copy[..];
2854 let packet = packet_bytes_ref.parse::<Ipv6Packet<_>>().unwrap();
2855
2856 for i in 1..(packet_len + 1) {
2857 let mut buf = vec![0u8; i];
2858 let result =
2859 packet.partial_serialize(PacketConstraints::UNCONSTRAINED, buf.as_mut_slice());
2860
2861 let bytes_written = if i >= packet_len { packet_len } else { i };
2862 assert_eq!(
2863 result,
2864 Ok(PartialSerializeResult { bytes_written, total_size: packet_len })
2865 );
2866 assert_eq!(buf[..bytes_written], packet_bytes[..bytes_written]);
2867 }
2868 }
2869}