packet/
records.rs

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