Skip to main content

packet/
records.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Utilities for parsing and serializing sequential records.
6//!
7//! This module provides utilities for parsing and serializing repeated,
8//! sequential records. Examples of packet formats which include such records
9//! include IPv4, IPv6, TCP, NDP, and IGMP.
10//!
11//! The utilities in this module are very flexible and generic. The user must
12//! supply a number of details about the format in order for parsing and
13//! serializing to work.
14//!
15//! Some packet formats use a [type-length-value]-like encoding for options.
16//! Examples include IPv4, TCP, and NDP options. Special support for these
17//! formats is provided by the [`options`] submodule.
18//!
19//! [type-length-value]: https://en.wikipedia.org/wiki/Type-length-value
20
21use core::borrow::Borrow;
22use core::convert::Infallible as Never;
23use core::marker::PhantomData;
24use core::num::NonZeroUsize;
25use core::ops::Deref;
26
27use zerocopy::{ByteSlice, IntoByteSlice, SplitByteSlice};
28
29use crate::serialize::InnerPacketBuilder;
30use crate::util::{FromRaw, MaybeParsed};
31use crate::{BufferView, BufferViewMut, SplitByteSliceBufView};
32
33/// A type that encapsuates the result of a record parsing operation.
34pub type RecordParseResult<T, E> = core::result::Result<ParsedRecord<T>, E>;
35
36/// A type that encapsulates the successful result of a parsing operation.
37pub enum ParsedRecord<T> {
38    /// A record was successfully consumed and parsed.
39    Parsed(T),
40
41    /// A record was consumed but not parsed for non-fatal reasons.
42    ///
43    /// The caller should attempt to parse the next record to get a successfully
44    /// parsed record.
45    ///
46    /// An example of a record that is skippable is a record used for padding.
47    Skipped,
48
49    /// All possible records have been already been consumed; there is nothing
50    /// left to parse.
51    ///
52    /// The behavior is unspecified if callers attempt to parse another record.
53    Done,
54}
55
56impl<T> ParsedRecord<T> {
57    /// Does this result indicate that a record was consumed?
58    ///
59    /// Returns `true` for `Parsed` and `Skipped` and `false` for `Done`.
60    pub fn consumed(&self) -> bool {
61        match self {
62            ParsedRecord::Parsed(_) | ParsedRecord::Skipped => true,
63            ParsedRecord::Done => false,
64        }
65    }
66}
67
68/// A type that encapsulates the result of measuring the next record.
69pub enum MeasuredRecord {
70    /// A record was measured. This record may be skipped once it is actually parsed.
71    Measured(NonZeroUsize),
72    /// All possible records have been already been consumed; there is nothing
73    /// left to parse.
74    Done,
75}
76
77/// A parsed sequence of records.
78///
79/// `Records` represents a pre-parsed sequence of records whose structure is
80/// enforced by the impl in `R`.
81#[derive(Debug, PartialEq)]
82pub struct Records<B, R: RecordsImplLayout> {
83    bytes: B,
84    record_count: usize,
85    context: R::Context,
86}
87
88/// An unchecked sequence of records.
89///
90/// `RecordsRaw` represents a not-yet-parsed and not-yet-validated sequence of
91/// records, whose structure is enforced by the impl in `R`.
92///
93/// [`Records`] provides an implementation of [`FromRaw`] that can be used to
94/// validate a `RecordsRaw`.
95#[derive(Debug)]
96pub struct RecordsRaw<B, R: RecordsImplLayout> {
97    bytes: B,
98    context: R::Context,
99}
100
101impl<B, R> RecordsRaw<B, R>
102where
103    R: RecordsImplLayout<Context = ()>,
104{
105    /// Creates a new `RecordsRaw` with the data in `bytes`.
106    pub fn new(bytes: B) -> Self {
107        Self { bytes, context: () }
108    }
109}
110
111impl<B, R> RecordsRaw<B, R>
112where
113    R: for<'a> RecordsRawImpl<'a>,
114    B: SplitByteSlice,
115{
116    /// Raw-parses a sequence of records with a context.
117    ///
118    /// See [`RecordsRaw::parse_raw_with_mut_context`] for details on `bytes`,
119    /// `context`, and return value. `parse_raw_with_context` just calls
120    /// `parse_raw_with_mut_context` with a mutable reference to the `context`
121    /// which is passed by value to this function.
122    pub fn parse_raw_with_context<BV: BufferView<B>>(
123        bytes: &mut BV,
124        mut context: R::Context,
125    ) -> MaybeParsed<Self, (B, R::Error)> {
126        Self::parse_raw_with_mut_context(bytes, &mut context)
127    }
128
129    /// Raw-parses a sequence of records with a mutable context.
130    ///
131    /// `parse_raw_with_mut_context` shallowly parses `bytes` as a sequence of
132    /// records. `context` may be used by implementers to maintain state.
133    ///
134    /// `parse_raw_with_mut_context` performs a single pass over all of the
135    /// records to be able to find the end of the records list and update
136    /// `bytes` accordingly. Upon return with [`MaybeParsed::Complete`],
137    /// `bytes` will include only those bytes which are not part of the records
138    /// list. Upon return with [`MaybeParsed::Incomplete`], `bytes` will still
139    /// contain the bytes which could not be parsed, and all subsequent bytes.
140    pub fn parse_raw_with_mut_context<BV: BufferView<B>>(
141        bytes: &mut BV,
142        context: &mut R::Context,
143    ) -> MaybeParsed<Self, (B, R::Error)> {
144        let c = context.clone();
145        let mut b = SplitSliceBufferView::new(bytes.as_ref());
146        let r = loop {
147            match R::parse_raw_with_context(&mut b, context) {
148                Ok(true) => {} // continue consuming from data
149                Ok(false) => {
150                    break None;
151                }
152                Err(e) => {
153                    break Some(e);
154                }
155            }
156        };
157
158        // When we get here, we know that whatever is left in `b` is not needed
159        // so we only take the amount of bytes we actually need from `bytes`,
160        // leaving the rest alone for the caller to continue parsing with.
161        let bytes_len = bytes.len();
162        let b_len = b.as_ref().len();
163        let taken = bytes.take_front(bytes_len - b_len).unwrap();
164
165        match r {
166            Some(error) => MaybeParsed::Incomplete((taken, error)),
167            None => MaybeParsed::Complete(RecordsRaw { bytes: taken, context: c }),
168        }
169    }
170}
171
172impl<B, R> RecordsRaw<B, R>
173where
174    R: for<'a> RecordsRawImpl<'a> + RecordsImplLayout<Context = ()>,
175    B: SplitByteSlice,
176{
177    /// Raw-parses a sequence of records.
178    ///
179    /// Equivalent to calling [`RecordsRaw::parse_raw_with_context`] with
180    /// `context = ()`.
181    pub fn parse_raw<BV: BufferView<B>>(bytes: &mut BV) -> MaybeParsed<Self, (B, R::Error)> {
182        Self::parse_raw_with_context(bytes, ())
183    }
184}
185
186impl<B, R> Deref for RecordsRaw<B, R>
187where
188    B: SplitByteSlice,
189    R: RecordsImplLayout,
190{
191    type Target = [u8];
192
193    fn deref(&self) -> &[u8] {
194        self.bytes.deref()
195    }
196}
197
198impl<B: Deref<Target = [u8]>, R: RecordsImplLayout> RecordsRaw<B, R> {
199    /// Gets the underlying bytes.
200    ///
201    /// `bytes` returns a reference to the byte slice backing this `RecordsRaw`.
202    pub fn bytes(&self) -> &[u8] {
203        &self.bytes
204    }
205}
206
207/// An iterator over the records contained inside a [`Records`] instance.
208#[derive(Copy, Clone, Debug)]
209pub struct RecordsIter<'a, B, R: RecordsImpl> {
210    bytes: B,
211    records_left: usize,
212    context: R::Context,
213    _marker: PhantomData<&'a ()>,
214}
215
216/// An iterator over the records bytes contained inside a [`Records`] instance.
217#[derive(Copy, Clone, Debug)]
218pub struct RecordsBytesIter<'a, B, R: RecordsImpl> {
219    bytes: B,
220    context: R::Context,
221    _marker: PhantomData<&'a ()>,
222}
223
224/// The context kept while performing records parsing.
225///
226/// Types which implement `RecordsContext` can be used as the long-lived context
227/// which is kept during records parsing. This context allows parsers to keep
228/// running computations over the span of multiple records.
229pub trait RecordsContext: Sized + Clone {
230    /// Clones a context for iterator purposes.
231    ///
232    /// `clone_for_iter` is useful for cloning a context to be used by
233    /// [`RecordsIter`]. Since [`Records::parse_with_context`] will do a full
234    /// pass over all the records to check for errors, a `RecordsIter` should
235    /// never error. Therefore, instead of doing checks when iterating (if a
236    /// context was used for checks), a clone of a context can be made
237    /// specifically for iterator purposes that does not do checks (which may be
238    /// expensive).
239    ///
240    /// The default implementation of this method is equivalent to
241    /// [`Clone::clone`].
242    fn clone_for_iter(&self) -> Self {
243        self.clone()
244    }
245}
246
247impl RecordsContext for usize {}
248impl RecordsContext for () {}
249
250/// Basic associated types used by a [`RecordsImpl`].
251///
252/// This trait is kept separate from `RecordsImpl` so that the associated types
253/// do not depend on the lifetime parameter to `RecordsImpl`.
254pub trait RecordsImplLayout {
255    // TODO(https://github.com/rust-lang/rust/issues/29661): Give the `Context`
256    // type a default of `()`.
257
258    /// A context type that can be used to maintain state while parsing multiple
259    /// records.
260    type Context: RecordsContext;
261
262    /// The type of errors that may be returned by a call to
263    /// [`RecordsImpl::parse_with_context`].
264    type Error;
265}
266
267/// An implementation of a records parser.
268///
269/// `RecordsImpl` provides functions to parse sequential records. It is required
270///  in order to construct a [`Records`] or [`RecordsIter`].
271pub trait RecordsImpl: RecordsImplLayout {
272    /// The type of a single record; the output from the [`parse_with_context`]
273    /// function.
274    ///
275    /// For long or variable-length data, implementers are advised to make
276    /// `Record` a reference into the bytes passed to `parse_with_context`. Such
277    /// a reference will need to carry the lifetime `'a`, which is the same
278    /// lifetime that is passed to `parse_with_context`, and is also the
279    /// lifetime parameter to this trait.
280    ///
281    /// [`parse_with_context`]: RecordsImpl::parse_with_context
282    type Record<'a>;
283
284    /// Parses a record with some context.
285    ///
286    /// `parse_with_context` takes a variable-length `data` and a `context` to
287    /// maintain state.
288    ///
289    /// `data` may be empty. It is up to the implementer to handle an exhausted
290    /// `data`.
291    ///
292    /// When returning `Ok(ParsedRecord::Skipped)`, it's the implementer's
293    /// responsibility to consume the bytes of the record from `data`. If this
294    /// doesn't happen, then `parse_with_context` will be called repeatedly on
295    /// the same `data`, and the program will be stuck in an infinite loop. If
296    /// the implementation is unable to determine how many bytes to consume from
297    /// `data` in order to skip the record, `parse_with_context` must return
298    /// `Err`.
299    ///
300    /// `parse_with_context` must be deterministic, or else
301    /// [`Records::parse_with_context`] cannot guarantee that future iterations
302    /// will not produce errors (and thus panic).
303    fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
304        data: &mut BV,
305        context: &mut Self::Context,
306    ) -> RecordParseResult<Self::Record<'a>, Self::Error>;
307}
308
309/// Implemented for [`RecordsImpl`] instances that allow peeking at the length
310/// of the first record in the buffer.
311pub trait MeasureRecordsImpl: RecordsImpl {
312    /// Returns the length in bytes of the next record.
313    fn measure_next_record<'a, BV: BufferView<&'a [u8]>>(
314        data: &BV,
315        context: &mut Self::Context,
316    ) -> core::result::Result<MeasuredRecord, Self::Error>;
317}
318
319/// An implementation of a raw records parser.
320///
321/// `RecordsRawImpl` provides functions to raw-parse sequential records. It is
322/// required to construct a partially-parsed [`RecordsRaw`].
323///
324/// `RecordsRawImpl` is meant to perform little or no validation on each record
325/// it consumes. It is primarily used to be able to walk record sequences with
326/// unknown lengths.
327pub trait RecordsRawImpl<'a>: RecordsImplLayout {
328    /// Raw-parses a single record with some context.
329    ///
330    /// `parse_raw_with_context` takes a variable length `data` and a `context`
331    /// to maintain state, and returns `Ok(true)` if a record is successfully
332    /// consumed, `Ok(false)` if it is unable to parse more records, and
333    /// `Err(err)` if the `data` is malformed in any way.
334    ///
335    /// `data` may be empty. It is up to the implementer to handle an exhausted
336    /// `data`.
337    ///
338    /// It's the implementer's responsibility to consume exactly one record from
339    /// `data` when returning `Ok(_)`.
340    fn parse_raw_with_context<BV: BufferView<&'a [u8]>>(
341        data: &mut BV,
342        context: &mut Self::Context,
343    ) -> Result<bool, Self::Error>;
344}
345
346/// A builder capable of serializing a record.
347///
348/// Given `R: RecordBuilder`, an iterator of `R` can be used with a
349/// [`RecordSequenceBuilder`] to serialize a sequence of records.
350pub trait RecordBuilder {
351    /// Provides the serialized length of a record.
352    ///
353    /// Returns the total length, in bytes, of the serialized encoding of
354    /// `self`.
355    fn serialized_len(&self) -> usize;
356
357    /// Serializes `self` into a buffer.
358    ///
359    /// `data` will be exactly `self.serialized_len()` bytes long.
360    ///
361    /// # Panics
362    ///
363    /// May panic if `data` is not exactly `self.serialized_len()` bytes long.
364    fn serialize_into(&self, data: &mut [u8]);
365}
366
367/// A builder capable of serializing a record with an alignment requirement.
368///
369/// Given `R: AlignedRecordBuilder`, an iterator of `R` can be used with an
370/// [`AlignedRecordSequenceBuilder`] to serialize a sequence of aligned records.
371pub trait AlignedRecordBuilder: RecordBuilder {
372    /// Returns the alignment requirement of `self`.
373    ///
374    /// The alignment requirement is returned as `(x, y)`, which means that the
375    /// record must be aligned at  `x * n + y` bytes from the beginning of the
376    /// records sequence for some non-negative `n`.
377    ///
378    /// It is guaranteed that `x > 0` and that `x > y`.
379    fn alignment_requirement(&self) -> (usize, usize);
380
381    /// Serializes the padding between subsequent aligned records.
382    ///
383    /// Some formats require that padding bytes have particular content. This
384    /// function serializes padding bytes as required by the format.
385    fn serialize_padding(buf: &mut [u8], length: usize);
386}
387
388/// A builder capable of serializing a sequence of records.
389///
390/// A `RecordSequenceBuilder` is instantiated with an [`Iterator`] that provides
391/// [`RecordBuilder`]s to be serialized. The item produced by the iterator can
392/// be any type which implements `Borrow<R>` for `R: RecordBuilder`.
393///
394/// `RecordSequenceBuilder` implements [`InnerPacketBuilder`].
395#[derive(Debug, Clone)]
396pub struct RecordSequenceBuilder<R, I> {
397    records: I,
398    _marker: PhantomData<R>,
399}
400
401impl<R, I> RecordSequenceBuilder<R, I> {
402    /// Creates a new `RecordSequenceBuilder` with the given `records`.
403    ///
404    /// `records` must produce the same sequence of values from every iteration,
405    /// even if cloned. Serialization is typically performed with two passes on
406    /// `records`: one to calculate the total length in bytes (`serialized_len`)
407    /// and another one to serialize to a buffer (`serialize_into`). Violating
408    /// this rule may result in panics or malformed serialized record sequences.
409    pub fn new(records: I) -> Self {
410        Self { records, _marker: PhantomData }
411    }
412}
413
414impl<R, I> RecordSequenceBuilder<R, I>
415where
416    R: RecordBuilder,
417    I: Iterator + Clone,
418    I::Item: Borrow<R>,
419{
420    /// Returns the total length, in bytes, of the serialized encoding of the
421    /// records contained within `self`.
422    pub fn serialized_len(&self) -> usize {
423        self.records.clone().map(|r| r.borrow().serialized_len()).sum()
424    }
425
426    /// Serializes all the records contained within `self` into the given
427    /// buffer.
428    ///
429    /// # Panics
430    ///
431    /// `serialize_into` expects that `buffer` has enough bytes to serialize the
432    /// contained records (as obtained from `serialized_len`), otherwise it's
433    /// considered a violation of the API contract and the call may panic.
434    pub fn serialize_into(&self, buffer: &mut [u8]) {
435        let mut b = &mut &mut buffer[..];
436        for r in self.records.clone() {
437            // SECURITY: Take a zeroed buffer from b to prevent leaking
438            // information from packets previously stored in this buffer.
439            r.borrow().serialize_into(b.take_front_zero(r.borrow().serialized_len()).unwrap());
440        }
441    }
442
443    /// Returns a reference to the inner records of this builder.
444    pub fn records(&self) -> &I {
445        &self.records
446    }
447}
448
449impl<R, I> InnerPacketBuilder for RecordSequenceBuilder<R, I>
450where
451    R: RecordBuilder,
452    I: Iterator + Clone,
453    I::Item: Borrow<R>,
454{
455    fn bytes_len(&self) -> usize {
456        self.serialized_len()
457    }
458
459    fn serialize(&self, buffer: &mut [u8]) {
460        self.serialize_into(buffer)
461    }
462}
463
464/// A builder capable of serializing a sequence of aligned records.
465///
466/// An `AlignedRecordSequenceBuilder` is instantiated with an [`Iterator`] that
467/// provides [`AlignedRecordBuilder`]s to be serialized. The item produced by
468/// the iterator can be any type which implements `Borrow<R>` for `R:
469/// AlignedRecordBuilder`.
470///
471/// `AlignedRecordSequenceBuilder` implements [`InnerPacketBuilder`].
472#[derive(Debug, Clone)]
473pub struct AlignedRecordSequenceBuilder<R, I> {
474    start_pos: usize,
475    records: I,
476    _marker: PhantomData<R>,
477}
478
479impl<R, I> AlignedRecordSequenceBuilder<R, I> {
480    /// Creates a new `AlignedRecordSequenceBuilder` with given `records` and
481    /// `start_pos`.
482    ///
483    /// `records` must produce the same sequence of values from every iteration,
484    /// even if cloned. See [`RecordSequenceBuilder`] for more details.
485    ///
486    /// Alignment is calculated relative to the beginning of a virtual space of
487    /// bytes. If non-zero, `start_pos` instructs the serializer to consider the
488    /// buffer passed to [`serialize_into`] to start at the byte `start_pos`
489    /// within this virtual space, and to calculate alignment and padding
490    /// accordingly. For example, in the IPv6 Hop-by-Hop extension header, a
491    /// fixed header of two bytes precedes that extension header's options, but
492    /// alignment is calculated relative to the beginning of the extension
493    /// header, not relative to the beginning of the options. Thus, when
494    /// constructing an `AlignedRecordSequenceBuilder` to serialize those
495    /// options, `start_pos` would be 2.
496    ///
497    /// [`serialize_into`]: AlignedRecordSequenceBuilder::serialize_into
498    pub fn new(start_pos: usize, records: I) -> Self {
499        Self { start_pos, records, _marker: PhantomData }
500    }
501}
502
503impl<R, I> AlignedRecordSequenceBuilder<R, I>
504where
505    R: AlignedRecordBuilder,
506    I: Iterator + Clone,
507    I::Item: Borrow<R>,
508{
509    /// Returns the total length, in bytes, of the serialized records contained
510    /// within `self`.
511    ///
512    /// Note that this length includes all padding required to ensure that all
513    /// records satisfy their alignment requirements.
514    pub fn serialized_len(&self) -> usize {
515        let mut pos = self.start_pos;
516        self.records
517            .clone()
518            .map(|r| {
519                let (x, y) = r.borrow().alignment_requirement();
520                let new_pos = align_up_to(pos, x, y) + r.borrow().serialized_len();
521                let result = new_pos - pos;
522                pos = new_pos;
523                result
524            })
525            .sum()
526    }
527
528    /// Serializes all the records contained within `self` into the given
529    /// buffer.
530    ///
531    /// # Panics
532    ///
533    /// `serialize_into` expects that `buffer` has enough bytes to serialize the
534    /// contained records (as obtained from `serialized_len`), otherwise it's
535    /// considered a violation of the API contract and the call may panic.
536    pub fn serialize_into(&self, buffer: &mut [u8]) {
537        let mut b = &mut &mut buffer[..];
538        let mut pos = self.start_pos;
539        for r in self.records.clone() {
540            let (x, y) = r.borrow().alignment_requirement();
541            let aligned = align_up_to(pos, x, y);
542            let pad_len = aligned - pos;
543            let pad = b.take_front_zero(pad_len).unwrap();
544            R::serialize_padding(pad, pad_len);
545            pos = aligned;
546            // SECURITY: Take a zeroed buffer from b to prevent leaking
547            // information from packets previously stored in this buffer.
548            r.borrow().serialize_into(b.take_front_zero(r.borrow().serialized_len()).unwrap());
549            pos += r.borrow().serialized_len();
550        }
551        // we have to pad the containing header to 8-octet boundary.
552        let padding = b.take_rest_front_zero();
553        R::serialize_padding(padding, padding.len());
554    }
555}
556
557/// Returns the aligned offset which is at `x * n + y`.
558///
559/// # Panics
560///
561/// Panics if `x == 0` or `y >= x`.
562fn align_up_to(offset: usize, x: usize, y: usize) -> usize {
563    assert!(x != 0 && y < x);
564    // first add `x` to prevent overflow.
565    (offset + x - 1 - y) / x * x + y
566}
567
568impl<B, R> Records<B, R>
569where
570    B: SplitByteSlice,
571    R: RecordsImpl,
572{
573    /// Parses a sequence of records with a context.
574    ///
575    /// See [`parse_with_mut_context`] for details on `bytes`, `context`, and
576    /// return value. `parse_with_context` just calls `parse_with_mut_context`
577    /// with a mutable reference to the `context` which is passed by value to
578    /// this function.
579    ///
580    /// [`parse_with_mut_context`]: Records::parse_with_mut_context
581    pub fn parse_with_context(
582        bytes: B,
583        mut context: R::Context,
584    ) -> Result<Records<B, R>, R::Error> {
585        Self::parse_with_mut_context(bytes, &mut context)
586    }
587
588    /// Parses a sequence of records with a mutable context.
589    ///
590    /// `context` may be used by implementers to maintain state while parsing
591    /// multiple records.
592    ///
593    /// `parse_with_mut_context` performs a single pass over all of the records
594    /// to verify that they are well-formed. Once `parse_with_context` returns
595    /// successfully, the resulting `Records` can be used to construct
596    /// infallible iterators.
597    pub fn parse_with_mut_context(
598        bytes: B,
599        context: &mut R::Context,
600    ) -> Result<Records<B, R>, R::Error> {
601        // First, do a single pass over the bytes to detect any errors up front.
602        // Once this is done, since we have a reference to `bytes`, these bytes
603        // can't change out from under us, and so we can treat any iterator over
604        // these bytes as infallible. This makes a few assumptions, but none of
605        // them are that big of a deal. In all cases, breaking these assumptions
606        // would at worst result in a runtime panic.
607        // - B could return different bytes each time
608        // - R::parse could be non-deterministic
609        let c = context.clone();
610        let mut b = SplitSliceBufferView::new(bytes.as_ref());
611        let mut record_count = 0;
612        while next::<_, R>(&mut b, context)?.is_some() {
613            record_count += 1;
614        }
615        Ok(Records { bytes, record_count, context: c })
616    }
617}
618
619impl<B, R> Records<B, R>
620where
621    B: SplitByteSlice,
622    R: RecordsImpl<Context = ()>,
623{
624    /// Parses a sequence of records.
625    ///
626    /// Equivalent to calling [`parse_with_context`] with `context = ()`.
627    ///
628    /// [`parse_with_context`]: Records::parse_with_context
629    pub fn parse(bytes: B) -> Result<Records<B, R>, R::Error> {
630        Self::parse_with_context(bytes, ())
631    }
632}
633
634impl<B, R> FromRaw<RecordsRaw<B, R>, ()> for Records<B, R>
635where
636    R: RecordsImpl,
637    B: SplitByteSlice,
638{
639    type Error = R::Error;
640
641    fn try_from_raw_with(raw: RecordsRaw<B, R>, _args: ()) -> Result<Self, R::Error> {
642        Records::<B, R>::parse_with_context(raw.bytes, raw.context)
643    }
644}
645
646impl<B: Deref<Target = [u8]>, R> Records<B, R>
647where
648    R: RecordsImpl,
649{
650    /// Gets the underlying bytes.
651    ///
652    /// `bytes` returns a reference to the byte slice backing this `Records`.
653    pub fn bytes(&self) -> &[u8] {
654        &self.bytes
655    }
656}
657
658impl<B, R> Records<B, R>
659where
660    B: ByteSlice,
661    R: RecordsImpl,
662{
663    /// Returns the same records but coerces the backing `B` type to `&[u8]`.
664    pub fn as_ref(&self) -> Records<&[u8], R> {
665        let Self { bytes, record_count, context } = self;
666        Records { bytes: &*bytes, record_count: *record_count, context: context.clone() }
667    }
668}
669
670impl<'a, B, R> Records<B, R>
671where
672    B: 'a + SplitByteSlice,
673    R: RecordsImpl,
674{
675    /// Iterates over options.
676    ///
677    /// Since the records were validated in [`parse`], then so long as
678    /// [`R::parse_with_context`] is deterministic, the iterator is infallible.
679    ///
680    /// [`parse`]: Records::parse
681    /// [`R::parse_with_context`]: RecordsImpl::parse_with_context
682    pub fn iter(&'a self) -> RecordsIter<'a, &'a [u8], R> {
683        RecordsIter {
684            bytes: &self.bytes,
685            records_left: self.record_count,
686            context: self.context.clone_for_iter(),
687            _marker: PhantomData,
688        }
689    }
690
691    /// Iterates over byte slices corresponding to options.
692    ///
693    /// Since the records were validated in [`parse`], then so long as
694    /// [`R::parse_with_context`] is deterministic, the iterator is infallible.
695    /// Unrecognized record types will still be included as long as they don't
696    /// fail length validation, even if they would be skipped by the
697    /// [`RecordsIter`] returned by [`Records::iter`].
698    ///
699    /// [`parse`]: Records::parse
700    /// [`R::parse_with_context`]: RecordsImpl::parse_with_context
701    pub fn iter_bytes(&'a self) -> RecordsBytesIter<'a, &'a [u8], R> {
702        RecordsBytesIter {
703            bytes: &self.bytes,
704            context: self.context.clone_for_iter(),
705            _marker: PhantomData,
706        }
707    }
708}
709
710impl<'a, B, R> Records<B, R>
711where
712    B: SplitByteSlice + IntoByteSlice<'a>,
713    R: RecordsImpl,
714{
715    /// Iterates over options.
716    ///
717    /// Since the records were validated in [`parse`], then so long as
718    /// [`R::parse_with_context`] is deterministic, the iterator is infallible.
719    ///
720    /// [`parse`]: Records::parse
721    /// [`R::parse_with_context`]: RecordsImpl::parse_with_context
722    pub fn into_iter(self) -> RecordsIter<'a, B, R> {
723        RecordsIter {
724            bytes: self.bytes,
725            records_left: self.record_count,
726            context: self.context,
727            _marker: PhantomData,
728        }
729    }
730}
731
732impl<'a, B, R> RecordsIter<'a, B, R>
733where
734    R: RecordsImpl,
735{
736    /// Gets a reference to the context.
737    pub fn context(&self) -> &R::Context {
738        &self.context
739    }
740}
741
742impl<'a, B, R> Iterator for RecordsIter<'a, B, R>
743where
744    R: RecordsImpl,
745    B: SplitByteSlice + IntoByteSlice<'a>,
746{
747    type Item = R::Record<'a>;
748
749    fn next(&mut self) -> Option<R::Record<'a>> {
750        replace_with::replace_with_and(&mut self.bytes, |bytes| {
751            let mut bytes = SplitSliceBufferView::new(bytes);
752            // use match rather than expect because expect requires that Err: Debug
753            #[allow(clippy::match_wild_err_arm)]
754            let result = match next::<_, R>(&mut bytes, &mut self.context) {
755                Ok(o) => o,
756                Err(_) => panic!("already-validated options should not fail to parse"),
757            };
758            if result.is_some() {
759                self.records_left -= 1;
760            }
761            (bytes.into_inner(), result)
762        })
763    }
764
765    fn size_hint(&self) -> (usize, Option<usize>) {
766        (self.records_left, Some(self.records_left))
767    }
768}
769
770impl<'a, B, R> ExactSizeIterator for RecordsIter<'a, B, R>
771where
772    R: RecordsImpl,
773    B: SplitByteSlice + IntoByteSlice<'a>,
774{
775    fn len(&self) -> usize {
776        self.records_left
777    }
778}
779
780impl<'a, B, R> RecordsBytesIter<'a, B, R>
781where
782    R: RecordsImpl,
783{
784    /// Gets a reference to the context.
785    pub fn context(&self) -> &R::Context {
786        &self.context
787    }
788}
789
790impl<'a, B, R> Iterator for RecordsBytesIter<'a, B, R>
791where
792    R: MeasureRecordsImpl,
793    B: SplitByteSlice + IntoByteSlice<'a>,
794{
795    type Item = &'a [u8];
796
797    fn next(&mut self) -> Option<&'a [u8]> {
798        replace_with::replace_with_and(&mut self.bytes, |bytes| {
799            let mut bytes = SplitSliceBufferView::new(bytes);
800            // use match rather than expect because expect requires that Err: Debug
801            #[allow(clippy::match_wild_err_arm)]
802            let result = match next_bytes::<_, R>(&mut bytes, &mut self.context) {
803                Ok(o) => o,
804                Err(_) => panic!("already-validated options should not fail to parse"),
805            };
806            (bytes.into_inner(), result)
807        })
808    }
809}
810
811fn next_bytes<'a, BV, R>(
812    bytes: &mut BV,
813    context: &mut R::Context,
814) -> Result<Option<&'a [u8]>, R::Error>
815where
816    R: MeasureRecordsImpl,
817    BV: BufferView<&'a [u8]>,
818{
819    match R::measure_next_record(bytes, context)? {
820        MeasuredRecord::Measured(len) => {
821            let buf = bytes.take_front(len.get()).expect("should have already measured");
822            Ok(Some(buf))
823        }
824        MeasuredRecord::Done => Ok(None),
825    }
826}
827
828/// Gets the next entry for a set of sequential records in `bytes`.
829///
830/// On return, `bytes` will be pointing to the start of where a next record
831/// would be.
832fn next<'a, BV, R>(
833    bytes: &mut BV,
834    context: &mut R::Context,
835) -> Result<Option<R::Record<'a>>, R::Error>
836where
837    R: RecordsImpl,
838    BV: BufferView<&'a [u8]>,
839{
840    loop {
841        match R::parse_with_context(bytes, context)? {
842            ParsedRecord::Done => {
843                return Ok(None);
844            }
845            ParsedRecord::Skipped => {}
846            ParsedRecord::Parsed(o) => {
847                return Ok(Some(o));
848            }
849        }
850    }
851}
852
853/// Like `SplitByteSliceBufferView`, but with a specialized
854/// `BufferView<&'a [u8]>` implementation.
855struct SplitSliceBufferView<B>(SplitByteSliceBufView<B>);
856
857impl<B> SplitSliceBufferView<B> {
858    fn new(buf: B) -> Self {
859        Self(SplitByteSliceBufView::new(buf))
860    }
861
862    fn into_inner(self) -> B {
863        let Self(buf) = self;
864        buf.into_inner()
865    }
866}
867
868impl<B: SplitByteSlice> AsRef<[u8]> for SplitSliceBufferView<B> {
869    fn as_ref(&self) -> &[u8] {
870        self.0.as_ref()
871    }
872}
873
874impl<'a, B: SplitByteSlice + IntoByteSlice<'a>> BufferView<&'a [u8]> for SplitSliceBufferView<B> {
875    fn take_front(&mut self, n: usize) -> Option<&'a [u8]> {
876        self.0.take_front(n).map(IntoByteSlice::into_byte_slice)
877    }
878
879    fn take_back(&mut self, n: usize) -> Option<&'a [u8]> {
880        self.0.take_back(n).map(IntoByteSlice::into_byte_slice)
881    }
882
883    fn into_rest(self) -> &'a [u8] {
884        self.0.into_rest().into_byte_slice()
885    }
886}
887
888#[cfg(test)]
889mod tests {
890    use test_case::test_case;
891    use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Ref, Unaligned};
892
893    use super::*;
894
895    const DUMMY_BYTES: [u8; 16] = [
896        0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03,
897        0x04,
898    ];
899
900    #[derive(Debug, IntoBytes, KnownLayout, FromBytes, Immutable, Unaligned)]
901    #[repr(C)]
902    struct DummyRecord {
903        a: [u8; 2],
904        b: u8,
905        c: u8,
906    }
907
908    #[derive(Copy, Clone, Debug, Eq, PartialEq)]
909    enum DummyRecordErr {
910        Parse,
911        TooFewRecords,
912    }
913
914    impl From<Never> for DummyRecordErr {
915        fn from(err: Never) -> DummyRecordErr {
916            match err {}
917        }
918    }
919
920    fn parse_dummy_rec<'a, BV>(
921        data: &mut BV,
922    ) -> RecordParseResult<Ref<&'a [u8], DummyRecord>, DummyRecordErr>
923    where
924        BV: BufferView<&'a [u8]>,
925    {
926        if data.is_empty() {
927            return Ok(ParsedRecord::Done);
928        }
929
930        match data.take_obj_front::<DummyRecord>() {
931            Some(res) => Ok(ParsedRecord::Parsed(res)),
932            None => Err(DummyRecordErr::Parse),
933        }
934    }
935
936    //
937    // Context-less records
938    //
939
940    #[derive(Debug)]
941    struct ContextlessRecordImpl;
942
943    impl RecordsImplLayout for ContextlessRecordImpl {
944        type Context = ();
945        type Error = DummyRecordErr;
946    }
947
948    impl RecordsImpl for ContextlessRecordImpl {
949        type Record<'a> = Ref<&'a [u8], DummyRecord>;
950
951        fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
952            data: &mut BV,
953            _context: &mut Self::Context,
954        ) -> RecordParseResult<Self::Record<'a>, Self::Error> {
955            parse_dummy_rec(data)
956        }
957    }
958
959    //
960    // Limit context records
961    //
962
963    #[derive(Debug)]
964    struct LimitContextRecordImpl;
965
966    impl RecordsImplLayout for LimitContextRecordImpl {
967        type Context = usize;
968        type Error = DummyRecordErr;
969    }
970
971    impl RecordsImpl for LimitContextRecordImpl {
972        type Record<'a> = Ref<&'a [u8], DummyRecord>;
973
974        fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
975            data: &mut BV,
976            context: &mut usize,
977        ) -> RecordParseResult<Self::Record<'a>, Self::Error> {
978            if *context == 0 {
979                return Ok(ParsedRecord::Done);
980            }
981            match parse_dummy_rec(data)? {
982                ParsedRecord::Done => Err(DummyRecordErr::TooFewRecords),
983                ParsedRecord::Skipped => Ok(ParsedRecord::Skipped),
984                ParsedRecord::Parsed(res) => {
985                    *context -= 1;
986                    Ok(ParsedRecord::Parsed(res))
987                }
988            }
989        }
990    }
991
992    //
993    // Filter context records
994    //
995
996    #[derive(Debug)]
997    struct FilterContextRecordImpl;
998
999    #[derive(Clone)]
1000    struct FilterContext {
1001        pub disallowed: [bool; 256],
1002    }
1003
1004    impl RecordsContext for FilterContext {}
1005
1006    impl RecordsImplLayout for FilterContextRecordImpl {
1007        type Context = FilterContext;
1008        type Error = DummyRecordErr;
1009    }
1010
1011    impl core::fmt::Debug for FilterContext {
1012        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1013            write!(f, "FilterContext{{disallowed:{:?}}}", &self.disallowed[..])
1014        }
1015    }
1016
1017    impl RecordsImpl for FilterContextRecordImpl {
1018        type Record<'a> = Ref<&'a [u8], DummyRecord>;
1019
1020        fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
1021            bytes: &mut BV,
1022            context: &mut Self::Context,
1023        ) -> RecordParseResult<Self::Record<'a>, Self::Error> {
1024            if bytes.len() < core::mem::size_of::<DummyRecord>() {
1025                Ok(ParsedRecord::Done)
1026            } else if bytes.as_ref()[0..core::mem::size_of::<DummyRecord>()]
1027                .iter()
1028                .any(|x| context.disallowed[*x as usize])
1029            {
1030                Err(DummyRecordErr::Parse)
1031            } else {
1032                parse_dummy_rec(bytes)
1033            }
1034        }
1035    }
1036
1037    //
1038    // Stateful context records
1039    //
1040
1041    #[derive(Debug)]
1042    struct StatefulContextRecordImpl;
1043
1044    #[derive(Clone, Debug)]
1045    struct StatefulContext {
1046        pub pre_parse_counter: usize,
1047        pub parse_counter: usize,
1048        pub post_parse_counter: usize,
1049        pub iter: bool,
1050    }
1051
1052    impl RecordsImplLayout for StatefulContextRecordImpl {
1053        type Context = StatefulContext;
1054        type Error = DummyRecordErr;
1055    }
1056
1057    impl StatefulContext {
1058        pub fn new() -> StatefulContext {
1059            StatefulContext {
1060                pre_parse_counter: 0,
1061                parse_counter: 0,
1062                post_parse_counter: 0,
1063                iter: false,
1064            }
1065        }
1066    }
1067
1068    impl RecordsContext for StatefulContext {
1069        fn clone_for_iter(&self) -> Self {
1070            let mut x = self.clone();
1071            x.iter = true;
1072            x
1073        }
1074    }
1075
1076    impl RecordsImpl for StatefulContextRecordImpl {
1077        type Record<'a> = Ref<&'a [u8], DummyRecord>;
1078
1079        fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
1080            data: &mut BV,
1081            context: &mut Self::Context,
1082        ) -> RecordParseResult<Self::Record<'a>, Self::Error> {
1083            if !context.iter {
1084                context.pre_parse_counter += 1;
1085            }
1086
1087            let ret = parse_dummy_rec_with_context(data, context);
1088
1089            if let Ok(ParsedRecord::Parsed(_)) = ret {
1090                if !context.iter {
1091                    context.post_parse_counter += 1;
1092                }
1093            }
1094
1095            ret
1096        }
1097    }
1098
1099    impl<'a> RecordsRawImpl<'a> for StatefulContextRecordImpl {
1100        fn parse_raw_with_context<BV: BufferView<&'a [u8]>>(
1101            data: &mut BV,
1102            context: &mut Self::Context,
1103        ) -> Result<bool, Self::Error> {
1104            Self::parse_with_context(data, context).map(|r| r.consumed())
1105        }
1106    }
1107
1108    fn parse_dummy_rec_with_context<'a, BV>(
1109        data: &mut BV,
1110        context: &mut StatefulContext,
1111    ) -> RecordParseResult<Ref<&'a [u8], DummyRecord>, DummyRecordErr>
1112    where
1113        BV: BufferView<&'a [u8]>,
1114    {
1115        if data.is_empty() {
1116            return Ok(ParsedRecord::Done);
1117        }
1118
1119        if !context.iter {
1120            context.parse_counter += 1;
1121        }
1122
1123        match data.take_obj_front::<DummyRecord>() {
1124            Some(res) => Ok(ParsedRecord::Parsed(res)),
1125            None => Err(DummyRecordErr::Parse),
1126        }
1127    }
1128
1129    fn check_parsed_record(rec: &DummyRecord) {
1130        assert_eq!(rec.a[0], 0x01);
1131        assert_eq!(rec.a[1], 0x02);
1132        assert_eq!(rec.b, 0x03);
1133    }
1134
1135    fn validate_parsed_stateful_context_records<B: SplitByteSlice>(
1136        records: Records<B, StatefulContextRecordImpl>,
1137        context: StatefulContext,
1138    ) {
1139        // Should be 5 because on the last iteration, we should realize that we
1140        // have no more bytes left and end before parsing (also explaining why
1141        // `parse_counter` should only be 4.
1142        assert_eq!(context.pre_parse_counter, 5);
1143        assert_eq!(context.parse_counter, 4);
1144        assert_eq!(context.post_parse_counter, 4);
1145
1146        let mut iter = records.iter();
1147        let context = &iter.context;
1148        assert_eq!(context.pre_parse_counter, 0);
1149        assert_eq!(context.parse_counter, 0);
1150        assert_eq!(context.post_parse_counter, 0);
1151        assert_eq!(context.iter, true);
1152
1153        // Manually iterate over `iter` so as to not move it.
1154        let mut count = 0;
1155        while let Some(_) = iter.next() {
1156            count += 1;
1157        }
1158        assert_eq!(count, 4);
1159
1160        // Check to see that when iterating, the context doesn't update counters
1161        // as that is how we implemented our StatefulContextRecordImpl..
1162        let context = &iter.context;
1163        assert_eq!(context.pre_parse_counter, 0);
1164        assert_eq!(context.parse_counter, 0);
1165        assert_eq!(context.post_parse_counter, 0);
1166        assert_eq!(context.iter, true);
1167    }
1168
1169    #[test]
1170    fn all_records_parsing() {
1171        let parsed = Records::<_, ContextlessRecordImpl>::parse(&DUMMY_BYTES[..]).unwrap();
1172        let mut iter = parsed.iter();
1173        // Test ExactSizeIterator implementation.
1174        assert_eq!(iter.len(), 4);
1175        let mut cnt = 4;
1176        while let Some(_) = iter.next() {
1177            cnt -= 1;
1178            assert_eq!(iter.len(), cnt);
1179        }
1180        assert_eq!(iter.len(), 0);
1181        for rec in parsed.iter() {
1182            check_parsed_record(rec.deref());
1183        }
1184    }
1185
1186    // `expect` is either the number of records that should have been parsed or
1187    // the error returned from the `Records` constructor.
1188    //
1189    // If there are more records than the limit, then we just truncate (not
1190    // parsing all of them) and don't return an error.
1191    #[test_case(0, Ok(0))]
1192    #[test_case(1, Ok(1))]
1193    #[test_case(2, Ok(2))]
1194    #[test_case(3, Ok(3))]
1195    // If there are the same number of records as the limit, then we
1196    // succeed.
1197    #[test_case(4, Ok(4))]
1198    // If there are fewer records than the limit, then we fail.
1199    #[test_case(5, Err(DummyRecordErr::TooFewRecords))]
1200    fn limit_records_parsing(limit: usize, expect: Result<usize, DummyRecordErr>) {
1201        // Test without mutable limit/context
1202        let check_result =
1203            |result: Result<Records<_, LimitContextRecordImpl>, _>| match (expect, result) {
1204                (Ok(expect_parsed), Ok(records)) => {
1205                    assert_eq!(records.iter().count(), expect_parsed);
1206                    for rec in records.iter() {
1207                        check_parsed_record(rec.deref());
1208                    }
1209                }
1210                (Err(expect), Err(got)) => assert_eq!(expect, got),
1211                (Ok(expect_parsed), Err(err)) => {
1212                    panic!("wanted {expect_parsed} successfully-parsed records; got error {err:?}")
1213                }
1214                (Err(expect), Ok(records)) => panic!(
1215                    "wanted error {expect:?}, got {} successfully-parsed records",
1216                    records.iter().count()
1217                ),
1218            };
1219
1220        check_result(Records::<_, LimitContextRecordImpl>::parse_with_context(
1221            &DUMMY_BYTES[..],
1222            limit,
1223        ));
1224        let mut mut_limit = limit;
1225        check_result(Records::<_, LimitContextRecordImpl>::parse_with_mut_context(
1226            &DUMMY_BYTES[..],
1227            &mut mut_limit,
1228        ));
1229        if let Ok(expect_parsed) = expect {
1230            assert_eq!(limit - mut_limit, expect_parsed);
1231        }
1232    }
1233
1234    #[test]
1235    fn context_filtering_some_byte_records_parsing() {
1236        // Do not disallow any bytes
1237        let context = FilterContext { disallowed: [false; 256] };
1238        let parsed =
1239            Records::<_, FilterContextRecordImpl>::parse_with_context(&DUMMY_BYTES[..], context)
1240                .unwrap();
1241        assert_eq!(parsed.iter().count(), 4);
1242        for rec in parsed.iter() {
1243            check_parsed_record(rec.deref());
1244        }
1245
1246        // Do not allow byte value 0x01
1247        let mut context = FilterContext { disallowed: [false; 256] };
1248        context.disallowed[1] = true;
1249        assert_eq!(
1250            Records::<_, FilterContextRecordImpl>::parse_with_context(&DUMMY_BYTES[..], context)
1251                .expect_err("fails if the buffer has an element with value 0x01"),
1252            DummyRecordErr::Parse
1253        );
1254    }
1255
1256    #[test]
1257    fn stateful_context_records_parsing() {
1258        let mut context = StatefulContext::new();
1259        let parsed = Records::<_, StatefulContextRecordImpl>::parse_with_mut_context(
1260            &DUMMY_BYTES[..],
1261            &mut context,
1262        )
1263        .unwrap();
1264        validate_parsed_stateful_context_records(parsed, context);
1265    }
1266
1267    #[test]
1268    fn raw_parse_success() {
1269        let mut context = StatefulContext::new();
1270        let mut bv = &mut &DUMMY_BYTES[..];
1271        let result = RecordsRaw::<_, StatefulContextRecordImpl>::parse_raw_with_mut_context(
1272            &mut bv,
1273            &mut context,
1274        )
1275        .complete()
1276        .unwrap();
1277        let RecordsRaw { bytes, context: _ } = &result;
1278        assert_eq!(*bytes, &DUMMY_BYTES[..]);
1279        let parsed = Records::try_from_raw(result).unwrap();
1280        validate_parsed_stateful_context_records(parsed, context);
1281    }
1282
1283    #[test]
1284    fn raw_parse_failure() {
1285        let mut context = StatefulContext::new();
1286        let mut bv = &mut &DUMMY_BYTES[0..15];
1287        let result = RecordsRaw::<_, StatefulContextRecordImpl>::parse_raw_with_mut_context(
1288            &mut bv,
1289            &mut context,
1290        )
1291        .incomplete()
1292        .unwrap();
1293        assert_eq!(result, (&DUMMY_BYTES[0..12], DummyRecordErr::Parse));
1294    }
1295}
1296
1297/// Utilities for parsing the options formats in protocols like IPv4, TCP, and
1298/// NDP.
1299///
1300/// This module provides parsing utilities for [type-length-value]-like records
1301/// encodings like those used by the options in an IPv4 or TCP header or an NDP
1302/// packet. These formats are not identical, but share enough in common that the
1303/// utilities provided here only need a small amount of customization by the
1304/// user to be fully functional.
1305///
1306/// [type-length-value]: https://en.wikipedia.org/wiki/Type-length-value
1307pub mod options {
1308    use core::mem;
1309    use core::num::{NonZeroUsize, TryFromIntError};
1310
1311    use zerocopy::byteorder::ByteOrder;
1312    use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
1313
1314    use super::*;
1315
1316    /// A parsed sequence of options.
1317    ///
1318    /// `Options` represents a parsed sequence of options, for example from an
1319    /// IPv4 or TCP header or an NDP packet. `Options` uses [`Records`] under
1320    /// the hood.
1321    ///
1322    /// [`Records`]: crate::records::Records
1323    pub type Options<B, O> = Records<B, O>;
1324
1325    /// A not-yet-parsed sequence of options.
1326    ///
1327    /// `OptionsRaw` represents a not-yet-parsed and not-yet-validated sequence
1328    /// of options, for example from an IPv4 or TCP header or an NDP packet.
1329    /// `OptionsRaw` uses [`RecordsRaw`] under the hood.
1330    ///
1331    /// [`RecordsRaw`]: crate::records::RecordsRaw
1332    pub type OptionsRaw<B, O> = RecordsRaw<B, O>;
1333
1334    /// A builder capable of serializing a sequence of options.
1335    ///
1336    /// An `OptionSequenceBuilder` is instantiated with an [`Iterator`] that
1337    /// provides [`OptionBuilder`]s to be serialized. The item produced by the
1338    /// iterator can be any type which implements `Borrow<O>` for `O:
1339    /// OptionBuilder`.
1340    ///
1341    /// `OptionSequenceBuilder` implements [`InnerPacketBuilder`].
1342    pub type OptionSequenceBuilder<R, I> = RecordSequenceBuilder<R, I>;
1343
1344    /// A builder capable of serializing a sequence of aligned options.
1345    ///
1346    /// An `AlignedOptionSequenceBuilder` is instantiated with an [`Iterator`]
1347    /// that provides [`AlignedOptionBuilder`]s to be serialized. The item
1348    /// produced by the iterator can be any type which implements `Borrow<O>`
1349    /// for `O: AlignedOptionBuilder`.
1350    ///
1351    /// `AlignedOptionSequenceBuilder` implements [`InnerPacketBuilder`].
1352    pub type AlignedOptionSequenceBuilder<R, I> = AlignedRecordSequenceBuilder<R, I>;
1353
1354    impl<O: OptionsImpl> RecordsImplLayout for O {
1355        type Context = ();
1356        type Error = O::Error;
1357    }
1358
1359    impl<O: OptionsImpl> RecordsImpl for O {
1360        type Record<'a> = O::Option<'a>;
1361
1362        fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
1363            data: &mut BV,
1364            _context: &mut Self::Context,
1365        ) -> RecordParseResult<Self::Record<'a>, Self::Error> {
1366            next::<_, O>(data)
1367        }
1368    }
1369
1370    impl<O: OptionsImpl> MeasureRecordsImpl for O {
1371        fn measure_next_record<'a, BV: BufferView<&'a [u8]>>(
1372            data: &BV,
1373            _context: &mut Self::Context,
1374        ) -> core::result::Result<MeasuredRecord, Self::Error> {
1375            if data.len() == 0 {
1376                return Ok(MeasuredRecord::Done);
1377            }
1378
1379            // First peek at the kind field.
1380            match data.peek_obj_front::<O::KindLenField>() {
1381                // Thanks to the preceding `if`, we know at this point that
1382                // `data.len() > 0`. If `peek_obj_front` returns `None`, that
1383                // means that `data.len()` is shorter than `O::KindLenField`.
1384                None => return Err(O::Error::SEQUENCE_FORMAT_ERROR),
1385                Some(k) => {
1386                    // Can't do pattern matching with associated constants, so
1387                    // do it the good-ol' way:
1388                    if Some(*k) == O::NOP {
1389                        // The next record is a NOP record which is always just
1390                        // the kind field itself.
1391                        return Ok(MeasuredRecord::Measured(
1392                            NonZeroUsize::new(size_of::<O::KindLenField>())
1393                                .expect("KindLenField must not be 0-sized"),
1394                        ));
1395                    } else if Some(*k) == O::END_OF_OPTIONS {
1396                        return Ok(MeasuredRecord::Done);
1397                    }
1398                }
1399            };
1400
1401            // Then, since we only _peeked_ before, we have to peek again to get
1402            // both the kind field (again) and the length field.
1403            let body_len = match data.peek_obj_front::<[O::KindLenField; 2]>() {
1404                None => return Err(O::Error::SEQUENCE_FORMAT_ERROR),
1405                Some([_kind, len]) => O::LENGTH_ENCODING
1406                    .decode_length::<O::KindLenField>(*len)
1407                    .ok_or(O::Error::SEQUENCE_FORMAT_ERROR)?,
1408            };
1409            Ok(MeasuredRecord::Measured(
1410                NonZeroUsize::new(
1411                    O::LENGTH_ENCODING
1412                        .record_length::<O::KindLenField>(body_len)
1413                        .expect("record_length(decode_length(..)) should succeed"),
1414                )
1415                .expect("should never get 0-length record"),
1416            ))
1417        }
1418    }
1419
1420    impl<O: OptionBuilder> RecordBuilder for O {
1421        fn serialized_len(&self) -> usize {
1422            // TODO(https://fxbug.dev/42158056): Remove this `.expect`
1423            <O::Layout as OptionLayout>::LENGTH_ENCODING
1424                .record_length::<<O::Layout as OptionLayout>::KindLenField>(
1425                    OptionBuilder::serialized_len(self),
1426                )
1427                .expect("integer overflow while computing record length")
1428        }
1429
1430        fn serialize_into(&self, mut data: &mut [u8]) {
1431            // NOTE(brunodalbo) we don't currently support serializing the two
1432            //  single-byte options used in TCP and IP: NOP and END_OF_OPTIONS.
1433            //  If it is necessary to support those as part of TLV options
1434            //  serialization, some changes will be required here.
1435
1436            // So that `data` implements `BufferViewMut`.
1437            let mut data = &mut data;
1438
1439            // Data not having enough space is a contract violation, so we panic
1440            // in that case.
1441            *BufferView::<&mut [u8]>::take_obj_front::<<O::Layout as OptionLayout>::KindLenField>(&mut data)
1442                .expect("buffer too short") = self.option_kind();
1443            let body_len = OptionBuilder::serialized_len(self);
1444            // TODO(https://fxbug.dev/42158056): Remove this `.expect`
1445            let length = <O::Layout as OptionLayout>::LENGTH_ENCODING
1446                .encode_length::<<O::Layout as OptionLayout>::KindLenField>(body_len)
1447                .expect("integer overflow while encoding length");
1448            // Length overflowing `O::Layout::KindLenField` is a contract
1449            // violation, so we panic in that case.
1450            *BufferView::<&mut [u8]>::take_obj_front::<<O::Layout as OptionLayout>::KindLenField>(&mut data)
1451                .expect("buffer too short") = length;
1452            // SECURITY: Because padding may have occurred, we zero-fill data
1453            // before passing it along in order to prevent leaking information
1454            // from packets previously stored in the buffer.
1455            let data = data.into_rest_zero();
1456            // Pass exactly `body_len` bytes even if there is padding.
1457            OptionBuilder::serialize_into(self, &mut data[..body_len]);
1458        }
1459    }
1460
1461    impl<O: AlignedOptionBuilder> AlignedRecordBuilder for O {
1462        fn alignment_requirement(&self) -> (usize, usize) {
1463            // Use the underlying option's alignment requirement as the
1464            // alignment requirement for the record.
1465            AlignedOptionBuilder::alignment_requirement(self)
1466        }
1467
1468        fn serialize_padding(buf: &mut [u8], length: usize) {
1469            <O as AlignedOptionBuilder>::serialize_padding(buf, length);
1470        }
1471    }
1472
1473    /// Whether the length field of an option encodes the length of the entire
1474    /// option (including kind and length fields) or only of the value field.
1475    ///
1476    /// For the `TypeLengthValue` variant, an `option_len_multiplier` may also
1477    /// be specified. Some formats (such as NDP) do not directly encode the
1478    /// length in bytes of each option, but instead encode a number which must
1479    /// be multiplied by `option_len_multiplier` in order to get the length in
1480    /// bytes.
1481    #[derive(Copy, Clone, Eq, PartialEq)]
1482    pub enum LengthEncoding {
1483        TypeLengthValue { option_len_multiplier: NonZeroUsize },
1484        ValueOnly,
1485    }
1486
1487    impl LengthEncoding {
1488        /// Computes the length of an entire option record - including kind and
1489        /// length fields - from the length of an option body.
1490        ///
1491        /// `record_length` takes into account the length of the kind and length
1492        /// fields and also adds any padding required to reach a multiple of
1493        /// `option_len_multiplier`, returning `None` if the value cannot be
1494        /// stored in a `usize`.
1495        fn record_length<F: KindLenField>(self, option_body_len: usize) -> Option<usize> {
1496            let unpadded_len = option_body_len.checked_add(2 * mem::size_of::<F>())?;
1497            match self {
1498                LengthEncoding::TypeLengthValue { option_len_multiplier } => {
1499                    round_up(unpadded_len, option_len_multiplier)
1500                }
1501                LengthEncoding::ValueOnly => Some(unpadded_len),
1502            }
1503        }
1504
1505        /// Encodes the length of an option's body.
1506        ///
1507        /// `option_body_len` is the length in bytes of the body option as
1508        /// returned from [`OptionsSerializerImpl::option_length`]. This value
1509        /// does not include the kind, length, or padding bytes.
1510        ///
1511        /// `encode_length` computes the value which should be stored in the
1512        /// length field, returning `None` if the value cannot be stored in an
1513        /// `F`.
1514        pub fn encode_length<F: KindLenField>(self, option_body_len: usize) -> Option<F> {
1515            let len = match self {
1516                LengthEncoding::TypeLengthValue { option_len_multiplier } => {
1517                    let unpadded_len = (2 * mem::size_of::<F>()).checked_add(option_body_len)?;
1518                    let padded_len = round_up(unpadded_len, option_len_multiplier)?;
1519                    padded_len / option_len_multiplier.get()
1520                }
1521                LengthEncoding::ValueOnly => option_body_len,
1522            };
1523            match F::try_from(len) {
1524                Ok(len) => Some(len),
1525                Err(TryFromIntError { .. }) => None,
1526            }
1527        }
1528
1529        /// Decodes the length of an option's body.
1530        ///
1531        /// `length_field` is the value of the length field. `decode_length`
1532        /// computes the length of the option's body which this value encodes,
1533        /// returning an error if `length_field` is invalid or if integer
1534        /// overflow occurs. `length_field` is invalid if it encodes a total
1535        /// length smaller than the header (specifically, if `self` is
1536        /// LengthEncoding::TypeLengthValue { option_len_multiplier }` and
1537        /// `length_field * option_len_multiplier < 2 * size_of::<F>()`).
1538        fn decode_length<F: KindLenField>(self, length_field: F) -> Option<usize> {
1539            let length_field = length_field.into();
1540            match self {
1541                LengthEncoding::TypeLengthValue { option_len_multiplier } => length_field
1542                    .checked_mul(option_len_multiplier.get())
1543                    .and_then(|product| product.checked_sub(2 * mem::size_of::<F>())),
1544                LengthEncoding::ValueOnly => Some(length_field),
1545            }
1546        }
1547    }
1548
1549    /// Rounds up `x` to the next multiple of `mul` unless `x` is already a
1550    /// multiple of `mul`.
1551    fn round_up(x: usize, mul: NonZeroUsize) -> Option<usize> {
1552        let mul = mul.get();
1553        // - Subtracting 1 can't underflow because we just added `mul`, which is
1554        //   at least 1, and the addition didn't overflow
1555        // - Dividing by `mul` can't overflow (and can't divide by 0 because
1556        //   `mul` is nonzero)
1557        // - Multiplying by `mul` can't overflow because division rounds down,
1558        //   so the result of the multiplication can't be any larger than the
1559        //   numerator in `(x_times_mul - 1) / mul`, which we already know
1560        //   didn't overflow
1561        x.checked_add(mul).map(|x_times_mul| ((x_times_mul - 1) / mul) * mul)
1562    }
1563
1564    /// The type of the "kind" and "length" fields in an option.
1565    ///
1566    /// See the docs for [`OptionLayout::KindLenField`] for more information.
1567    pub trait KindLenField:
1568        FromBytes
1569        + IntoBytes
1570        + KnownLayout
1571        + Immutable
1572        + Unaligned
1573        + Into<usize>
1574        + TryFrom<usize, Error = TryFromIntError>
1575        + Eq
1576        + Copy
1577        + crate::sealed::Sealed
1578    {
1579    }
1580
1581    impl crate::sealed::Sealed for u8 {}
1582    impl KindLenField for u8 {}
1583    impl<O: ByteOrder> crate::sealed::Sealed for zerocopy::U16<O> {}
1584    impl<O: ByteOrder> KindLenField for zerocopy::U16<O> {}
1585
1586    /// Information about an option's layout.
1587    ///
1588    /// It is recommended that this trait be implemented for an uninhabited type
1589    /// since it never needs to be instantiated:
1590    ///
1591    /// ```rust
1592    /// # use packet::records::options::{OptionLayout, LengthEncoding};
1593    /// /// A carrier for information about the layout of the IPv4 option
1594    /// /// format.
1595    /// ///
1596    /// /// This type exists only at the type level, and does not need to be
1597    /// /// constructed.
1598    /// pub enum Ipv4OptionLayout {}
1599    ///
1600    /// impl OptionLayout for Ipv4OptionLayout {
1601    ///     type KindLenField = u8;
1602    /// }
1603    /// ```
1604    pub trait OptionLayout {
1605        /// The type of the "kind" and "length" fields in an option.
1606        ///
1607        /// For most protocols, this is simply `u8`, as the "kind" and "length"
1608        /// fields are each a single byte. For protocols which use two bytes for
1609        /// these fields, this is [`zerocopy::U16`].
1610        // TODO(https://github.com/rust-lang/rust/issues/29661): Have
1611        // `KindLenField` default to `u8`.
1612        type KindLenField: KindLenField;
1613
1614        /// The encoding of the length byte.
1615        ///
1616        /// Some formats (such as IPv4) use the length field to encode the
1617        /// length of the entire option, including the kind and length bytes.
1618        /// Other formats (such as IPv6) use the length field to encode the
1619        /// length of only the value. This constant specifies which encoding is
1620        /// used.
1621        ///
1622        /// Additionally, some formats (such as NDP) do not directly encode the
1623        /// length in bytes of each option, but instead encode a number which
1624        /// must be multiplied by a constant in order to get the length in
1625        /// bytes. This is set using the [`TypeLengthValue`] variant's
1626        /// `option_len_multiplier` field, and it defaults to 1.
1627        ///
1628        /// [`TypeLengthValue`]: LengthEncoding::TypeLengthValue
1629        const LENGTH_ENCODING: LengthEncoding = LengthEncoding::TypeLengthValue {
1630            option_len_multiplier: NonZeroUsize::new(1).unwrap(),
1631        };
1632    }
1633
1634    /// An error encountered while parsing an option or sequence of options.
1635    pub trait OptionParseError: From<Never> {
1636        /// An error encountered while parsing a sequence of options.
1637        ///
1638        /// If an error is encountered while parsing a sequence of [`Options`],
1639        /// this is the error that will be emitted. This is the only type of
1640        /// error that can be generated by the [`Options`] parser itself. All
1641        /// other errors come from the user-provided [`OptionsImpl::parse`],
1642        /// which parses the data of a single option.
1643        const SEQUENCE_FORMAT_ERROR: Self;
1644    }
1645
1646    /// An error encountered while parsing an option or sequence of options.
1647    ///
1648    /// `OptionParseErr` is a simple implementation of [`OptionParseError`] that
1649    /// doesn't carry information other than the fact that an error was
1650    /// encountered.
1651    #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1652    pub struct OptionParseErr;
1653
1654    impl From<Never> for OptionParseErr {
1655        fn from(err: Never) -> OptionParseErr {
1656            match err {}
1657        }
1658    }
1659
1660    impl OptionParseError for OptionParseErr {
1661        const SEQUENCE_FORMAT_ERROR: OptionParseErr = OptionParseErr;
1662    }
1663
1664    /// Information about an option's layout required in order to parse it.
1665    pub trait OptionParseLayout: OptionLayout {
1666        /// The type of errors that may be returned by a call to
1667        /// [`OptionsImpl::parse`].
1668        type Error: OptionParseError;
1669
1670        /// The End of options kind (if one exists).
1671        const END_OF_OPTIONS: Option<Self::KindLenField>;
1672
1673        /// The No-op kind (if one exists).
1674        const NOP: Option<Self::KindLenField>;
1675    }
1676
1677    /// An implementation of an options parser.
1678    ///
1679    /// `OptionsImpl` provides functions to parse fixed- and variable-length
1680    /// options. It is required in order to construct an [`Options`].
1681    pub trait OptionsImpl: OptionParseLayout {
1682        /// The type of an option; the output from the [`parse`] function.
1683        ///
1684        /// For long or variable-length data, implementers are advised to make
1685        /// `Option` a reference into the bytes passed to `parse`. Such a
1686        /// reference will need to carry the lifetime `'a`, which is the same
1687        /// lifetime that is passed to `parse`, and is also the lifetime
1688        /// parameter to this trait.
1689        ///
1690        /// [`parse`]: crate::records::options::OptionsImpl::parse
1691        type Option<'a>;
1692
1693        /// Parses an option.
1694        ///
1695        /// `parse` takes a kind byte and variable-length data and returns
1696        /// `Ok(Some(o))` if the option successfully parsed as `o`, `Ok(None)`
1697        /// if the kind byte was unrecognized, and `Err(err)` if the kind byte
1698        /// was recognized but `data` was malformed for that option kind.
1699        ///
1700        /// `parse` is allowed to not recognize certain option kinds, as the
1701        /// length field can still be used to safely skip over them, but it must
1702        /// recognize all single-byte options (if it didn't, a single-byte
1703        /// option would be spuriously interpreted as a multi-byte option, and
1704        /// the first byte of the next option byte would be spuriously
1705        /// interpreted as the option's length byte).
1706        ///
1707        /// `parse` must be deterministic, or else [`Options::parse`] cannot
1708        /// guarantee that future iterations will not produce errors (and thus
1709        /// panic).
1710        ///
1711        /// [`Options::parse`]: crate::records::Records::parse
1712        fn parse<'a>(
1713            kind: Self::KindLenField,
1714            data: &'a [u8],
1715        ) -> Result<Option<Self::Option<'a>>, Self::Error>;
1716    }
1717
1718    /// A builder capable of serializing an option.
1719    ///
1720    /// Given `O: OptionBuilder`, an iterator of `O` can be used with a
1721    /// [`OptionSequenceBuilder`] to serialize a sequence of options.
1722    pub trait OptionBuilder {
1723        /// Information about the option's layout.
1724        type Layout: OptionLayout;
1725
1726        /// Returns the serialized length, in bytes, of `self`.
1727        ///
1728        /// Implementers must return the length, in bytes, of the **data***
1729        /// portion of the option field (not counting the kind and length
1730        /// bytes). The internal machinery of options serialization takes care
1731        /// of aligning options to their [`option_len_multiplier`] boundaries,
1732        /// adding padding bytes if necessary.
1733        ///
1734        /// [`option_len_multiplier`]: LengthEncoding::TypeLengthValue::option_len_multiplier
1735        fn serialized_len(&self) -> usize;
1736
1737        /// Returns the wire value for this option kind.
1738        fn option_kind(&self) -> <Self::Layout as OptionLayout>::KindLenField;
1739
1740        /// Serializes `self` into `data`.
1741        ///
1742        /// `data` will be exactly `self.serialized_len()` bytes long.
1743        /// Implementers must write the **data** portion of `self` into `data`
1744        /// (not the kind or length fields).
1745        ///
1746        /// # Panics
1747        ///
1748        /// May panic if `data` is not exactly `self.serialized_len()` bytes
1749        /// long.
1750        fn serialize_into(&self, data: &mut [u8]);
1751    }
1752
1753    /// A builder capable of serializing an option with an alignment
1754    /// requirement.
1755    ///
1756    /// Given `O: AlignedOptionBuilder`, an iterator of `O` can be used with an
1757    /// [`AlignedOptionSequenceBuilder`] to serialize a sequence of aligned
1758    /// options.
1759    pub trait AlignedOptionBuilder: OptionBuilder {
1760        /// Returns the alignment requirement of `self`.
1761        ///
1762        /// `option.alignment_requirement()` returns `(x, y)`, which means that
1763        /// the serialized encoding of `option` must be aligned at `x * n + y`
1764        /// bytes from the beginning of the options sequence for some
1765        /// non-negative `n`. For example, the IPv6 Router Alert Hop-by-Hop
1766        /// option has alignment (2, 0), while the Jumbo Payload option has
1767        /// alignment (4, 2). (1, 0) means there is no alignment requirement.
1768        ///
1769        /// `x` must be non-zero and `y` must be smaller than `x`.
1770        fn alignment_requirement(&self) -> (usize, usize);
1771
1772        /// Serializes the padding between subsequent aligned options.
1773        ///
1774        /// Some formats require that padding bytes have particular content.
1775        /// This function serializes padding bytes as required by the format.
1776        fn serialize_padding(buf: &mut [u8], length: usize);
1777    }
1778
1779    fn next<'a, BV, O>(bytes: &mut BV) -> RecordParseResult<O::Option<'a>, O::Error>
1780    where
1781        BV: BufferView<&'a [u8]>,
1782        O: OptionsImpl,
1783    {
1784        // For an explanation of this format, see the "Options" section of
1785        // https://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_segment_structure
1786        loop {
1787            if bytes.len() == 0 {
1788                return Ok(ParsedRecord::Done);
1789            }
1790            let kind = match bytes.take_obj_front::<O::KindLenField>() {
1791                // Thanks to the preceding `if`, we know at this point that
1792                // `bytes.len() > 0`. If `take_obj_front` returns `None`, that
1793                // means that `bytes.len()` is shorter than `O::KindLenField`.
1794                None => return Err(O::Error::SEQUENCE_FORMAT_ERROR),
1795                Some(k) => {
1796                    // Can't do pattern matching with associated constants, so
1797                    // do it the good-ol' way:
1798                    if Some(*k) == O::NOP {
1799                        continue;
1800                    } else if Some(*k) == O::END_OF_OPTIONS {
1801                        return Ok(ParsedRecord::Done);
1802                    }
1803                    k
1804                }
1805            };
1806            let body_len = match bytes.take_obj_front::<O::KindLenField>() {
1807                None => return Err(O::Error::SEQUENCE_FORMAT_ERROR),
1808                Some(len) => O::LENGTH_ENCODING
1809                    .decode_length::<O::KindLenField>(*len)
1810                    .ok_or(O::Error::SEQUENCE_FORMAT_ERROR)?,
1811            };
1812
1813            let option_data = bytes.take_front(body_len).ok_or(O::Error::SEQUENCE_FORMAT_ERROR)?;
1814            match O::parse(*kind, option_data) {
1815                Ok(Some(o)) => return Ok(ParsedRecord::Parsed(o)),
1816                Ok(None) => {}
1817                Err(err) => return Err(err),
1818            }
1819        }
1820    }
1821
1822    #[cfg(test)]
1823    mod tests {
1824        use core::convert::TryInto as _;
1825        use core::fmt::Debug;
1826
1827        use zerocopy::byteorder::network_endian::U16;
1828
1829        use super::*;
1830        use crate::{NoOpSerializationContext, Serializer};
1831
1832        #[derive(Debug)]
1833        struct DummyOptionsImpl;
1834
1835        #[derive(Debug)]
1836        struct DummyOption {
1837            kind: u8,
1838            data: Vec<u8>,
1839        }
1840
1841        impl OptionLayout for DummyOptionsImpl {
1842            type KindLenField = u8;
1843        }
1844
1845        impl OptionParseLayout for DummyOptionsImpl {
1846            type Error = OptionParseErr;
1847            const END_OF_OPTIONS: Option<u8> = Some(0);
1848            const NOP: Option<u8> = Some(1);
1849        }
1850
1851        impl OptionsImpl for DummyOptionsImpl {
1852            type Option<'a> = DummyOption;
1853
1854            fn parse<'a>(
1855                kind: u8,
1856                data: &'a [u8],
1857            ) -> Result<Option<Self::Option<'a>>, OptionParseErr> {
1858                let mut v = Vec::new();
1859                v.extend_from_slice(data);
1860                Ok(Some(DummyOption { kind, data: v }))
1861            }
1862        }
1863
1864        impl OptionBuilder for DummyOption {
1865            type Layout = DummyOptionsImpl;
1866
1867            fn serialized_len(&self) -> usize {
1868                self.data.len()
1869            }
1870
1871            fn option_kind(&self) -> u8 {
1872                self.kind
1873            }
1874
1875            fn serialize_into(&self, data: &mut [u8]) {
1876                assert_eq!(data.len(), OptionBuilder::serialized_len(self));
1877                data.copy_from_slice(&self.data);
1878            }
1879        }
1880
1881        impl AlignedOptionBuilder for DummyOption {
1882            // For our `DummyOption`, we simply regard (length, kind) as their
1883            // alignment requirement.
1884            fn alignment_requirement(&self) -> (usize, usize) {
1885                (self.data.len(), self.kind as usize)
1886            }
1887
1888            fn serialize_padding(buf: &mut [u8], length: usize) {
1889                assert!(length <= buf.len());
1890                assert!(length <= (std::u8::MAX as usize) + 2);
1891
1892                if length == 1 {
1893                    // Use Pad1
1894                    buf[0] = 0
1895                } else if length > 1 {
1896                    // Use PadN
1897                    buf[0] = 1;
1898                    buf[1] = (length - 2) as u8;
1899                    for i in 2..length {
1900                        buf[i] = 0
1901                    }
1902                }
1903            }
1904        }
1905
1906        #[derive(Debug, Eq, PartialEq)]
1907        enum AlwaysErrorErr {
1908            Sequence,
1909            Option,
1910        }
1911
1912        impl From<Never> for AlwaysErrorErr {
1913            fn from(err: Never) -> AlwaysErrorErr {
1914                match err {}
1915            }
1916        }
1917
1918        impl OptionParseError for AlwaysErrorErr {
1919            const SEQUENCE_FORMAT_ERROR: AlwaysErrorErr = AlwaysErrorErr::Sequence;
1920        }
1921
1922        #[derive(Debug)]
1923        struct AlwaysErrOptionsImpl;
1924
1925        impl OptionLayout for AlwaysErrOptionsImpl {
1926            type KindLenField = u8;
1927        }
1928
1929        impl OptionParseLayout for AlwaysErrOptionsImpl {
1930            type Error = AlwaysErrorErr;
1931            const END_OF_OPTIONS: Option<u8> = Some(0);
1932            const NOP: Option<u8> = Some(1);
1933        }
1934
1935        impl OptionsImpl for AlwaysErrOptionsImpl {
1936            type Option<'a> = ();
1937
1938            fn parse<'a>(_kind: u8, _data: &'a [u8]) -> Result<Option<()>, AlwaysErrorErr> {
1939                Err(AlwaysErrorErr::Option)
1940            }
1941        }
1942
1943        #[derive(Debug)]
1944        struct DummyNdpOptionsImpl;
1945
1946        #[derive(Debug, PartialEq, Eq)]
1947        struct NdpOption {
1948            kind: u8,
1949            data: Vec<u8>,
1950        }
1951
1952        impl OptionLayout for NdpOption {
1953            type KindLenField = u8;
1954
1955            const LENGTH_ENCODING: LengthEncoding = LengthEncoding::TypeLengthValue {
1956                option_len_multiplier: NonZeroUsize::new(8).unwrap(),
1957            };
1958        }
1959
1960        impl OptionLayout for DummyNdpOptionsImpl {
1961            type KindLenField = u8;
1962
1963            const LENGTH_ENCODING: LengthEncoding = LengthEncoding::TypeLengthValue {
1964                option_len_multiplier: NonZeroUsize::new(8).unwrap(),
1965            };
1966        }
1967
1968        impl OptionParseLayout for DummyNdpOptionsImpl {
1969            type Error = OptionParseErr;
1970
1971            const END_OF_OPTIONS: Option<u8> = None;
1972
1973            const NOP: Option<u8> = None;
1974        }
1975
1976        impl OptionsImpl for DummyNdpOptionsImpl {
1977            type Option<'a> = NdpOption;
1978
1979            fn parse<'a>(
1980                kind: u8,
1981                data: &'a [u8],
1982            ) -> Result<Option<Self::Option<'a>>, OptionParseErr> {
1983                let mut v = Vec::with_capacity(data.len());
1984                v.extend_from_slice(data);
1985                Ok(Some(NdpOption { kind, data: v }))
1986            }
1987        }
1988
1989        impl OptionBuilder for NdpOption {
1990            type Layout = DummyNdpOptionsImpl;
1991
1992            fn serialized_len(&self) -> usize {
1993                self.data.len()
1994            }
1995
1996            fn option_kind(&self) -> u8 {
1997                self.kind
1998            }
1999
2000            fn serialize_into(&self, data: &mut [u8]) {
2001                assert_eq!(data.len(), OptionBuilder::serialized_len(self));
2002                data.copy_from_slice(&self.data)
2003            }
2004        }
2005
2006        #[derive(Debug)]
2007        struct DummyMultiByteKindOptionsImpl;
2008
2009        #[derive(Debug)]
2010        struct MultiByteOption {
2011            kind: U16,
2012            data: Vec<u8>,
2013        }
2014
2015        impl OptionLayout for MultiByteOption {
2016            type KindLenField = U16;
2017        }
2018
2019        impl OptionLayout for DummyMultiByteKindOptionsImpl {
2020            type KindLenField = U16;
2021        }
2022
2023        impl OptionParseLayout for DummyMultiByteKindOptionsImpl {
2024            type Error = OptionParseErr;
2025
2026            const END_OF_OPTIONS: Option<U16> = None;
2027
2028            const NOP: Option<U16> = None;
2029        }
2030
2031        impl OptionsImpl for DummyMultiByteKindOptionsImpl {
2032            type Option<'a> = MultiByteOption;
2033
2034            fn parse<'a>(
2035                kind: U16,
2036                data: &'a [u8],
2037            ) -> Result<Option<Self::Option<'a>>, OptionParseErr> {
2038                let mut v = Vec::with_capacity(data.len());
2039                v.extend_from_slice(data);
2040                Ok(Some(MultiByteOption { kind, data: v }))
2041            }
2042        }
2043
2044        impl OptionBuilder for MultiByteOption {
2045            type Layout = DummyMultiByteKindOptionsImpl;
2046
2047            fn serialized_len(&self) -> usize {
2048                self.data.len()
2049            }
2050
2051            fn option_kind(&self) -> U16 {
2052                self.kind
2053            }
2054
2055            fn serialize_into(&self, data: &mut [u8]) {
2056                data.copy_from_slice(&self.data)
2057            }
2058        }
2059
2060        #[test]
2061        fn test_length_encoding() {
2062            const TLV_1: LengthEncoding = LengthEncoding::TypeLengthValue {
2063                option_len_multiplier: NonZeroUsize::new(1).unwrap(),
2064            };
2065            const TLV_2: LengthEncoding = LengthEncoding::TypeLengthValue {
2066                option_len_multiplier: NonZeroUsize::new(2).unwrap(),
2067            };
2068
2069            // Test LengthEncoding::record_length
2070
2071            // For `ValueOnly`, `record_length` should always add 2 or 4 for the kind
2072            // and length bytes, but never add padding.
2073            assert_eq!(LengthEncoding::ValueOnly.record_length::<u8>(0), Some(2));
2074            assert_eq!(LengthEncoding::ValueOnly.record_length::<u8>(1), Some(3));
2075            assert_eq!(LengthEncoding::ValueOnly.record_length::<u8>(2), Some(4));
2076            assert_eq!(LengthEncoding::ValueOnly.record_length::<u8>(3), Some(5));
2077
2078            assert_eq!(LengthEncoding::ValueOnly.record_length::<U16>(0), Some(4));
2079            assert_eq!(LengthEncoding::ValueOnly.record_length::<U16>(1), Some(5));
2080            assert_eq!(LengthEncoding::ValueOnly.record_length::<U16>(2), Some(6));
2081            assert_eq!(LengthEncoding::ValueOnly.record_length::<U16>(3), Some(7));
2082
2083            // For `TypeLengthValue` with `option_len_multiplier = 1`,
2084            // `record_length` should always add 2 or 4 for the kind and length
2085            // bytes, but never add padding.
2086            assert_eq!(TLV_1.record_length::<u8>(0), Some(2));
2087            assert_eq!(TLV_1.record_length::<u8>(1), Some(3));
2088            assert_eq!(TLV_1.record_length::<u8>(2), Some(4));
2089            assert_eq!(TLV_1.record_length::<u8>(3), Some(5));
2090
2091            assert_eq!(TLV_1.record_length::<U16>(0), Some(4));
2092            assert_eq!(TLV_1.record_length::<U16>(1), Some(5));
2093            assert_eq!(TLV_1.record_length::<U16>(2), Some(6));
2094            assert_eq!(TLV_1.record_length::<U16>(3), Some(7));
2095
2096            // For `TypeLengthValue` with `option_len_multiplier = 2`,
2097            // `record_length` should always add 2 or 4 for the kind and length
2098            // bytes, and add padding if necessary to reach a multiple of 2.
2099            assert_eq!(TLV_2.record_length::<u8>(0), Some(2)); // (0 + 2)
2100            assert_eq!(TLV_2.record_length::<u8>(1), Some(4)); // (1 + 2 + 1)
2101            assert_eq!(TLV_2.record_length::<u8>(2), Some(4)); // (2 + 2)
2102            assert_eq!(TLV_2.record_length::<u8>(3), Some(6)); // (3 + 2 + 1)
2103
2104            assert_eq!(TLV_2.record_length::<U16>(0), Some(4)); // (0 + 4)
2105            assert_eq!(TLV_2.record_length::<U16>(1), Some(6)); // (1 + 4 + 1)
2106            assert_eq!(TLV_2.record_length::<U16>(2), Some(6)); // (2 + 4)
2107            assert_eq!(TLV_2.record_length::<U16>(3), Some(8)); // (3 + 4 + 1)
2108
2109            // Test LengthEncoding::encode_length
2110
2111            fn encode_length<K: KindLenField>(
2112                length_encoding: LengthEncoding,
2113                option_body_len: usize,
2114            ) -> Option<usize> {
2115                length_encoding.encode_length::<K>(option_body_len).map(Into::into)
2116            }
2117
2118            // For `ValueOnly`, `encode_length` should always return the
2119            // argument unmodified.
2120            assert_eq!(encode_length::<u8>(LengthEncoding::ValueOnly, 0), Some(0));
2121            assert_eq!(encode_length::<u8>(LengthEncoding::ValueOnly, 1), Some(1));
2122            assert_eq!(encode_length::<u8>(LengthEncoding::ValueOnly, 2), Some(2));
2123            assert_eq!(encode_length::<u8>(LengthEncoding::ValueOnly, 3), Some(3));
2124
2125            assert_eq!(encode_length::<U16>(LengthEncoding::ValueOnly, 0), Some(0));
2126            assert_eq!(encode_length::<U16>(LengthEncoding::ValueOnly, 1), Some(1));
2127            assert_eq!(encode_length::<U16>(LengthEncoding::ValueOnly, 2), Some(2));
2128            assert_eq!(encode_length::<U16>(LengthEncoding::ValueOnly, 3), Some(3));
2129
2130            // For `TypeLengthValue` with `option_len_multiplier = 1`,
2131            // `encode_length` should always add 2 or 4 for the kind and length
2132            // bytes.
2133            assert_eq!(encode_length::<u8>(TLV_1, 0), Some(2));
2134            assert_eq!(encode_length::<u8>(TLV_1, 1), Some(3));
2135            assert_eq!(encode_length::<u8>(TLV_1, 2), Some(4));
2136            assert_eq!(encode_length::<u8>(TLV_1, 3), Some(5));
2137
2138            assert_eq!(encode_length::<U16>(TLV_1, 0), Some(4));
2139            assert_eq!(encode_length::<U16>(TLV_1, 1), Some(5));
2140            assert_eq!(encode_length::<U16>(TLV_1, 2), Some(6));
2141            assert_eq!(encode_length::<U16>(TLV_1, 3), Some(7));
2142
2143            // For `TypeLengthValue` with `option_len_multiplier = 2`,
2144            // `encode_length` should always add 2 or 4 for the kind and length
2145            // bytes, add padding if necessary to reach a multiple of 2, and
2146            // then divide by 2.
2147            assert_eq!(encode_length::<u8>(TLV_2, 0), Some(1)); // (0 + 2)     / 2
2148            assert_eq!(encode_length::<u8>(TLV_2, 1), Some(2)); // (1 + 2 + 1) / 2
2149            assert_eq!(encode_length::<u8>(TLV_2, 2), Some(2)); // (2 + 2)     / 2
2150            assert_eq!(encode_length::<u8>(TLV_2, 3), Some(3)); // (3 + 2 + 1) / 2
2151
2152            assert_eq!(encode_length::<U16>(TLV_2, 0), Some(2)); // (0 + 4)     / 2
2153            assert_eq!(encode_length::<U16>(TLV_2, 1), Some(3)); // (1 + 4 + 1) / 2
2154            assert_eq!(encode_length::<U16>(TLV_2, 2), Some(3)); // (2 + 4)     / 2
2155            assert_eq!(encode_length::<U16>(TLV_2, 3), Some(4)); // (3 + 4 + 1) / 2
2156
2157            // Test LengthEncoding::decode_length
2158
2159            fn decode_length<K: KindLenField>(
2160                length_encoding: LengthEncoding,
2161                length_field: usize,
2162            ) -> Option<usize> {
2163                length_encoding.decode_length::<K>(length_field.try_into().unwrap())
2164            }
2165
2166            // For `ValueOnly`, `decode_length` should always return the
2167            // argument unmodified.
2168            assert_eq!(decode_length::<u8>(LengthEncoding::ValueOnly, 0), Some(0));
2169            assert_eq!(decode_length::<u8>(LengthEncoding::ValueOnly, 1), Some(1));
2170            assert_eq!(decode_length::<u8>(LengthEncoding::ValueOnly, 2), Some(2));
2171            assert_eq!(decode_length::<u8>(LengthEncoding::ValueOnly, 3), Some(3));
2172
2173            assert_eq!(decode_length::<U16>(LengthEncoding::ValueOnly, 0), Some(0));
2174            assert_eq!(decode_length::<U16>(LengthEncoding::ValueOnly, 1), Some(1));
2175            assert_eq!(decode_length::<U16>(LengthEncoding::ValueOnly, 2), Some(2));
2176            assert_eq!(decode_length::<U16>(LengthEncoding::ValueOnly, 3), Some(3));
2177
2178            // For `TypeLengthValue` with `option_len_multiplier = 1`,
2179            // `decode_length` should always subtract 2 or 4 for the kind and
2180            // length bytes.
2181            assert_eq!(decode_length::<u8>(TLV_1, 0), None);
2182            assert_eq!(decode_length::<u8>(TLV_1, 1), None);
2183            assert_eq!(decode_length::<u8>(TLV_1, 2), Some(0));
2184            assert_eq!(decode_length::<u8>(TLV_1, 3), Some(1));
2185
2186            assert_eq!(decode_length::<U16>(TLV_1, 0), None);
2187            assert_eq!(decode_length::<U16>(TLV_1, 1), None);
2188            assert_eq!(decode_length::<U16>(TLV_1, 2), None);
2189            assert_eq!(decode_length::<U16>(TLV_1, 3), None);
2190            assert_eq!(decode_length::<U16>(TLV_1, 4), Some(0));
2191            assert_eq!(decode_length::<U16>(TLV_1, 5), Some(1));
2192
2193            // For `TypeLengthValue` with `option_len_multiplier = 2`,
2194            // `decode_length` should always multiply by 2 or 4 and then
2195            // subtract 2 for the kind and length bytes.
2196            assert_eq!(decode_length::<u8>(TLV_2, 0), None);
2197            assert_eq!(decode_length::<u8>(TLV_2, 1), Some(0));
2198            assert_eq!(decode_length::<u8>(TLV_2, 2), Some(2));
2199            assert_eq!(decode_length::<u8>(TLV_2, 3), Some(4));
2200
2201            assert_eq!(decode_length::<U16>(TLV_2, 0), None);
2202            assert_eq!(decode_length::<U16>(TLV_2, 1), None);
2203            assert_eq!(decode_length::<U16>(TLV_2, 2), Some(0));
2204            assert_eq!(decode_length::<U16>(TLV_2, 3), Some(2));
2205
2206            // Test end-to-end by creating options implementation with different
2207            // length encodings.
2208
2209            /// Declare a new options impl type with a custom `LENGTH_ENCODING`.
2210            macro_rules! declare_options_impl {
2211                ($opt:ident, $impl:ident, $encoding:expr) => {
2212                    #[derive(Debug)]
2213                    enum $impl {}
2214
2215                    #[derive(Debug, PartialEq)]
2216                    struct $opt {
2217                        kind: u8,
2218                        data: Vec<u8>,
2219                    }
2220
2221                    impl<'a> From<&'a (u8, Vec<u8>)> for $opt {
2222                        fn from((kind, data): &'a (u8, Vec<u8>)) -> $opt {
2223                            $opt { kind: *kind, data: data.clone() }
2224                        }
2225                    }
2226
2227                    impl OptionLayout for $opt {
2228                        const LENGTH_ENCODING: LengthEncoding = $encoding;
2229                        type KindLenField = u8;
2230                    }
2231
2232                    impl OptionLayout for $impl {
2233                        const LENGTH_ENCODING: LengthEncoding = $encoding;
2234                        type KindLenField = u8;
2235                    }
2236
2237                    impl OptionParseLayout for $impl {
2238                        type Error = OptionParseErr;
2239                        const END_OF_OPTIONS: Option<u8> = Some(0);
2240                        const NOP: Option<u8> = Some(1);
2241                    }
2242
2243                    impl OptionsImpl for $impl {
2244                        type Option<'a> = $opt;
2245
2246                        fn parse<'a>(
2247                            kind: u8,
2248                            data: &'a [u8],
2249                        ) -> Result<Option<Self::Option<'a>>, OptionParseErr> {
2250                            let mut v = Vec::new();
2251                            v.extend_from_slice(data);
2252                            Ok(Some($opt { kind, data: v }))
2253                        }
2254                    }
2255
2256                    impl OptionBuilder for $opt {
2257                        type Layout = $impl;
2258
2259                        fn serialized_len(&self) -> usize {
2260                            self.data.len()
2261                        }
2262
2263                        fn option_kind(&self) -> u8 {
2264                            self.kind
2265                        }
2266
2267                        fn serialize_into(&self, data: &mut [u8]) {
2268                            assert_eq!(data.len(), OptionBuilder::serialized_len(self));
2269                            data.copy_from_slice(&self.data);
2270                        }
2271                    }
2272                };
2273            }
2274
2275            declare_options_impl!(
2276                DummyImplValueOnly,
2277                DummyImplValueOnlyImpl,
2278                LengthEncoding::ValueOnly
2279            );
2280            declare_options_impl!(DummyImplTlv1, DummyImplTlv1Impl, TLV_1);
2281            declare_options_impl!(DummyImplTlv2, DummyImplTlv2Impl, TLV_2);
2282
2283            /// Tests that a given option is parsed from different byte
2284            /// sequences for different options layouts.
2285            ///
2286            /// Since some options cannot be parsed from any byte sequence using
2287            /// the `DummyImplTlv2` layout (namely, those whose lengths are not
2288            /// a multiple of 2), `tlv_2` may be `None`.
2289            fn test_parse(
2290                (expect_kind, expect_data): (u8, Vec<u8>),
2291                value_only: &[u8],
2292                tlv_1: &[u8],
2293                tlv_2: Option<&[u8]>,
2294            ) {
2295                let options = Options::<_, DummyImplValueOnlyImpl>::parse(value_only)
2296                    .unwrap()
2297                    .iter()
2298                    .collect::<Vec<_>>();
2299                let data = expect_data.clone();
2300                assert_eq!(options, [DummyImplValueOnly { kind: expect_kind, data }]);
2301
2302                let options = Options::<_, DummyImplTlv1Impl>::parse(tlv_1)
2303                    .unwrap()
2304                    .iter()
2305                    .collect::<Vec<_>>();
2306                let data = expect_data.clone();
2307                assert_eq!(options, [DummyImplTlv1 { kind: expect_kind, data }]);
2308
2309                if let Some(tlv_2) = tlv_2 {
2310                    let options = Options::<_, DummyImplTlv2Impl>::parse(tlv_2)
2311                        .unwrap()
2312                        .iter()
2313                        .collect::<Vec<_>>();
2314                    assert_eq!(options, [DummyImplTlv2 { kind: expect_kind, data: expect_data }]);
2315                }
2316            }
2317
2318            // 0-byte body
2319            test_parse((0xFF, vec![]), &[0xFF, 0], &[0xFF, 2], Some(&[0xFF, 1]));
2320            // 1-byte body
2321            test_parse((0xFF, vec![0]), &[0xFF, 1, 0], &[0xFF, 3, 0], None);
2322            // 2-byte body
2323            test_parse(
2324                (0xFF, vec![0, 1]),
2325                &[0xFF, 2, 0, 1],
2326                &[0xFF, 4, 0, 1],
2327                Some(&[0xFF, 2, 0, 1]),
2328            );
2329            // 3-byte body
2330            test_parse((0xFF, vec![0, 1, 2]), &[0xFF, 3, 0, 1, 2], &[0xFF, 5, 0, 1, 2], None);
2331            // 4-byte body
2332            test_parse(
2333                (0xFF, vec![0, 1, 2, 3]),
2334                &[0xFF, 4, 0, 1, 2, 3],
2335                &[0xFF, 6, 0, 1, 2, 3],
2336                Some(&[0xFF, 3, 0, 1, 2, 3]),
2337            );
2338
2339            /// Tests that an option can be serialized and then parsed in each
2340            /// option layout.
2341            ///
2342            /// In some cases (when the body length is not a multiple of 2), the
2343            /// `DummyImplTlv2` layout will parse a different option than was
2344            /// originally serialized. In this case, `expect_tlv_2` can be used
2345            /// to provide a different value to expect as the result of parsing.
2346            fn test_serialize_parse(opt: (u8, Vec<u8>), expect_tlv_2: Option<(u8, Vec<u8>)>) {
2347                let opts = [opt.clone()];
2348
2349                fn test_serialize_parse_inner<
2350                    O: OptionBuilder + Debug + PartialEq + for<'a> From<&'a (u8, Vec<u8>)>,
2351                    I: for<'a> OptionsImpl<Error = OptionParseErr, Option<'a> = O> + std::fmt::Debug,
2352                >(
2353                    opts: &[(u8, Vec<u8>)],
2354                    expect: &[(u8, Vec<u8>)],
2355                ) {
2356                    let opts = opts.iter().map(Into::into).collect::<Vec<_>>();
2357                    let expect = expect.iter().map(Into::into).collect::<Vec<_>>();
2358
2359                    let ser = OptionSequenceBuilder::<O, _>::new(opts.iter());
2360                    let serialized = ser
2361                        .into_serializer()
2362                        .serialize_vec_outer(&mut NoOpSerializationContext)
2363                        .unwrap()
2364                        .as_ref()
2365                        .to_vec();
2366                    let options = Options::<_, I>::parse(serialized.as_slice())
2367                        .unwrap()
2368                        .iter()
2369                        .collect::<Vec<_>>();
2370                    assert_eq!(options, expect);
2371                }
2372
2373                test_serialize_parse_inner::<DummyImplValueOnly, DummyImplValueOnlyImpl>(
2374                    &opts, &opts,
2375                );
2376                test_serialize_parse_inner::<DummyImplTlv1, DummyImplTlv1Impl>(&opts, &opts);
2377                let expect = if let Some(expect) = expect_tlv_2 { expect } else { opt };
2378                test_serialize_parse_inner::<DummyImplTlv2, DummyImplTlv2Impl>(&opts, &[expect]);
2379            }
2380
2381            // 0-byte body
2382            test_serialize_parse((0xFF, vec![]), None);
2383            // 1-byte body
2384            test_serialize_parse((0xFF, vec![0]), Some((0xFF, vec![0, 0])));
2385            // 2-byte body
2386            test_serialize_parse((0xFF, vec![0, 1]), None);
2387            // 3-byte body
2388            test_serialize_parse((0xFF, vec![0, 1, 2]), Some((0xFF, vec![0, 1, 2, 0])));
2389            // 4-byte body
2390            test_serialize_parse((0xFF, vec![0, 1, 2, 3]), None);
2391        }
2392
2393        #[test]
2394        fn test_empty_options() {
2395            // all END_OF_OPTIONS
2396            let bytes = [0; 64];
2397            let options = Options::<_, DummyOptionsImpl>::parse(&bytes[..]).unwrap();
2398            assert_eq!(options.iter().count(), 0);
2399
2400            // all NOP
2401            let bytes = [1; 64];
2402            let options = Options::<_, DummyOptionsImpl>::parse(&bytes[..]).unwrap();
2403            assert_eq!(options.iter().count(), 0);
2404        }
2405
2406        #[test]
2407        fn test_parse() {
2408            // Construct byte sequences in the pattern [3, 2], [4, 3, 2], [5, 4,
2409            // 3, 2], etc. The second byte is the length byte, so these are all
2410            // valid options (with data [], [2], [3, 2], etc).
2411            let mut bytes = Vec::new();
2412            for i in 4..16 {
2413                // from the user's perspective, these NOPs should be transparent
2414                bytes.push(1);
2415                for j in (2..i).rev() {
2416                    bytes.push(j);
2417                }
2418                // from the user's perspective, these NOPs should be transparent
2419                bytes.push(1);
2420            }
2421
2422            let options = Options::<_, DummyOptionsImpl>::parse(bytes.as_slice()).unwrap();
2423            for (idx, DummyOption { kind, data }) in options.iter().enumerate() {
2424                assert_eq!(kind as usize, idx + 3);
2425                assert_eq!(data.len(), idx);
2426                let mut bytes = Vec::new();
2427                for i in (2..(idx + 2)).rev() {
2428                    bytes.push(i as u8);
2429                }
2430                assert_eq!(data, bytes);
2431            }
2432
2433            // Test that we get no parse errors so long as
2434            // AlwaysErrOptionsImpl::parse is never called.
2435            //
2436            // `bytes` is a sequence of NOPs.
2437            let bytes = [1; 64];
2438            let options = Options::<_, AlwaysErrOptionsImpl>::parse(&bytes[..]).unwrap();
2439            assert_eq!(options.iter().count(), 0);
2440        }
2441
2442        #[test]
2443        fn test_parse_ndp_options() {
2444            let mut bytes = Vec::new();
2445            for i in 0..16 {
2446                bytes.push(i);
2447                // NDP uses len*8 for the actual length.
2448                bytes.push(i + 1);
2449                // Write remaining 6 bytes.
2450                for j in 2..((i + 1) * 8) {
2451                    bytes.push(j)
2452                }
2453            }
2454
2455            let options = Options::<_, DummyNdpOptionsImpl>::parse(bytes.as_slice()).unwrap();
2456            for (idx, NdpOption { kind, data }) in options.iter().enumerate() {
2457                assert_eq!(kind as usize, idx);
2458                assert_eq!(data.len(), ((idx + 1) * 8) - 2);
2459                let mut bytes = Vec::new();
2460                for i in 2..((idx + 1) * 8) {
2461                    bytes.push(i as u8);
2462                }
2463                assert_eq!(data, bytes);
2464            }
2465        }
2466
2467        #[test]
2468        fn test_parse_err() {
2469            // the length byte is too short
2470            let bytes = [2, 1];
2471            assert_eq!(
2472                Options::<_, DummyOptionsImpl>::parse(&bytes[..]).unwrap_err(),
2473                OptionParseErr
2474            );
2475
2476            // the length byte is 0 (similar check to above, but worth
2477            // explicitly testing since this was a bug in the Linux kernel:
2478            // https://bugzilla.redhat.com/show_bug.cgi?id=1622404)
2479            let bytes = [2, 0];
2480            assert_eq!(
2481                Options::<_, DummyOptionsImpl>::parse(&bytes[..]).unwrap_err(),
2482                OptionParseErr
2483            );
2484
2485            // the length byte is too long
2486            let bytes = [2, 3];
2487            assert_eq!(
2488                Options::<_, DummyOptionsImpl>::parse(&bytes[..]).unwrap_err(),
2489                OptionParseErr
2490            );
2491
2492            // the buffer is fine, but the implementation returns a parse error
2493            let bytes = [2, 2];
2494            assert_eq!(
2495                Options::<_, AlwaysErrOptionsImpl>::parse(&bytes[..]).unwrap_err(),
2496                AlwaysErrorErr::Option,
2497            );
2498        }
2499
2500        #[test]
2501        fn test_missing_length_bytes() {
2502            // Construct a sequence with a valid record followed by an
2503            // incomplete one, where `kind` is specified but `len` is missing.
2504            // So we can assert that we'll fail cleanly in that case.
2505            //
2506            // Added as part of Change-Id
2507            // Ibd46ac7384c7c5e0d74cb344b48c88876c351b1a.
2508            //
2509            // Before the small refactor in the Change-Id above, there was a
2510            // check during parsing that guaranteed that the length of the
2511            // remaining buffer was >= 1, but it should've been a check for
2512            // >= 2, and the case below would have caused it to panic while
2513            // trying to access the length byte, which was a DoS vulnerability.
2514            assert_matches::assert_matches!(
2515                Options::<_, DummyOptionsImpl>::parse(&[0x03, 0x03, 0x01, 0x03][..]),
2516                Err(OptionParseErr)
2517            );
2518        }
2519
2520        #[test]
2521        fn test_partial_kind_field() {
2522            // Construct a sequence with only one byte where a two-byte kind
2523            // field is expected.
2524            //
2525            // Added as part of Change-Id
2526            // I468121f5712b73c4e704460f580f166c876ee7d6.
2527            //
2528            // Before the small refactor in the Change-Id above, we treated any
2529            // failure to consume the kind field from the byte slice as
2530            // indicating that there were no bytes left, and we would stop
2531            // parsing successfully. This logic was correct when we only
2532            // supported 1-byte kind fields, but it became incorrect once we
2533            // introduced multi-byte kind fields.
2534            assert_matches::assert_matches!(
2535                Options::<_, DummyMultiByteKindOptionsImpl>::parse(&[0x00][..]),
2536                Err(OptionParseErr)
2537            );
2538        }
2539
2540        #[test]
2541        fn test_parse_and_serialize() {
2542            // Construct byte sequences in the pattern [3, 2], [4, 3, 2], [5, 4,
2543            // 3, 2], etc. The second byte is the length byte, so these are all
2544            // valid options (with data [], [2], [3, 2], etc).
2545            let mut bytes = Vec::new();
2546            for i in 4..16 {
2547                // from the user's perspective, these NOPs should be transparent
2548                for j in (2..i).rev() {
2549                    bytes.push(j);
2550                }
2551            }
2552
2553            let options = Options::<_, DummyOptionsImpl>::parse(bytes.as_slice()).unwrap();
2554
2555            let collected = options.iter().collect::<Vec<_>>();
2556            // Pass `collected.iter()` instead of `options.iter()` since we need
2557            // an iterator over references, and `options.iter()` produces an
2558            // iterator over values.
2559            let ser = OptionSequenceBuilder::<DummyOption, _>::new(collected.iter());
2560
2561            let serialized = ser
2562                .into_serializer()
2563                .serialize_vec_outer(&mut NoOpSerializationContext)
2564                .unwrap()
2565                .as_ref()
2566                .to_vec();
2567
2568            assert_eq!(serialized, bytes);
2569        }
2570
2571        fn test_ndp_bytes() -> Vec<u8> {
2572            let mut bytes = Vec::new();
2573            for i in 0..16 {
2574                bytes.push(i);
2575                // NDP uses len*8 for the actual length.
2576                bytes.push(i + 1);
2577                // Write remaining 6 bytes.
2578                for j in 2..((i + 1) * 8) {
2579                    bytes.push(j)
2580                }
2581            }
2582            bytes
2583        }
2584
2585        #[test]
2586        fn test_parse_and_serialize_ndp() {
2587            let bytes = test_ndp_bytes();
2588            let options = Options::<_, DummyNdpOptionsImpl>::parse(bytes.as_slice()).unwrap();
2589            let collected = options.iter().collect::<Vec<_>>();
2590            // Pass `collected.iter()` instead of `options.iter()` since we need
2591            // an iterator over references, and `options.iter()` produces an
2592            // iterator over values.
2593            let ser = OptionSequenceBuilder::<NdpOption, _>::new(collected.iter());
2594
2595            let serialized = ser
2596                .into_serializer()
2597                .serialize_vec_outer(&mut NoOpSerializationContext)
2598                .unwrap()
2599                .as_ref()
2600                .to_vec();
2601
2602            assert_eq!(serialized, bytes);
2603        }
2604
2605        #[test]
2606        fn measure_ndp_records() {
2607            let bytes = test_ndp_bytes();
2608            let options = Options::<_, DummyNdpOptionsImpl>::parse(bytes.as_slice()).unwrap();
2609            let collected = options.iter().collect::<Vec<_>>();
2610
2611            for (i, mut bytes) in options.iter_bytes().enumerate() {
2612                // Each byte slice we iterate over should parse as the equivalent NDP option.
2613                let parsed = <DummyNdpOptionsImpl as RecordsImpl>::parse_with_context(
2614                    &mut &mut bytes,
2615                    &mut (),
2616                )
2617                .expect("should parse successfully");
2618                let option = match parsed {
2619                    ParsedRecord::Parsed(option) => option,
2620                    ParsedRecord::Skipped => panic!("no options should be skipped"),
2621                    ParsedRecord::Done => panic!("should not be done"),
2622                };
2623                assert_eq!(option, collected[i]);
2624
2625                // The byte slice should be exhausted after re-parsing the record.
2626                assert_eq!(bytes, &[]);
2627            }
2628        }
2629
2630        #[test]
2631        fn test_parse_and_serialize_multi_byte_fields() {
2632            let mut bytes = Vec::new();
2633            for i in 4..16 {
2634                // Push kind U16<NetworkEndian>.
2635                bytes.push(0);
2636                bytes.push(i);
2637                // Push length U16<NetworkEndian>.
2638                bytes.push(0);
2639                bytes.push(i);
2640                // Write `i` - 4 bytes.
2641                for j in 4..i {
2642                    bytes.push(j);
2643                }
2644            }
2645
2646            let options =
2647                Options::<_, DummyMultiByteKindOptionsImpl>::parse(bytes.as_slice()).unwrap();
2648            for (idx, MultiByteOption { kind, data }) in options.iter().enumerate() {
2649                assert_eq!(usize::from(kind), idx + 4);
2650                let idx: u8 = idx.try_into().unwrap();
2651                let bytes: Vec<_> = (4..(idx + 4)).collect();
2652                assert_eq!(data, bytes);
2653            }
2654
2655            let collected = options.iter().collect::<Vec<_>>();
2656            // Pass `collected.iter()` instead of `options.iter()` since we need
2657            // an iterator over references, and `options.iter()` produces an
2658            // iterator over values.
2659            let ser = OptionSequenceBuilder::<MultiByteOption, _>::new(collected.iter());
2660            let mut output = vec![0u8; ser.serialized_len()];
2661            ser.serialize_into(output.as_mut_slice());
2662            assert_eq!(output, bytes);
2663        }
2664
2665        #[test]
2666        fn test_align_up_to() {
2667            // We are doing some sort of property testing here:
2668            // We generate a random alignment requirement (x, y) and a random offset `pos`.
2669            // The resulting `new_pos` must:
2670            //   - 1. be at least as large as the original `pos`.
2671            //   - 2. be in form of x * n + y for some integer n.
2672            //   - 3. for any number in between, they shouldn't be in form of x * n + y.
2673            use rand::Rng;
2674            let mut rng = rand::rng();
2675            for _ in 0..100_000 {
2676                let x = rng.random_range(1usize..256);
2677                let y = rng.random_range(0..x);
2678                let pos = rng.random_range(0usize..65536);
2679                let new_pos = align_up_to(pos, x, y);
2680                // 1)
2681                assert!(new_pos >= pos);
2682                // 2)
2683                assert_eq!((new_pos - y) % x, 0);
2684                // 3) Note: `p` is not guaranteed to be bigger than `y`, plus `x` to avoid overflow.
2685                assert!((pos..new_pos).all(|p| (p + x - y) % x != 0))
2686            }
2687        }
2688
2689        #[test]
2690        #[rustfmt::skip]
2691        fn test_aligned_dummy_options_serializer() {
2692            // testing for cases: 2n+{0,1}, 3n+{1,2}, 1n+0, 4n+2
2693            let dummy_options = [
2694                // alignment requirement: 2 * n + 1,
2695                //
2696                DummyOption { kind: 1, data: vec![42, 42] },
2697                DummyOption { kind: 0, data: vec![42, 42] },
2698                DummyOption { kind: 1, data: vec![1, 2, 3] },
2699                DummyOption { kind: 2, data: vec![3, 2, 1] },
2700                DummyOption { kind: 0, data: vec![42] },
2701                DummyOption { kind: 2, data: vec![9, 9, 9, 9] },
2702            ];
2703            let ser = AlignedRecordSequenceBuilder::<DummyOption, _>::new(
2704                0,
2705                dummy_options.iter(),
2706            );
2707            assert_eq!(ser.serialized_len(), 32);
2708            let mut buf = [0u8; 32];
2709            ser.serialize_into(&mut buf[..]);
2710            assert_eq!(
2711                &buf[..],
2712                &[
2713                    0, // Pad1 padding
2714                    1, 4, 42, 42, // (1, [42, 42]) starting at 2 * 0 + 1 = 3
2715                    0,  // Pad1 padding
2716                    0, 4, 42, 42, // (0, [42, 42]) starting at 2 * 3 + 0 = 6
2717                    1, 5, 1, 2, 3, // (1, [1, 2, 3]) starting at 3 * 2 + 1 = 7
2718                    1, 0, // PadN padding
2719                    2, 5, 3, 2, 1, // (2, [3, 2, 1]) starting at 3 * 4 + 2 = 14
2720                    0, 3, 42, // (0, [42]) starting at 1 * 19 + 0 = 19
2721                    0,  // PAD1 padding
2722                    2, 6, 9, 9, 9, 9 // (2, [9, 9, 9, 9]) starting at 4 * 6 + 2 = 26
2723                    // total length: 32
2724                ]
2725            );
2726        }
2727    }
2728}