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::{IpParseErrorAction, IpParseResult, Ipv6ParseError, 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) -> Ipv6ParseError {
76 match err {
95 Ipv6ExtensionHeaderParsingError::ErroneousHeaderField { pointer, must_send_icmp } => {
96 let (pointer, action) = match pointer.checked_add(IPV6_FIXED_HDR_LEN as u32) {
97 None => (0, IpParseErrorAction::DiscardPacket),
101 Some(p) => (p, IpParseErrorAction::DiscardPacketSendIcmpNoMulticast),
105 };
106
107 Ipv6ParseError::ParameterProblem {
108 src_ip: hdr.src_ip,
109 dst_ip: hdr.dst_ip,
110 code: Icmpv6ParameterProblemCode::ErroneousHeaderField,
111 pointer,
112 must_send_icmp,
113 action,
114 }
115 }
116 Ipv6ExtensionHeaderParsingError::UnrecognizedNextHeader { pointer, must_send_icmp } => {
117 let (pointer, action) = match pointer.checked_add(IPV6_FIXED_HDR_LEN as u32) {
118 None => (0, IpParseErrorAction::DiscardPacket),
119 Some(p) => (p, IpParseErrorAction::DiscardPacketSendIcmpNoMulticast),
120 };
121
122 Ipv6ParseError::ParameterProblem {
123 src_ip: hdr.src_ip,
124 dst_ip: hdr.dst_ip,
125 code: Icmpv6ParameterProblemCode::UnrecognizedNextHeaderType,
126 pointer,
127 must_send_icmp,
128 action,
129 }
130 }
131 Ipv6ExtensionHeaderParsingError::UnrecognizedOption { pointer, must_send_icmp, action } => {
132 let (pointer, action) = match pointer.checked_add(IPV6_FIXED_HDR_LEN as u32) {
133 None => (0, IpParseErrorAction::DiscardPacket),
134 Some(p) => {
135 let action = match action {
136 ExtensionHeaderOptionAction::SkipAndContinue => unreachable!(
137 "Should never end up here because this action should never result in an error"
138 ),
139 ExtensionHeaderOptionAction::DiscardPacket => {
140 IpParseErrorAction::DiscardPacket
141 }
142 ExtensionHeaderOptionAction::DiscardPacketSendIcmp => {
143 IpParseErrorAction::DiscardPacketSendIcmp
144 }
145 ExtensionHeaderOptionAction::DiscardPacketSendIcmpNoMulticast => {
146 IpParseErrorAction::DiscardPacketSendIcmpNoMulticast
147 }
148 };
149
150 (p, action)
151 }
152 };
153
154 Ipv6ParseError::ParameterProblem {
155 src_ip: hdr.src_ip,
156 dst_ip: hdr.dst_ip,
157 code: Icmpv6ParameterProblemCode::UnrecognizedIpv6Option,
158 pointer,
159 must_send_icmp,
160 action,
161 }
162 }
163 Ipv6ExtensionHeaderParsingError::BufferExhausted
164 | Ipv6ExtensionHeaderParsingError::MalformedData => {
165 Ipv6ParseError::Parse { error: ParseError::Format }
168 }
169 }
170}
171
172#[derive(Debug, Default, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned, PartialEq)]
174#[repr(C)]
175pub struct FixedHeader {
176 version_tc_flowlabel: [u8; 4],
177 payload_len: U16,
178 next_hdr: u8,
179 hop_limit: u8,
180 src_ip: Ipv6Addr,
181 dst_ip: Ipv6Addr,
182}
183
184const IP_VERSION: u8 = 6;
185const VERSION_OFFSET: u8 = 4;
186const FLOW_LABEL_MAX: u32 = (1 << 20) - 1;
187
188impl FixedHeader {
189 #[allow(clippy::too_many_arguments)]
190 fn new(
191 dscp_and_ecn: DscpAndEcn,
192 flow_label: u32,
193 payload_len: u16,
194 next_hdr: u8,
195 hop_limit: u8,
196 src_ip: Ipv6Addr,
197 dst_ip: Ipv6Addr,
198 ) -> FixedHeader {
199 debug_assert!(flow_label <= FLOW_LABEL_MAX);
200
201 let traffic_class = dscp_and_ecn.raw();
202 FixedHeader {
203 version_tc_flowlabel: [
204 IP_VERSION << VERSION_OFFSET | traffic_class >> 4,
205 (traffic_class << 4) | ((flow_label >> 16) as u8),
206 (flow_label >> 8) as u8,
207 flow_label as u8,
208 ],
209 payload_len: U16::new(payload_len),
210 next_hdr,
211 hop_limit,
212 src_ip,
213 dst_ip,
214 }
215 }
216
217 fn version(&self) -> u8 {
218 self.version_tc_flowlabel[0] >> 4
219 }
220
221 fn dscp_and_ecn(&self) -> DscpAndEcn {
222 ((self.version_tc_flowlabel[0] & 0xF) << 4 | self.version_tc_flowlabel[1] >> 4).into()
223 }
224
225 fn flowlabel(&self) -> u32 {
226 (u32::from(self.version_tc_flowlabel[1]) & 0xF) << 16
227 | u32::from(self.version_tc_flowlabel[2]) << 8
228 | u32::from(self.version_tc_flowlabel[3])
229 }
230}
231
232pub trait Ipv6Header {
237 fn get_fixed_header(&self) -> &FixedHeader;
239
240 fn hop_limit(&self) -> u8 {
242 self.get_fixed_header().hop_limit
243 }
244
245 fn next_header(&self) -> u8 {
247 self.get_fixed_header().next_hdr
248 }
249
250 fn src_ip(&self) -> Ipv6Addr {
252 self.get_fixed_header().src_ip
253 }
254
255 fn dst_ip(&self) -> Ipv6Addr {
257 self.get_fixed_header().dst_ip
258 }
259
260 fn dscp_and_ecn(&self) -> DscpAndEcn {
263 self.get_fixed_header().dscp_and_ecn()
264 }
265}
266
267impl Ipv6Header for FixedHeader {
268 fn get_fixed_header(&self) -> &FixedHeader {
269 self
270 }
271}
272
273pub struct Ipv6Packet<B> {
279 fixed_hdr: Ref<B, FixedHeader>,
280 extension_hdrs: Records<B, Ipv6ExtensionHeaderImpl>,
281 body: B,
282 proto: Ipv6Proto,
283}
284
285impl<B: SplitByteSlice, I: IpExt> GenericOverIp<I> for Ipv6Packet<B> {
286 type Type = <I as IpExt>::Packet<B>;
287}
288
289impl<B: SplitByteSlice> Ipv6Header for Ipv6Packet<B> {
290 fn get_fixed_header(&self) -> &FixedHeader {
291 &self.fixed_hdr
292 }
293}
294
295impl<B: SplitByteSlice> ParsablePacket<B, ()> for Ipv6Packet<B> {
296 type Error = Ipv6ParseError;
297
298 fn parse_metadata(&self) -> ParseMetadata {
299 let header_len = Ref::bytes(&self.fixed_hdr).len() + self.extension_hdrs.bytes().len();
300 ParseMetadata::from_packet(header_len, self.body.len(), 0)
301 }
302
303 fn parse<BV: BufferView<B>>(buffer: BV, _args: ()) -> Result<Self, Ipv6ParseError> {
304 Ipv6PacketRaw::parse(buffer, ()).and_then(Ipv6Packet::try_from_raw)
305 }
306}
307
308impl<B: SplitByteSlice> FromRaw<Ipv6PacketRaw<B>, ()> for Ipv6Packet<B> {
309 type Error = Ipv6ParseError;
310
311 fn try_from_raw_with(raw: Ipv6PacketRaw<B>, _args: ()) -> Result<Self, Self::Error> {
312 let fixed_hdr = raw.fixed_hdr;
313
314 if !is_valid_next_header(fixed_hdr.next_hdr, true) {
317 return debug_err!(
318 Err(Ipv6ParseError::ParameterProblem {
319 src_ip: fixed_hdr.src_ip,
320 dst_ip: fixed_hdr.dst_ip,
321 code: Icmpv6ParameterProblemCode::UnrecognizedNextHeaderType,
322 pointer: u32::from(NEXT_HEADER_OFFSET),
323 must_send_icmp: false,
324 action: IpParseErrorAction::DiscardPacketSendIcmpNoMulticast,
325 }),
326 "Unrecognized next header value"
327 );
328 }
329
330 let extension_hdrs = match raw.extension_hdrs {
331 MaybeParsed::Complete(v) => {
332 Records::try_from_raw(v).map_err(|e| ext_hdr_err_fn(&fixed_hdr, e))?
333 }
334 MaybeParsed::Incomplete(_) => {
335 return debug_err!(
336 Err(ParseError::Format.into()),
337 "Incomplete IPv6 extension headers"
338 );
339 }
340 };
341
342 let (body, proto) =
346 raw.body_proto.expect("Unable to retrieve Ipv6Proto or MaybeParsed body from raw");
347 debug_assert!(is_valid_next_header_upper_layer(proto.into()));
348
349 let body = match body {
350 MaybeParsed::Complete(b) => b,
351 MaybeParsed::Incomplete(_b) => {
352 return debug_err!(Err(ParseError::Format.into()), "IPv6 body unretrievable.");
353 }
354 };
355
356 if extension_hdrs.bytes().len() + body.len() != usize::from(fixed_hdr.payload_len.get()) {
361 return debug_err!(
362 Err(ParseError::Format.into()),
363 "Payload len does not match body and extension headers"
364 );
365 }
366
367 if fixed_hdr.version() != 6 {
369 return debug_err!(
370 Err(ParseError::Format.into()),
371 "unexpected IP version: {}",
372 fixed_hdr.version()
373 );
374 }
375
376 Ok(Ipv6Packet { fixed_hdr, extension_hdrs, body, proto })
377 }
378}
379
380impl<B: SplitByteSlice> PartialSerializer for Ipv6Packet<B> {
381 fn partial_serialize(
382 &self,
383 _outer: PacketConstraints,
384 mut buffer: &mut [u8],
385 ) -> Result<PartialSerializeResult, SerializeError<Never>> {
386 let fixed_hdr = Ref::bytes(&self.fixed_hdr);
387 let extension_hdrs = self.extension_hdrs.bytes();
388
389 let mut buffer = &mut buffer;
390 let bytes_written = buffer.write_bytes_front_allow_partial(Ref::bytes(&self.fixed_hdr))
391 + buffer.write_bytes_front_allow_partial(self.extension_hdrs.bytes())
392 + buffer.write_bytes_front_allow_partial(&self.body);
393 let total_size = fixed_hdr.len() + extension_hdrs.len() + self.body.len();
394
395 Ok(PartialSerializeResult { bytes_written, total_size })
396 }
397}
398
399impl<B: SplitByteSlice> Ipv6Packet<B> {
400 pub fn iter_extension_hdrs(&self) -> impl Iterator<Item = Ipv6ExtensionHeader<'_>> {
402 self.extension_hdrs.iter()
403 }
404
405 pub fn body(&self) -> &[u8] {
407 &self.body
408 }
409
410 pub fn dscp_and_ecn(&self) -> DscpAndEcn {
413 self.fixed_hdr.dscp_and_ecn()
414 }
415
416 pub fn flowlabel(&self) -> u32 {
418 self.fixed_hdr.flowlabel()
419 }
420
421 pub fn proto(&self) -> Ipv6Proto {
427 self.proto
428 }
429
430 pub fn src_ipv6(&self) -> Option<Ipv6SourceAddr> {
437 Ipv6SourceAddr::new(self.fixed_hdr.src_ip)
438 }
439
440 pub fn copy_header_bytes_for_fragment(&self) -> Vec<u8> {
451 let expected_bytes_len = self.header_len() - IPV6_FRAGMENT_EXT_HDR_LEN;
454 let mut bytes = Vec::with_capacity(expected_bytes_len);
455
456 bytes.extend_from_slice(Ref::bytes(&self.fixed_hdr));
457
458 let mut iter = self.extension_hdrs.iter();
462
463 let ext_hdr = iter.next().expect("packet must have at least one extension header");
467
468 if self.fixed_hdr.next_hdr == Ipv6ExtHdrType::Fragment.into() {
469 bytes[6] = ext_hdr.next_header;
475
476 bytes.extend_from_slice(&self.extension_hdrs.bytes()[IPV6_FRAGMENT_EXT_HDR_LEN..]);
478 } else {
479 let mut ext_hdr = ext_hdr;
480 let mut ext_hdr_start = 0;
481 let mut ext_hdr_end = iter.context().bytes_parsed;
482
483 loop {
489 let next_ext_hdr = iter
495 .next()
496 .expect("exhausted all extension headers without finding fragment header");
497
498 if let Ipv6ExtensionHeaderData::Fragment { .. } = next_ext_hdr.data() {
499 let fragment_hdr_end = ext_hdr_end + IPV6_FRAGMENT_EXT_HDR_LEN;
506 assert_eq!(fragment_hdr_end, iter.context().bytes_parsed);
507
508 let extension_hdr_bytes = self.extension_hdrs.bytes();
509
510 bytes.extend_from_slice(&extension_hdr_bytes[..ext_hdr_end]);
512
513 bytes.extend_from_slice(&extension_hdr_bytes[fragment_hdr_end..]);
515
516 match ext_hdr.data() {
519 Ipv6ExtensionHeaderData::HopByHopOptions { .. }
522 | Ipv6ExtensionHeaderData::DestinationOptions { .. } => {
523 bytes[IPV6_FIXED_HDR_LEN + ext_hdr_start] = next_ext_hdr.next_header;
524 }
525 Ipv6ExtensionHeaderData::Fragment { .. } => unreachable!(
526 "If we had a fragment header before `ext_hdr`, we should have used that instead"
527 ),
528 }
529
530 break;
531 }
532
533 ext_hdr = next_ext_hdr;
534 ext_hdr_start = ext_hdr_end;
535 ext_hdr_end = iter.context().bytes_parsed;
536 }
537 }
538
539 assert_eq!(bytes.len(), expected_bytes_len);
541 bytes
542 }
543
544 fn header_len(&self) -> usize {
545 Ref::bytes(&self.fixed_hdr).len() + self.extension_hdrs.bytes().len()
546 }
547
548 fn fragment_header_present(&self) -> bool {
549 for ext_hdr in self.extension_hdrs.iter() {
550 if matches!(ext_hdr.data(), Ipv6ExtensionHeaderData::Fragment { .. }) {
551 return true;
552 }
553 }
554 false
555 }
556
557 pub fn builder(&self) -> Ipv6PacketBuilder {
559 Ipv6PacketBuilder {
560 dscp_and_ecn: self.dscp_and_ecn(),
561 flowlabel: self.flowlabel(),
562 hop_limit: self.hop_limit(),
563 proto: self.proto(),
564 src_ip: self.src_ip(),
565 dst_ip: self.dst_ip(),
566 }
567 }
568
569 pub fn nat64_translate(
595 &self,
596 v4_src_addr: Ipv4Addr,
597 v4_dst_addr: Ipv4Addr,
598 ) -> Nat64TranslationResult<impl Serializer<Buffer = EmptyBuf> + Debug + '_, Nat64Error> {
599 #[derive(Debug)]
602 enum Nat64Serializer<T, U, O> {
603 Tcp(T),
604 Udp(U),
605 Other(O),
606 }
607
608 impl<T, U, O> Serializer for Nat64Serializer<T, U, O>
609 where
610 T: Serializer<Buffer = EmptyBuf>,
611 U: Serializer<Buffer = EmptyBuf>,
612 O: Serializer<Buffer = EmptyBuf>,
613 {
614 type Buffer = EmptyBuf;
615 fn serialize<B, P>(
616 self,
617 outer: PacketConstraints,
618 provider: P,
619 ) -> Result<B, (SerializeError<P::Error>, Self)>
620 where
621 B: GrowBufferMut,
622 P: BufferProvider<Self::Buffer, B>,
623 {
624 match self {
625 Nat64Serializer::Tcp(serializer) => serializer
626 .serialize(outer, provider)
627 .map_err(|(err, ser)| (err, Nat64Serializer::Tcp(ser))),
628 Nat64Serializer::Udp(serializer) => serializer
629 .serialize(outer, provider)
630 .map_err(|(err, ser)| (err, Nat64Serializer::Udp(ser))),
631 Nat64Serializer::Other(serializer) => serializer
632 .serialize(outer, provider)
633 .map_err(|(err, ser)| (err, Nat64Serializer::Other(ser))),
634 }
635 }
636
637 fn serialize_new_buf<B: GrowBufferMut, A: LayoutBufferAlloc<B>>(
638 &self,
639 outer: PacketConstraints,
640 alloc: A,
641 ) -> Result<B, SerializeError<A::Error>> {
642 match self {
643 Nat64Serializer::Tcp(serializer) => serializer.serialize_new_buf(outer, alloc),
644 Nat64Serializer::Udp(serializer) => serializer.serialize_new_buf(outer, alloc),
645 Nat64Serializer::Other(serializer) => {
646 serializer.serialize_new_buf(outer, alloc)
647 }
648 }
649 }
650 }
651
652 if self.fragment_header_present() {
655 return Nat64TranslationResult::Err(Nat64Error::NotImplemented);
656 }
657
658 let v4_builder = |v4_proto| {
659 let mut builder =
660 Ipv4PacketBuilder::new(v4_src_addr, v4_dst_addr, self.hop_limit(), v4_proto);
661 builder.dscp_and_ecn(self.dscp_and_ecn());
662
663 const IPV4_HEADER_LEN_BYTES: usize = HDR_PREFIX_LEN;
668
669 builder.df_flag(self.body().len() + IPV4_HEADER_LEN_BYTES > 1260);
675
676 builder.fragment_offset(FragmentOffset::ZERO);
679 builder.mf_flag(false);
680
681 builder
682 };
683
684 match self.proto() {
685 Ipv6Proto::Proto(IpProto::Tcp) => {
686 let v4_pkt_builder = v4_builder(Ipv4Proto::Proto(IpProto::Tcp));
687 let args = TcpParseArgs::new(self.src_ip(), self.dst_ip());
688 match TcpSegment::parse(&mut self.body.as_bytes(), args) {
693 Ok(tcp) => {
694 let tcp_serializer =
698 Nat64Serializer::Tcp(tcp.into_serializer(v4_src_addr, v4_dst_addr));
699 Nat64TranslationResult::Forward(v4_pkt_builder.wrap_body(tcp_serializer))
700 }
701 Err(msg) => {
702 debug!("Parsing of TCP segment failed: {:?}", msg);
703
704 let common_serializer =
713 Nat64Serializer::Other(self.body().into_serializer());
714 Nat64TranslationResult::Forward(v4_pkt_builder.wrap_body(common_serializer))
715 }
716 }
717 }
718
719 Ipv6Proto::Proto(IpProto::Udp) => {
724 let v4_pkt_builder = v4_builder(Ipv4Proto::Proto(IpProto::Udp));
725 let args = UdpParseArgs::new(self.src_ip(), self.dst_ip());
726 match UdpPacket::parse(&mut self.body.as_bytes(), args) {
727 Ok(udp) => {
728 let udp_serializer =
732 Nat64Serializer::Udp(udp.into_serializer(v4_src_addr, v4_dst_addr));
733 Nat64TranslationResult::Forward(v4_pkt_builder.wrap_body(udp_serializer))
734 }
735 Err(msg) => {
736 debug!("Parsing of UDP packet failed: {:?}", msg);
737
738 let common_serializer =
748 Nat64Serializer::Other(self.body().into_serializer());
749 Nat64TranslationResult::Forward(v4_pkt_builder.wrap_body(common_serializer))
750 }
751 }
752 }
753
754 Ipv6Proto::Icmpv6 => Nat64TranslationResult::Err(Nat64Error::NotImplemented),
757
758 Ipv6Proto::Other(val) => {
778 let v4_pkt_builder = v4_builder(Ipv4Proto::Other(val));
779 let common_serializer = Nat64Serializer::Other(self.body().into_serializer());
780 Nat64TranslationResult::Forward(v4_pkt_builder.wrap_body(common_serializer))
781 }
782
783 Ipv6Proto::NoNextHeader => {
784 let v4_pkt_builder = v4_builder(Ipv4Proto::Other(Ipv6Proto::NoNextHeader.into()));
785 let common_serializer = Nat64Serializer::Other(self.body().into_serializer());
786 Nat64TranslationResult::Forward(v4_pkt_builder.wrap_body(common_serializer))
787 }
788
789 Ipv6Proto::Proto(IpProto::Reserved) => Nat64TranslationResult::Drop,
792 }
793 }
794
795 pub fn to_vec(&self) -> Vec<u8> {
797 let Ipv6Packet { fixed_hdr, extension_hdrs, body, proto: _ } = self;
798 let mut buf = Vec::with_capacity(
799 Ref::bytes(&fixed_hdr).len() + extension_hdrs.bytes().len() + body.as_bytes().len(),
800 );
801 buf.extend(Ref::bytes(&fixed_hdr));
802 buf.extend(extension_hdrs.bytes());
803 buf.extend(body.as_bytes());
804 buf
805 }
806}
807
808impl<B: SplitByteSliceMut> Ipv6Packet<B> {
809 pub fn set_src_ip(&mut self, addr: Ipv6Addr) {
811 self.fixed_hdr.src_ip = addr;
812 }
813
814 pub fn set_dst_ip(&mut self, addr: Ipv6Addr) {
816 self.fixed_hdr.dst_ip = addr;
817 }
818
819 pub fn set_hop_limit(&mut self, hlim: u8) {
821 self.fixed_hdr.hop_limit = hlim;
822 }
823
824 pub fn body_mut(&mut self) -> &mut [u8] {
826 &mut self.body
827 }
828
829 pub fn parts_with_body_mut(&mut self) -> (&FixedHeader, ExtensionHeaders<'_>, &mut [u8]) {
832 (&self.fixed_hdr, ExtensionHeaders(self.extension_hdrs.as_ref()), &mut self.body)
833 }
834}
835
836impl<B: SplitByteSlice> Debug for Ipv6Packet<B> {
837 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
838 f.debug_struct("Ipv6Packet")
839 .field("src_ip", &self.src_ip())
840 .field("dst_ip", &self.dst_ip())
841 .field("hop_limit", &self.hop_limit())
842 .field("proto", &self.proto())
843 .field("dscp", &self.dscp_and_ecn().dscp())
844 .field("ecn", &self.dscp_and_ecn().ecn())
845 .field("flowlabel", &self.flowlabel())
846 .field("extension headers", &"TODO")
847 .field("body", &alloc::format!("<{} bytes>", self.body.len()))
848 .finish()
849 }
850}
851
852pub struct ExtensionHeaders<'a>(Records<&'a [u8], Ipv6ExtensionHeaderImpl>);
854
855impl<'a> ExtensionHeaders<'a> {
856 pub fn iter(&self) -> impl Iterator<Item = Ipv6ExtensionHeader<'_>> {
858 self.0.iter()
859 }
860
861 pub fn bytes(&self) -> &[u8] {
863 self.0.bytes()
864 }
865}
866
867#[derive(Copy, Clone, Debug, Eq, PartialEq)]
873pub struct ExtHdrParseError;
874
875pub struct Ipv6PacketRaw<B> {
885 fixed_hdr: Ref<B, FixedHeader>,
887 extension_hdrs: MaybeParsed<RecordsRaw<B, Ipv6ExtensionHeaderImpl>, B>,
893 body_proto: Result<(MaybeParsed<B, B>, Ipv6Proto), ExtHdrParseError>,
906}
907
908impl<B> Ipv6PacketRaw<B> {
909 pub fn body_mut(&mut self) -> Option<&mut B> {
913 match self.body_proto {
914 Ok(ref mut b) => match b {
915 (MaybeParsed::Complete(b), _) => Some(b),
916 (MaybeParsed::Incomplete(b), _) => Some(b),
917 },
918 Err(_) => None,
919 }
920 }
921}
922
923impl<B: SplitByteSlice> Ipv6Header for Ipv6PacketRaw<B> {
924 fn get_fixed_header(&self) -> &FixedHeader {
925 &self.fixed_hdr
926 }
927}
928
929impl<B: SplitByteSlice> ParsablePacket<B, ()> for Ipv6PacketRaw<B> {
930 type Error = Ipv6ParseError;
931
932 fn parse<BV: BufferView<B>>(mut buffer: BV, _args: ()) -> Result<Self, Self::Error> {
933 let fixed_hdr = buffer
934 .take_obj_front::<FixedHeader>()
935 .ok_or_else(debug_err_fn!(ParseError::Format, "too few bytes for header"))?;
936 let payload_len = fixed_hdr.payload_len.get().into();
937 let _: Option<B> = buffer.len().checked_sub(payload_len).map(|padding| {
939 buffer.take_back(padding).unwrap_or_else(|| {
940 panic!("buffer.len()={} padding={}", buffer.len(), padding);
941 })
942 });
943
944 let mut extension_hdr_context = Ipv6ExtensionHeaderParsingContext::new(fixed_hdr.next_hdr);
945
946 let extension_hdrs =
947 RecordsRaw::parse_raw_with_mut_context(&mut buffer, &mut extension_hdr_context)
948 .map_incomplete(|(b, _)| b);
949
950 let body_proto = match &extension_hdrs {
951 MaybeParsed::Complete(r) => {
952 let _: &RecordsRaw<B, _> = r;
953 assert!(is_valid_next_header_upper_layer(extension_hdr_context.next_header));
974 let proto = Ipv6Proto::from(extension_hdr_context.next_header);
975 let body = MaybeParsed::new_with_min_len(
976 buffer.into_rest(),
977 payload_len.saturating_sub(extension_hdrs.len()),
978 );
979 Ok((body, proto))
980 }
981 MaybeParsed::Incomplete(b) => {
982 let _: &B = b;
983 Err(ExtHdrParseError)
984 }
985 };
986
987 Ok(Ipv6PacketRaw { fixed_hdr, extension_hdrs, body_proto })
988 }
989
990 fn parse_metadata(&self) -> ParseMetadata {
991 let header_len = Ref::bytes(&self.fixed_hdr).len() + self.extension_hdrs.len();
992 let body_len = self.body_proto.as_ref().map(|(b, _p)| b.len()).unwrap_or(0);
993 ParseMetadata::from_packet(header_len, body_len, 0)
994 }
995}
996
997impl<B: SplitByteSlice> Ipv6PacketRaw<B> {
998 pub fn body_proto(&self) -> Result<(MaybeParsed<&[u8], &[u8]>, Ipv6Proto), ExtHdrParseError> {
1011 self.body_proto
1012 .as_ref()
1013 .map(|(mp, proto)| {
1014 (mp.as_ref().map(|b| b.deref()).map_incomplete(|b| b.deref()), *proto)
1015 })
1016 .map_err(|e| *e)
1017 }
1018
1019 pub fn body(&self) -> Result<MaybeParsed<&[u8], &[u8]>, ExtHdrParseError> {
1030 self.body_proto().map(|(body, _proto)| body)
1031 }
1032
1033 pub fn proto(&self) -> Result<Ipv6Proto, ExtHdrParseError> {
1040 self.body_proto().map(|(_body, proto)| proto)
1041 }
1042}
1043
1044impl<B: SplitByteSliceMut> Ipv6PacketRaw<B> {
1045 pub fn set_src_ip(&mut self, addr: Ipv6Addr) {
1047 self.fixed_hdr.src_ip = addr;
1048 }
1049
1050 pub fn set_dst_ip(&mut self, addr: Ipv6Addr) {
1052 self.fixed_hdr.dst_ip = addr;
1053 }
1054}
1055
1056pub enum NextHeader {
1059 NextLayer(Ipv6Proto),
1061 Extension(Ipv6ExtHdrType),
1063}
1064
1065impl From<NextHeader> for u8 {
1066 fn from(next_hdr: NextHeader) -> Self {
1067 match next_hdr {
1068 NextHeader::NextLayer(n) => n.into(),
1069 NextHeader::Extension(e) => e.into(),
1070 }
1071 }
1072}
1073
1074mod sealed {
1075 use super::*;
1076 pub trait Ipv6HeaderBefore<T> {}
1084
1085 impl<'a, O, T> Ipv6HeaderBefore<T> for &'a O where O: Ipv6HeaderBefore<T> {}
1086
1087 pub trait Ipv6HeaderBuilder {
1089 fn fixed_header(&self) -> &Ipv6PacketBuilder;
1091
1092 fn extension_headers_len(&self) -> usize;
1095
1096 fn serialize_header<B: SplitByteSliceMut, BV: BufferViewMut<B>>(
1101 &self,
1102 buffer: &mut BV,
1103 next_header: NextHeader,
1104 payload_len: usize,
1105 );
1106 }
1107}
1108use sealed::{Ipv6HeaderBefore, Ipv6HeaderBuilder};
1109
1110impl<'a, O> Ipv6HeaderBuilder for &'a O
1111where
1112 O: Ipv6HeaderBuilder,
1113{
1114 fn fixed_header(&self) -> &Ipv6PacketBuilder {
1115 O::fixed_header(self)
1116 }
1117
1118 fn extension_headers_len(&self) -> usize {
1119 O::extension_headers_len(self)
1120 }
1121
1122 fn serialize_header<B: SplitByteSliceMut, BV: BufferViewMut<B>>(
1123 &self,
1124 buffer: &mut BV,
1125 next_header: NextHeader,
1126 payload_len: usize,
1127 ) {
1128 O::serialize_header(self, buffer, next_header, payload_len)
1129 }
1130}
1131
1132macro_rules! impl_packet_builder {
1137 {} => {
1138 fn constraints(&self) -> PacketConstraints {
1139 let ext_headers = self.extension_headers_len();
1140 let header_len = IPV6_FIXED_HDR_LEN + ext_headers;
1141 let footer_len = 0;
1142 let min_body_len = 0;
1143 let max_body_len = IPV6_MAX_PAYLOAD_LENGTH - ext_headers;
1146 PacketConstraints::new(header_len, footer_len, min_body_len, max_body_len)
1147 }
1148
1149 fn serialize(&self, target: &mut SerializeTarget<'_>, body: FragmentedBytesMut<'_, '_>) {
1150 let mut bv = &mut target.header;
1151 self.serialize_header(
1152 &mut bv,
1153 NextHeader::NextLayer(self.fixed_header().proto()),
1154 body.len(),
1155 );
1156 }
1157 }
1158}
1159
1160macro_rules! impl_partial_packet_builder {
1161 {} => {
1162 fn partial_serialize(&self, body_len: usize, mut buffer: &mut [u8]) {
1163 self.serialize_header(
1164 &mut &mut buffer,
1165 NextHeader::NextLayer(self.fixed_header().proto()),
1166 body_len,
1167 );
1168 }
1169 }
1170}
1171#[derive(Debug, Clone, Eq, PartialEq)]
1173pub struct Ipv6PacketBuilder {
1174 dscp_and_ecn: DscpAndEcn,
1175 flowlabel: u32,
1176 hop_limit: u8,
1177 proto: Ipv6Proto,
1180 src_ip: Ipv6Addr,
1181 dst_ip: Ipv6Addr,
1182}
1183
1184impl Ipv6PacketBuilder {
1185 pub fn new<S: Into<Ipv6Addr>, D: Into<Ipv6Addr>>(
1191 src_ip: S,
1192 dst_ip: D,
1193 hop_limit: u8,
1194 proto: Ipv6Proto,
1195 ) -> Ipv6PacketBuilder {
1196 Ipv6PacketBuilder {
1197 dscp_and_ecn: DscpAndEcn::default(),
1198 flowlabel: 0,
1199 hop_limit,
1200 proto,
1201 src_ip: src_ip.into(),
1202 dst_ip: dst_ip.into(),
1203 }
1204 }
1205
1206 pub fn dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
1209 self.dscp_and_ecn = dscp_and_ecn;
1210 }
1211
1212 pub fn flowlabel(&mut self, flowlabel: u32) {
1218 assert!(flowlabel <= 1 << 20, "invalid flowlabel: {:x}", flowlabel);
1219 self.flowlabel = flowlabel;
1220 }
1221}
1222
1223impl Ipv6HeaderBuilder for Ipv6PacketBuilder {
1224 fn fixed_header(&self) -> &Ipv6PacketBuilder {
1225 self
1226 }
1227
1228 fn extension_headers_len(&self) -> usize {
1229 0
1230 }
1231
1232 fn serialize_header<B: SplitByteSliceMut, BV: BufferViewMut<B>>(
1233 &self,
1234 buffer: &mut BV,
1235 next_header: NextHeader,
1236 payload_len: usize,
1237 ) {
1238 buffer
1239 .write_obj_front(&FixedHeader::new(
1240 self.dscp_and_ecn,
1241 self.flowlabel,
1242 {
1243 debug_assert!(payload_len <= core::u16::MAX as usize);
1250 payload_len as u16
1251 },
1252 next_header.into(),
1253 self.hop_limit,
1254 self.src_ip,
1255 self.dst_ip,
1256 ))
1257 .expect("not enough bytes for IPv6 fixed header");
1258 }
1259}
1260
1261impl PacketBuilder for Ipv6PacketBuilder {
1262 impl_packet_builder! {}
1263}
1264
1265impl PartialPacketBuilder for Ipv6PacketBuilder {
1266 impl_partial_packet_builder! {}
1267}
1268
1269#[derive(Debug, Clone)]
1271pub struct Ipv6PacketBuilderWithHbhOptions<'a, I> {
1272 prefix_builder: Ipv6PacketBuilder,
1273 hbh_options: AlignedRecordSequenceBuilder<HopByHopOption<'a>, I>,
1274}
1275
1276impl<'a, I> Ipv6PacketBuilderWithHbhOptions<'a, I>
1277where
1278 I: Iterator + Clone,
1279 I::Item: Borrow<HopByHopOption<'a>>,
1280{
1281 pub fn new<T: IntoIterator<Item = I::Item, IntoIter = I>>(
1283 prefix_builder: Ipv6PacketBuilder,
1284 options: T,
1285 ) -> Option<Ipv6PacketBuilderWithHbhOptions<'a, I>> {
1286 let iter = options.into_iter();
1287 if iter
1290 .clone()
1291 .filter(|r| matches!(r.borrow().data, HopByHopOptionData::RouterAlert { .. }))
1292 .count()
1293 > 1
1294 {
1295 return None;
1296 }
1297 let hbh_options = AlignedRecordSequenceBuilder::new(2, iter);
1298 if next_multiple_of_eight(2 + hbh_options.serialized_len()) > IPV6_HBH_OPTIONS_MAX_LEN {
1300 return None;
1301 }
1302 Some(Ipv6PacketBuilderWithHbhOptions { prefix_builder, hbh_options })
1303 }
1304
1305 fn aligned_hbh_len(&self) -> usize {
1306 let opt_len = self.hbh_options.serialized_len();
1307 let hbh_len = opt_len + 2;
1308 next_multiple_of_eight(hbh_len)
1309 }
1310}
1311
1312fn next_multiple_of_eight(x: usize) -> usize {
1313 (x + 7) & (!7)
1314}
1315
1316impl IpPacketBuilder<Ipv6> for Ipv6PacketBuilder {
1317 fn new(src_ip: Ipv6Addr, dst_ip: Ipv6Addr, ttl: u8, proto: Ipv6Proto) -> Self {
1318 Ipv6PacketBuilder::new(src_ip, dst_ip, ttl, proto)
1319 }
1320
1321 fn src_ip(&self) -> Ipv6Addr {
1322 self.src_ip
1323 }
1324
1325 fn set_src_ip(&mut self, addr: Ipv6Addr) {
1326 self.src_ip = addr;
1327 }
1328
1329 fn dst_ip(&self) -> Ipv6Addr {
1330 self.dst_ip
1331 }
1332
1333 fn set_dst_ip(&mut self, addr: Ipv6Addr) {
1334 self.dst_ip = addr;
1335 }
1336
1337 fn proto(&self) -> Ipv6Proto {
1338 self.proto
1339 }
1340
1341 fn set_dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
1342 self.dscp_and_ecn = dscp_and_ecn;
1343 }
1344}
1345
1346impl<'a, I> Ipv6HeaderBuilder for Ipv6PacketBuilderWithHbhOptions<'a, I>
1347where
1348 I: Iterator + Clone,
1349 I::Item: Borrow<HopByHopOption<'a>>,
1350{
1351 fn fixed_header(&self) -> &Ipv6PacketBuilder {
1352 &self.prefix_builder
1353 }
1354
1355 fn extension_headers_len(&self) -> usize {
1356 self.prefix_builder.extension_headers_len() + self.aligned_hbh_len()
1357 }
1358
1359 fn serialize_header<B: SplitByteSliceMut, BV: BufferViewMut<B>>(
1360 &self,
1361 buffer: &mut BV,
1362 next_header: NextHeader,
1363 payload_len: usize,
1364 ) {
1365 let aligned_hbh_len = self.aligned_hbh_len();
1366 self.prefix_builder.serialize_header(
1368 buffer,
1369 NextHeader::Extension(Ipv6ExtHdrType::HopByHopOptions),
1370 payload_len + aligned_hbh_len,
1371 );
1372 let mut hbh_header = buffer.take_front(aligned_hbh_len).unwrap();
1374 let hbh_header = hbh_header.as_mut();
1375 hbh_header[0] = next_header.into();
1376 hbh_header[1] = u8::try_from((aligned_hbh_len - 8) / 8).expect("extension header too big");
1377 self.hbh_options.serialize_into(&mut hbh_header[2..]);
1378 }
1379}
1380
1381impl<'a, I> PacketBuilder for Ipv6PacketBuilderWithHbhOptions<'a, I>
1382where
1383 I: Iterator + Clone,
1384 I::Item: Borrow<HopByHopOption<'a>>,
1385{
1386 impl_packet_builder! {}
1387}
1388
1389impl<'a, I> PartialPacketBuilder for Ipv6PacketBuilderWithHbhOptions<'a, I>
1390where
1391 I: Iterator + Clone,
1392 I::Item: Borrow<HopByHopOption<'a>>,
1393{
1394 impl_partial_packet_builder! {}
1395}
1396
1397impl<'a, I> IpPacketBuilder<Ipv6> for Ipv6PacketBuilderWithHbhOptions<'a, I>
1398where
1399 I: Iterator<Item: Borrow<HopByHopOption<'a>>> + Debug + Default + Clone,
1400{
1401 fn new(src_ip: Ipv6Addr, dst_ip: Ipv6Addr, ttl: u8, proto: Ipv6Proto) -> Self {
1402 Ipv6PacketBuilderWithHbhOptions::new(
1403 Ipv6PacketBuilder::new(src_ip, dst_ip, ttl, proto),
1404 I::default(),
1405 )
1406 .expect("packet builder with no options should be valid")
1407 }
1408
1409 fn src_ip(&self) -> Ipv6Addr {
1410 self.prefix_builder.src_ip
1411 }
1412
1413 fn set_src_ip(&mut self, addr: Ipv6Addr) {
1414 self.prefix_builder.src_ip = addr;
1415 }
1416
1417 fn dst_ip(&self) -> Ipv6Addr {
1418 self.prefix_builder.dst_ip
1419 }
1420
1421 fn set_dst_ip(&mut self, addr: Ipv6Addr) {
1422 self.prefix_builder.dst_ip = addr;
1423 }
1424
1425 fn proto(&self) -> Ipv6Proto {
1426 self.prefix_builder.proto
1427 }
1428
1429 fn set_dscp_and_ecn(&mut self, dscp_and_ecn: DscpAndEcn) {
1430 self.prefix_builder.set_dscp_and_ecn(dscp_and_ecn)
1431 }
1432}
1433
1434#[derive(Debug, Eq, PartialEq)]
1443pub struct Ipv6PacketBuilderWithFragmentHeader<B> {
1444 header_builder: B,
1445 fragment_offset: FragmentOffset,
1446 more_fragments: bool,
1447 identification: u32,
1448}
1449
1450impl<B: Ipv6HeaderBefore<Self>> Ipv6PacketBuilderWithFragmentHeader<B> {
1451 pub fn new(
1453 header_builder: B,
1454 fragment_offset: FragmentOffset,
1455 more_fragments: bool,
1456 identification: u32,
1457 ) -> Self {
1458 Self { header_builder, fragment_offset, more_fragments, identification }
1459 }
1460}
1461
1462impl<B> Ipv6HeaderBefore<Ipv6PacketBuilderWithFragmentHeader<B>> for Ipv6PacketBuilder {}
1463impl<B, I> Ipv6HeaderBefore<Ipv6PacketBuilderWithFragmentHeader<B>>
1464 for Ipv6PacketBuilderWithHbhOptions<'_, I>
1465{
1466}
1467
1468pub trait Ipv6PacketBuilderBeforeFragment:
1471 Ipv6HeaderBefore<Ipv6PacketBuilderWithFragmentHeader<Self>> + Ipv6HeaderBuilder + Sized
1472{
1473}
1474impl<B> Ipv6PacketBuilderBeforeFragment for B where
1475 B: Ipv6HeaderBefore<Ipv6PacketBuilderWithFragmentHeader<Self>> + Ipv6HeaderBuilder + Sized
1476{
1477}
1478
1479impl<B: Ipv6HeaderBuilder> Ipv6HeaderBuilder for Ipv6PacketBuilderWithFragmentHeader<B> {
1480 fn fixed_header(&self) -> &Ipv6PacketBuilder {
1481 self.header_builder.fixed_header()
1482 }
1483
1484 fn extension_headers_len(&self) -> usize {
1485 self.header_builder.extension_headers_len() + IPV6_FRAGMENT_EXT_HDR_LEN
1486 }
1487
1488 fn serialize_header<BB: SplitByteSliceMut, BV: BufferViewMut<BB>>(
1489 &self,
1490 buffer: &mut BV,
1491 next_header: NextHeader,
1492 payload_len: usize,
1493 ) {
1494 let Self { header_builder, fragment_offset, more_fragments, identification } = self;
1495 let payload_len = payload_len + IPV6_FRAGMENT_EXT_HDR_LEN;
1496 header_builder.serialize_header(
1497 buffer,
1498 NextHeader::Extension(Ipv6ExtHdrType::Fragment),
1499 payload_len,
1500 );
1501 buffer.write_obj_front(&u8::from(next_header)).unwrap();
1502 let _: BB = buffer.take_front_zero(1).unwrap();
1504 let more_fragments = u16::from(*more_fragments);
1505 buffer
1506 .write_obj_front(&U16::new(fragment_offset.into_raw() << 3 | more_fragments))
1507 .unwrap();
1508 buffer.write_obj_front(&U32::new(*identification)).unwrap();
1509 }
1510}
1511
1512impl<B: Ipv6HeaderBuilder> PacketBuilder for Ipv6PacketBuilderWithFragmentHeader<B> {
1513 impl_packet_builder! {}
1514}
1515
1516impl<B: Ipv6HeaderBuilder> PartialPacketBuilder for Ipv6PacketBuilderWithFragmentHeader<B> {
1517 impl_partial_packet_builder! {}
1518}
1519
1520pub(crate) fn reassemble_fragmented_packet<
1522 B: SplitByteSliceMut,
1523 BV: BufferViewMut<B>,
1524 I: Iterator<Item = Vec<u8>>,
1525>(
1526 mut buffer: BV,
1527 header: Vec<u8>,
1528 body_fragments: I,
1529) -> IpParseResult<Ipv6, ()> {
1530 let bytes = buffer.as_mut();
1531
1532 bytes[0..header.len()].copy_from_slice(&header[..]);
1534 let mut byte_count = header.len();
1535
1536 for p in body_fragments {
1538 bytes[byte_count..byte_count + p.len()].copy_from_slice(&p[..]);
1539 byte_count += p.len();
1540 }
1541
1542 let payload_length = byte_count - IPV6_FIXED_HDR_LEN;
1554
1555 if payload_length > usize::from(core::u16::MAX) {
1558 return debug_err!(
1559 Err(ParseError::Format.into()),
1560 "fragmented packet payload length of {} bytes is too large",
1561 payload_length
1562 );
1563 }
1564
1565 let mut header = Ref::<_, FixedHeader>::from_prefix(bytes).unwrap().0;
1568
1569 header.payload_len.set(u16::try_from(payload_length).unwrap());
1571
1572 Ok(())
1573}
1574
1575#[cfg(test)]
1576mod tests {
1577 use assert_matches::assert_matches;
1578 use packet::{Buf, FragmentedBuffer, ParseBuffer};
1579 use test_case::test_case;
1580
1581 use crate::ethernet::{EthernetFrame, EthernetFrameLengthCheck};
1582 use crate::testutil::*;
1583
1584 use super::ext_hdrs::*;
1585 use super::*;
1586
1587 const DEFAULT_SRC_IP: Ipv6Addr =
1588 Ipv6Addr::from_bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
1589 const DEFAULT_DST_IP: Ipv6Addr =
1590 Ipv6Addr::from_bytes([17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]);
1591
1592 const DEFAULT_V4_SRC_IP: Ipv4Addr = Ipv4Addr::new([1, 2, 3, 4]);
1593 const DEFAULT_V4_DST_IP: Ipv4Addr = Ipv4Addr::new([5, 6, 7, 8]);
1594
1595 #[test]
1596 fn test_parse_serialize_full_tcp() {
1597 use crate::testdata::syn_v6::*;
1598
1599 let mut buf = ETHERNET_FRAME.bytes;
1600 let frame = buf.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1601 verify_ethernet_frame(&frame, ETHERNET_FRAME);
1602
1603 let mut body = frame.body();
1604 let packet = body.parse::<Ipv6Packet<_>>().unwrap();
1605 verify_ipv6_packet(&packet, IPV6_PACKET);
1606
1607 let buffer = packet
1609 .body()
1610 .into_serializer()
1611 .wrap_in(packet.builder())
1612 .wrap_in(frame.builder())
1613 .serialize_vec_outer()
1614 .unwrap();
1615 assert_eq!(buffer.as_ref(), ETHERNET_FRAME.bytes);
1616
1617 assert_eq!(&packet.to_vec()[..], IPV6_PACKET.bytes);
1619 }
1620
1621 #[test]
1622 fn test_parse_serialize_full_udp() {
1623 use crate::testdata::dns_request_v6::*;
1624
1625 let mut buf = ETHERNET_FRAME.bytes;
1626 let frame = buf.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1627 verify_ethernet_frame(&frame, ETHERNET_FRAME);
1628
1629 let mut body = frame.body();
1630 let packet = body.parse::<Ipv6Packet<_>>().unwrap();
1631 verify_ipv6_packet(&packet, IPV6_PACKET);
1632
1633 let buffer = packet
1635 .body()
1636 .into_serializer()
1637 .wrap_in(packet.builder())
1638 .wrap_in(frame.builder())
1639 .serialize_vec_outer()
1640 .unwrap();
1641 assert_eq!(buffer.as_ref(), ETHERNET_FRAME.bytes);
1642
1643 assert_eq!(&packet.to_vec()[..], IPV6_PACKET.bytes);
1645 }
1646
1647 #[test]
1648 fn test_parse_serialize_with_extension_headers() {
1649 use crate::testdata::mld_router_report::*;
1652
1653 let mut buf = REPORT;
1654 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
1655 assert_eq!(packet.iter_extension_hdrs().count(), 1);
1656
1657 assert_eq!(&packet.to_vec()[..], REPORT);
1662 }
1663
1664 fn fixed_hdr_to_bytes(fixed_hdr: FixedHeader) -> [u8; IPV6_FIXED_HDR_LEN] {
1665 zerocopy::transmute!(fixed_hdr)
1666 }
1667
1668 fn new_fixed_hdr() -> FixedHeader {
1670 FixedHeader::new(
1671 DscpAndEcn::new(0, 2),
1672 0x77,
1673 0,
1674 IpProto::Tcp.into(),
1675 64,
1676 DEFAULT_SRC_IP,
1677 DEFAULT_DST_IP,
1678 )
1679 }
1680
1681 #[test]
1682 fn test_parse() {
1683 let mut buf = &fixed_hdr_to_bytes(new_fixed_hdr())[..];
1684 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
1685 assert_eq!(packet.dscp_and_ecn().dscp(), 0);
1686 assert_eq!(packet.dscp_and_ecn().ecn(), 2);
1687 assert_eq!(packet.flowlabel(), 0x77);
1688 assert_eq!(packet.hop_limit(), 64);
1689 assert_eq!(packet.fixed_hdr.next_hdr, IpProto::Tcp.into());
1690 assert_eq!(packet.proto(), IpProto::Tcp.into());
1691 assert_eq!(packet.src_ip(), DEFAULT_SRC_IP);
1692 assert_eq!(packet.dst_ip(), DEFAULT_DST_IP);
1693 assert_eq!(packet.body(), []);
1694 }
1695
1696 #[test]
1697 fn test_parse_with_ext_hdrs() {
1698 #[rustfmt::skip]
1699 let mut buf = [
1700 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1702 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1703
1704 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,
1719 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1720
1721 IpProto::Tcp.into(), 1, 0, 1, 0, 1, 1, 0, 1, 6, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5,
1731 ];
1732 let mut fixed_hdr = new_fixed_hdr();
1733 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
1734 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
1735 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
1736 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
1737 let mut buf = &buf[..];
1738 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
1739 assert_eq!(packet.dscp_and_ecn().dscp(), 0);
1740 assert_eq!(packet.dscp_and_ecn().ecn(), 2);
1741 assert_eq!(packet.flowlabel(), 0x77);
1742 assert_eq!(packet.hop_limit(), 64);
1743 assert_eq!(packet.fixed_hdr.next_hdr, Ipv6ExtHdrType::HopByHopOptions.into());
1744 assert_eq!(packet.proto(), IpProto::Tcp.into());
1745 assert_eq!(packet.src_ip(), DEFAULT_SRC_IP);
1746 assert_eq!(packet.dst_ip(), DEFAULT_DST_IP);
1747 assert_eq!(packet.body(), [1, 2, 3, 4, 5]);
1748 let ext_hdrs: Vec<Ipv6ExtensionHeader<'_>> = packet.iter_extension_hdrs().collect();
1749 assert_eq!(ext_hdrs.len(), 2);
1750 assert_eq!(ext_hdrs[0].next_header, Ipv6ExtHdrType::Routing.into());
1752 if let Ipv6ExtensionHeaderData::HopByHopOptions { options } = ext_hdrs[0].data() {
1753 assert_eq!(options.iter().count(), 0);
1755 } else {
1756 panic!("Should have matched HopByHopOptions!");
1757 }
1758
1759 assert_eq!(ext_hdrs[1].next_header, IpProto::Tcp.into());
1764 if let Ipv6ExtensionHeaderData::DestinationOptions { options } = ext_hdrs[1].data() {
1765 assert_eq!(options.iter().count(), 0);
1767 } else {
1768 panic!("Should have matched DestinationOptions!");
1769 }
1770
1771 #[rustfmt::skip]
1773 let mut buf = [
1774 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1776 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1777
1778 Ipv6Proto::NoNextHeader.into(), 0, 0, 1, 0, 1, 1, 0, 1, 2, 3, 4, 5,
1787 ];
1788 let mut fixed_hdr = new_fixed_hdr();
1789 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
1790 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
1791 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
1792 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
1793 let mut buf = &buf[..];
1794 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
1795 assert_eq!(packet.dscp_and_ecn().dscp(), 0);
1796 assert_eq!(packet.dscp_and_ecn().ecn(), 2);
1797 assert_eq!(packet.flowlabel(), 0x77);
1798 assert_eq!(packet.hop_limit(), 64);
1799 assert_eq!(packet.fixed_hdr.next_hdr, Ipv6ExtHdrType::HopByHopOptions.into());
1800 assert_eq!(packet.proto(), Ipv6Proto::NoNextHeader);
1801 assert_eq!(packet.src_ip(), DEFAULT_SRC_IP);
1802 assert_eq!(packet.dst_ip(), DEFAULT_DST_IP);
1803 assert_eq!(packet.body(), [1, 2, 3, 4, 5]);
1804 let ext_hdrs: Vec<Ipv6ExtensionHeader<'_>> = packet.iter_extension_hdrs().collect();
1805 assert_eq!(ext_hdrs.len(), 1);
1806 assert_eq!(ext_hdrs[0].next_header, Ipv6Proto::NoNextHeader.into());
1808 if let Ipv6ExtensionHeaderData::HopByHopOptions { options } = ext_hdrs[0].data() {
1809 assert_eq!(options.iter().count(), 0);
1811 } else {
1812 panic!("Should have matched HopByHopOptions!");
1813 }
1814 }
1815
1816 #[test]
1817 fn test_parse_error() {
1818 let mut fixed_hdr = new_fixed_hdr();
1820 fixed_hdr.version_tc_flowlabel[0] = 0x50;
1821 assert_eq!(
1822 (&fixed_hdr_to_bytes(fixed_hdr)[..]).parse::<Ipv6Packet<_>>().unwrap_err(),
1823 ParseError::Format.into()
1824 );
1825
1826 let mut fixed_hdr = new_fixed_hdr();
1828 fixed_hdr.payload_len = U16::new(2);
1829 assert_eq!(
1830 (&fixed_hdr_to_bytes(fixed_hdr)[..]).parse::<Ipv6Packet<_>>().unwrap_err(),
1831 ParseError::Format.into()
1832 );
1833
1834 let mut fixed_hdr = new_fixed_hdr();
1836 fixed_hdr.next_hdr = 255;
1837 assert_eq!(
1838 (&fixed_hdr_to_bytes(fixed_hdr)[..]).parse::<Ipv6Packet<_>>().unwrap_err(),
1839 Ipv6ParseError::ParameterProblem {
1840 src_ip: DEFAULT_SRC_IP,
1841 dst_ip: DEFAULT_DST_IP,
1842 code: Icmpv6ParameterProblemCode::UnrecognizedNextHeaderType,
1843 pointer: u32::from(NEXT_HEADER_OFFSET),
1844 must_send_icmp: false,
1845 action: IpParseErrorAction::DiscardPacketSendIcmpNoMulticast,
1846 }
1847 );
1848
1849 let mut fixed_hdr = new_fixed_hdr();
1851 fixed_hdr.next_hdr = Ipv4Proto::Icmp.into();
1852 assert_eq!(
1853 (&fixed_hdr_to_bytes(fixed_hdr)[..]).parse::<Ipv6Packet<_>>().unwrap_err(),
1854 Ipv6ParseError::ParameterProblem {
1855 src_ip: DEFAULT_SRC_IP,
1856 dst_ip: DEFAULT_DST_IP,
1857 code: Icmpv6ParameterProblemCode::UnrecognizedNextHeaderType,
1858 pointer: u32::from(NEXT_HEADER_OFFSET),
1859 must_send_icmp: false,
1860 action: IpParseErrorAction::DiscardPacketSendIcmpNoMulticast,
1861 }
1862 );
1863
1864 #[rustfmt::skip]
1866 let mut buf = [
1867 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1869 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1870
1871 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,
1879 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1880
1881 IpProto::Tcp.into(), 0, 0, 1, 0, 1, 1, 0, 1, 2, 3, 4, 5,
1890 ];
1891 let mut fixed_hdr = new_fixed_hdr();
1892 fixed_hdr.next_hdr = Ipv6ExtHdrType::Routing.into();
1893 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
1894 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
1895 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
1896 let mut buf = &buf[..];
1897 assert_eq!(
1898 buf.parse::<Ipv6Packet<_>>().unwrap_err(),
1899 Ipv6ParseError::ParameterProblem {
1900 src_ip: DEFAULT_SRC_IP,
1901 dst_ip: DEFAULT_DST_IP,
1902 code: Icmpv6ParameterProblemCode::UnrecognizedNextHeaderType,
1903 pointer: IPV6_FIXED_HDR_LEN as u32,
1904 must_send_icmp: false,
1905 action: IpParseErrorAction::DiscardPacketSendIcmpNoMulticast,
1906 }
1907 );
1908
1909 #[rustfmt::skip]
1911 let mut buf = [
1912 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1914 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1915
1916 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,
1924 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1925
1926 1, 2, 3, 4, 5,
1928 ];
1929 let mut fixed_hdr = new_fixed_hdr();
1930 fixed_hdr.next_hdr = Ipv6ExtHdrType::Routing.into();
1931 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
1932 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
1933 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
1934 let mut buf = &buf[..];
1935 assert_eq!(
1936 buf.parse::<Ipv6Packet<_>>().unwrap_err(),
1937 Ipv6ParseError::ParameterProblem {
1938 src_ip: DEFAULT_SRC_IP,
1939 dst_ip: DEFAULT_DST_IP,
1940 code: Icmpv6ParameterProblemCode::ErroneousHeaderField,
1941 pointer: (IPV6_FIXED_HDR_LEN as u32) + 2,
1942 must_send_icmp: true,
1943 action: IpParseErrorAction::DiscardPacketSendIcmpNoMulticast,
1944 }
1945 );
1946 }
1947
1948 #[test]
1949 fn test_parse_all_next_header_values() {
1950 let mut buf = [
1956 0x81, 0x13, 0x27, 0xeb, 0x75, 0x92, 0x33, 0x89, 0x01, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
1957 0x03, 0x70, 0x00, 0x22, 0xf7, 0x30, 0x2c, 0x06, 0xfe, 0xc9, 0x00, 0x2d, 0x3b, 0xeb,
1958 0xad, 0x3e, 0x5c, 0x41, 0xc8, 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x11, 0x00,
1959 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x4f, 0x4f, 0x6f, 0x4f, 0x4f, 0x4f, 0x4f,
1960 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x19, 0x19,
1961 0x19, 0x19, 0x19, 0x4f, 0x4f, 0x4f, 0x4f, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1962 0x00, 0x4f, 0x4f, 0x5a, 0x5a, 0x5a, 0xc9, 0x5a, 0x46, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
1963 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0xe4, 0x5a, 0x5a, 0x5a, 0x5a,
1964 ];
1965
1966 assert_matches!(
1969 (&buf[..]).parse::<Ipv6Packet<_>>(),
1970 Err(Ipv6ParseError::ParameterProblem {
1971 src_ip: _,
1972 dst_ip: _,
1973 code: Icmpv6ParameterProblemCode::UnrecognizedNextHeaderType,
1974 pointer: 0,
1975 must_send_icmp: false,
1976 action: IpParseErrorAction::DiscardPacket,
1977 })
1978 );
1979
1980 for b in 0u8..=255 {
1983 buf[6] = b;
1985 let _: Result<_, _> = (&buf[..]).parse::<Ipv6Packet<_>>();
1986 }
1987 }
1988
1989 #[test]
1990 fn test_partial_parse() {
1991 use core::convert::TryInto as _;
1992 use core::ops::Deref as _;
1993
1994 #[rustfmt::skip]
1996 let mut buf = [
1997 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1999 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2000
2001 IpProto::Tcp.into(), 0, 0, 1, 0, 1, 1, 0, 1, 2, 3, 4, 5,
2010 ];
2011 let len = buf.len() - IPV6_FIXED_HDR_LEN;
2012 let len = len.try_into().unwrap();
2013 let make_fixed_hdr = || {
2014 let mut fixed_hdr = new_fixed_hdr();
2015 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2016 fixed_hdr.payload_len = U16::new(len);
2017 fixed_hdr
2018 };
2019 const MALFORMED_BYTE: u8 = 10;
2021 buf[IPV6_FIXED_HDR_LEN + 1] = MALFORMED_BYTE;
2022 let fixed_hdr = fixed_hdr_to_bytes(make_fixed_hdr());
2023 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr);
2024 let mut buf = &buf[..];
2025 let partial = buf.parse::<Ipv6PacketRaw<_>>().unwrap();
2026 let Ipv6PacketRaw { fixed_hdr, extension_hdrs, body_proto } = &partial;
2027 assert_eq!(fixed_hdr.deref(), &make_fixed_hdr());
2028 assert_eq!(
2029 *extension_hdrs.as_ref().incomplete().unwrap(),
2030 [IpProto::Tcp.into(), MALFORMED_BYTE]
2031 );
2032 assert_eq!(body_proto, &Err(ExtHdrParseError));
2033 assert!(Ipv6Packet::try_from_raw(partial).is_err());
2034
2035 let mut buf = [
2037 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,
2039 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5,
2041 ];
2042 let make_fixed_hdr = || {
2043 let mut fixed_hdr = new_fixed_hdr();
2044 fixed_hdr.next_hdr = IpProto::Tcp.into();
2045 fixed_hdr.payload_len = U16::new(10);
2046 fixed_hdr
2047 };
2048 let fixed_hdr = fixed_hdr_to_bytes(make_fixed_hdr());
2049 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr);
2050 let mut parsebuff = &buf[..];
2051 let partial = parsebuff.parse::<Ipv6PacketRaw<_>>().unwrap();
2052 let Ipv6PacketRaw { fixed_hdr, extension_hdrs, body_proto } = &partial;
2053 assert_eq!(fixed_hdr.deref(), &make_fixed_hdr());
2054 assert_eq!(extension_hdrs.as_ref().complete().unwrap().deref(), []);
2055 let (body, proto) = body_proto.unwrap();
2056 assert_eq!(body.incomplete().unwrap(), &buf[IPV6_FIXED_HDR_LEN..]);
2057 assert_eq!(proto, IpProto::Tcp.into());
2058 assert!(Ipv6Packet::try_from_raw(partial).is_err());
2059 }
2060
2061 fn new_builder() -> Ipv6PacketBuilder {
2063 Ipv6PacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, 64, IpProto::Tcp.into())
2064 }
2065
2066 #[test]
2067 fn test_serialize() {
2068 let mut builder = new_builder();
2069 builder.dscp_and_ecn(DscpAndEcn::new(0x12, 3));
2070 builder.flowlabel(0x10405);
2071 let mut buf = (&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
2072 .into_serializer()
2073 .wrap_in(builder)
2074 .serialize_vec_outer()
2075 .unwrap();
2076 assert_eq!(
2078 buf.as_ref(),
2079 &[
2080 100, 177, 4, 5, 0, 10, 6, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
2081 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 1, 2, 3, 4,
2082 5, 6, 7, 8, 9
2083 ][..],
2084 );
2085
2086 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2087 assert_eq!(packet.dscp_and_ecn().dscp(), 0x12);
2090 assert_eq!(packet.dscp_and_ecn().ecn(), 3);
2091 assert_eq!(packet.flowlabel(), 0x10405);
2092 }
2093
2094 #[test]
2095 fn test_partial_serialize() {
2096 let mut builder = new_builder();
2097 builder.dscp_and_ecn(DscpAndEcn::new(0x12, 3));
2098 builder.flowlabel(0x10405);
2099 let body = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
2100 let packet = (&body).into_serializer().wrap_in(builder);
2101
2102 const HEADER_LEN: usize = 40;
2105 const HEADER: [u8; HEADER_LEN] = [
2106 100, 177, 4, 5, 0, 10, 6, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
2107 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
2108 ];
2109 let mut expected_partial = HEADER.to_vec();
2110 expected_partial.resize(expected_partial.len() + body.len(), 0);
2111
2112 for i in 1..expected_partial.len() {
2113 let mut buf = vec![0u8; i];
2114 let result =
2115 packet.partial_serialize(PacketConstraints::UNCONSTRAINED, buf.as_mut_slice());
2116
2117 let bytes_written = if i >= HEADER_LEN { HEADER_LEN } else { 0 };
2120 assert_eq!(
2121 result,
2122 Ok(PartialSerializeResult { bytes_written, total_size: body.len() + HEADER_LEN })
2123 );
2124 if bytes_written > 0 {
2125 assert_eq!(buf, expected_partial[..i]);
2126 }
2127 }
2128 }
2129
2130 #[test]
2131 fn test_serialize_zeroes() {
2132 let mut buf_0 = [0; IPV6_FIXED_HDR_LEN];
2135 let _: Buf<&mut [u8]> = Buf::new(&mut buf_0[..], IPV6_FIXED_HDR_LEN..)
2136 .wrap_in(new_builder())
2137 .serialize_vec_outer()
2138 .unwrap()
2139 .unwrap_a();
2140 let mut buf_1 = [0xFF; IPV6_FIXED_HDR_LEN];
2141 let _: Buf<&mut [u8]> = Buf::new(&mut buf_1[..], IPV6_FIXED_HDR_LEN..)
2142 .wrap_in(new_builder())
2143 .serialize_vec_outer()
2144 .unwrap()
2145 .unwrap_a();
2146 assert_eq!(&buf_0[..], &buf_1[..]);
2147 }
2148
2149 #[test]
2150 fn test_packet_builder_proto_not_next_header() {
2151 let mut buf = (&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
2155 .into_serializer()
2156 .wrap_in(
2157 Ipv6PacketBuilderWithHbhOptions::new(
2158 new_builder(),
2159 &[HopByHopOption {
2160 action: ExtensionHeaderOptionAction::SkipAndContinue,
2161 mutable: false,
2162 data: HopByHopOptionData::RouterAlert { data: 0 },
2163 }],
2164 )
2165 .unwrap(),
2166 )
2167 .serialize_vec_outer()
2168 .unwrap();
2169 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2170 assert_eq!(packet.proto(), IpProto::Tcp.into());
2171 assert_eq!(packet.next_header(), Ipv6ExtHdrType::HopByHopOptions.into());
2172 }
2173
2174 #[test]
2175 #[should_panic(expected = "SizeLimitExceeded, Nested { inner: Buf { buf:")]
2176 fn test_serialize_panic_packet_length() {
2177 let _: Buf<&mut [u8]> = Buf::new(&mut [0; 1 << 16][..], ..)
2180 .wrap_in(new_builder())
2181 .serialize_vec_outer()
2182 .unwrap()
2183 .unwrap_a();
2184 }
2185
2186 #[test]
2187 #[should_panic(expected = "packet must have at least one extension header")]
2188 fn test_copy_header_bytes_for_fragment_without_ext_hdrs() {
2189 let mut buf = &fixed_hdr_to_bytes(new_fixed_hdr())[..];
2190 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2191 let _: Vec<_> = packet.copy_header_bytes_for_fragment();
2192 }
2193
2194 #[test]
2195 #[should_panic(expected = "exhausted all extension headers without finding fragment header")]
2196 fn test_copy_header_bytes_for_fragment_with_1_ext_hdr_no_fragment() {
2197 #[rustfmt::skip]
2198 let mut buf = [
2199 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2201 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2202
2203 IpProto::Tcp.into(), 0, 0, 1, 0, 1, 1, 0, 1, 2, 3, 4, 5,
2212 ];
2213 let mut fixed_hdr = new_fixed_hdr();
2214 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2215 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
2216 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2217 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2218 let mut buf = &buf[..];
2219 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2220 let _: Vec<_> = packet.copy_header_bytes_for_fragment();
2221 }
2222
2223 #[test]
2224 #[should_panic(expected = "exhausted all extension headers without finding fragment header")]
2225 fn test_copy_header_bytes_for_fragment_with_2_ext_hdr_no_fragment() {
2226 #[rustfmt::skip]
2227 let mut buf = [
2228 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2230 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2231
2232 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,
2249 ];
2250 let mut fixed_hdr = new_fixed_hdr();
2251 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2252 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
2253 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2254 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2255 let mut buf = &buf[..];
2256 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2257 let _: Vec<_> = packet.copy_header_bytes_for_fragment();
2258 }
2259
2260 #[test]
2261 fn test_copy_header_bytes_for_fragment() {
2262 #[rustfmt::skip]
2267 let mut bytes = [
2268 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2270 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2271
2272 IpProto::Tcp.into(), 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5,
2280 ];
2281 let mut fixed_hdr = new_fixed_hdr();
2282 fixed_hdr.next_hdr = Ipv6ExtHdrType::Fragment.into();
2283 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2284 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2285 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2286 let mut buf = &bytes[..];
2287 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2288 let copied_bytes = packet.copy_header_bytes_for_fragment();
2289 bytes[6] = IpProto::Tcp.into();
2290 assert_eq!(&copied_bytes[..], &bytes[..IPV6_FIXED_HDR_LEN]);
2291
2292 #[rustfmt::skip]
2297 let mut bytes = [
2298 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2300 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2301
2302 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,
2317 ];
2318 let mut fixed_hdr = new_fixed_hdr();
2319 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2320 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2321 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2322 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2323 let mut buf = &bytes[..];
2324 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2325 let copied_bytes = packet.copy_header_bytes_for_fragment();
2326 bytes[IPV6_FIXED_HDR_LEN] = IpProto::Tcp.into();
2327 assert_eq!(&copied_bytes[..], &bytes[..IPV6_FIXED_HDR_LEN + 8]);
2328
2329 #[rustfmt::skip]
2334 let mut bytes = [
2335 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2337 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2338
2339 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,
2362 ];
2363 let mut fixed_hdr = new_fixed_hdr();
2364 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2365 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2366 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2367 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2368 let mut buf = &bytes[..];
2369 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2370 let copied_bytes = packet.copy_header_bytes_for_fragment();
2371 bytes[IPV6_FIXED_HDR_LEN + 8] = IpProto::Tcp.into();
2372 assert_eq!(&copied_bytes[..], &bytes[..IPV6_FIXED_HDR_LEN + 24]);
2373
2374 #[rustfmt::skip]
2379 let mut bytes = [
2380 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2382 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2383
2384 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,
2400 ];
2401 let mut fixed_hdr = new_fixed_hdr();
2402 fixed_hdr.next_hdr = Ipv6ExtHdrType::Fragment.into();
2403 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2404 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2405 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2406 let mut buf = &bytes[..];
2407 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2408 let copied_bytes = packet.copy_header_bytes_for_fragment();
2409 let mut expected_bytes = Vec::new();
2410 expected_bytes.extend_from_slice(&bytes[..IPV6_FIXED_HDR_LEN]);
2411 expected_bytes.extend_from_slice(&bytes[IPV6_FIXED_HDR_LEN + 8..bytes.len() - 5]);
2412 expected_bytes[6] = Ipv6ExtHdrType::DestinationOptions.into();
2413 assert_eq!(&copied_bytes[..], &expected_bytes[..]);
2414
2415 #[rustfmt::skip]
2420 let mut bytes = [
2421 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2423 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2424
2425 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,
2447 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
2448
2449 1, 2, 3, 4, 5,
2451 ];
2452 let mut fixed_hdr = new_fixed_hdr();
2453 fixed_hdr.next_hdr = Ipv6ExtHdrType::Fragment.into();
2454 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2455 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2456 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2457 let mut buf = &bytes[..];
2458 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2459 let copied_bytes = packet.copy_header_bytes_for_fragment();
2460 let mut expected_bytes = Vec::new();
2461 expected_bytes.extend_from_slice(&bytes[..IPV6_FIXED_HDR_LEN]);
2462 expected_bytes.extend_from_slice(&bytes[IPV6_FIXED_HDR_LEN + 8..bytes.len() - 5]);
2463 expected_bytes[6] = Ipv6ExtHdrType::DestinationOptions.into();
2464 assert_eq!(&copied_bytes[..], &expected_bytes[..]);
2465
2466 #[rustfmt::skip]
2471 let mut bytes = [
2472 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2474 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2475
2476 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,
2499 ];
2500 let mut fixed_hdr = new_fixed_hdr();
2501 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2502 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2503 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2504 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2505 let mut buf = &bytes[..];
2506 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2507 let copied_bytes = packet.copy_header_bytes_for_fragment();
2508 let mut expected_bytes = Vec::new();
2509 expected_bytes.extend_from_slice(&bytes[..IPV6_FIXED_HDR_LEN + 8]);
2510 expected_bytes.extend_from_slice(&bytes[IPV6_FIXED_HDR_LEN + 16..bytes.len() - 5]);
2511 expected_bytes[IPV6_FIXED_HDR_LEN] = Ipv6ExtHdrType::DestinationOptions.into();
2512 assert_eq!(&copied_bytes[..], &expected_bytes[..]);
2513
2514 #[rustfmt::skip]
2519 let mut bytes = [
2520 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2522 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2523
2524 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,
2538 ];
2539 let mut fixed_hdr = new_fixed_hdr();
2540 fixed_hdr.next_hdr = Ipv6ExtHdrType::Fragment.into();
2541 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2542 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2543 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2544 let mut buf = &bytes[..];
2545 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2546 let copied_bytes = packet.copy_header_bytes_for_fragment();
2547 let mut expected_bytes = Vec::new();
2548 expected_bytes.extend_from_slice(&bytes[..IPV6_FIXED_HDR_LEN]);
2549 expected_bytes.extend_from_slice(&bytes[IPV6_FIXED_HDR_LEN + 8..bytes.len() - 5]);
2550 assert_eq!(&copied_bytes[..], &expected_bytes[..]);
2551 }
2552
2553 #[test]
2554 fn test_next_multiple_of_eight() {
2555 for x in 0usize..=IPV6_HBH_OPTIONS_MAX_LEN {
2556 let y = next_multiple_of_eight(x);
2557 assert_eq!(y % 8, 0);
2558 assert!(y >= x);
2559 if x % 8 == 0 {
2560 assert_eq!(x, y);
2561 } else {
2562 assert_eq!(x + (8 - x % 8), y);
2563 }
2564 }
2565 }
2566
2567 fn create_ipv4_and_ipv6_builders(
2568 proto_v4: Ipv4Proto,
2569 proto_v6: Ipv6Proto,
2570 ) -> (Ipv4PacketBuilder, Ipv6PacketBuilder) {
2571 const IP_DSCP_AND_ECN: DscpAndEcn = DscpAndEcn::new(0x12, 3);
2572 const IP_TTL: u8 = 64;
2573
2574 let mut ipv4_builder =
2575 Ipv4PacketBuilder::new(DEFAULT_V4_SRC_IP, DEFAULT_V4_DST_IP, IP_TTL, proto_v4);
2576 ipv4_builder.dscp_and_ecn(IP_DSCP_AND_ECN);
2577 ipv4_builder.df_flag(false);
2578 ipv4_builder.mf_flag(false);
2579 ipv4_builder.fragment_offset(FragmentOffset::ZERO);
2580
2581 let mut ipv6_builder =
2582 Ipv6PacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, IP_TTL, proto_v6);
2583 ipv6_builder.dscp_and_ecn(IP_DSCP_AND_ECN);
2584 ipv6_builder.flowlabel(0x456);
2585
2586 (ipv4_builder, ipv6_builder)
2587 }
2588
2589 fn create_tcp_ipv4_and_ipv6_pkt()
2590 -> (packet::Either<EmptyBuf, Buf<Vec<u8>>>, packet::Either<EmptyBuf, Buf<Vec<u8>>>) {
2591 use crate::tcp::TcpSegmentBuilder;
2592 use core::num::NonZeroU16;
2593
2594 let tcp_src_port: NonZeroU16 = NonZeroU16::new(20).unwrap();
2595 let tcp_dst_port: NonZeroU16 = NonZeroU16::new(30).unwrap();
2596 const TCP_SEQ_NUM: u32 = 4321;
2597 const TCP_ACK_NUM: Option<u32> = Some(1234);
2598 const TCP_WINDOW_SIZE: u16 = 12345;
2599 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
2600
2601 let (ipv4_builder, ipv6_builder) =
2602 create_ipv4_and_ipv6_builders(IpProto::Tcp.into(), IpProto::Tcp.into());
2603
2604 let tcp_builder = TcpSegmentBuilder::new(
2605 DEFAULT_V4_SRC_IP,
2606 DEFAULT_V4_DST_IP,
2607 tcp_src_port,
2608 tcp_dst_port,
2609 TCP_SEQ_NUM,
2610 TCP_ACK_NUM,
2611 TCP_WINDOW_SIZE,
2612 );
2613
2614 let v4_pkt_buf = (&PAYLOAD)
2615 .into_serializer()
2616 .wrap_in(tcp_builder)
2617 .wrap_in(ipv4_builder)
2618 .serialize_vec_outer()
2619 .expect("Failed to serialize to v4_pkt_buf");
2620
2621 let v6_tcp_builder = TcpSegmentBuilder::new(
2622 DEFAULT_SRC_IP,
2623 DEFAULT_DST_IP,
2624 tcp_src_port,
2625 tcp_dst_port,
2626 TCP_SEQ_NUM,
2627 TCP_ACK_NUM,
2628 TCP_WINDOW_SIZE,
2629 );
2630
2631 let v6_pkt_buf = (&PAYLOAD)
2632 .into_serializer()
2633 .wrap_in(v6_tcp_builder)
2634 .wrap_in(ipv6_builder)
2635 .serialize_vec_outer()
2636 .expect("Failed to serialize to v4_pkt_buf");
2637
2638 (v4_pkt_buf, v6_pkt_buf)
2639 }
2640
2641 #[test]
2642 fn test_nat64_translate_tcp() {
2643 let (expected_v4_pkt_buf, mut v6_pkt_buf) = create_tcp_ipv4_and_ipv6_pkt();
2644
2645 let parsed_v6_packet =
2646 v6_pkt_buf.parse::<Ipv6Packet<_>>().expect("Failed to parse v6_pkt_buf");
2647 let nat64_translation_result =
2648 parsed_v6_packet.nat64_translate(DEFAULT_V4_SRC_IP, DEFAULT_V4_DST_IP);
2649
2650 let serializable_pkt =
2651 assert_matches!(nat64_translation_result, Nat64TranslationResult::Forward(s) => s);
2652
2653 let translated_v4_pkt_buf = serializable_pkt
2654 .serialize_vec_outer()
2655 .expect("Failed to serialize to translated_v4_pkt_buf");
2656
2657 assert_eq!(
2658 expected_v4_pkt_buf.to_flattened_vec(),
2659 translated_v4_pkt_buf.to_flattened_vec()
2660 );
2661 }
2662
2663 fn create_udp_ipv4_and_ipv6_pkt()
2664 -> (packet::Either<EmptyBuf, Buf<Vec<u8>>>, packet::Either<EmptyBuf, Buf<Vec<u8>>>) {
2665 use crate::udp::UdpPacketBuilder;
2666 use core::num::NonZeroU16;
2667
2668 let udp_src_port: NonZeroU16 = NonZeroU16::new(35000).unwrap();
2669 let udp_dst_port: NonZeroU16 = NonZeroU16::new(53).unwrap();
2670 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
2671
2672 let (ipv4_builder, ipv6_builder) =
2673 create_ipv4_and_ipv6_builders(IpProto::Udp.into(), IpProto::Udp.into());
2674
2675 let v4_udp_builder = UdpPacketBuilder::new(
2676 DEFAULT_V4_SRC_IP,
2677 DEFAULT_V4_DST_IP,
2678 Some(udp_src_port),
2679 udp_dst_port,
2680 );
2681
2682 let v4_pkt_buf = (&PAYLOAD)
2683 .into_serializer()
2684 .wrap_in(v4_udp_builder)
2685 .wrap_in(ipv4_builder)
2686 .serialize_vec_outer()
2687 .expect("Unable to serialize to v4_pkt_buf");
2688
2689 let v6_udp_builder =
2690 UdpPacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, Some(udp_src_port), udp_dst_port);
2691
2692 let v6_pkt_buf = (&PAYLOAD)
2693 .into_serializer()
2694 .wrap_in(v6_udp_builder)
2695 .wrap_in(ipv6_builder)
2696 .serialize_vec_outer()
2697 .expect("Unable to serialize to v6_pkt_buf");
2698
2699 (v4_pkt_buf, v6_pkt_buf)
2700 }
2701
2702 #[test]
2703 fn test_nat64_translate_udp() {
2704 let (expected_v4_pkt_buf, mut v6_pkt_buf) = create_udp_ipv4_and_ipv6_pkt();
2705
2706 let parsed_v6_packet =
2707 v6_pkt_buf.parse::<Ipv6Packet<_>>().expect("Unable to parse Ipv6Packet");
2708 let nat64_translation_result =
2709 parsed_v6_packet.nat64_translate(DEFAULT_V4_SRC_IP, DEFAULT_V4_DST_IP);
2710
2711 let serializable_pkt = assert_matches!(nat64_translation_result,
2712 Nat64TranslationResult::Forward(s) => s);
2713
2714 let translated_v4_pkt_buf = serializable_pkt
2715 .serialize_vec_outer()
2716 .expect("Unable to serialize to translated_v4_pkt_buf");
2717
2718 assert_eq!(
2719 expected_v4_pkt_buf.to_flattened_vec(),
2720 translated_v4_pkt_buf.to_flattened_vec()
2721 );
2722 }
2723
2724 #[test]
2725 fn test_nat64_translate_non_tcp_udp_icmp() {
2726 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
2727
2728 let (ipv4_builder, ipv6_builder) =
2729 create_ipv4_and_ipv6_builders(Ipv4Proto::Other(59), Ipv6Proto::Other(59));
2730
2731 let expected_v4_pkt_buf = (&PAYLOAD)
2732 .into_serializer()
2733 .wrap_in(ipv4_builder)
2734 .serialize_vec_outer()
2735 .expect("Unable to serialize to expected_v4_pkt_buf");
2736
2737 let mut v6_pkt_buf = (&PAYLOAD)
2738 .into_serializer()
2739 .wrap_in(ipv6_builder)
2740 .serialize_vec_outer()
2741 .expect("Unable to serialize to v6_pkt_buf");
2742
2743 let translated_v4_pkt_buf = {
2744 let parsed_v6_packet = v6_pkt_buf
2745 .parse::<Ipv6Packet<_>>()
2746 .expect("Unable to serialize to translated_v4_pkt_buf");
2747
2748 let nat64_translation_result =
2749 parsed_v6_packet.nat64_translate(DEFAULT_V4_SRC_IP, DEFAULT_V4_DST_IP);
2750
2751 let serializable_pkt = assert_matches!(nat64_translation_result,
2752 Nat64TranslationResult::Forward(s) => s);
2753
2754 let translated_buf = serializable_pkt
2755 .serialize_vec_outer()
2756 .expect("Unable to serialize to translated_buf");
2757
2758 translated_buf
2759 };
2760
2761 assert_eq!(
2762 expected_v4_pkt_buf.to_flattened_vec(),
2763 translated_v4_pkt_buf.to_flattened_vec()
2764 );
2765 }
2766
2767 #[test_case(new_builder(), true; "fixed header more frags")]
2768 #[test_case(Ipv6PacketBuilderWithHbhOptions::new(
2769 new_builder(),
2770 &[HopByHopOption {
2771 action: ExtensionHeaderOptionAction::SkipAndContinue,
2772 mutable: false,
2773 data: HopByHopOptionData::RouterAlert { data: 0 },
2774 }]).unwrap(), false; "hbh last frag")]
2775 fn ipv6_packet_builder_with_fragment_header<
2776 B: Ipv6HeaderBuilder + Ipv6HeaderBefore<Ipv6PacketBuilderWithFragmentHeader<B>> + Debug,
2777 >(
2778 inner: B,
2779 more_fragments: bool,
2780 ) {
2781 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
2782 let fragment_offset = FragmentOffset::new(13).unwrap();
2783 let identification = 0xABCDABCD;
2784 let builder = Ipv6PacketBuilderWithFragmentHeader::new(
2785 inner,
2786 fragment_offset,
2787 more_fragments,
2788 identification,
2789 );
2790 let mut serialized =
2791 builder.wrap_body(PAYLOAD.into_serializer()).serialize_vec_outer().unwrap().unwrap_b();
2792 let packet = serialized.parse::<Ipv6Packet<_>>().unwrap();
2793 assert!(packet.fragment_header_present());
2794 assert_eq!(packet.proto(), Ipv6Proto::Proto(IpProto::Tcp));
2795 let fragment_data = packet
2796 .extension_hdrs
2797 .into_iter()
2798 .find_map(|ext_hdr| match ext_hdr.into_data() {
2799 Ipv6ExtensionHeaderData::Fragment { fragment_data } => Some(fragment_data),
2800 _ => None,
2801 })
2802 .unwrap();
2803 assert_eq!(fragment_data.fragment_offset(), fragment_offset);
2804 assert_eq!(fragment_data.identification(), identification);
2805 assert_eq!(fragment_data.m_flag(), more_fragments);
2806 }
2807
2808 #[test]
2811 fn extension_headers_take_from_max_body_size() {
2812 let builder = new_builder();
2813 assert_eq!(builder.constraints().max_body_len(), IPV6_MAX_PAYLOAD_LENGTH);
2814 let builder =
2815 Ipv6PacketBuilderWithFragmentHeader::new(builder, FragmentOffset::ZERO, false, 1234);
2816 assert_eq!(
2817 builder.constraints().max_body_len(),
2818 IPV6_MAX_PAYLOAD_LENGTH - IPV6_FRAGMENT_EXT_HDR_LEN
2819 );
2820 }
2821
2822 #[test]
2823 fn test_partial_serialize_parsed() {
2824 let packet_bytes = [
2825 100, 177, 4, 5, 0, 10, 6, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
2826 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 1, 2, 3, 4, 5, 6, 7,
2827 8, 9,
2828 ];
2829 let packet_len = packet_bytes.len();
2830 let mut packet_bytes_copy = packet_bytes;
2831 let mut packet_bytes_ref: &mut [u8] = &mut packet_bytes_copy[..];
2832 let packet = packet_bytes_ref.parse::<Ipv6Packet<_>>().unwrap();
2833
2834 for i in 1..(packet_len + 1) {
2835 let mut buf = vec![0u8; i];
2836 let result =
2837 packet.partial_serialize(PacketConstraints::UNCONSTRAINED, buf.as_mut_slice());
2838
2839 let bytes_written = if i >= packet_len { packet_len } else { i };
2840 assert_eq!(
2841 result,
2842 Ok(PartialSerializeResult { bytes_written, total_size: packet_len })
2843 );
2844 assert_eq!(buf[..bytes_written], packet_bytes[..bytes_written]);
2845 }
2846 }
2847}