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