packet/records.rs
1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Utilities for parsing and serializing sequential records.
6//!
7//! This module provides utilities for parsing and serializing repeated,
8//! sequential records. Examples of packet formats which include such records
9//! include IPv4, IPv6, TCP, NDP, and IGMP.
10//!
11//! The utilities in this module are very flexible and generic. The user must
12//! supply a number of details about the format in order for parsing and
13//! serializing to work.
14//!
15//! Some packet formats use a [type-length-value]-like encoding for options.
16//! Examples include IPv4, TCP, and NDP options. Special support for these
17//! formats is provided by the [`options`] submodule.
18//!
19//! [type-length-value]: https://en.wikipedia.org/wiki/Type-length-value
20
21use core::borrow::Borrow;
22use core::convert::Infallible as Never;
23use core::marker::PhantomData;
24use core::num::NonZeroUsize;
25use core::ops::Deref;
26
27use zerocopy::{ByteSlice, IntoByteSlice, SplitByteSlice};
28
29use crate::serialize::InnerPacketBuilder;
30use crate::util::{FromRaw, MaybeParsed};
31use crate::{BufferView, BufferViewMut, SplitByteSliceBufView};
32
33/// A type that encapsuates the result of a record parsing operation.
34pub type RecordParseResult<T, E> = core::result::Result<ParsedRecord<T>, E>;
35
36/// A type that encapsulates the successful result of a parsing operation.
37pub enum ParsedRecord<T> {
38 /// A record was successfully consumed and parsed.
39 Parsed(T),
40
41 /// A record was consumed but not parsed for non-fatal reasons.
42 ///
43 /// The caller should attempt to parse the next record to get a successfully
44 /// parsed record.
45 ///
46 /// An example of a record that is skippable is a record used for padding.
47 Skipped,
48
49 /// All possible records have been already been consumed; there is nothing
50 /// left to parse.
51 ///
52 /// The behavior is unspecified if callers attempt to parse another record.
53 Done,
54}
55
56impl<T> ParsedRecord<T> {
57 /// Does this result indicate that a record was consumed?
58 ///
59 /// Returns `true` for `Parsed` and `Skipped` and `false` for `Done`.
60 pub fn consumed(&self) -> bool {
61 match self {
62 ParsedRecord::Parsed(_) | ParsedRecord::Skipped => true,
63 ParsedRecord::Done => false,
64 }
65 }
66}
67
68/// A type that encapsulates the result of measuring the next record.
69pub enum MeasuredRecord {
70 /// A record was measured. This record may be skipped once it is actually parsed.
71 Measured(NonZeroUsize),
72 /// All possible records have been already been consumed; there is nothing
73 /// left to parse.
74 Done,
75}
76
77/// A parsed sequence of records.
78///
79/// `Records` represents a pre-parsed sequence of records whose structure is
80/// enforced by the impl in `R`.
81#[derive(Debug, PartialEq)]
82pub struct Records<B, R: RecordsImplLayout> {
83 bytes: B,
84 record_count: usize,
85 context: R::Context,
86}
87
88/// An unchecked sequence of records.
89///
90/// `RecordsRaw` represents a not-yet-parsed and not-yet-validated sequence of
91/// records, whose structure is enforced by the impl in `R`.
92///
93/// [`Records`] provides an implementation of [`FromRaw`] that can be used to
94/// validate a `RecordsRaw`.
95#[derive(Debug)]
96pub struct RecordsRaw<B, R: RecordsImplLayout> {
97 bytes: B,
98 context: R::Context,
99}
100
101impl<B, R> RecordsRaw<B, R>
102where
103 R: RecordsImplLayout<Context = ()>,
104{
105 /// Creates a new `RecordsRaw` with the data in `bytes`.
106 pub fn new(bytes: B) -> Self {
107 Self { bytes, context: () }
108 }
109}
110
111impl<B, R> RecordsRaw<B, R>
112where
113 R: for<'a> RecordsRawImpl<'a>,
114 B: SplitByteSlice,
115{
116 /// Raw-parses a sequence of records with a context.
117 ///
118 /// See [`RecordsRaw::parse_raw_with_mut_context`] for details on `bytes`,
119 /// `context`, and return value. `parse_raw_with_context` just calls
120 /// `parse_raw_with_mut_context` with a mutable reference to the `context`
121 /// which is passed by value to this function.
122 pub fn parse_raw_with_context<BV: BufferView<B>>(
123 bytes: &mut BV,
124 mut context: R::Context,
125 ) -> MaybeParsed<Self, (B, R::Error)> {
126 Self::parse_raw_with_mut_context(bytes, &mut context)
127 }
128
129 /// Raw-parses a sequence of records with a mutable context.
130 ///
131 /// `parse_raw_with_mut_context` shallowly parses `bytes` as a sequence of
132 /// records. `context` may be used by implementers to maintain state.
133 ///
134 /// `parse_raw_with_mut_context` performs a single pass over all of the
135 /// records to be able to find the end of the records list and update
136 /// `bytes` accordingly. Upon return with [`MaybeParsed::Complete`],
137 /// `bytes` will include only those bytes which are not part of the records
138 /// list. Upon return with [`MaybeParsed::Incomplete`], `bytes` will still
139 /// contain the bytes which could not be parsed, and all subsequent bytes.
140 pub fn parse_raw_with_mut_context<BV: BufferView<B>>(
141 bytes: &mut BV,
142 context: &mut R::Context,
143 ) -> MaybeParsed<Self, (B, R::Error)> {
144 let c = context.clone();
145 let mut b = SplitSliceBufferView::new(bytes.as_ref());
146 let r = loop {
147 match R::parse_raw_with_context(&mut b, context) {
148 Ok(true) => {} // continue consuming from data
149 Ok(false) => {
150 break None;
151 }
152 Err(e) => {
153 break Some(e);
154 }
155 }
156 };
157
158 // When we get here, we know that whatever is left in `b` is not needed
159 // so we only take the amount of bytes we actually need from `bytes`,
160 // leaving the rest alone for the caller to continue parsing with.
161 let bytes_len = bytes.len();
162 let b_len = b.as_ref().len();
163 let taken = bytes.take_front(bytes_len - b_len).unwrap();
164
165 match r {
166 Some(error) => MaybeParsed::Incomplete((taken, error)),
167 None => MaybeParsed::Complete(RecordsRaw { bytes: taken, context: c }),
168 }
169 }
170}
171
172impl<B, R> RecordsRaw<B, R>
173where
174 R: for<'a> RecordsRawImpl<'a> + RecordsImplLayout<Context = ()>,
175 B: SplitByteSlice,
176{
177 /// Raw-parses a sequence of records.
178 ///
179 /// Equivalent to calling [`RecordsRaw::parse_raw_with_context`] with
180 /// `context = ()`.
181 pub fn parse_raw<BV: BufferView<B>>(bytes: &mut BV) -> MaybeParsed<Self, (B, R::Error)> {
182 Self::parse_raw_with_context(bytes, ())
183 }
184}
185
186impl<B, R> Deref for RecordsRaw<B, R>
187where
188 B: SplitByteSlice,
189 R: RecordsImplLayout,
190{
191 type Target = [u8];
192
193 fn deref(&self) -> &[u8] {
194 self.bytes.deref()
195 }
196}
197
198impl<B: Deref<Target = [u8]>, R: RecordsImplLayout> RecordsRaw<B, R> {
199 /// Gets the underlying bytes.
200 ///
201 /// `bytes` returns a reference to the byte slice backing this `RecordsRaw`.
202 pub fn bytes(&self) -> &[u8] {
203 &self.bytes
204 }
205}
206
207/// An iterator over the records contained inside a [`Records`] instance.
208#[derive(Copy, Clone, Debug)]
209pub struct RecordsIter<'a, B, R: RecordsImpl> {
210 bytes: B,
211 records_left: usize,
212 context: R::Context,
213 _marker: PhantomData<&'a ()>,
214}
215
216/// An iterator over the records bytes contained inside a [`Records`] instance.
217#[derive(Copy, Clone, Debug)]
218pub struct RecordsBytesIter<'a, B, R: RecordsImpl> {
219 bytes: B,
220 context: R::Context,
221 _marker: PhantomData<&'a ()>,
222}
223
224/// The 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::new(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::new(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 (bytes.into_inner(), result)
884 })
885 }
886
887 fn size_hint(&self) -> (usize, Option<usize>) {
888 (self.records_left, Some(self.records_left))
889 }
890}
891
892impl<'a, B, R> ExactSizeIterator for RecordsIter<'a, B, R>
893where
894 R: RecordsImpl,
895 B: SplitByteSlice + IntoByteSlice<'a>,
896{
897 fn len(&self) -> usize {
898 self.records_left
899 }
900}
901
902impl<'a, B, R> RecordsBytesIter<'a, B, R>
903where
904 R: RecordsImpl,
905{
906 /// Gets a reference to the context.
907 pub fn context(&self) -> &R::Context {
908 &self.context
909 }
910}
911
912impl<'a, B, R> Iterator for RecordsBytesIter<'a, B, R>
913where
914 R: MeasureRecordsImpl,
915 B: SplitByteSlice + IntoByteSlice<'a>,
916{
917 type Item = &'a [u8];
918
919 fn next(&mut self) -> Option<&'a [u8]> {
920 replace_with::replace_with_and(&mut self.bytes, |bytes| {
921 let mut bytes = SplitSliceBufferView::new(bytes);
922 // use match rather than expect because expect requires that Err: Debug
923 #[allow(clippy::match_wild_err_arm)]
924 let result = match next_bytes::<_, R>(&mut bytes, &mut self.context) {
925 Ok(o) => o,
926 Err(_) => panic!("already-validated options should not fail to parse"),
927 };
928 (bytes.into_inner(), result)
929 })
930 }
931}
932
933fn next_bytes<'a, BV, R>(
934 bytes: &mut BV,
935 context: &mut R::Context,
936) -> Result<Option<&'a [u8]>, R::Error>
937where
938 R: MeasureRecordsImpl,
939 BV: BufferView<&'a [u8]>,
940{
941 match R::measure_next_record(bytes, context)? {
942 MeasuredRecord::Measured(len) => {
943 let buf = bytes.take_front(len.get()).expect("should have already measured");
944 Ok(Some(buf))
945 }
946 MeasuredRecord::Done => Ok(None),
947 }
948}
949
950/// Gets the next entry for a set of sequential records in `bytes`.
951///
952/// On return, `bytes` will be pointing to the start of where a next record
953/// would be.
954fn next<'a, BV, R>(
955 bytes: &mut BV,
956 context: &mut R::Context,
957) -> Result<Option<R::Record<'a>>, R::Error>
958where
959 R: RecordsImpl,
960 BV: BufferView<&'a [u8]>,
961{
962 loop {
963 // If we're already at 0, don't attempt to parse any more records.
964 let next_lowest_counter_val = match context.counter_mut().next_lowest_value() {
965 Some(val) => val,
966 None => return Ok(None),
967 };
968 match R::parse_with_context(bytes, context)? {
969 ParsedRecord::Done => {
970 return context
971 .counter_mut()
972 .result_for_end_of_records()
973 .map_err(Into::into)
974 .map(|()| None);
975 }
976 ParsedRecord::Skipped => {}
977 ParsedRecord::Parsed(o) => {
978 *context.counter_mut() = next_lowest_counter_val;
979 return Ok(Some(o));
980 }
981 }
982 }
983}
984
985/// Like `SplitByteSliceBufferView`, but with a specialized
986/// `BufferView<&'a [u8]>` implementation.
987struct SplitSliceBufferView<B>(SplitByteSliceBufView<B>);
988
989impl<B> SplitSliceBufferView<B> {
990 fn new(buf: B) -> Self {
991 Self(SplitByteSliceBufView::new(buf))
992 }
993
994 fn into_inner(self) -> B {
995 let Self(buf) = self;
996 buf.into_inner()
997 }
998}
999
1000impl<B: SplitByteSlice> AsRef<[u8]> for SplitSliceBufferView<B> {
1001 fn as_ref(&self) -> &[u8] {
1002 self.0.as_ref()
1003 }
1004}
1005
1006impl<'a, B: SplitByteSlice + IntoByteSlice<'a>> BufferView<&'a [u8]> for SplitSliceBufferView<B> {
1007 fn take_front(&mut self, n: usize) -> Option<&'a [u8]> {
1008 self.0.take_front(n).map(IntoByteSlice::into_byte_slice)
1009 }
1010
1011 fn take_back(&mut self, n: usize) -> Option<&'a [u8]> {
1012 self.0.take_back(n).map(IntoByteSlice::into_byte_slice)
1013 }
1014
1015 fn into_rest(self) -> &'a [u8] {
1016 self.0.into_rest().into_byte_slice()
1017 }
1018}
1019
1020#[cfg(test)]
1021mod tests {
1022 use test_case::test_case;
1023 use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Ref, Unaligned};
1024
1025 use super::*;
1026
1027 const DUMMY_BYTES: [u8; 16] = [
1028 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03,
1029 0x04,
1030 ];
1031
1032 fn get_empty_tuple_mut_ref<'a>() -> &'a mut () {
1033 // This is a hack since `&mut ()` is invalid.
1034 let bytes: &mut [u8] = &mut [];
1035 zerocopy::Ref::into_mut(zerocopy::Ref::<_, ()>::from_bytes(bytes).unwrap())
1036 }
1037
1038 #[derive(Debug, IntoBytes, KnownLayout, FromBytes, Immutable, Unaligned)]
1039 #[repr(C)]
1040 struct DummyRecord {
1041 a: [u8; 2],
1042 b: u8,
1043 c: u8,
1044 }
1045
1046 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1047 enum DummyRecordErr {
1048 Parse,
1049 TooFewRecords,
1050 }
1051
1052 impl From<Never> for DummyRecordErr {
1053 fn from(err: Never) -> DummyRecordErr {
1054 match err {}
1055 }
1056 }
1057
1058 impl From<TooFewRecordsErr> for DummyRecordErr {
1059 fn from(_: TooFewRecordsErr) -> DummyRecordErr {
1060 DummyRecordErr::TooFewRecords
1061 }
1062 }
1063
1064 fn parse_dummy_rec<'a, BV>(
1065 data: &mut BV,
1066 ) -> RecordParseResult<Ref<&'a [u8], DummyRecord>, DummyRecordErr>
1067 where
1068 BV: BufferView<&'a [u8]>,
1069 {
1070 if data.is_empty() {
1071 return Ok(ParsedRecord::Done);
1072 }
1073
1074 match data.take_obj_front::<DummyRecord>() {
1075 Some(res) => Ok(ParsedRecord::Parsed(res)),
1076 None => Err(DummyRecordErr::Parse),
1077 }
1078 }
1079
1080 //
1081 // Context-less records
1082 //
1083
1084 #[derive(Debug)]
1085 struct ContextlessRecordImpl;
1086
1087 impl RecordsImplLayout for ContextlessRecordImpl {
1088 type Context = ();
1089 type Error = DummyRecordErr;
1090 }
1091
1092 impl RecordsImpl for ContextlessRecordImpl {
1093 type Record<'a> = Ref<&'a [u8], DummyRecord>;
1094
1095 fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
1096 data: &mut BV,
1097 _context: &mut Self::Context,
1098 ) -> RecordParseResult<Self::Record<'a>, Self::Error> {
1099 parse_dummy_rec(data)
1100 }
1101 }
1102
1103 //
1104 // Limit context records
1105 //
1106
1107 #[derive(Debug)]
1108 struct LimitContextRecordImpl;
1109
1110 impl RecordsImplLayout for LimitContextRecordImpl {
1111 type Context = usize;
1112 type Error = DummyRecordErr;
1113 }
1114
1115 impl RecordsImpl for LimitContextRecordImpl {
1116 type Record<'a> = Ref<&'a [u8], DummyRecord>;
1117
1118 fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
1119 data: &mut BV,
1120 _context: &mut usize,
1121 ) -> RecordParseResult<Self::Record<'a>, Self::Error> {
1122 parse_dummy_rec(data)
1123 }
1124 }
1125
1126 //
1127 // Filter context records
1128 //
1129
1130 #[derive(Debug)]
1131 struct FilterContextRecordImpl;
1132
1133 #[derive(Clone)]
1134 struct FilterContext {
1135 pub disallowed: [bool; 256],
1136 }
1137
1138 impl RecordsContext for FilterContext {
1139 type Counter = ();
1140 fn counter_mut(&mut self) -> &mut () {
1141 get_empty_tuple_mut_ref()
1142 }
1143 }
1144
1145 impl RecordsImplLayout for FilterContextRecordImpl {
1146 type Context = FilterContext;
1147 type Error = DummyRecordErr;
1148 }
1149
1150 impl core::fmt::Debug for FilterContext {
1151 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1152 write!(f, "FilterContext{{disallowed:{:?}}}", &self.disallowed[..])
1153 }
1154 }
1155
1156 impl RecordsImpl for FilterContextRecordImpl {
1157 type Record<'a> = Ref<&'a [u8], DummyRecord>;
1158
1159 fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
1160 bytes: &mut BV,
1161 context: &mut Self::Context,
1162 ) -> RecordParseResult<Self::Record<'a>, Self::Error> {
1163 if bytes.len() < core::mem::size_of::<DummyRecord>() {
1164 Ok(ParsedRecord::Done)
1165 } else if bytes.as_ref()[0..core::mem::size_of::<DummyRecord>()]
1166 .iter()
1167 .any(|x| context.disallowed[*x as usize])
1168 {
1169 Err(DummyRecordErr::Parse)
1170 } else {
1171 parse_dummy_rec(bytes)
1172 }
1173 }
1174 }
1175
1176 //
1177 // Stateful context records
1178 //
1179
1180 #[derive(Debug)]
1181 struct StatefulContextRecordImpl;
1182
1183 #[derive(Clone, Debug)]
1184 struct StatefulContext {
1185 pub pre_parse_counter: usize,
1186 pub parse_counter: usize,
1187 pub post_parse_counter: usize,
1188 pub iter: bool,
1189 }
1190
1191 impl RecordsImplLayout for StatefulContextRecordImpl {
1192 type Context = StatefulContext;
1193 type Error = DummyRecordErr;
1194 }
1195
1196 impl StatefulContext {
1197 pub fn new() -> StatefulContext {
1198 StatefulContext {
1199 pre_parse_counter: 0,
1200 parse_counter: 0,
1201 post_parse_counter: 0,
1202 iter: false,
1203 }
1204 }
1205 }
1206
1207 impl RecordsContext for StatefulContext {
1208 type Counter = ();
1209
1210 fn clone_for_iter(&self) -> Self {
1211 let mut x = self.clone();
1212 x.iter = true;
1213 x
1214 }
1215
1216 fn counter_mut(&mut self) -> &mut () {
1217 get_empty_tuple_mut_ref()
1218 }
1219 }
1220
1221 impl RecordsImpl for StatefulContextRecordImpl {
1222 type Record<'a> = Ref<&'a [u8], DummyRecord>;
1223
1224 fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
1225 data: &mut BV,
1226 context: &mut Self::Context,
1227 ) -> RecordParseResult<Self::Record<'a>, Self::Error> {
1228 if !context.iter {
1229 context.pre_parse_counter += 1;
1230 }
1231
1232 let ret = parse_dummy_rec_with_context(data, context);
1233
1234 if let Ok(ParsedRecord::Parsed(_)) = ret {
1235 if !context.iter {
1236 context.post_parse_counter += 1;
1237 }
1238 }
1239
1240 ret
1241 }
1242 }
1243
1244 impl<'a> RecordsRawImpl<'a> for StatefulContextRecordImpl {
1245 fn parse_raw_with_context<BV: BufferView<&'a [u8]>>(
1246 data: &mut BV,
1247 context: &mut Self::Context,
1248 ) -> Result<bool, Self::Error> {
1249 Self::parse_with_context(data, context).map(|r| r.consumed())
1250 }
1251 }
1252
1253 fn parse_dummy_rec_with_context<'a, BV>(
1254 data: &mut BV,
1255 context: &mut StatefulContext,
1256 ) -> RecordParseResult<Ref<&'a [u8], DummyRecord>, DummyRecordErr>
1257 where
1258 BV: BufferView<&'a [u8]>,
1259 {
1260 if data.is_empty() {
1261 return Ok(ParsedRecord::Done);
1262 }
1263
1264 if !context.iter {
1265 context.parse_counter += 1;
1266 }
1267
1268 match data.take_obj_front::<DummyRecord>() {
1269 Some(res) => Ok(ParsedRecord::Parsed(res)),
1270 None => Err(DummyRecordErr::Parse),
1271 }
1272 }
1273
1274 fn check_parsed_record(rec: &DummyRecord) {
1275 assert_eq!(rec.a[0], 0x01);
1276 assert_eq!(rec.a[1], 0x02);
1277 assert_eq!(rec.b, 0x03);
1278 }
1279
1280 fn validate_parsed_stateful_context_records<B: SplitByteSlice>(
1281 records: Records<B, StatefulContextRecordImpl>,
1282 context: StatefulContext,
1283 ) {
1284 // Should be 5 because on the last iteration, we should realize that we
1285 // have no more bytes left and end before parsing (also explaining why
1286 // `parse_counter` should only be 4.
1287 assert_eq!(context.pre_parse_counter, 5);
1288 assert_eq!(context.parse_counter, 4);
1289 assert_eq!(context.post_parse_counter, 4);
1290
1291 let mut iter = records.iter();
1292 let context = &iter.context;
1293 assert_eq!(context.pre_parse_counter, 0);
1294 assert_eq!(context.parse_counter, 0);
1295 assert_eq!(context.post_parse_counter, 0);
1296 assert_eq!(context.iter, true);
1297
1298 // Manually iterate over `iter` so as to not move it.
1299 let mut count = 0;
1300 while let Some(_) = iter.next() {
1301 count += 1;
1302 }
1303 assert_eq!(count, 4);
1304
1305 // Check to see that when iterating, the context doesn't update counters
1306 // as that is how we implemented our StatefulContextRecordImpl..
1307 let context = &iter.context;
1308 assert_eq!(context.pre_parse_counter, 0);
1309 assert_eq!(context.parse_counter, 0);
1310 assert_eq!(context.post_parse_counter, 0);
1311 assert_eq!(context.iter, true);
1312 }
1313
1314 #[test]
1315 fn all_records_parsing() {
1316 let parsed = Records::<_, ContextlessRecordImpl>::parse(&DUMMY_BYTES[..]).unwrap();
1317 let mut iter = parsed.iter();
1318 // Test ExactSizeIterator implementation.
1319 assert_eq!(iter.len(), 4);
1320 let mut cnt = 4;
1321 while let Some(_) = iter.next() {
1322 cnt -= 1;
1323 assert_eq!(iter.len(), cnt);
1324 }
1325 assert_eq!(iter.len(), 0);
1326 for rec in parsed.iter() {
1327 check_parsed_record(rec.deref());
1328 }
1329 }
1330
1331 // `expect` is either the number of records that should have been parsed or
1332 // the error returned from the `Records` constructor.
1333 //
1334 // If there are more records than the limit, then we just truncate (not
1335 // parsing all of them) and don't return an error.
1336 #[test_case(0, Ok(0))]
1337 #[test_case(1, Ok(1))]
1338 #[test_case(2, Ok(2))]
1339 #[test_case(3, Ok(3))]
1340 // If there are the same number of records as the limit, then we
1341 // succeed.
1342 #[test_case(4, Ok(4))]
1343 // If there are fewer records than the limit, then we fail.
1344 #[test_case(5, Err(DummyRecordErr::TooFewRecords))]
1345 fn limit_records_parsing(limit: usize, expect: Result<usize, DummyRecordErr>) {
1346 // Test without mutable limit/context
1347 let check_result =
1348 |result: Result<Records<_, LimitContextRecordImpl>, _>| match (expect, result) {
1349 (Ok(expect_parsed), Ok(records)) => {
1350 assert_eq!(records.iter().count(), expect_parsed);
1351 for rec in records.iter() {
1352 check_parsed_record(rec.deref());
1353 }
1354 }
1355 (Err(expect), Err(got)) => assert_eq!(expect, got),
1356 (Ok(expect_parsed), Err(err)) => {
1357 panic!("wanted {expect_parsed} successfully-parsed records; got error {err:?}")
1358 }
1359 (Err(expect), Ok(records)) => panic!(
1360 "wanted error {expect:?}, got {} successfully-parsed records",
1361 records.iter().count()
1362 ),
1363 };
1364
1365 check_result(Records::<_, LimitContextRecordImpl>::parse_with_context(
1366 &DUMMY_BYTES[..],
1367 limit,
1368 ));
1369 let mut mut_limit = limit;
1370 check_result(Records::<_, LimitContextRecordImpl>::parse_with_mut_context(
1371 &DUMMY_BYTES[..],
1372 &mut mut_limit,
1373 ));
1374 if let Ok(expect_parsed) = expect {
1375 assert_eq!(limit - mut_limit, expect_parsed);
1376 }
1377 }
1378
1379 #[test]
1380 fn context_filtering_some_byte_records_parsing() {
1381 // Do not disallow any bytes
1382 let context = FilterContext { disallowed: [false; 256] };
1383 let parsed =
1384 Records::<_, FilterContextRecordImpl>::parse_with_context(&DUMMY_BYTES[..], context)
1385 .unwrap();
1386 assert_eq!(parsed.iter().count(), 4);
1387 for rec in parsed.iter() {
1388 check_parsed_record(rec.deref());
1389 }
1390
1391 // Do not allow byte value 0x01
1392 let mut context = FilterContext { disallowed: [false; 256] };
1393 context.disallowed[1] = true;
1394 assert_eq!(
1395 Records::<_, FilterContextRecordImpl>::parse_with_context(&DUMMY_BYTES[..], context)
1396 .expect_err("fails if the buffer has an element with value 0x01"),
1397 DummyRecordErr::Parse
1398 );
1399 }
1400
1401 #[test]
1402 fn stateful_context_records_parsing() {
1403 let mut context = StatefulContext::new();
1404 let parsed = Records::<_, StatefulContextRecordImpl>::parse_with_mut_context(
1405 &DUMMY_BYTES[..],
1406 &mut context,
1407 )
1408 .unwrap();
1409 validate_parsed_stateful_context_records(parsed, context);
1410 }
1411
1412 #[test]
1413 fn raw_parse_success() {
1414 let mut context = StatefulContext::new();
1415 let mut bv = &mut &DUMMY_BYTES[..];
1416 let result = RecordsRaw::<_, StatefulContextRecordImpl>::parse_raw_with_mut_context(
1417 &mut bv,
1418 &mut context,
1419 )
1420 .complete()
1421 .unwrap();
1422 let RecordsRaw { bytes, context: _ } = &result;
1423 assert_eq!(*bytes, &DUMMY_BYTES[..]);
1424 let parsed = Records::try_from_raw(result).unwrap();
1425 validate_parsed_stateful_context_records(parsed, context);
1426 }
1427
1428 #[test]
1429 fn raw_parse_failure() {
1430 let mut context = StatefulContext::new();
1431 let mut bv = &mut &DUMMY_BYTES[0..15];
1432 let result = RecordsRaw::<_, StatefulContextRecordImpl>::parse_raw_with_mut_context(
1433 &mut bv,
1434 &mut context,
1435 )
1436 .incomplete()
1437 .unwrap();
1438 assert_eq!(result, (&DUMMY_BYTES[0..12], DummyRecordErr::Parse));
1439 }
1440}
1441
1442/// Utilities for parsing the options formats in protocols like IPv4, TCP, and
1443/// NDP.
1444///
1445/// This module provides parsing utilities for [type-length-value]-like records
1446/// encodings like those used by the options in an IPv4 or TCP header or an NDP
1447/// packet. These formats are not identical, but share enough in common that the
1448/// utilities provided here only need a small amount of customization by the
1449/// user to be fully functional.
1450///
1451/// [type-length-value]: https://en.wikipedia.org/wiki/Type-length-value
1452pub mod options {
1453 use core::mem;
1454 use core::num::{NonZeroUsize, TryFromIntError};
1455
1456 use zerocopy::byteorder::ByteOrder;
1457 use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
1458
1459 use super::*;
1460
1461 /// A parsed sequence of options.
1462 ///
1463 /// `Options` represents a parsed sequence of options, for example from an
1464 /// IPv4 or TCP header or an NDP packet. `Options` uses [`Records`] under
1465 /// the hood.
1466 ///
1467 /// [`Records`]: crate::records::Records
1468 pub type Options<B, O> = Records<B, O>;
1469
1470 /// A not-yet-parsed sequence of options.
1471 ///
1472 /// `OptionsRaw` represents a not-yet-parsed and not-yet-validated sequence
1473 /// of options, for example from an IPv4 or TCP header or an NDP packet.
1474 /// `OptionsRaw` uses [`RecordsRaw`] under the hood.
1475 ///
1476 /// [`RecordsRaw`]: crate::records::RecordsRaw
1477 pub type OptionsRaw<B, O> = RecordsRaw<B, O>;
1478
1479 /// A builder capable of serializing a sequence of options.
1480 ///
1481 /// An `OptionSequenceBuilder` is instantiated with an [`Iterator`] that
1482 /// provides [`OptionBuilder`]s to be serialized. The item produced by the
1483 /// iterator can be any type which implements `Borrow<O>` for `O:
1484 /// OptionBuilder`.
1485 ///
1486 /// `OptionSequenceBuilder` implements [`InnerPacketBuilder`].
1487 pub type OptionSequenceBuilder<R, I> = RecordSequenceBuilder<R, I>;
1488
1489 /// A builder capable of serializing a sequence of aligned options.
1490 ///
1491 /// An `AlignedOptionSequenceBuilder` is instantiated with an [`Iterator`]
1492 /// that provides [`AlignedOptionBuilder`]s to be serialized. The item
1493 /// produced by the iterator can be any type which implements `Borrow<O>`
1494 /// for `O: AlignedOptionBuilder`.
1495 ///
1496 /// `AlignedOptionSequenceBuilder` implements [`InnerPacketBuilder`].
1497 pub type AlignedOptionSequenceBuilder<R, I> = AlignedRecordSequenceBuilder<R, I>;
1498
1499 impl<O: OptionsImpl> RecordsImplLayout for O {
1500 type Context = ();
1501 type Error = O::Error;
1502 }
1503
1504 impl<O: OptionsImpl> RecordsImpl for O {
1505 type Record<'a> = O::Option<'a>;
1506
1507 fn parse_with_context<'a, BV: BufferView<&'a [u8]>>(
1508 data: &mut BV,
1509 _context: &mut Self::Context,
1510 ) -> RecordParseResult<Self::Record<'a>, Self::Error> {
1511 next::<_, O>(data)
1512 }
1513 }
1514
1515 impl<O: OptionsImpl> MeasureRecordsImpl for O {
1516 fn measure_next_record<'a, BV: BufferView<&'a [u8]>>(
1517 data: &BV,
1518 _context: &mut Self::Context,
1519 ) -> core::result::Result<MeasuredRecord, Self::Error> {
1520 if data.len() == 0 {
1521 return Ok(MeasuredRecord::Done);
1522 }
1523
1524 // First peek at the kind field.
1525 match data.peek_obj_front::<O::KindLenField>() {
1526 // Thanks to the preceding `if`, we know at this point that
1527 // `data.len() > 0`. If `peek_obj_front` returns `None`, that
1528 // means that `data.len()` is shorter than `O::KindLenField`.
1529 None => return Err(O::Error::SEQUENCE_FORMAT_ERROR),
1530 Some(k) => {
1531 // Can't do pattern matching with associated constants, so
1532 // do it the good-ol' way:
1533 if Some(*k) == O::NOP {
1534 // The next record is a NOP record which is always just
1535 // the kind field itself.
1536 return Ok(MeasuredRecord::Measured(
1537 NonZeroUsize::new(size_of::<O::KindLenField>())
1538 .expect("KindLenField must not be 0-sized"),
1539 ));
1540 } else if Some(*k) == O::END_OF_OPTIONS {
1541 return Ok(MeasuredRecord::Done);
1542 }
1543 }
1544 };
1545
1546 // Then, since we only _peeked_ before, we have to peek again to get
1547 // both the kind field (again) and the length field.
1548 let body_len = match data.peek_obj_front::<[O::KindLenField; 2]>() {
1549 None => return Err(O::Error::SEQUENCE_FORMAT_ERROR),
1550 Some([_kind, len]) => O::LENGTH_ENCODING
1551 .decode_length::<O::KindLenField>(*len)
1552 .ok_or(O::Error::SEQUENCE_FORMAT_ERROR)?,
1553 };
1554 Ok(MeasuredRecord::Measured(
1555 NonZeroUsize::new(
1556 O::LENGTH_ENCODING
1557 .record_length::<O::KindLenField>(body_len)
1558 .expect("record_length(decode_length(..)) should succeed"),
1559 )
1560 .expect("should never get 0-length record"),
1561 ))
1562 }
1563 }
1564
1565 impl<O: OptionBuilder> RecordBuilder for O {
1566 fn serialized_len(&self) -> usize {
1567 // TODO(https://fxbug.dev/42158056): Remove this `.expect`
1568 <O::Layout as OptionLayout>::LENGTH_ENCODING
1569 .record_length::<<O::Layout as OptionLayout>::KindLenField>(
1570 OptionBuilder::serialized_len(self),
1571 )
1572 .expect("integer overflow while computing record length")
1573 }
1574
1575 fn serialize_into(&self, mut data: &mut [u8]) {
1576 // NOTE(brunodalbo) we don't currently support serializing the two
1577 // single-byte options used in TCP and IP: NOP and END_OF_OPTIONS.
1578 // If it is necessary to support those as part of TLV options
1579 // serialization, some changes will be required here.
1580
1581 // So that `data` implements `BufferViewMut`.
1582 let mut data = &mut data;
1583
1584 // Data not having enough space is a contract violation, so we panic
1585 // in that case.
1586 *BufferView::<&mut [u8]>::take_obj_front::<<O::Layout as OptionLayout>::KindLenField>(&mut data)
1587 .expect("buffer too short") = self.option_kind();
1588 let body_len = OptionBuilder::serialized_len(self);
1589 // TODO(https://fxbug.dev/42158056): Remove this `.expect`
1590 let length = <O::Layout as OptionLayout>::LENGTH_ENCODING
1591 .encode_length::<<O::Layout as OptionLayout>::KindLenField>(body_len)
1592 .expect("integer overflow while encoding length");
1593 // Length overflowing `O::Layout::KindLenField` is a contract
1594 // violation, so we panic in that case.
1595 *BufferView::<&mut [u8]>::take_obj_front::<<O::Layout as OptionLayout>::KindLenField>(&mut data)
1596 .expect("buffer too short") = length;
1597 // SECURITY: Because padding may have occurred, we zero-fill data
1598 // before passing it along in order to prevent leaking information
1599 // from packets previously stored in the buffer.
1600 let data = data.into_rest_zero();
1601 // Pass exactly `body_len` bytes even if there is padding.
1602 OptionBuilder::serialize_into(self, &mut data[..body_len]);
1603 }
1604 }
1605
1606 impl<O: AlignedOptionBuilder> AlignedRecordBuilder for O {
1607 fn alignment_requirement(&self) -> (usize, usize) {
1608 // Use the underlying option's alignment requirement as the
1609 // alignment requirement for the record.
1610 AlignedOptionBuilder::alignment_requirement(self)
1611 }
1612
1613 fn serialize_padding(buf: &mut [u8], length: usize) {
1614 <O as AlignedOptionBuilder>::serialize_padding(buf, length);
1615 }
1616 }
1617
1618 /// Whether the length field of an option encodes the length of the entire
1619 /// option (including kind and length fields) or only of the value field.
1620 ///
1621 /// For the `TypeLengthValue` variant, an `option_len_multiplier` may also
1622 /// be specified. Some formats (such as NDP) do not directly encode the
1623 /// length in bytes of each option, but instead encode a number which must
1624 /// be multiplied by `option_len_multiplier` in order to get the length in
1625 /// bytes.
1626 #[derive(Copy, Clone, Eq, PartialEq)]
1627 pub enum LengthEncoding {
1628 TypeLengthValue { option_len_multiplier: NonZeroUsize },
1629 ValueOnly,
1630 }
1631
1632 impl LengthEncoding {
1633 /// Computes the length of an entire option record - including kind and
1634 /// length fields - from the length of an option body.
1635 ///
1636 /// `record_length` takes into account the length of the kind and length
1637 /// fields and also adds any padding required to reach a multiple of
1638 /// `option_len_multiplier`, returning `None` if the value cannot be
1639 /// stored in a `usize`.
1640 fn record_length<F: KindLenField>(self, option_body_len: usize) -> Option<usize> {
1641 let unpadded_len = option_body_len.checked_add(2 * mem::size_of::<F>())?;
1642 match self {
1643 LengthEncoding::TypeLengthValue { option_len_multiplier } => {
1644 round_up(unpadded_len, option_len_multiplier)
1645 }
1646 LengthEncoding::ValueOnly => Some(unpadded_len),
1647 }
1648 }
1649
1650 /// Encodes the length of an option's body.
1651 ///
1652 /// `option_body_len` is the length in bytes of the body option as
1653 /// returned from [`OptionsSerializerImpl::option_length`]. This value
1654 /// does not include the kind, length, or padding bytes.
1655 ///
1656 /// `encode_length` computes the value which should be stored in the
1657 /// length field, returning `None` if the value cannot be stored in an
1658 /// `F`.
1659 pub fn encode_length<F: KindLenField>(self, option_body_len: usize) -> Option<F> {
1660 let len = match self {
1661 LengthEncoding::TypeLengthValue { option_len_multiplier } => {
1662 let unpadded_len = (2 * mem::size_of::<F>()).checked_add(option_body_len)?;
1663 let padded_len = round_up(unpadded_len, option_len_multiplier)?;
1664 padded_len / option_len_multiplier.get()
1665 }
1666 LengthEncoding::ValueOnly => option_body_len,
1667 };
1668 match F::try_from(len) {
1669 Ok(len) => Some(len),
1670 Err(TryFromIntError { .. }) => None,
1671 }
1672 }
1673
1674 /// Decodes the length of an option's body.
1675 ///
1676 /// `length_field` is the value of the length field. `decode_length`
1677 /// computes the length of the option's body which this value encodes,
1678 /// returning an error if `length_field` is invalid or if integer
1679 /// overflow occurs. `length_field` is invalid if it encodes a total
1680 /// length smaller than the header (specifically, if `self` is
1681 /// LengthEncoding::TypeLengthValue { option_len_multiplier }` and
1682 /// `length_field * option_len_multiplier < 2 * size_of::<F>()`).
1683 fn decode_length<F: KindLenField>(self, length_field: F) -> Option<usize> {
1684 let length_field = length_field.into();
1685 match self {
1686 LengthEncoding::TypeLengthValue { option_len_multiplier } => length_field
1687 .checked_mul(option_len_multiplier.get())
1688 .and_then(|product| product.checked_sub(2 * mem::size_of::<F>())),
1689 LengthEncoding::ValueOnly => Some(length_field),
1690 }
1691 }
1692 }
1693
1694 /// Rounds up `x` to the next multiple of `mul` unless `x` is already a
1695 /// multiple of `mul`.
1696 fn round_up(x: usize, mul: NonZeroUsize) -> Option<usize> {
1697 let mul = mul.get();
1698 // - Subtracting 1 can't underflow because we just added `mul`, which is
1699 // at least 1, and the addition didn't overflow
1700 // - Dividing by `mul` can't overflow (and can't divide by 0 because
1701 // `mul` is nonzero)
1702 // - Multiplying by `mul` can't overflow because division rounds down,
1703 // so the result of the multiplication can't be any larger than the
1704 // numerator in `(x_times_mul - 1) / mul`, which we already know
1705 // didn't overflow
1706 x.checked_add(mul).map(|x_times_mul| ((x_times_mul - 1) / mul) * mul)
1707 }
1708
1709 /// The type of the "kind" and "length" fields in an option.
1710 ///
1711 /// See the docs for [`OptionLayout::KindLenField`] for more information.
1712 pub trait KindLenField:
1713 FromBytes
1714 + IntoBytes
1715 + KnownLayout
1716 + Immutable
1717 + Unaligned
1718 + Into<usize>
1719 + TryFrom<usize, Error = TryFromIntError>
1720 + Eq
1721 + Copy
1722 + crate::sealed::Sealed
1723 {
1724 }
1725
1726 impl crate::sealed::Sealed for u8 {}
1727 impl KindLenField for u8 {}
1728 impl<O: ByteOrder> crate::sealed::Sealed for zerocopy::U16<O> {}
1729 impl<O: ByteOrder> KindLenField for zerocopy::U16<O> {}
1730
1731 /// Information about an option's layout.
1732 ///
1733 /// It is recommended that this trait be implemented for an uninhabited type
1734 /// since it never needs to be instantiated:
1735 ///
1736 /// ```rust
1737 /// # use packet::records::options::{OptionLayout, LengthEncoding};
1738 /// /// A carrier for information about the layout of the IPv4 option
1739 /// /// format.
1740 /// ///
1741 /// /// This type exists only at the type level, and does not need to be
1742 /// /// constructed.
1743 /// pub enum Ipv4OptionLayout {}
1744 ///
1745 /// impl OptionLayout for Ipv4OptionLayout {
1746 /// type KindLenField = u8;
1747 /// }
1748 /// ```
1749 pub trait OptionLayout {
1750 /// The type of the "kind" and "length" fields in an option.
1751 ///
1752 /// For most protocols, this is simply `u8`, as the "kind" and "length"
1753 /// fields are each a single byte. For protocols which use two bytes for
1754 /// these fields, this is [`zerocopy::U16`].
1755 // TODO(https://github.com/rust-lang/rust/issues/29661): Have
1756 // `KindLenField` default to `u8`.
1757 type KindLenField: KindLenField;
1758
1759 /// The encoding of the length byte.
1760 ///
1761 /// Some formats (such as IPv4) use the length field to encode the
1762 /// length of the entire option, including the kind and length bytes.
1763 /// Other formats (such as IPv6) use the length field to encode the
1764 /// length of only the value. This constant specifies which encoding is
1765 /// used.
1766 ///
1767 /// Additionally, some formats (such as NDP) do not directly encode the
1768 /// length in bytes of each option, but instead encode a number which
1769 /// must be multiplied by a constant in order to get the length in
1770 /// bytes. This is set using the [`TypeLengthValue`] variant's
1771 /// `option_len_multiplier` field, and it defaults to 1.
1772 ///
1773 /// [`TypeLengthValue`]: LengthEncoding::TypeLengthValue
1774 const LENGTH_ENCODING: LengthEncoding = LengthEncoding::TypeLengthValue {
1775 option_len_multiplier: NonZeroUsize::new(1).unwrap(),
1776 };
1777 }
1778
1779 /// An error encountered while parsing an option or sequence of options.
1780 pub trait OptionParseError: From<Never> {
1781 /// An error encountered while parsing a sequence of options.
1782 ///
1783 /// If an error is encountered while parsing a sequence of [`Options`],
1784 /// this is the error that will be emitted. This is the only type of
1785 /// error that can be generated by the [`Options`] parser itself. All
1786 /// other errors come from the user-provided [`OptionsImpl::parse`],
1787 /// which parses the data of a single option.
1788 const SEQUENCE_FORMAT_ERROR: Self;
1789 }
1790
1791 /// An error encountered while parsing an option or sequence of options.
1792 ///
1793 /// `OptionParseErr` is a simple implementation of [`OptionParseError`] that
1794 /// doesn't carry information other than the fact that an error was
1795 /// encountered.
1796 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
1797 pub struct OptionParseErr;
1798
1799 impl From<Never> for OptionParseErr {
1800 fn from(err: Never) -> OptionParseErr {
1801 match err {}
1802 }
1803 }
1804
1805 impl OptionParseError for OptionParseErr {
1806 const SEQUENCE_FORMAT_ERROR: OptionParseErr = OptionParseErr;
1807 }
1808
1809 /// Information about an option's layout required in order to parse it.
1810 pub trait OptionParseLayout: OptionLayout {
1811 /// The type of errors that may be returned by a call to
1812 /// [`OptionsImpl::parse`].
1813 type Error: OptionParseError;
1814
1815 /// The End of options kind (if one exists).
1816 const END_OF_OPTIONS: Option<Self::KindLenField>;
1817
1818 /// The No-op kind (if one exists).
1819 const NOP: Option<Self::KindLenField>;
1820 }
1821
1822 /// An implementation of an options parser.
1823 ///
1824 /// `OptionsImpl` provides functions to parse fixed- and variable-length
1825 /// options. It is required in order to construct an [`Options`].
1826 pub trait OptionsImpl: OptionParseLayout {
1827 /// The type of an option; the output from the [`parse`] function.
1828 ///
1829 /// For long or variable-length data, implementers are advised to make
1830 /// `Option` a reference into the bytes passed to `parse`. Such a
1831 /// reference will need to carry the lifetime `'a`, which is the same
1832 /// lifetime that is passed to `parse`, and is also the lifetime
1833 /// parameter to this trait.
1834 ///
1835 /// [`parse`]: crate::records::options::OptionsImpl::parse
1836 type Option<'a>;
1837
1838 /// Parses an option.
1839 ///
1840 /// `parse` takes a kind byte and variable-length data and returns
1841 /// `Ok(Some(o))` if the option successfully parsed as `o`, `Ok(None)`
1842 /// if the kind byte was unrecognized, and `Err(err)` if the kind byte
1843 /// was recognized but `data` was malformed for that option kind.
1844 ///
1845 /// `parse` is allowed to not recognize certain option kinds, as the
1846 /// length field can still be used to safely skip over them, but it must
1847 /// recognize all single-byte options (if it didn't, a single-byte
1848 /// option would be spuriously interpreted as a multi-byte option, and
1849 /// the first byte of the next option byte would be spuriously
1850 /// interpreted as the option's length byte).
1851 ///
1852 /// `parse` must be deterministic, or else [`Options::parse`] cannot
1853 /// guarantee that future iterations will not produce errors (and thus
1854 /// panic).
1855 ///
1856 /// [`Options::parse`]: crate::records::Records::parse
1857 fn parse<'a>(
1858 kind: Self::KindLenField,
1859 data: &'a [u8],
1860 ) -> Result<Option<Self::Option<'a>>, Self::Error>;
1861 }
1862
1863 /// A builder capable of serializing an option.
1864 ///
1865 /// Given `O: OptionBuilder`, an iterator of `O` can be used with a
1866 /// [`OptionSequenceBuilder`] to serialize a sequence of options.
1867 pub trait OptionBuilder {
1868 /// Information about the option's layout.
1869 type Layout: OptionLayout;
1870
1871 /// Returns the serialized length, in bytes, of `self`.
1872 ///
1873 /// Implementers must return the length, in bytes, of the **data***
1874 /// portion of the option field (not counting the kind and length
1875 /// bytes). The internal machinery of options serialization takes care
1876 /// of aligning options to their [`option_len_multiplier`] boundaries,
1877 /// adding padding bytes if necessary.
1878 ///
1879 /// [`option_len_multiplier`]: LengthEncoding::TypeLengthValue::option_len_multiplier
1880 fn serialized_len(&self) -> usize;
1881
1882 /// Returns the wire value for this option kind.
1883 fn option_kind(&self) -> <Self::Layout as OptionLayout>::KindLenField;
1884
1885 /// Serializes `self` into `data`.
1886 ///
1887 /// `data` will be exactly `self.serialized_len()` bytes long.
1888 /// Implementers must write the **data** portion of `self` into `data`
1889 /// (not the kind or length fields).
1890 ///
1891 /// # Panics
1892 ///
1893 /// May panic if `data` is not exactly `self.serialized_len()` bytes
1894 /// long.
1895 fn serialize_into(&self, data: &mut [u8]);
1896 }
1897
1898 /// A builder capable of serializing an option with an alignment
1899 /// requirement.
1900 ///
1901 /// Given `O: AlignedOptionBuilder`, an iterator of `O` can be used with an
1902 /// [`AlignedOptionSequenceBuilder`] to serialize a sequence of aligned
1903 /// options.
1904 pub trait AlignedOptionBuilder: OptionBuilder {
1905 /// Returns the alignment requirement of `self`.
1906 ///
1907 /// `option.alignment_requirement()` returns `(x, y)`, which means that
1908 /// the serialized encoding of `option` must be aligned at `x * n + y`
1909 /// bytes from the beginning of the options sequence for some
1910 /// non-negative `n`. For example, the IPv6 Router Alert Hop-by-Hop
1911 /// option has alignment (2, 0), while the Jumbo Payload option has
1912 /// alignment (4, 2). (1, 0) means there is no alignment requirement.
1913 ///
1914 /// `x` must be non-zero and `y` must be smaller than `x`.
1915 fn alignment_requirement(&self) -> (usize, usize);
1916
1917 /// Serializes the padding between subsequent aligned options.
1918 ///
1919 /// Some formats require that padding bytes have particular content.
1920 /// This function serializes padding bytes as required by the format.
1921 fn serialize_padding(buf: &mut [u8], length: usize);
1922 }
1923
1924 fn next<'a, BV, O>(bytes: &mut BV) -> RecordParseResult<O::Option<'a>, O::Error>
1925 where
1926 BV: BufferView<&'a [u8]>,
1927 O: OptionsImpl,
1928 {
1929 // For an explanation of this format, see the "Options" section of
1930 // https://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_segment_structure
1931 loop {
1932 if bytes.len() == 0 {
1933 return Ok(ParsedRecord::Done);
1934 }
1935 let kind = match bytes.take_obj_front::<O::KindLenField>() {
1936 // Thanks to the preceding `if`, we know at this point that
1937 // `bytes.len() > 0`. If `take_obj_front` returns `None`, that
1938 // means that `bytes.len()` is shorter than `O::KindLenField`.
1939 None => return Err(O::Error::SEQUENCE_FORMAT_ERROR),
1940 Some(k) => {
1941 // Can't do pattern matching with associated constants, so
1942 // do it the good-ol' way:
1943 if Some(*k) == O::NOP {
1944 continue;
1945 } else if Some(*k) == O::END_OF_OPTIONS {
1946 return Ok(ParsedRecord::Done);
1947 }
1948 k
1949 }
1950 };
1951 let body_len = match bytes.take_obj_front::<O::KindLenField>() {
1952 None => return Err(O::Error::SEQUENCE_FORMAT_ERROR),
1953 Some(len) => O::LENGTH_ENCODING
1954 .decode_length::<O::KindLenField>(*len)
1955 .ok_or(O::Error::SEQUENCE_FORMAT_ERROR)?,
1956 };
1957
1958 let option_data = bytes.take_front(body_len).ok_or(O::Error::SEQUENCE_FORMAT_ERROR)?;
1959 match O::parse(*kind, option_data) {
1960 Ok(Some(o)) => return Ok(ParsedRecord::Parsed(o)),
1961 Ok(None) => {}
1962 Err(err) => return Err(err),
1963 }
1964 }
1965 }
1966
1967 #[cfg(test)]
1968 mod tests {
1969 use core::convert::TryInto as _;
1970 use core::fmt::Debug;
1971
1972 use zerocopy::byteorder::network_endian::U16;
1973
1974 use super::*;
1975 use crate::Serializer;
1976
1977 #[derive(Debug)]
1978 struct DummyOptionsImpl;
1979
1980 #[derive(Debug)]
1981 struct DummyOption {
1982 kind: u8,
1983 data: Vec<u8>,
1984 }
1985
1986 impl OptionLayout for DummyOptionsImpl {
1987 type KindLenField = u8;
1988 }
1989
1990 impl OptionParseLayout for DummyOptionsImpl {
1991 type Error = OptionParseErr;
1992 const END_OF_OPTIONS: Option<u8> = Some(0);
1993 const NOP: Option<u8> = Some(1);
1994 }
1995
1996 impl OptionsImpl for DummyOptionsImpl {
1997 type Option<'a> = DummyOption;
1998
1999 fn parse<'a>(
2000 kind: u8,
2001 data: &'a [u8],
2002 ) -> Result<Option<Self::Option<'a>>, OptionParseErr> {
2003 let mut v = Vec::new();
2004 v.extend_from_slice(data);
2005 Ok(Some(DummyOption { kind, data: v }))
2006 }
2007 }
2008
2009 impl OptionBuilder for DummyOption {
2010 type Layout = DummyOptionsImpl;
2011
2012 fn serialized_len(&self) -> usize {
2013 self.data.len()
2014 }
2015
2016 fn option_kind(&self) -> u8 {
2017 self.kind
2018 }
2019
2020 fn serialize_into(&self, data: &mut [u8]) {
2021 assert_eq!(data.len(), OptionBuilder::serialized_len(self));
2022 data.copy_from_slice(&self.data);
2023 }
2024 }
2025
2026 impl AlignedOptionBuilder for DummyOption {
2027 // For our `DummyOption`, we simply regard (length, kind) as their
2028 // alignment requirement.
2029 fn alignment_requirement(&self) -> (usize, usize) {
2030 (self.data.len(), self.kind as usize)
2031 }
2032
2033 fn serialize_padding(buf: &mut [u8], length: usize) {
2034 assert!(length <= buf.len());
2035 assert!(length <= (std::u8::MAX as usize) + 2);
2036
2037 if length == 1 {
2038 // Use Pad1
2039 buf[0] = 0
2040 } else if length > 1 {
2041 // Use PadN
2042 buf[0] = 1;
2043 buf[1] = (length - 2) as u8;
2044 for i in 2..length {
2045 buf[i] = 0
2046 }
2047 }
2048 }
2049 }
2050
2051 #[derive(Debug, Eq, PartialEq)]
2052 enum AlwaysErrorErr {
2053 Sequence,
2054 Option,
2055 }
2056
2057 impl From<Never> for AlwaysErrorErr {
2058 fn from(err: Never) -> AlwaysErrorErr {
2059 match err {}
2060 }
2061 }
2062
2063 impl OptionParseError for AlwaysErrorErr {
2064 const SEQUENCE_FORMAT_ERROR: AlwaysErrorErr = AlwaysErrorErr::Sequence;
2065 }
2066
2067 #[derive(Debug)]
2068 struct AlwaysErrOptionsImpl;
2069
2070 impl OptionLayout for AlwaysErrOptionsImpl {
2071 type KindLenField = u8;
2072 }
2073
2074 impl OptionParseLayout for AlwaysErrOptionsImpl {
2075 type Error = AlwaysErrorErr;
2076 const END_OF_OPTIONS: Option<u8> = Some(0);
2077 const NOP: Option<u8> = Some(1);
2078 }
2079
2080 impl OptionsImpl for AlwaysErrOptionsImpl {
2081 type Option<'a> = ();
2082
2083 fn parse<'a>(_kind: u8, _data: &'a [u8]) -> Result<Option<()>, AlwaysErrorErr> {
2084 Err(AlwaysErrorErr::Option)
2085 }
2086 }
2087
2088 #[derive(Debug)]
2089 struct DummyNdpOptionsImpl;
2090
2091 #[derive(Debug, PartialEq, Eq)]
2092 struct NdpOption {
2093 kind: u8,
2094 data: Vec<u8>,
2095 }
2096
2097 impl OptionLayout for NdpOption {
2098 type KindLenField = u8;
2099
2100 const LENGTH_ENCODING: LengthEncoding = LengthEncoding::TypeLengthValue {
2101 option_len_multiplier: NonZeroUsize::new(8).unwrap(),
2102 };
2103 }
2104
2105 impl OptionLayout for DummyNdpOptionsImpl {
2106 type KindLenField = u8;
2107
2108 const LENGTH_ENCODING: LengthEncoding = LengthEncoding::TypeLengthValue {
2109 option_len_multiplier: NonZeroUsize::new(8).unwrap(),
2110 };
2111 }
2112
2113 impl OptionParseLayout for DummyNdpOptionsImpl {
2114 type Error = OptionParseErr;
2115
2116 const END_OF_OPTIONS: Option<u8> = None;
2117
2118 const NOP: Option<u8> = None;
2119 }
2120
2121 impl OptionsImpl for DummyNdpOptionsImpl {
2122 type Option<'a> = NdpOption;
2123
2124 fn parse<'a>(
2125 kind: u8,
2126 data: &'a [u8],
2127 ) -> Result<Option<Self::Option<'a>>, OptionParseErr> {
2128 let mut v = Vec::with_capacity(data.len());
2129 v.extend_from_slice(data);
2130 Ok(Some(NdpOption { kind, data: v }))
2131 }
2132 }
2133
2134 impl OptionBuilder for NdpOption {
2135 type Layout = DummyNdpOptionsImpl;
2136
2137 fn serialized_len(&self) -> usize {
2138 self.data.len()
2139 }
2140
2141 fn option_kind(&self) -> u8 {
2142 self.kind
2143 }
2144
2145 fn serialize_into(&self, data: &mut [u8]) {
2146 assert_eq!(data.len(), OptionBuilder::serialized_len(self));
2147 data.copy_from_slice(&self.data)
2148 }
2149 }
2150
2151 #[derive(Debug)]
2152 struct DummyMultiByteKindOptionsImpl;
2153
2154 #[derive(Debug)]
2155 struct MultiByteOption {
2156 kind: U16,
2157 data: Vec<u8>,
2158 }
2159
2160 impl OptionLayout for MultiByteOption {
2161 type KindLenField = U16;
2162 }
2163
2164 impl OptionLayout for DummyMultiByteKindOptionsImpl {
2165 type KindLenField = U16;
2166 }
2167
2168 impl OptionParseLayout for DummyMultiByteKindOptionsImpl {
2169 type Error = OptionParseErr;
2170
2171 const END_OF_OPTIONS: Option<U16> = None;
2172
2173 const NOP: Option<U16> = None;
2174 }
2175
2176 impl OptionsImpl for DummyMultiByteKindOptionsImpl {
2177 type Option<'a> = MultiByteOption;
2178
2179 fn parse<'a>(
2180 kind: U16,
2181 data: &'a [u8],
2182 ) -> Result<Option<Self::Option<'a>>, OptionParseErr> {
2183 let mut v = Vec::with_capacity(data.len());
2184 v.extend_from_slice(data);
2185 Ok(Some(MultiByteOption { kind, data: v }))
2186 }
2187 }
2188
2189 impl OptionBuilder for MultiByteOption {
2190 type Layout = DummyMultiByteKindOptionsImpl;
2191
2192 fn serialized_len(&self) -> usize {
2193 self.data.len()
2194 }
2195
2196 fn option_kind(&self) -> U16 {
2197 self.kind
2198 }
2199
2200 fn serialize_into(&self, data: &mut [u8]) {
2201 data.copy_from_slice(&self.data)
2202 }
2203 }
2204
2205 #[test]
2206 fn test_length_encoding() {
2207 const TLV_1: LengthEncoding = LengthEncoding::TypeLengthValue {
2208 option_len_multiplier: NonZeroUsize::new(1).unwrap(),
2209 };
2210 const TLV_2: LengthEncoding = LengthEncoding::TypeLengthValue {
2211 option_len_multiplier: NonZeroUsize::new(2).unwrap(),
2212 };
2213
2214 // Test LengthEncoding::record_length
2215
2216 // For `ValueOnly`, `record_length` should always add 2 or 4 for the kind
2217 // and length bytes, but never add padding.
2218 assert_eq!(LengthEncoding::ValueOnly.record_length::<u8>(0), Some(2));
2219 assert_eq!(LengthEncoding::ValueOnly.record_length::<u8>(1), Some(3));
2220 assert_eq!(LengthEncoding::ValueOnly.record_length::<u8>(2), Some(4));
2221 assert_eq!(LengthEncoding::ValueOnly.record_length::<u8>(3), Some(5));
2222
2223 assert_eq!(LengthEncoding::ValueOnly.record_length::<U16>(0), Some(4));
2224 assert_eq!(LengthEncoding::ValueOnly.record_length::<U16>(1), Some(5));
2225 assert_eq!(LengthEncoding::ValueOnly.record_length::<U16>(2), Some(6));
2226 assert_eq!(LengthEncoding::ValueOnly.record_length::<U16>(3), Some(7));
2227
2228 // For `TypeLengthValue` with `option_len_multiplier = 1`,
2229 // `record_length` should always add 2 or 4 for the kind and length
2230 // bytes, but never add padding.
2231 assert_eq!(TLV_1.record_length::<u8>(0), Some(2));
2232 assert_eq!(TLV_1.record_length::<u8>(1), Some(3));
2233 assert_eq!(TLV_1.record_length::<u8>(2), Some(4));
2234 assert_eq!(TLV_1.record_length::<u8>(3), Some(5));
2235
2236 assert_eq!(TLV_1.record_length::<U16>(0), Some(4));
2237 assert_eq!(TLV_1.record_length::<U16>(1), Some(5));
2238 assert_eq!(TLV_1.record_length::<U16>(2), Some(6));
2239 assert_eq!(TLV_1.record_length::<U16>(3), Some(7));
2240
2241 // For `TypeLengthValue` with `option_len_multiplier = 2`,
2242 // `record_length` should always add 2 or 4 for the kind and length
2243 // bytes, and add padding if necessary to reach a multiple of 2.
2244 assert_eq!(TLV_2.record_length::<u8>(0), Some(2)); // (0 + 2)
2245 assert_eq!(TLV_2.record_length::<u8>(1), Some(4)); // (1 + 2 + 1)
2246 assert_eq!(TLV_2.record_length::<u8>(2), Some(4)); // (2 + 2)
2247 assert_eq!(TLV_2.record_length::<u8>(3), Some(6)); // (3 + 2 + 1)
2248
2249 assert_eq!(TLV_2.record_length::<U16>(0), Some(4)); // (0 + 4)
2250 assert_eq!(TLV_2.record_length::<U16>(1), Some(6)); // (1 + 4 + 1)
2251 assert_eq!(TLV_2.record_length::<U16>(2), Some(6)); // (2 + 4)
2252 assert_eq!(TLV_2.record_length::<U16>(3), Some(8)); // (3 + 4 + 1)
2253
2254 // Test LengthEncoding::encode_length
2255
2256 fn encode_length<K: KindLenField>(
2257 length_encoding: LengthEncoding,
2258 option_body_len: usize,
2259 ) -> Option<usize> {
2260 length_encoding.encode_length::<K>(option_body_len).map(Into::into)
2261 }
2262
2263 // For `ValueOnly`, `encode_length` should always return the
2264 // argument unmodified.
2265 assert_eq!(encode_length::<u8>(LengthEncoding::ValueOnly, 0), Some(0));
2266 assert_eq!(encode_length::<u8>(LengthEncoding::ValueOnly, 1), Some(1));
2267 assert_eq!(encode_length::<u8>(LengthEncoding::ValueOnly, 2), Some(2));
2268 assert_eq!(encode_length::<u8>(LengthEncoding::ValueOnly, 3), Some(3));
2269
2270 assert_eq!(encode_length::<U16>(LengthEncoding::ValueOnly, 0), Some(0));
2271 assert_eq!(encode_length::<U16>(LengthEncoding::ValueOnly, 1), Some(1));
2272 assert_eq!(encode_length::<U16>(LengthEncoding::ValueOnly, 2), Some(2));
2273 assert_eq!(encode_length::<U16>(LengthEncoding::ValueOnly, 3), Some(3));
2274
2275 // For `TypeLengthValue` with `option_len_multiplier = 1`,
2276 // `encode_length` should always add 2 or 4 for the kind and length
2277 // bytes.
2278 assert_eq!(encode_length::<u8>(TLV_1, 0), Some(2));
2279 assert_eq!(encode_length::<u8>(TLV_1, 1), Some(3));
2280 assert_eq!(encode_length::<u8>(TLV_1, 2), Some(4));
2281 assert_eq!(encode_length::<u8>(TLV_1, 3), Some(5));
2282
2283 assert_eq!(encode_length::<U16>(TLV_1, 0), Some(4));
2284 assert_eq!(encode_length::<U16>(TLV_1, 1), Some(5));
2285 assert_eq!(encode_length::<U16>(TLV_1, 2), Some(6));
2286 assert_eq!(encode_length::<U16>(TLV_1, 3), Some(7));
2287
2288 // For `TypeLengthValue` with `option_len_multiplier = 2`,
2289 // `encode_length` should always add 2 or 4 for the kind and length
2290 // bytes, add padding if necessary to reach a multiple of 2, and
2291 // then divide by 2.
2292 assert_eq!(encode_length::<u8>(TLV_2, 0), Some(1)); // (0 + 2) / 2
2293 assert_eq!(encode_length::<u8>(TLV_2, 1), Some(2)); // (1 + 2 + 1) / 2
2294 assert_eq!(encode_length::<u8>(TLV_2, 2), Some(2)); // (2 + 2) / 2
2295 assert_eq!(encode_length::<u8>(TLV_2, 3), Some(3)); // (3 + 2 + 1) / 2
2296
2297 assert_eq!(encode_length::<U16>(TLV_2, 0), Some(2)); // (0 + 4) / 2
2298 assert_eq!(encode_length::<U16>(TLV_2, 1), Some(3)); // (1 + 4 + 1) / 2
2299 assert_eq!(encode_length::<U16>(TLV_2, 2), Some(3)); // (2 + 4) / 2
2300 assert_eq!(encode_length::<U16>(TLV_2, 3), Some(4)); // (3 + 4 + 1) / 2
2301
2302 // Test LengthEncoding::decode_length
2303
2304 fn decode_length<K: KindLenField>(
2305 length_encoding: LengthEncoding,
2306 length_field: usize,
2307 ) -> Option<usize> {
2308 length_encoding.decode_length::<K>(length_field.try_into().unwrap())
2309 }
2310
2311 // For `ValueOnly`, `decode_length` should always return the
2312 // argument unmodified.
2313 assert_eq!(decode_length::<u8>(LengthEncoding::ValueOnly, 0), Some(0));
2314 assert_eq!(decode_length::<u8>(LengthEncoding::ValueOnly, 1), Some(1));
2315 assert_eq!(decode_length::<u8>(LengthEncoding::ValueOnly, 2), Some(2));
2316 assert_eq!(decode_length::<u8>(LengthEncoding::ValueOnly, 3), Some(3));
2317
2318 assert_eq!(decode_length::<U16>(LengthEncoding::ValueOnly, 0), Some(0));
2319 assert_eq!(decode_length::<U16>(LengthEncoding::ValueOnly, 1), Some(1));
2320 assert_eq!(decode_length::<U16>(LengthEncoding::ValueOnly, 2), Some(2));
2321 assert_eq!(decode_length::<U16>(LengthEncoding::ValueOnly, 3), Some(3));
2322
2323 // For `TypeLengthValue` with `option_len_multiplier = 1`,
2324 // `decode_length` should always subtract 2 or 4 for the kind and
2325 // length bytes.
2326 assert_eq!(decode_length::<u8>(TLV_1, 0), None);
2327 assert_eq!(decode_length::<u8>(TLV_1, 1), None);
2328 assert_eq!(decode_length::<u8>(TLV_1, 2), Some(0));
2329 assert_eq!(decode_length::<u8>(TLV_1, 3), Some(1));
2330
2331 assert_eq!(decode_length::<U16>(TLV_1, 0), None);
2332 assert_eq!(decode_length::<U16>(TLV_1, 1), None);
2333 assert_eq!(decode_length::<U16>(TLV_1, 2), None);
2334 assert_eq!(decode_length::<U16>(TLV_1, 3), None);
2335 assert_eq!(decode_length::<U16>(TLV_1, 4), Some(0));
2336 assert_eq!(decode_length::<U16>(TLV_1, 5), Some(1));
2337
2338 // For `TypeLengthValue` with `option_len_multiplier = 2`,
2339 // `decode_length` should always multiply by 2 or 4 and then
2340 // subtract 2 for the kind and length bytes.
2341 assert_eq!(decode_length::<u8>(TLV_2, 0), None);
2342 assert_eq!(decode_length::<u8>(TLV_2, 1), Some(0));
2343 assert_eq!(decode_length::<u8>(TLV_2, 2), Some(2));
2344 assert_eq!(decode_length::<u8>(TLV_2, 3), Some(4));
2345
2346 assert_eq!(decode_length::<U16>(TLV_2, 0), None);
2347 assert_eq!(decode_length::<U16>(TLV_2, 1), None);
2348 assert_eq!(decode_length::<U16>(TLV_2, 2), Some(0));
2349 assert_eq!(decode_length::<U16>(TLV_2, 3), Some(2));
2350
2351 // Test end-to-end by creating options implementation with different
2352 // length encodings.
2353
2354 /// Declare a new options impl type with a custom `LENGTH_ENCODING`.
2355 macro_rules! declare_options_impl {
2356 ($opt:ident, $impl:ident, $encoding:expr) => {
2357 #[derive(Debug)]
2358 enum $impl {}
2359
2360 #[derive(Debug, PartialEq)]
2361 struct $opt {
2362 kind: u8,
2363 data: Vec<u8>,
2364 }
2365
2366 impl<'a> From<&'a (u8, Vec<u8>)> for $opt {
2367 fn from((kind, data): &'a (u8, Vec<u8>)) -> $opt {
2368 $opt { kind: *kind, data: data.clone() }
2369 }
2370 }
2371
2372 impl OptionLayout for $opt {
2373 const LENGTH_ENCODING: LengthEncoding = $encoding;
2374 type KindLenField = u8;
2375 }
2376
2377 impl OptionLayout for $impl {
2378 const LENGTH_ENCODING: LengthEncoding = $encoding;
2379 type KindLenField = u8;
2380 }
2381
2382 impl OptionParseLayout for $impl {
2383 type Error = OptionParseErr;
2384 const END_OF_OPTIONS: Option<u8> = Some(0);
2385 const NOP: Option<u8> = Some(1);
2386 }
2387
2388 impl OptionsImpl for $impl {
2389 type Option<'a> = $opt;
2390
2391 fn parse<'a>(
2392 kind: u8,
2393 data: &'a [u8],
2394 ) -> Result<Option<Self::Option<'a>>, OptionParseErr> {
2395 let mut v = Vec::new();
2396 v.extend_from_slice(data);
2397 Ok(Some($opt { kind, data: v }))
2398 }
2399 }
2400
2401 impl OptionBuilder for $opt {
2402 type Layout = $impl;
2403
2404 fn serialized_len(&self) -> usize {
2405 self.data.len()
2406 }
2407
2408 fn option_kind(&self) -> u8 {
2409 self.kind
2410 }
2411
2412 fn serialize_into(&self, data: &mut [u8]) {
2413 assert_eq!(data.len(), OptionBuilder::serialized_len(self));
2414 data.copy_from_slice(&self.data);
2415 }
2416 }
2417 };
2418 }
2419
2420 declare_options_impl!(
2421 DummyImplValueOnly,
2422 DummyImplValueOnlyImpl,
2423 LengthEncoding::ValueOnly
2424 );
2425 declare_options_impl!(DummyImplTlv1, DummyImplTlv1Impl, TLV_1);
2426 declare_options_impl!(DummyImplTlv2, DummyImplTlv2Impl, TLV_2);
2427
2428 /// Tests that a given option is parsed from different byte
2429 /// sequences for different options layouts.
2430 ///
2431 /// Since some options cannot be parsed from any byte sequence using
2432 /// the `DummyImplTlv2` layout (namely, those whose lengths are not
2433 /// a multiple of 2), `tlv_2` may be `None`.
2434 fn test_parse(
2435 (expect_kind, expect_data): (u8, Vec<u8>),
2436 value_only: &[u8],
2437 tlv_1: &[u8],
2438 tlv_2: Option<&[u8]>,
2439 ) {
2440 let options = Options::<_, DummyImplValueOnlyImpl>::parse(value_only)
2441 .unwrap()
2442 .iter()
2443 .collect::<Vec<_>>();
2444 let data = expect_data.clone();
2445 assert_eq!(options, [DummyImplValueOnly { kind: expect_kind, data }]);
2446
2447 let options = Options::<_, DummyImplTlv1Impl>::parse(tlv_1)
2448 .unwrap()
2449 .iter()
2450 .collect::<Vec<_>>();
2451 let data = expect_data.clone();
2452 assert_eq!(options, [DummyImplTlv1 { kind: expect_kind, data }]);
2453
2454 if let Some(tlv_2) = tlv_2 {
2455 let options = Options::<_, DummyImplTlv2Impl>::parse(tlv_2)
2456 .unwrap()
2457 .iter()
2458 .collect::<Vec<_>>();
2459 assert_eq!(options, [DummyImplTlv2 { kind: expect_kind, data: expect_data }]);
2460 }
2461 }
2462
2463 // 0-byte body
2464 test_parse((0xFF, vec![]), &[0xFF, 0], &[0xFF, 2], Some(&[0xFF, 1]));
2465 // 1-byte body
2466 test_parse((0xFF, vec![0]), &[0xFF, 1, 0], &[0xFF, 3, 0], None);
2467 // 2-byte body
2468 test_parse(
2469 (0xFF, vec![0, 1]),
2470 &[0xFF, 2, 0, 1],
2471 &[0xFF, 4, 0, 1],
2472 Some(&[0xFF, 2, 0, 1]),
2473 );
2474 // 3-byte body
2475 test_parse((0xFF, vec![0, 1, 2]), &[0xFF, 3, 0, 1, 2], &[0xFF, 5, 0, 1, 2], None);
2476 // 4-byte body
2477 test_parse(
2478 (0xFF, vec![0, 1, 2, 3]),
2479 &[0xFF, 4, 0, 1, 2, 3],
2480 &[0xFF, 6, 0, 1, 2, 3],
2481 Some(&[0xFF, 3, 0, 1, 2, 3]),
2482 );
2483
2484 /// Tests that an option can be serialized and then parsed in each
2485 /// option layout.
2486 ///
2487 /// In some cases (when the body length is not a multiple of 2), the
2488 /// `DummyImplTlv2` layout will parse a different option than was
2489 /// originally serialized. In this case, `expect_tlv_2` can be used
2490 /// to provide a different value to expect as the result of parsing.
2491 fn test_serialize_parse(opt: (u8, Vec<u8>), expect_tlv_2: Option<(u8, Vec<u8>)>) {
2492 let opts = [opt.clone()];
2493
2494 fn test_serialize_parse_inner<
2495 O: OptionBuilder + Debug + PartialEq + for<'a> From<&'a (u8, Vec<u8>)>,
2496 I: for<'a> OptionsImpl<Error = OptionParseErr, Option<'a> = O> + std::fmt::Debug,
2497 >(
2498 opts: &[(u8, Vec<u8>)],
2499 expect: &[(u8, Vec<u8>)],
2500 ) {
2501 let opts = opts.iter().map(Into::into).collect::<Vec<_>>();
2502 let expect = expect.iter().map(Into::into).collect::<Vec<_>>();
2503
2504 let ser = OptionSequenceBuilder::<O, _>::new(opts.iter());
2505 let serialized =
2506 ser.into_serializer().serialize_vec_outer().unwrap().as_ref().to_vec();
2507 let options = Options::<_, I>::parse(serialized.as_slice())
2508 .unwrap()
2509 .iter()
2510 .collect::<Vec<_>>();
2511 assert_eq!(options, expect);
2512 }
2513
2514 test_serialize_parse_inner::<DummyImplValueOnly, DummyImplValueOnlyImpl>(
2515 &opts, &opts,
2516 );
2517 test_serialize_parse_inner::<DummyImplTlv1, DummyImplTlv1Impl>(&opts, &opts);
2518 let expect = if let Some(expect) = expect_tlv_2 { expect } else { opt };
2519 test_serialize_parse_inner::<DummyImplTlv2, DummyImplTlv2Impl>(&opts, &[expect]);
2520 }
2521
2522 // 0-byte body
2523 test_serialize_parse((0xFF, vec![]), None);
2524 // 1-byte body
2525 test_serialize_parse((0xFF, vec![0]), Some((0xFF, vec![0, 0])));
2526 // 2-byte body
2527 test_serialize_parse((0xFF, vec![0, 1]), None);
2528 // 3-byte body
2529 test_serialize_parse((0xFF, vec![0, 1, 2]), Some((0xFF, vec![0, 1, 2, 0])));
2530 // 4-byte body
2531 test_serialize_parse((0xFF, vec![0, 1, 2, 3]), None);
2532 }
2533
2534 #[test]
2535 fn test_empty_options() {
2536 // all END_OF_OPTIONS
2537 let bytes = [0; 64];
2538 let options = Options::<_, DummyOptionsImpl>::parse(&bytes[..]).unwrap();
2539 assert_eq!(options.iter().count(), 0);
2540
2541 // all NOP
2542 let bytes = [1; 64];
2543 let options = Options::<_, DummyOptionsImpl>::parse(&bytes[..]).unwrap();
2544 assert_eq!(options.iter().count(), 0);
2545 }
2546
2547 #[test]
2548 fn test_parse() {
2549 // Construct byte sequences in the pattern [3, 2], [4, 3, 2], [5, 4,
2550 // 3, 2], etc. The second byte is the length byte, so these are all
2551 // valid options (with data [], [2], [3, 2], etc).
2552 let mut bytes = Vec::new();
2553 for i in 4..16 {
2554 // from the user's perspective, these NOPs should be transparent
2555 bytes.push(1);
2556 for j in (2..i).rev() {
2557 bytes.push(j);
2558 }
2559 // from the user's perspective, these NOPs should be transparent
2560 bytes.push(1);
2561 }
2562
2563 let options = Options::<_, DummyOptionsImpl>::parse(bytes.as_slice()).unwrap();
2564 for (idx, DummyOption { kind, data }) in options.iter().enumerate() {
2565 assert_eq!(kind as usize, idx + 3);
2566 assert_eq!(data.len(), idx);
2567 let mut bytes = Vec::new();
2568 for i in (2..(idx + 2)).rev() {
2569 bytes.push(i as u8);
2570 }
2571 assert_eq!(data, bytes);
2572 }
2573
2574 // Test that we get no parse errors so long as
2575 // AlwaysErrOptionsImpl::parse is never called.
2576 //
2577 // `bytes` is a sequence of NOPs.
2578 let bytes = [1; 64];
2579 let options = Options::<_, AlwaysErrOptionsImpl>::parse(&bytes[..]).unwrap();
2580 assert_eq!(options.iter().count(), 0);
2581 }
2582
2583 #[test]
2584 fn test_parse_ndp_options() {
2585 let mut bytes = Vec::new();
2586 for i in 0..16 {
2587 bytes.push(i);
2588 // NDP uses len*8 for the actual length.
2589 bytes.push(i + 1);
2590 // Write remaining 6 bytes.
2591 for j in 2..((i + 1) * 8) {
2592 bytes.push(j)
2593 }
2594 }
2595
2596 let options = Options::<_, DummyNdpOptionsImpl>::parse(bytes.as_slice()).unwrap();
2597 for (idx, NdpOption { kind, data }) in options.iter().enumerate() {
2598 assert_eq!(kind as usize, idx);
2599 assert_eq!(data.len(), ((idx + 1) * 8) - 2);
2600 let mut bytes = Vec::new();
2601 for i in 2..((idx + 1) * 8) {
2602 bytes.push(i as u8);
2603 }
2604 assert_eq!(data, bytes);
2605 }
2606 }
2607
2608 #[test]
2609 fn test_parse_err() {
2610 // the length byte is too short
2611 let bytes = [2, 1];
2612 assert_eq!(
2613 Options::<_, DummyOptionsImpl>::parse(&bytes[..]).unwrap_err(),
2614 OptionParseErr
2615 );
2616
2617 // the length byte is 0 (similar check to above, but worth
2618 // explicitly testing since this was a bug in the Linux kernel:
2619 // https://bugzilla.redhat.com/show_bug.cgi?id=1622404)
2620 let bytes = [2, 0];
2621 assert_eq!(
2622 Options::<_, DummyOptionsImpl>::parse(&bytes[..]).unwrap_err(),
2623 OptionParseErr
2624 );
2625
2626 // the length byte is too long
2627 let bytes = [2, 3];
2628 assert_eq!(
2629 Options::<_, DummyOptionsImpl>::parse(&bytes[..]).unwrap_err(),
2630 OptionParseErr
2631 );
2632
2633 // the buffer is fine, but the implementation returns a parse error
2634 let bytes = [2, 2];
2635 assert_eq!(
2636 Options::<_, AlwaysErrOptionsImpl>::parse(&bytes[..]).unwrap_err(),
2637 AlwaysErrorErr::Option,
2638 );
2639 }
2640
2641 #[test]
2642 fn test_missing_length_bytes() {
2643 // Construct a sequence with a valid record followed by an
2644 // incomplete one, where `kind` is specified but `len` is missing.
2645 // So we can assert that we'll fail cleanly in that case.
2646 //
2647 // Added as part of Change-Id
2648 // Ibd46ac7384c7c5e0d74cb344b48c88876c351b1a.
2649 //
2650 // Before the small refactor in the Change-Id above, there was a
2651 // check during parsing that guaranteed that the length of the
2652 // remaining buffer was >= 1, but it should've been a check for
2653 // >= 2, and the case below would have caused it to panic while
2654 // trying to access the length byte, which was a DoS vulnerability.
2655 assert_matches::assert_matches!(
2656 Options::<_, DummyOptionsImpl>::parse(&[0x03, 0x03, 0x01, 0x03][..]),
2657 Err(OptionParseErr)
2658 );
2659 }
2660
2661 #[test]
2662 fn test_partial_kind_field() {
2663 // Construct a sequence with only one byte where a two-byte kind
2664 // field is expected.
2665 //
2666 // Added as part of Change-Id
2667 // I468121f5712b73c4e704460f580f166c876ee7d6.
2668 //
2669 // Before the small refactor in the Change-Id above, we treated any
2670 // failure to consume the kind field from the byte slice as
2671 // indicating that there were no bytes left, and we would stop
2672 // parsing successfully. This logic was correct when we only
2673 // supported 1-byte kind fields, but it became incorrect once we
2674 // introduced multi-byte kind fields.
2675 assert_matches::assert_matches!(
2676 Options::<_, DummyMultiByteKindOptionsImpl>::parse(&[0x00][..]),
2677 Err(OptionParseErr)
2678 );
2679 }
2680
2681 #[test]
2682 fn test_parse_and_serialize() {
2683 // Construct byte sequences in the pattern [3, 2], [4, 3, 2], [5, 4,
2684 // 3, 2], etc. The second byte is the length byte, so these are all
2685 // valid options (with data [], [2], [3, 2], etc).
2686 let mut bytes = Vec::new();
2687 for i in 4..16 {
2688 // from the user's perspective, these NOPs should be transparent
2689 for j in (2..i).rev() {
2690 bytes.push(j);
2691 }
2692 }
2693
2694 let options = Options::<_, DummyOptionsImpl>::parse(bytes.as_slice()).unwrap();
2695
2696 let collected = options.iter().collect::<Vec<_>>();
2697 // Pass `collected.iter()` instead of `options.iter()` since we need
2698 // an iterator over references, and `options.iter()` produces an
2699 // iterator over values.
2700 let ser = OptionSequenceBuilder::<DummyOption, _>::new(collected.iter());
2701
2702 let serialized = ser.into_serializer().serialize_vec_outer().unwrap().as_ref().to_vec();
2703
2704 assert_eq!(serialized, bytes);
2705 }
2706
2707 fn test_ndp_bytes() -> Vec<u8> {
2708 let mut bytes = Vec::new();
2709 for i in 0..16 {
2710 bytes.push(i);
2711 // NDP uses len*8 for the actual length.
2712 bytes.push(i + 1);
2713 // Write remaining 6 bytes.
2714 for j in 2..((i + 1) * 8) {
2715 bytes.push(j)
2716 }
2717 }
2718 bytes
2719 }
2720
2721 #[test]
2722 fn test_parse_and_serialize_ndp() {
2723 let bytes = test_ndp_bytes();
2724 let options = Options::<_, DummyNdpOptionsImpl>::parse(bytes.as_slice()).unwrap();
2725 let collected = options.iter().collect::<Vec<_>>();
2726 // Pass `collected.iter()` instead of `options.iter()` since we need
2727 // an iterator over references, and `options.iter()` produces an
2728 // iterator over values.
2729 let ser = OptionSequenceBuilder::<NdpOption, _>::new(collected.iter());
2730
2731 let serialized = ser.into_serializer().serialize_vec_outer().unwrap().as_ref().to_vec();
2732
2733 assert_eq!(serialized, bytes);
2734 }
2735
2736 #[test]
2737 fn measure_ndp_records() {
2738 let bytes = test_ndp_bytes();
2739 let options = Options::<_, DummyNdpOptionsImpl>::parse(bytes.as_slice()).unwrap();
2740 let collected = options.iter().collect::<Vec<_>>();
2741
2742 for (i, mut bytes) in options.iter_bytes().enumerate() {
2743 // Each byte slice we iterate over should parse as the equivalent NDP option.
2744 let parsed = <DummyNdpOptionsImpl as RecordsImpl>::parse_with_context(
2745 &mut &mut bytes,
2746 &mut (),
2747 )
2748 .expect("should parse successfully");
2749 let option = match parsed {
2750 ParsedRecord::Parsed(option) => option,
2751 ParsedRecord::Skipped => panic!("no options should be skipped"),
2752 ParsedRecord::Done => panic!("should not be done"),
2753 };
2754 assert_eq!(option, collected[i]);
2755
2756 // The byte slice should be exhausted after re-parsing the record.
2757 assert_eq!(bytes, &[]);
2758 }
2759 }
2760
2761 #[test]
2762 fn test_parse_and_serialize_multi_byte_fields() {
2763 let mut bytes = Vec::new();
2764 for i in 4..16 {
2765 // Push kind U16<NetworkEndian>.
2766 bytes.push(0);
2767 bytes.push(i);
2768 // Push length U16<NetworkEndian>.
2769 bytes.push(0);
2770 bytes.push(i);
2771 // Write `i` - 4 bytes.
2772 for j in 4..i {
2773 bytes.push(j);
2774 }
2775 }
2776
2777 let options =
2778 Options::<_, DummyMultiByteKindOptionsImpl>::parse(bytes.as_slice()).unwrap();
2779 for (idx, MultiByteOption { kind, data }) in options.iter().enumerate() {
2780 assert_eq!(usize::from(kind), idx + 4);
2781 let idx: u8 = idx.try_into().unwrap();
2782 let bytes: Vec<_> = (4..(idx + 4)).collect();
2783 assert_eq!(data, bytes);
2784 }
2785
2786 let collected = options.iter().collect::<Vec<_>>();
2787 // Pass `collected.iter()` instead of `options.iter()` since we need
2788 // an iterator over references, and `options.iter()` produces an
2789 // iterator over values.
2790 let ser = OptionSequenceBuilder::<MultiByteOption, _>::new(collected.iter());
2791 let mut output = vec![0u8; ser.serialized_len()];
2792 ser.serialize_into(output.as_mut_slice());
2793 assert_eq!(output, bytes);
2794 }
2795
2796 #[test]
2797 fn test_align_up_to() {
2798 // We are doing some sort of property testing here:
2799 // We generate a random alignment requirement (x, y) and a random offset `pos`.
2800 // The resulting `new_pos` must:
2801 // - 1. be at least as large as the original `pos`.
2802 // - 2. be in form of x * n + y for some integer n.
2803 // - 3. for any number in between, they shouldn't be in form of x * n + y.
2804 use rand::Rng;
2805 let mut rng = rand::rng();
2806 for _ in 0..100_000 {
2807 let x = rng.random_range(1usize..256);
2808 let y = rng.random_range(0..x);
2809 let pos = rng.random_range(0usize..65536);
2810 let new_pos = align_up_to(pos, x, y);
2811 // 1)
2812 assert!(new_pos >= pos);
2813 // 2)
2814 assert_eq!((new_pos - y) % x, 0);
2815 // 3) Note: `p` is not guaranteed to be bigger than `y`, plus `x` to avoid overflow.
2816 assert!((pos..new_pos).all(|p| (p + x - y) % x != 0))
2817 }
2818 }
2819
2820 #[test]
2821 #[rustfmt::skip]
2822 fn test_aligned_dummy_options_serializer() {
2823 // testing for cases: 2n+{0,1}, 3n+{1,2}, 1n+0, 4n+2
2824 let dummy_options = [
2825 // alignment requirement: 2 * n + 1,
2826 //
2827 DummyOption { kind: 1, data: vec![42, 42] },
2828 DummyOption { kind: 0, data: vec![42, 42] },
2829 DummyOption { kind: 1, data: vec![1, 2, 3] },
2830 DummyOption { kind: 2, data: vec![3, 2, 1] },
2831 DummyOption { kind: 0, data: vec![42] },
2832 DummyOption { kind: 2, data: vec![9, 9, 9, 9] },
2833 ];
2834 let ser = AlignedRecordSequenceBuilder::<DummyOption, _>::new(
2835 0,
2836 dummy_options.iter(),
2837 );
2838 assert_eq!(ser.serialized_len(), 32);
2839 let mut buf = [0u8; 32];
2840 ser.serialize_into(&mut buf[..]);
2841 assert_eq!(
2842 &buf[..],
2843 &[
2844 0, // Pad1 padding
2845 1, 4, 42, 42, // (1, [42, 42]) starting at 2 * 0 + 1 = 3
2846 0, // Pad1 padding
2847 0, 4, 42, 42, // (0, [42, 42]) starting at 2 * 3 + 0 = 6
2848 1, 5, 1, 2, 3, // (1, [1, 2, 3]) starting at 3 * 2 + 1 = 7
2849 1, 0, // PadN padding
2850 2, 5, 3, 2, 1, // (2, [3, 2, 1]) starting at 3 * 4 + 2 = 14
2851 0, 3, 42, // (0, [42]) starting at 1 * 19 + 0 = 19
2852 0, // PAD1 padding
2853 2, 6, 9, 9, 9, 9 // (2, [9, 9, 9, 9]) starting at 4 * 6 + 2 = 26
2854 // total length: 32
2855 ]
2856 );
2857 }
2858 }
2859}