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<
1526 B: SplitByteSliceMut,
1527 BV: BufferViewMut<B>,
1528 I: Iterator<Item = Vec<u8>>,
1529>(
1530 mut buffer: BV,
1531 header: Vec<u8>,
1532 body_fragments: I,
1533) -> IpParseResult<Ipv6, ()> {
1534 assert!(header.len() >= IPV6_FIXED_HDR_LEN);
1535
1536 let bytes = buffer.as_mut();
1537
1538 bytes[0..header.len()].copy_from_slice(&header[..]);
1540 let mut byte_count = header.len();
1541
1542 for p in body_fragments {
1544 bytes[byte_count..byte_count + p.len()].copy_from_slice(&p[..]);
1545 byte_count += p.len();
1546 }
1547
1548 let payload_length = byte_count - IPV6_FIXED_HDR_LEN;
1560
1561 if payload_length > usize::from(core::u16::MAX) {
1564 return debug_err!(
1565 Err(ParseError::Format.into()),
1566 "fragmented packet payload length of {} bytes is too large",
1567 payload_length
1568 );
1569 }
1570
1571 let mut header = Ref::<_, FixedHeader>::from_prefix(bytes).unwrap().0;
1574
1575 header.payload_len.set(u16::try_from(payload_length).unwrap());
1577
1578 Ok(())
1579}
1580
1581#[cfg(test)]
1582mod tests {
1583 use assert_matches::assert_matches;
1584 use packet::{Buf, FragmentedBuffer, ParseBuffer};
1585 use test_case::test_case;
1586
1587 use crate::ethernet::{EthernetFrame, EthernetFrameLengthCheck};
1588 use crate::testutil::*;
1589
1590 use super::ext_hdrs::*;
1591 use super::*;
1592
1593 const DEFAULT_SRC_IP: Ipv6Addr =
1594 Ipv6Addr::from_bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
1595 const DEFAULT_DST_IP: Ipv6Addr =
1596 Ipv6Addr::from_bytes([17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]);
1597
1598 const DEFAULT_V4_SRC_IP: Ipv4Addr = Ipv4Addr::new([1, 2, 3, 4]);
1599 const DEFAULT_V4_DST_IP: Ipv4Addr = Ipv4Addr::new([5, 6, 7, 8]);
1600
1601 #[test]
1602 fn test_parse_serialize_full_tcp() {
1603 use crate::testdata::syn_v6::*;
1604
1605 let mut buf = ETHERNET_FRAME.bytes;
1606 let frame = buf.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1607 verify_ethernet_frame(&frame, ETHERNET_FRAME);
1608
1609 let mut body = frame.body();
1610 let packet = body.parse::<Ipv6Packet<_>>().unwrap();
1611 verify_ipv6_packet(&packet, IPV6_PACKET);
1612
1613 let buffer = packet
1615 .body()
1616 .into_serializer()
1617 .wrap_in(packet.builder())
1618 .wrap_in(frame.builder())
1619 .serialize_vec_outer()
1620 .unwrap();
1621 assert_eq!(buffer.as_ref(), ETHERNET_FRAME.bytes);
1622
1623 assert_eq!(&packet.to_vec()[..], IPV6_PACKET.bytes);
1625 }
1626
1627 #[test]
1628 fn test_parse_serialize_full_udp() {
1629 use crate::testdata::dns_request_v6::*;
1630
1631 let mut buf = ETHERNET_FRAME.bytes;
1632 let frame = buf.parse_with::<_, EthernetFrame<_>>(EthernetFrameLengthCheck::Check).unwrap();
1633 verify_ethernet_frame(&frame, ETHERNET_FRAME);
1634
1635 let mut body = frame.body();
1636 let packet = body.parse::<Ipv6Packet<_>>().unwrap();
1637 verify_ipv6_packet(&packet, IPV6_PACKET);
1638
1639 let buffer = packet
1641 .body()
1642 .into_serializer()
1643 .wrap_in(packet.builder())
1644 .wrap_in(frame.builder())
1645 .serialize_vec_outer()
1646 .unwrap();
1647 assert_eq!(buffer.as_ref(), ETHERNET_FRAME.bytes);
1648
1649 assert_eq!(&packet.to_vec()[..], IPV6_PACKET.bytes);
1651 }
1652
1653 #[test]
1654 fn test_parse_serialize_with_extension_headers() {
1655 use crate::testdata::mld_router_report::*;
1658
1659 let mut buf = REPORT;
1660 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
1661 assert_eq!(packet.iter_extension_hdrs().count(), 1);
1662
1663 assert_eq!(&packet.to_vec()[..], REPORT);
1668 }
1669
1670 fn fixed_hdr_to_bytes(fixed_hdr: FixedHeader) -> [u8; IPV6_FIXED_HDR_LEN] {
1671 zerocopy::transmute!(fixed_hdr)
1672 }
1673
1674 fn new_fixed_hdr() -> FixedHeader {
1676 FixedHeader::new(
1677 DscpAndEcn::new(0, 2),
1678 0x77,
1679 0,
1680 IpProto::Tcp.into(),
1681 64,
1682 DEFAULT_SRC_IP,
1683 DEFAULT_DST_IP,
1684 )
1685 }
1686
1687 #[test]
1688 fn test_parse() {
1689 let mut buf = &fixed_hdr_to_bytes(new_fixed_hdr())[..];
1690 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
1691 assert_eq!(packet.dscp_and_ecn().dscp(), 0);
1692 assert_eq!(packet.dscp_and_ecn().ecn(), 2);
1693 assert_eq!(packet.flowlabel(), 0x77);
1694 assert_eq!(packet.hop_limit(), 64);
1695 assert_eq!(packet.fixed_hdr.next_hdr, IpProto::Tcp.into());
1696 assert_eq!(packet.proto(), IpProto::Tcp.into());
1697 assert_eq!(packet.src_ip(), DEFAULT_SRC_IP);
1698 assert_eq!(packet.dst_ip(), DEFAULT_DST_IP);
1699 assert_eq!(packet.body(), []);
1700 }
1701
1702 #[test]
1703 fn test_parse_with_ext_hdrs() {
1704 #[rustfmt::skip]
1705 let mut buf = [
1706 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1708 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1709
1710 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,
1725 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1726
1727 IpProto::Tcp.into(), 1, 0, 1, 0, 1, 1, 0, 1, 6, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5,
1737 ];
1738 let mut fixed_hdr = new_fixed_hdr();
1739 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
1740 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
1741 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
1742 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
1743 let mut buf = &buf[..];
1744 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
1745 assert_eq!(packet.dscp_and_ecn().dscp(), 0);
1746 assert_eq!(packet.dscp_and_ecn().ecn(), 2);
1747 assert_eq!(packet.flowlabel(), 0x77);
1748 assert_eq!(packet.hop_limit(), 64);
1749 assert_eq!(packet.fixed_hdr.next_hdr, Ipv6ExtHdrType::HopByHopOptions.into());
1750 assert_eq!(packet.proto(), IpProto::Tcp.into());
1751 assert_eq!(packet.src_ip(), DEFAULT_SRC_IP);
1752 assert_eq!(packet.dst_ip(), DEFAULT_DST_IP);
1753 assert_eq!(packet.body(), [1, 2, 3, 4, 5]);
1754 let ext_hdrs: Vec<Ipv6ExtensionHeader<'_>> = packet.iter_extension_hdrs().collect();
1755 assert_eq!(ext_hdrs.len(), 2);
1756 assert_eq!(ext_hdrs[0].next_header, Ipv6ExtHdrType::Routing.into());
1758 if let Ipv6ExtensionHeaderData::HopByHopOptions { options } = ext_hdrs[0].data() {
1759 assert_eq!(options.iter().count(), 0);
1761 } else {
1762 panic!("Should have matched HopByHopOptions!");
1763 }
1764
1765 assert_eq!(ext_hdrs[1].next_header, IpProto::Tcp.into());
1770 if let Ipv6ExtensionHeaderData::DestinationOptions { options } = ext_hdrs[1].data() {
1771 assert_eq!(options.iter().count(), 0);
1773 } else {
1774 panic!("Should have matched DestinationOptions!");
1775 }
1776
1777 #[rustfmt::skip]
1779 let mut buf = [
1780 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1782 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1783
1784 Ipv6Proto::NoNextHeader.into(), 0, 0, 1, 0, 1, 1, 0, 1, 2, 3, 4, 5,
1793 ];
1794 let mut fixed_hdr = new_fixed_hdr();
1795 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
1796 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
1797 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
1798 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
1799 let mut buf = &buf[..];
1800 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
1801 assert_eq!(packet.dscp_and_ecn().dscp(), 0);
1802 assert_eq!(packet.dscp_and_ecn().ecn(), 2);
1803 assert_eq!(packet.flowlabel(), 0x77);
1804 assert_eq!(packet.hop_limit(), 64);
1805 assert_eq!(packet.fixed_hdr.next_hdr, Ipv6ExtHdrType::HopByHopOptions.into());
1806 assert_eq!(packet.proto(), Ipv6Proto::NoNextHeader);
1807 assert_eq!(packet.src_ip(), DEFAULT_SRC_IP);
1808 assert_eq!(packet.dst_ip(), DEFAULT_DST_IP);
1809 assert_eq!(packet.body(), [1, 2, 3, 4, 5]);
1810 let ext_hdrs: Vec<Ipv6ExtensionHeader<'_>> = packet.iter_extension_hdrs().collect();
1811 assert_eq!(ext_hdrs.len(), 1);
1812 assert_eq!(ext_hdrs[0].next_header, Ipv6Proto::NoNextHeader.into());
1814 if let Ipv6ExtensionHeaderData::HopByHopOptions { options } = ext_hdrs[0].data() {
1815 assert_eq!(options.iter().count(), 0);
1817 } else {
1818 panic!("Should have matched HopByHopOptions!");
1819 }
1820 }
1821
1822 #[test]
1823 fn test_parse_error() {
1824 let mut fixed_hdr = new_fixed_hdr();
1826 fixed_hdr.version_tc_flowlabel[0] = 0x50;
1827 assert_eq!(
1828 (&fixed_hdr_to_bytes(fixed_hdr)[..]).parse::<Ipv6Packet<_>>().unwrap_err(),
1829 ParseError::Format.into()
1830 );
1831
1832 let mut fixed_hdr = new_fixed_hdr();
1834 fixed_hdr.payload_len = U16::new(2);
1835 assert_eq!(
1836 (&fixed_hdr_to_bytes(fixed_hdr)[..]).parse::<Ipv6Packet<_>>().unwrap_err(),
1837 ParseError::Format.into()
1838 );
1839
1840 let mut fixed_hdr = new_fixed_hdr();
1842 fixed_hdr.next_hdr = 255;
1843 assert_eq!(
1844 (&fixed_hdr_to_bytes(fixed_hdr)[..]).parse::<Ipv6Packet<_>>().unwrap_err(),
1845 Ipv6ParseError::ParameterProblem {
1846 src_ip: DEFAULT_SRC_IP,
1847 dst_ip: DEFAULT_DST_IP,
1848 code: Icmpv6ParameterProblemCode::UnrecognizedNextHeaderType,
1849 pointer: u32::from(NEXT_HEADER_OFFSET),
1850 must_send_icmp: false,
1851 action: IpParseErrorAction::DiscardPacketSendIcmpNoMulticast,
1852 }
1853 );
1854
1855 let mut fixed_hdr = new_fixed_hdr();
1857 fixed_hdr.next_hdr = Ipv4Proto::Icmp.into();
1858 assert_eq!(
1859 (&fixed_hdr_to_bytes(fixed_hdr)[..]).parse::<Ipv6Packet<_>>().unwrap_err(),
1860 Ipv6ParseError::ParameterProblem {
1861 src_ip: DEFAULT_SRC_IP,
1862 dst_ip: DEFAULT_DST_IP,
1863 code: Icmpv6ParameterProblemCode::UnrecognizedNextHeaderType,
1864 pointer: u32::from(NEXT_HEADER_OFFSET),
1865 must_send_icmp: false,
1866 action: IpParseErrorAction::DiscardPacketSendIcmpNoMulticast,
1867 }
1868 );
1869
1870 #[rustfmt::skip]
1872 let mut buf = [
1873 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1875 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1876
1877 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,
1885 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1886
1887 IpProto::Tcp.into(), 0, 0, 1, 0, 1, 1, 0, 1, 2, 3, 4, 5,
1896 ];
1897 let mut fixed_hdr = new_fixed_hdr();
1898 fixed_hdr.next_hdr = Ipv6ExtHdrType::Routing.into();
1899 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
1900 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
1901 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
1902 let mut buf = &buf[..];
1903 assert_eq!(
1904 buf.parse::<Ipv6Packet<_>>().unwrap_err(),
1905 Ipv6ParseError::ParameterProblem {
1906 src_ip: DEFAULT_SRC_IP,
1907 dst_ip: DEFAULT_DST_IP,
1908 code: Icmpv6ParameterProblemCode::UnrecognizedNextHeaderType,
1909 pointer: IPV6_FIXED_HDR_LEN as u32,
1910 must_send_icmp: false,
1911 action: IpParseErrorAction::DiscardPacketSendIcmpNoMulticast,
1912 }
1913 );
1914
1915 #[rustfmt::skip]
1917 let mut buf = [
1918 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1920 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1921
1922 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,
1930 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1931
1932 1, 2, 3, 4, 5,
1934 ];
1935 let mut fixed_hdr = new_fixed_hdr();
1936 fixed_hdr.next_hdr = Ipv6ExtHdrType::Routing.into();
1937 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
1938 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
1939 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
1940 let mut buf = &buf[..];
1941 assert_eq!(
1942 buf.parse::<Ipv6Packet<_>>().unwrap_err(),
1943 Ipv6ParseError::ParameterProblem {
1944 src_ip: DEFAULT_SRC_IP,
1945 dst_ip: DEFAULT_DST_IP,
1946 code: Icmpv6ParameterProblemCode::ErroneousHeaderField,
1947 pointer: (IPV6_FIXED_HDR_LEN as u32) + 2,
1948 must_send_icmp: true,
1949 action: IpParseErrorAction::DiscardPacketSendIcmpNoMulticast,
1950 }
1951 );
1952 }
1953
1954 #[test]
1955 fn test_parse_all_next_header_values() {
1956 let mut buf = [
1962 0x81, 0x13, 0x27, 0xeb, 0x75, 0x92, 0x33, 0x89, 0x01, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
1963 0x03, 0x70, 0x00, 0x22, 0xf7, 0x30, 0x2c, 0x06, 0xfe, 0xc9, 0x00, 0x2d, 0x3b, 0xeb,
1964 0xad, 0x3e, 0x5c, 0x41, 0xc8, 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x11, 0x00,
1965 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x4f, 0x4f, 0x6f, 0x4f, 0x4f, 0x4f, 0x4f,
1966 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x19, 0x19,
1967 0x19, 0x19, 0x19, 0x4f, 0x4f, 0x4f, 0x4f, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1968 0x00, 0x4f, 0x4f, 0x5a, 0x5a, 0x5a, 0xc9, 0x5a, 0x46, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
1969 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0xe4, 0x5a, 0x5a, 0x5a, 0x5a,
1970 ];
1971
1972 assert_matches!(
1975 (&buf[..]).parse::<Ipv6Packet<_>>(),
1976 Err(Ipv6ParseError::ParameterProblem {
1977 src_ip: _,
1978 dst_ip: _,
1979 code: Icmpv6ParameterProblemCode::UnrecognizedNextHeaderType,
1980 pointer: 0,
1981 must_send_icmp: false,
1982 action: IpParseErrorAction::DiscardPacket,
1983 })
1984 );
1985
1986 for b in 0u8..=255 {
1989 buf[6] = b;
1991 let _: Result<_, _> = (&buf[..]).parse::<Ipv6Packet<_>>();
1992 }
1993 }
1994
1995 #[test]
1996 fn test_partial_parse() {
1997 use core::convert::TryInto as _;
1998 use core::ops::Deref as _;
1999
2000 #[rustfmt::skip]
2002 let mut buf = [
2003 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2005 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2006
2007 IpProto::Tcp.into(), 0, 0, 1, 0, 1, 1, 0, 1, 2, 3, 4, 5,
2016 ];
2017 let len = buf.len() - IPV6_FIXED_HDR_LEN;
2018 let len = len.try_into().unwrap();
2019 let make_fixed_hdr = || {
2020 let mut fixed_hdr = new_fixed_hdr();
2021 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2022 fixed_hdr.payload_len = U16::new(len);
2023 fixed_hdr
2024 };
2025 const MALFORMED_BYTE: u8 = 10;
2027 buf[IPV6_FIXED_HDR_LEN + 1] = MALFORMED_BYTE;
2028 let fixed_hdr = fixed_hdr_to_bytes(make_fixed_hdr());
2029 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr);
2030 let mut buf = &buf[..];
2031 let partial = buf.parse::<Ipv6PacketRaw<_>>().unwrap();
2032 let Ipv6PacketRaw { fixed_hdr, extension_hdrs, body_proto } = &partial;
2033 assert_eq!(fixed_hdr.deref(), &make_fixed_hdr());
2034 assert_eq!(
2035 *extension_hdrs.as_ref().incomplete().unwrap(),
2036 [IpProto::Tcp.into(), MALFORMED_BYTE]
2037 );
2038 assert_eq!(body_proto, &Err(ExtHdrParseError));
2039 assert!(Ipv6Packet::try_from_raw(partial).is_err());
2040
2041 let mut buf = [
2043 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,
2045 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5,
2047 ];
2048 let make_fixed_hdr = || {
2049 let mut fixed_hdr = new_fixed_hdr();
2050 fixed_hdr.next_hdr = IpProto::Tcp.into();
2051 fixed_hdr.payload_len = U16::new(10);
2052 fixed_hdr
2053 };
2054 let fixed_hdr = fixed_hdr_to_bytes(make_fixed_hdr());
2055 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr);
2056 let mut parsebuff = &buf[..];
2057 let partial = parsebuff.parse::<Ipv6PacketRaw<_>>().unwrap();
2058 let Ipv6PacketRaw { fixed_hdr, extension_hdrs, body_proto } = &partial;
2059 assert_eq!(fixed_hdr.deref(), &make_fixed_hdr());
2060 assert_eq!(extension_hdrs.as_ref().complete().unwrap().deref(), []);
2061 let (body, proto) = body_proto.unwrap();
2062 assert_eq!(body.incomplete().unwrap(), &buf[IPV6_FIXED_HDR_LEN..]);
2063 assert_eq!(proto, IpProto::Tcp.into());
2064 assert!(Ipv6Packet::try_from_raw(partial).is_err());
2065 }
2066
2067 fn new_builder() -> Ipv6PacketBuilder {
2069 Ipv6PacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, 64, IpProto::Tcp.into())
2070 }
2071
2072 #[test]
2073 fn test_serialize() {
2074 let mut builder = new_builder();
2075 builder.dscp_and_ecn(DscpAndEcn::new(0x12, 3));
2076 builder.flowlabel(0x10405);
2077 let mut buf = (&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
2078 .into_serializer()
2079 .wrap_in(builder)
2080 .serialize_vec_outer()
2081 .unwrap();
2082 assert_eq!(
2084 buf.as_ref(),
2085 &[
2086 100, 177, 4, 5, 0, 10, 6, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
2087 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 1, 2, 3, 4,
2088 5, 6, 7, 8, 9
2089 ][..],
2090 );
2091
2092 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2093 assert_eq!(packet.dscp_and_ecn().dscp(), 0x12);
2096 assert_eq!(packet.dscp_and_ecn().ecn(), 3);
2097 assert_eq!(packet.flowlabel(), 0x10405);
2098 }
2099
2100 #[test]
2101 fn test_partial_serialize() {
2102 let mut builder = new_builder();
2103 builder.dscp_and_ecn(DscpAndEcn::new(0x12, 3));
2104 builder.flowlabel(0x10405);
2105 let body = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
2106 let packet = (&body).into_serializer().wrap_in(builder);
2107
2108 const HEADER_LEN: usize = 40;
2111 const HEADER: [u8; HEADER_LEN] = [
2112 100, 177, 4, 5, 0, 10, 6, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
2113 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
2114 ];
2115 let mut expected_partial = HEADER.to_vec();
2116 expected_partial.resize(expected_partial.len() + body.len(), 0);
2117
2118 for i in 1..expected_partial.len() {
2119 let mut buf = vec![0u8; i];
2120 let result =
2121 packet.partial_serialize(PacketConstraints::UNCONSTRAINED, buf.as_mut_slice());
2122
2123 let bytes_written = if i >= HEADER_LEN { HEADER_LEN } else { 0 };
2126 assert_eq!(
2127 result,
2128 Ok(PartialSerializeResult { bytes_written, total_size: body.len() + HEADER_LEN })
2129 );
2130 if bytes_written > 0 {
2131 assert_eq!(buf, expected_partial[..i]);
2132 }
2133 }
2134 }
2135
2136 #[test]
2137 fn test_serialize_zeroes() {
2138 let mut buf_0 = [0; IPV6_FIXED_HDR_LEN];
2141 let _: Buf<&mut [u8]> = Buf::new(&mut buf_0[..], IPV6_FIXED_HDR_LEN..)
2142 .wrap_in(new_builder())
2143 .serialize_vec_outer()
2144 .unwrap()
2145 .unwrap_a();
2146 let mut buf_1 = [0xFF; IPV6_FIXED_HDR_LEN];
2147 let _: Buf<&mut [u8]> = Buf::new(&mut buf_1[..], IPV6_FIXED_HDR_LEN..)
2148 .wrap_in(new_builder())
2149 .serialize_vec_outer()
2150 .unwrap()
2151 .unwrap_a();
2152 assert_eq!(&buf_0[..], &buf_1[..]);
2153 }
2154
2155 #[test]
2156 fn test_packet_builder_proto_not_next_header() {
2157 let mut buf = (&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
2161 .into_serializer()
2162 .wrap_in(
2163 Ipv6PacketBuilderWithHbhOptions::new(
2164 new_builder(),
2165 &[HopByHopOption {
2166 action: ExtensionHeaderOptionAction::SkipAndContinue,
2167 mutable: false,
2168 data: HopByHopOptionData::RouterAlert { data: 0 },
2169 }],
2170 )
2171 .unwrap(),
2172 )
2173 .serialize_vec_outer()
2174 .unwrap();
2175 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2176 assert_eq!(packet.proto(), IpProto::Tcp.into());
2177 assert_eq!(packet.next_header(), Ipv6ExtHdrType::HopByHopOptions.into());
2178 }
2179
2180 #[test]
2181 #[should_panic(expected = "SizeLimitExceeded, Nested { inner: Buf { buf:")]
2182 fn test_serialize_panic_packet_length() {
2183 let _: Buf<&mut [u8]> = Buf::new(&mut [0; 1 << 16][..], ..)
2186 .wrap_in(new_builder())
2187 .serialize_vec_outer()
2188 .unwrap()
2189 .unwrap_a();
2190 }
2191
2192 #[test]
2193 #[should_panic(expected = "packet must have at least one extension header")]
2194 fn test_copy_header_bytes_for_fragment_without_ext_hdrs() {
2195 let mut buf = &fixed_hdr_to_bytes(new_fixed_hdr())[..];
2196 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2197 let _: Vec<_> = packet.copy_header_bytes_for_fragment();
2198 }
2199
2200 #[test]
2201 #[should_panic(expected = "exhausted all extension headers without finding fragment header")]
2202 fn test_copy_header_bytes_for_fragment_with_1_ext_hdr_no_fragment() {
2203 #[rustfmt::skip]
2204 let mut buf = [
2205 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2207 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2208
2209 IpProto::Tcp.into(), 0, 0, 1, 0, 1, 1, 0, 1, 2, 3, 4, 5,
2218 ];
2219 let mut fixed_hdr = new_fixed_hdr();
2220 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2221 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
2222 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2223 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2224 let mut buf = &buf[..];
2225 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2226 let _: Vec<_> = packet.copy_header_bytes_for_fragment();
2227 }
2228
2229 #[test]
2230 #[should_panic(expected = "exhausted all extension headers without finding fragment header")]
2231 fn test_copy_header_bytes_for_fragment_with_2_ext_hdr_no_fragment() {
2232 #[rustfmt::skip]
2233 let mut buf = [
2234 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2236 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2237
2238 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,
2255 ];
2256 let mut fixed_hdr = new_fixed_hdr();
2257 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2258 fixed_hdr.payload_len = U16::new((buf.len() - IPV6_FIXED_HDR_LEN) as u16);
2259 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2260 buf[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2261 let mut buf = &buf[..];
2262 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2263 let _: Vec<_> = packet.copy_header_bytes_for_fragment();
2264 }
2265
2266 #[test]
2267 fn test_copy_header_bytes_for_fragment() {
2268 #[rustfmt::skip]
2273 let mut bytes = [
2274 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2276 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2277
2278 IpProto::Tcp.into(), 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5,
2286 ];
2287 let mut fixed_hdr = new_fixed_hdr();
2288 fixed_hdr.next_hdr = Ipv6ExtHdrType::Fragment.into();
2289 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2290 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2291 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2292 let mut buf = &bytes[..];
2293 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2294 let copied_bytes = packet.copy_header_bytes_for_fragment();
2295 bytes[6] = IpProto::Tcp.into();
2296 assert_eq!(&copied_bytes[..], &bytes[..IPV6_FIXED_HDR_LEN]);
2297
2298 #[rustfmt::skip]
2303 let mut bytes = [
2304 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2306 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2307
2308 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,
2323 ];
2324 let mut fixed_hdr = new_fixed_hdr();
2325 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2326 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2327 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2328 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2329 let mut buf = &bytes[..];
2330 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2331 let copied_bytes = packet.copy_header_bytes_for_fragment();
2332 bytes[IPV6_FIXED_HDR_LEN] = IpProto::Tcp.into();
2333 assert_eq!(&copied_bytes[..], &bytes[..IPV6_FIXED_HDR_LEN + 8]);
2334
2335 #[rustfmt::skip]
2340 let mut bytes = [
2341 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2343 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2344
2345 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,
2368 ];
2369 let mut fixed_hdr = new_fixed_hdr();
2370 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2371 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2372 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2373 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2374 let mut buf = &bytes[..];
2375 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2376 let copied_bytes = packet.copy_header_bytes_for_fragment();
2377 bytes[IPV6_FIXED_HDR_LEN + 8] = IpProto::Tcp.into();
2378 assert_eq!(&copied_bytes[..], &bytes[..IPV6_FIXED_HDR_LEN + 24]);
2379
2380 #[rustfmt::skip]
2385 let mut bytes = [
2386 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2388 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2389
2390 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,
2406 ];
2407 let mut fixed_hdr = new_fixed_hdr();
2408 fixed_hdr.next_hdr = Ipv6ExtHdrType::Fragment.into();
2409 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2410 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2411 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2412 let mut buf = &bytes[..];
2413 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2414 let copied_bytes = packet.copy_header_bytes_for_fragment();
2415 let mut expected_bytes = Vec::new();
2416 expected_bytes.extend_from_slice(&bytes[..IPV6_FIXED_HDR_LEN]);
2417 expected_bytes.extend_from_slice(&bytes[IPV6_FIXED_HDR_LEN + 8..bytes.len() - 5]);
2418 expected_bytes[6] = Ipv6ExtHdrType::DestinationOptions.into();
2419 assert_eq!(&copied_bytes[..], &expected_bytes[..]);
2420
2421 #[rustfmt::skip]
2426 let mut bytes = [
2427 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2429 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2430
2431 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,
2453 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
2454
2455 1, 2, 3, 4, 5,
2457 ];
2458 let mut fixed_hdr = new_fixed_hdr();
2459 fixed_hdr.next_hdr = Ipv6ExtHdrType::Fragment.into();
2460 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2461 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2462 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2463 let mut buf = &bytes[..];
2464 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2465 let copied_bytes = packet.copy_header_bytes_for_fragment();
2466 let mut expected_bytes = Vec::new();
2467 expected_bytes.extend_from_slice(&bytes[..IPV6_FIXED_HDR_LEN]);
2468 expected_bytes.extend_from_slice(&bytes[IPV6_FIXED_HDR_LEN + 8..bytes.len() - 5]);
2469 expected_bytes[6] = Ipv6ExtHdrType::DestinationOptions.into();
2470 assert_eq!(&copied_bytes[..], &expected_bytes[..]);
2471
2472 #[rustfmt::skip]
2477 let mut bytes = [
2478 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2480 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2481
2482 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,
2505 ];
2506 let mut fixed_hdr = new_fixed_hdr();
2507 fixed_hdr.next_hdr = Ipv6ExtHdrType::HopByHopOptions.into();
2508 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2509 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2510 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2511 let mut buf = &bytes[..];
2512 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2513 let copied_bytes = packet.copy_header_bytes_for_fragment();
2514 let mut expected_bytes = Vec::new();
2515 expected_bytes.extend_from_slice(&bytes[..IPV6_FIXED_HDR_LEN + 8]);
2516 expected_bytes.extend_from_slice(&bytes[IPV6_FIXED_HDR_LEN + 16..bytes.len() - 5]);
2517 expected_bytes[IPV6_FIXED_HDR_LEN] = Ipv6ExtHdrType::DestinationOptions.into();
2518 assert_eq!(&copied_bytes[..], &expected_bytes[..]);
2519
2520 #[rustfmt::skip]
2525 let mut bytes = [
2526 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2528 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2529
2530 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,
2544 ];
2545 let mut fixed_hdr = new_fixed_hdr();
2546 fixed_hdr.next_hdr = Ipv6ExtHdrType::Fragment.into();
2547 fixed_hdr.payload_len = U16::new((bytes.len() - IPV6_FIXED_HDR_LEN) as u16);
2548 let fixed_hdr_buf = fixed_hdr_to_bytes(fixed_hdr);
2549 bytes[..IPV6_FIXED_HDR_LEN].copy_from_slice(&fixed_hdr_buf);
2550 let mut buf = &bytes[..];
2551 let packet = buf.parse::<Ipv6Packet<_>>().unwrap();
2552 let copied_bytes = packet.copy_header_bytes_for_fragment();
2553 let mut expected_bytes = Vec::new();
2554 expected_bytes.extend_from_slice(&bytes[..IPV6_FIXED_HDR_LEN]);
2555 expected_bytes.extend_from_slice(&bytes[IPV6_FIXED_HDR_LEN + 8..bytes.len() - 5]);
2556 assert_eq!(&copied_bytes[..], &expected_bytes[..]);
2557 }
2558
2559 #[test]
2560 fn test_next_multiple_of_eight() {
2561 for x in 0usize..=IPV6_HBH_OPTIONS_MAX_LEN {
2562 let y = next_multiple_of_eight(x);
2563 assert_eq!(y % 8, 0);
2564 assert!(y >= x);
2565 if x % 8 == 0 {
2566 assert_eq!(x, y);
2567 } else {
2568 assert_eq!(x + (8 - x % 8), y);
2569 }
2570 }
2571 }
2572
2573 fn create_ipv4_and_ipv6_builders(
2574 proto_v4: Ipv4Proto,
2575 proto_v6: Ipv6Proto,
2576 ) -> (Ipv4PacketBuilder, Ipv6PacketBuilder) {
2577 const IP_DSCP_AND_ECN: DscpAndEcn = DscpAndEcn::new(0x12, 3);
2578 const IP_TTL: u8 = 64;
2579
2580 let mut ipv4_builder =
2581 Ipv4PacketBuilder::new(DEFAULT_V4_SRC_IP, DEFAULT_V4_DST_IP, IP_TTL, proto_v4);
2582 ipv4_builder.dscp_and_ecn(IP_DSCP_AND_ECN);
2583 ipv4_builder.df_flag(false);
2584 ipv4_builder.mf_flag(false);
2585 ipv4_builder.fragment_offset(FragmentOffset::ZERO);
2586
2587 let mut ipv6_builder =
2588 Ipv6PacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, IP_TTL, proto_v6);
2589 ipv6_builder.dscp_and_ecn(IP_DSCP_AND_ECN);
2590 ipv6_builder.flowlabel(0x456);
2591
2592 (ipv4_builder, ipv6_builder)
2593 }
2594
2595 fn create_tcp_ipv4_and_ipv6_pkt()
2596 -> (packet::Either<EmptyBuf, Buf<Vec<u8>>>, packet::Either<EmptyBuf, Buf<Vec<u8>>>) {
2597 use crate::tcp::TcpSegmentBuilder;
2598 use core::num::NonZeroU16;
2599
2600 let tcp_src_port: NonZeroU16 = NonZeroU16::new(20).unwrap();
2601 let tcp_dst_port: NonZeroU16 = NonZeroU16::new(30).unwrap();
2602 const TCP_SEQ_NUM: u32 = 4321;
2603 const TCP_ACK_NUM: Option<u32> = Some(1234);
2604 const TCP_WINDOW_SIZE: u16 = 12345;
2605 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
2606
2607 let (ipv4_builder, ipv6_builder) =
2608 create_ipv4_and_ipv6_builders(IpProto::Tcp.into(), IpProto::Tcp.into());
2609
2610 let tcp_builder = TcpSegmentBuilder::new(
2611 DEFAULT_V4_SRC_IP,
2612 DEFAULT_V4_DST_IP,
2613 tcp_src_port,
2614 tcp_dst_port,
2615 TCP_SEQ_NUM,
2616 TCP_ACK_NUM,
2617 TCP_WINDOW_SIZE,
2618 );
2619
2620 let v4_pkt_buf = (&PAYLOAD)
2621 .into_serializer()
2622 .wrap_in(tcp_builder)
2623 .wrap_in(ipv4_builder)
2624 .serialize_vec_outer()
2625 .expect("Failed to serialize to v4_pkt_buf");
2626
2627 let v6_tcp_builder = TcpSegmentBuilder::new(
2628 DEFAULT_SRC_IP,
2629 DEFAULT_DST_IP,
2630 tcp_src_port,
2631 tcp_dst_port,
2632 TCP_SEQ_NUM,
2633 TCP_ACK_NUM,
2634 TCP_WINDOW_SIZE,
2635 );
2636
2637 let v6_pkt_buf = (&PAYLOAD)
2638 .into_serializer()
2639 .wrap_in(v6_tcp_builder)
2640 .wrap_in(ipv6_builder)
2641 .serialize_vec_outer()
2642 .expect("Failed to serialize to v4_pkt_buf");
2643
2644 (v4_pkt_buf, v6_pkt_buf)
2645 }
2646
2647 #[test]
2648 fn test_nat64_translate_tcp() {
2649 let (expected_v4_pkt_buf, mut v6_pkt_buf) = create_tcp_ipv4_and_ipv6_pkt();
2650
2651 let parsed_v6_packet =
2652 v6_pkt_buf.parse::<Ipv6Packet<_>>().expect("Failed to parse v6_pkt_buf");
2653 let nat64_translation_result =
2654 parsed_v6_packet.nat64_translate(DEFAULT_V4_SRC_IP, DEFAULT_V4_DST_IP);
2655
2656 let serializable_pkt =
2657 assert_matches!(nat64_translation_result, Nat64TranslationResult::Forward(s) => s);
2658
2659 let translated_v4_pkt_buf = serializable_pkt
2660 .serialize_vec_outer()
2661 .expect("Failed to serialize to translated_v4_pkt_buf");
2662
2663 assert_eq!(
2664 expected_v4_pkt_buf.to_flattened_vec(),
2665 translated_v4_pkt_buf.to_flattened_vec()
2666 );
2667 }
2668
2669 fn create_udp_ipv4_and_ipv6_pkt()
2670 -> (packet::Either<EmptyBuf, Buf<Vec<u8>>>, packet::Either<EmptyBuf, Buf<Vec<u8>>>) {
2671 use crate::udp::UdpPacketBuilder;
2672 use core::num::NonZeroU16;
2673
2674 let udp_src_port: NonZeroU16 = NonZeroU16::new(35000).unwrap();
2675 let udp_dst_port: NonZeroU16 = NonZeroU16::new(53).unwrap();
2676 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
2677
2678 let (ipv4_builder, ipv6_builder) =
2679 create_ipv4_and_ipv6_builders(IpProto::Udp.into(), IpProto::Udp.into());
2680
2681 let v4_udp_builder = UdpPacketBuilder::new(
2682 DEFAULT_V4_SRC_IP,
2683 DEFAULT_V4_DST_IP,
2684 Some(udp_src_port),
2685 udp_dst_port,
2686 );
2687
2688 let v4_pkt_buf = (&PAYLOAD)
2689 .into_serializer()
2690 .wrap_in(v4_udp_builder)
2691 .wrap_in(ipv4_builder)
2692 .serialize_vec_outer()
2693 .expect("Unable to serialize to v4_pkt_buf");
2694
2695 let v6_udp_builder =
2696 UdpPacketBuilder::new(DEFAULT_SRC_IP, DEFAULT_DST_IP, Some(udp_src_port), udp_dst_port);
2697
2698 let v6_pkt_buf = (&PAYLOAD)
2699 .into_serializer()
2700 .wrap_in(v6_udp_builder)
2701 .wrap_in(ipv6_builder)
2702 .serialize_vec_outer()
2703 .expect("Unable to serialize to v6_pkt_buf");
2704
2705 (v4_pkt_buf, v6_pkt_buf)
2706 }
2707
2708 #[test]
2709 fn test_nat64_translate_udp() {
2710 let (expected_v4_pkt_buf, mut v6_pkt_buf) = create_udp_ipv4_and_ipv6_pkt();
2711
2712 let parsed_v6_packet =
2713 v6_pkt_buf.parse::<Ipv6Packet<_>>().expect("Unable to parse Ipv6Packet");
2714 let nat64_translation_result =
2715 parsed_v6_packet.nat64_translate(DEFAULT_V4_SRC_IP, DEFAULT_V4_DST_IP);
2716
2717 let serializable_pkt = assert_matches!(nat64_translation_result,
2718 Nat64TranslationResult::Forward(s) => s);
2719
2720 let translated_v4_pkt_buf = serializable_pkt
2721 .serialize_vec_outer()
2722 .expect("Unable to serialize to translated_v4_pkt_buf");
2723
2724 assert_eq!(
2725 expected_v4_pkt_buf.to_flattened_vec(),
2726 translated_v4_pkt_buf.to_flattened_vec()
2727 );
2728 }
2729
2730 #[test]
2731 fn test_nat64_translate_non_tcp_udp_icmp() {
2732 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
2733
2734 let (ipv4_builder, ipv6_builder) =
2735 create_ipv4_and_ipv6_builders(Ipv4Proto::Other(59), Ipv6Proto::Other(59));
2736
2737 let expected_v4_pkt_buf = (&PAYLOAD)
2738 .into_serializer()
2739 .wrap_in(ipv4_builder)
2740 .serialize_vec_outer()
2741 .expect("Unable to serialize to expected_v4_pkt_buf");
2742
2743 let mut v6_pkt_buf = (&PAYLOAD)
2744 .into_serializer()
2745 .wrap_in(ipv6_builder)
2746 .serialize_vec_outer()
2747 .expect("Unable to serialize to v6_pkt_buf");
2748
2749 let translated_v4_pkt_buf = {
2750 let parsed_v6_packet = v6_pkt_buf
2751 .parse::<Ipv6Packet<_>>()
2752 .expect("Unable to serialize to translated_v4_pkt_buf");
2753
2754 let nat64_translation_result =
2755 parsed_v6_packet.nat64_translate(DEFAULT_V4_SRC_IP, DEFAULT_V4_DST_IP);
2756
2757 let serializable_pkt = assert_matches!(nat64_translation_result,
2758 Nat64TranslationResult::Forward(s) => s);
2759
2760 let translated_buf = serializable_pkt
2761 .serialize_vec_outer()
2762 .expect("Unable to serialize to translated_buf");
2763
2764 translated_buf
2765 };
2766
2767 assert_eq!(
2768 expected_v4_pkt_buf.to_flattened_vec(),
2769 translated_v4_pkt_buf.to_flattened_vec()
2770 );
2771 }
2772
2773 #[test_case(new_builder(), true; "fixed header more frags")]
2774 #[test_case(Ipv6PacketBuilderWithHbhOptions::new(
2775 new_builder(),
2776 &[HopByHopOption {
2777 action: ExtensionHeaderOptionAction::SkipAndContinue,
2778 mutable: false,
2779 data: HopByHopOptionData::RouterAlert { data: 0 },
2780 }]).unwrap(), false; "hbh last frag")]
2781 fn ipv6_packet_builder_with_fragment_header<
2782 B: Ipv6HeaderBuilder + Ipv6HeaderBefore<Ipv6PacketBuilderWithFragmentHeader<B>> + Debug,
2783 >(
2784 inner: B,
2785 more_fragments: bool,
2786 ) {
2787 const PAYLOAD: [u8; 10] = [0, 1, 2, 3, 3, 4, 5, 7, 8, 9];
2788 let fragment_offset = FragmentOffset::new(13).unwrap();
2789 let identification = 0xABCDABCD;
2790 let builder = Ipv6PacketBuilderWithFragmentHeader::new(
2791 inner,
2792 fragment_offset,
2793 more_fragments,
2794 identification,
2795 );
2796 let mut serialized =
2797 builder.wrap_body(PAYLOAD.into_serializer()).serialize_vec_outer().unwrap().unwrap_b();
2798 let packet = serialized.parse::<Ipv6Packet<_>>().unwrap();
2799 assert!(packet.fragment_header_present());
2800 assert_eq!(packet.proto(), Ipv6Proto::Proto(IpProto::Tcp));
2801 let fragment_data = packet
2802 .extension_hdrs
2803 .into_iter()
2804 .find_map(|ext_hdr| match ext_hdr.into_data() {
2805 Ipv6ExtensionHeaderData::Fragment { fragment_data } => Some(fragment_data),
2806 _ => None,
2807 })
2808 .unwrap();
2809 assert_eq!(fragment_data.fragment_offset(), fragment_offset);
2810 assert_eq!(fragment_data.identification(), identification);
2811 assert_eq!(fragment_data.m_flag(), more_fragments);
2812 }
2813
2814 #[test]
2817 fn extension_headers_take_from_max_body_size() {
2818 let builder = new_builder();
2819 assert_eq!(builder.constraints().max_body_len(), IPV6_MAX_PAYLOAD_LENGTH);
2820 let builder =
2821 Ipv6PacketBuilderWithFragmentHeader::new(builder, FragmentOffset::ZERO, false, 1234);
2822 assert_eq!(
2823 builder.constraints().max_body_len(),
2824 IPV6_MAX_PAYLOAD_LENGTH - IPV6_FRAGMENT_EXT_HDR_LEN
2825 );
2826 }
2827
2828 #[test]
2829 fn test_partial_serialize_parsed() {
2830 let packet_bytes = [
2831 100, 177, 4, 5, 0, 10, 6, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
2832 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0, 1, 2, 3, 4, 5, 6, 7,
2833 8, 9,
2834 ];
2835 let packet_len = packet_bytes.len();
2836 let mut packet_bytes_copy = packet_bytes;
2837 let mut packet_bytes_ref: &mut [u8] = &mut packet_bytes_copy[..];
2838 let packet = packet_bytes_ref.parse::<Ipv6Packet<_>>().unwrap();
2839
2840 for i in 1..(packet_len + 1) {
2841 let mut buf = vec![0u8; i];
2842 let result =
2843 packet.partial_serialize(PacketConstraints::UNCONSTRAINED, buf.as_mut_slice());
2844
2845 let bytes_written = if i >= packet_len { packet_len } else { i };
2846 assert_eq!(
2847 result,
2848 Ok(PartialSerializeResult { bytes_written, total_size: packet_len })
2849 );
2850 assert_eq!(buf[..bytes_written], packet_bytes[..bytes_written]);
2851 }
2852 }
2853}