Skip to main content

ts_packet/
lib.rs

1#![doc = include_str!("../README.md")]
2#![no_std]
3
4extern crate alloc;
5
6/// Geneve (RFC 8926) fixed-header codec for Tailscale peer-relay framing.
7pub mod geneve;
8
9use alloc::{borrow::ToOwned, string::String, vec::Vec};
10use core::{
11    fmt::{self, LowerHex, UpperHex},
12    net::IpAddr,
13    ops::{Index, IndexMut},
14    slice::{Iter, IterMut, SliceIndex},
15};
16
17use bytes::{Buf, BufMut, Bytes, BytesMut, buf::UninitSlice};
18use ts_hexdump::{AsHexExt, Case, hex_fmt};
19
20/// An immutable, contiguous sequence of bytes, specialized for networking applications.
21#[derive(Clone, Eq, PartialEq, Ord, PartialOrd)]
22pub struct Packet {
23    contents: Bytes,
24}
25
26impl Packet {
27    /// The empty packet.
28    pub const EMPTY: Packet = Packet {
29        contents: Bytes::from_static(&[]),
30    };
31
32    /// Returns `true` if this [`Packet`] has a length of 0.
33    ///
34    /// # Examples
35    /// ```
36    /// # use ts_packet::Packet;
37    /// let pkt = Packet::from(vec![]);
38    /// assert!(pkt.is_empty());
39    /// ```
40    pub fn is_empty(&self) -> bool {
41        self.contents.is_empty()
42    }
43
44    /// Returns an iterator over the bytes in this [`Packet`]. The iterator yields all bytes in
45    /// order from start to end.
46    ///
47    /// # Examples
48    /// ```
49    /// # use ts_packet::Packet;
50    /// let pkt = Packet::from(vec![0xAA, 0xBB, 0xCC]);
51    /// let mut iter = pkt.iter();
52    /// assert_eq!(iter.next(), Some(&0xAA));
53    /// assert_eq!(iter.next(), Some(&0xBB));
54    /// assert_eq!(iter.next(), Some(&0xCC));
55    /// assert_eq!(iter.next(), None);
56    /// ```
57    pub fn iter(&'_ self) -> Iter<'_, u8> {
58        self.contents.iter()
59    }
60
61    /// Returns the number of bytes contained in this [`Packet`].
62    ///
63    /// # Examples
64    /// ```
65    /// # use ts_packet::Packet;
66    /// let pkt = Packet::from(vec![1, 2, 3]);
67    /// assert_eq!(pkt.len(), 3);
68    /// ```
69    pub fn len(&self) -> usize {
70        self.contents.len()
71    }
72}
73
74impl fmt::Debug for Packet {
75    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76        write!(f, "{self:X}")
77    }
78}
79
80impl AsRef<[u8]> for Packet {
81    fn as_ref(&self) -> &[u8] {
82        self.contents.as_ref()
83    }
84}
85
86impl Buf for Packet {
87    fn remaining(&self) -> usize {
88        self.contents.remaining()
89    }
90
91    fn chunk(&self) -> &[u8] {
92        &self.contents
93    }
94
95    fn advance(&mut self, cnt: usize) {
96        self.contents.advance(cnt);
97    }
98}
99
100impl From<&[u8]> for Packet {
101    fn from(value: &[u8]) -> Self {
102        Self {
103            contents: Bytes::from(value.to_owned()),
104        }
105    }
106}
107impl From<Bytes> for Packet {
108    fn from(value: Bytes) -> Self {
109        Self { contents: value }
110    }
111}
112
113impl From<BytesMut> for Packet {
114    fn from(value: BytesMut) -> Self {
115        Self {
116            contents: value.freeze(),
117        }
118    }
119}
120
121impl From<PacketMut> for Packet {
122    fn from(value: PacketMut) -> Self {
123        value.freeze()
124    }
125}
126
127impl From<Vec<u8>> for Packet {
128    fn from(value: Vec<u8>) -> Self {
129        Self {
130            contents: value.into(),
131        }
132    }
133}
134
135impl<T> Index<T> for Packet
136where
137    // This instance is provided by implicit deref to [u8] on Bytes
138    [u8]: Index<T>,
139{
140    type Output = <[u8] as Index<T>>::Output;
141
142    #[inline]
143    fn index(&self, index: T) -> &Self::Output {
144        self.contents.index(index)
145    }
146}
147
148impl LowerHex for Packet {
149    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150        write!(
151            f,
152            "{}",
153            self.iter().hex(Case::Lower).flatten().collect::<String>()
154        )
155    }
156}
157
158impl UpperHex for Packet {
159    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160        write!(
161            f,
162            "{}",
163            self.iter().hex(Case::Upper).flatten().collect::<String>()
164        )
165    }
166}
167
168/// A mutable, contiguous, growable sequence of bytes, specialized for networking applications.
169#[derive(Clone, Eq, PartialEq, Ord, PartialOrd)]
170pub struct PacketMut {
171    /// The backing buffer for this packet; effectively a pointer, length, and capacity of a
172    /// contiguous slice of memory. Supports dynamic resizing/reallocation when necessary.
173    contents: BytesMut,
174}
175
176impl PacketMut {
177    /// Constructs a new [PacketMut] and allocates an underlying buffer of the given `size` on the
178    /// heap. The newly-allocated underlying buffer is filled with zero bytes (`0u8`).
179    ///
180    /// # Examples
181    /// ```
182    /// # use ts_packet::PacketMut;
183    /// let mut pkt = PacketMut::new(5);
184    /// assert_eq!(pkt.len(), 5);
185    /// assert_eq!(pkt.as_ref(), &[0, 0, 0, 0, 0]);
186    /// pkt[4] = 42;
187    /// assert_eq!(pkt.as_ref(), &[0, 0, 0, 0, 42]);
188    /// ```
189    pub fn new(size: usize) -> Self {
190        Self {
191            contents: BytesMut::zeroed(size),
192        }
193    }
194
195    /// Constructs a new [PacketMut] with at least the specified capacity. The packet will be able
196    /// to hold at least `size` bytes without reallocating.
197    ///
198    /// Note that the packet will have at least the given *capacity*, but will have a *length* of
199    /// zero until bytes are added to it.
200    ///
201    /// # Examples
202    /// ```
203    /// # use ts_packet::PacketMut;
204    /// let mut pkt = PacketMut::with_capacity(5);
205    /// assert_eq!(pkt.len(), 0);
206    /// assert_eq!(pkt.capacity(), 5);
207    /// ```
208    pub fn with_capacity(size: usize) -> Self {
209        Self {
210            contents: BytesMut::with_capacity(size),
211        }
212    }
213
214    /// Returns the number of contiguous bytes the underlying buffer can hold without reallocating.
215    ///
216    /// # Examples
217    /// ```
218    /// # use ts_packet::PacketMut;
219    /// let mut pkt = PacketMut::with_capacity(3);
220    /// assert_eq!(pkt.len(), 0);
221    /// assert_eq!(pkt.capacity(), 3);
222    /// ```
223    pub fn capacity(&self) -> usize {
224        self.contents.capacity()
225    }
226
227    /// Appends the given bytes to the end of this [`PacketMut`]. The underlying buffer is
228    /// resized if it does not have enough capacity.
229    ///
230    /// # Examples
231    /// Extending within the underlying buffer's capacity increases the length, but not the
232    /// capacity:
233    /// ```
234    /// # use ts_packet::PacketMut;
235    /// let mut pkt = PacketMut::with_capacity(3);
236    /// pkt.extend_from_slice(&[1, 2, 3]);
237    /// assert_eq!(pkt.len(), 3);
238    /// assert_eq!(pkt.capacity(), 3);
239    /// ```
240    ///
241    /// Extending *beyond* the backing buffer's capacity triggers a reallocation, changing both the
242    /// length and the capacity:
243    /// ```
244    /// # use ts_packet::PacketMut;
245    /// let mut pkt = PacketMut::with_capacity(3);
246    /// pkt.extend_from_slice(&[1, 2, 3, 4]);
247    /// assert_eq!(pkt.len(), 4);
248    /// assert_eq!(pkt.capacity(), 8);
249    /// ```
250    pub fn extend_from_slice(&mut self, slice: &[u8]) {
251        self.contents.extend_from_slice(slice);
252    }
253
254    /// Add the given number of zero bytes to the front of this `[PacketMut]`. The underlying
255    /// buffer is resized if it does not have enough capacity.
256    pub fn grow_front(&mut self, len: usize) {
257        let existing_len = self.contents.len();
258        self.contents.resize(existing_len + len, 0);
259        self.contents.copy_within(..existing_len, len);
260        self.contents[..len].fill(0);
261    }
262
263    /// Prepends the given bytes to this [`PacketMut`]. The underlying buffer is resized if it
264    /// does not have enough capacity.
265    pub fn extend_front_from_slice(&mut self, slice: &[u8]) {
266        self.grow_front(slice.len());
267        self.contents[..slice.len()].copy_from_slice(slice);
268    }
269
270    /// Returns a reference to an element or subslice depending on the type of index.
271    ///
272    /// If given a position, returns a reference to the element at that position or None if out of bounds.
273    /// If given a range, returns the subslice corresponding to that range, or None if out of bounds.
274    pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[u8]>>::Output>
275    where
276        I: SliceIndex<[u8]>,
277    {
278        self.contents.get(index)
279    }
280
281    /// Returns a mutable reference to an element or subslice depending on the type of index.
282    ///
283    /// If given a position, returns a reference to the element at that position or None if out of bounds.
284    /// If given a range, returns the subslice corresponding to that range, or None if out of bounds.
285    pub fn get_mut<I>(&mut self, index: I) -> Option<&mut <I as SliceIndex<[u8]>>::Output>
286    where
287        I: SliceIndex<[u8]>,
288    {
289        self.contents.get_mut(index)
290    }
291
292    /// Converts `self` into an immutable [`Packet`]. This is a zero-cost type conversion simply to
293    /// indicate the returned packet won't be mutated anymore, allowing the packet to be cheaply
294    /// cloned and moved between execution contexts (threads/async tasks).
295    ///
296    /// # Examples
297    ///  ```
298    /// # use ts_packet::PacketMut;
299    /// let mut pkt_mut = PacketMut::with_capacity(4);
300    /// pkt_mut.extend_from_slice(b"hello world");
301    /// let pkt1 = pkt_mut.freeze();
302    /// let pkt2 = pkt1.clone();
303    /// assert_eq!(pkt1, pkt2);
304    /// let th = std::thread::spawn(move || {
305    ///     assert_eq!(&pkt1[..], b"hello world");
306    /// });
307    /// assert_eq!(&pkt2[..], b"hello world");
308    /// th.join().unwrap();
309    /// ```
310    pub fn freeze(self) -> Packet {
311        Packet {
312            contents: self.contents.freeze(),
313        }
314    }
315
316    /// Returns `true` if this [`PacketMut`] has a length of 0.
317    ///
318    /// # Examples
319    /// ```
320    /// # use ts_packet::PacketMut;
321    /// let pkt = PacketMut::from(&[]);
322    /// assert!(pkt.is_empty());
323    /// ```
324    pub fn is_empty(&self) -> bool {
325        self.len() == 0
326    }
327
328    /// Returns an iterator over the bytes in this [`PacketMut`]. The iterator yields all bytes in
329    /// order from start to end.
330    ///
331    /// # Examples
332    /// ```
333    /// # use ts_packet::PacketMut;
334    /// let pkt = PacketMut::from(&[0xAA, 0xBB, 0xCC]);
335    /// let mut iter = pkt.iter();
336    /// assert_eq!(iter.next(), Some(&0xAA));
337    /// assert_eq!(iter.next(), Some(&0xBB));
338    /// assert_eq!(iter.next(), Some(&0xCC));
339    /// assert_eq!(iter.next(), None);
340    /// ```
341    pub fn iter(&'_ self) -> Iter<'_, u8> {
342        self.contents.iter()
343    }
344
345    /// Returns an iterator over the bytes in this [`PacketMut`] that allows modifying each value.
346    /// The iterator yields all bytes in order from start to end.
347    ///
348    /// # Examples
349    /// ```
350    /// # use ts_packet::PacketMut;
351    /// let mut pkt = PacketMut::from(&[0xAA, 0xBB, 0xCC]);
352    /// for byte in pkt.iter_mut() {
353    ///     *byte += 1;
354    /// }
355    /// assert_eq!(pkt.as_ref(), &[0xAB, 0xBC, 0xCD]);
356    /// ```
357    pub fn iter_mut(&'_ mut self) -> IterMut<'_, u8> {
358        self.contents.iter_mut()
359    }
360
361    /// Returns the number of bytes contained in this [`PacketMut`].
362    ///
363    /// # Examples
364    /// ```
365    /// # use ts_packet::PacketMut;
366    /// let pkt = PacketMut::from(&[1, 2, 3]);
367    /// assert_eq!(pkt.len(), 3);
368    /// ```
369    pub fn len(&self) -> usize {
370        self.contents.len()
371    }
372
373    /// Removes the last `count` bytes from the end of this [`PacketMut`], leaving
374    /// `self.len() - count` bytes in the packet. Existing capacity is preserved and the backing
375    /// buffer is not changed.
376    ///
377    /// # Examples
378    /// ```
379    /// # use ts_packet::PacketMut;
380    /// let mut pkt = PacketMut::from(&[1, 2, 3, 4, 5]);
381    /// pkt.truncate(3);
382    /// assert_eq!(pkt, PacketMut::from(&[1, 2, 3]));
383    /// ```
384    pub fn truncate(&mut self, count: usize) {
385        self.contents.truncate(count);
386    }
387
388    /// Removes the first `count` bytes from the front of this [`PacketMut`], leaving
389    /// `self.len() - count` bytes in the packet. Existing capacity is preserved and the backing
390    /// buffer is not changed.
391    ///
392    /// # Panics
393    ///
394    /// Panics if `at > self.len()`.
395    ///
396    /// # Examples
397    /// ```
398    /// # use ts_packet::PacketMut;
399    /// let mut pkt = PacketMut::from(&[1, 2, 3, 4, 5]);
400    /// pkt.truncate_front(2);
401    /// assert_eq!(pkt, PacketMut::from(&[3, 4, 5]));
402    /// ```
403    pub fn truncate_front(&mut self, count: usize) {
404        self.contents.advance(count);
405    }
406
407    /// Splits the [`PacketMut`] into two at the given index.
408    ///
409    /// After the call, `self` will contain the bytes `[0, at)`, and the returned [`PacketMut`]
410    /// will contain the bytes `[at, capacity)`. Existing capacity is preserved, the backing buffer
411    /// is not changed, and both `self` and the returned [`PacketMut`] share the same backing
412    /// buffer.
413    ///
414    /// # Panics
415    ///
416    /// Panics if `at > len`.
417    ///
418    /// # Complexity
419    ///
420    /// O(1). Indices are adjusted and reference counts are updated, but none of the backing
421    /// buffer is traversed or cloned.
422    ///
423    /// # Examples
424    ///
425    /// ```
426    /// # use ts_packet::PacketMut;
427    /// let mut pkt1 = PacketMut::from(&[1, 2, 3, 4, 5]);
428    /// let pkt2 = pkt1.split_off(2);
429    /// assert_eq!(pkt1, PacketMut::from(&[1, 2]));
430    /// assert_eq!(pkt2, PacketMut::from(&[3, 4, 5]));
431    /// ```
432    pub fn split_off(&mut self, at: usize) -> PacketMut {
433        Self {
434            contents: self.contents.split_off(at),
435        }
436    }
437
438    /// Splits the [`PacketMut`] into two at the given index.
439    ///
440    /// After the call, `self` will contain the bytes `[at, len)`, and the returned [`PacketMut`]
441    /// will contain the bytes `[0, at)`. Existing capacity is preserved, the backing buffer
442    /// is not changed, and both `self` and the returned [`PacketMut`] share the same backing
443    /// buffer.
444    ///
445    /// # Panics
446    ///
447    /// Panics if `at > len`.
448    ///
449    /// # Complexity
450    ///
451    /// O(1). Indices are adjusted and reference counts are updated, but none of the backing
452    /// buffer is traversed or cloned.
453    ///
454    /// # Examples
455    ///
456    /// ```
457    /// # use ts_packet::PacketMut;
458    /// let mut pkt1 = PacketMut::from(&[1, 2, 3, 4, 5]);
459    /// let pkt2 = pkt1.split_to(2);
460    /// assert_eq!(pkt1, PacketMut::from(&[3, 4, 5]));
461    /// assert_eq!(pkt2, PacketMut::from(&[1, 2]));
462    /// ```
463    pub fn split_to(&mut self, at: usize) -> PacketMut {
464        Self {
465            contents: self.contents.split_to(at),
466        }
467    }
468
469    fn get_ip_family(&self) -> Option<u8> {
470        match self.get(0)? >> 4 {
471            4 => Some(4),
472            6 => Some(6),
473            _ => None,
474        }
475    }
476
477    /// Returns the bytes at idx..idx+4 interpreted as a network-endian IPv4 address.
478    fn ipv4_at(&self, idx: usize) -> Option<IpAddr> {
479        let octets: [u8; 4] = self.get(idx..idx + 4)?.try_into().unwrap();
480        Some(IpAddr::from(octets))
481    }
482
483    /// Returns the bytes at idx..idx+16 interpreted as a network-endian IPv6 address.
484    fn ipv6_at(&self, idx: usize) -> Option<IpAddr> {
485        let octets: [u8; 16] = self.get(idx..idx + 16)?.try_into().unwrap();
486        Some(IpAddr::from(octets))
487    }
488
489    /// Returns the source IP address of the packet.
490    ///
491    /// Returns None if the packet structure doesn't match an IPv4 or IPv6 datagram.
492    pub fn get_src_addr(&self) -> Option<IpAddr> {
493        match self.get_ip_family() {
494            Some(4) => self.ipv4_at(12),
495            Some(6) => self.ipv6_at(8),
496            _ => None,
497        }
498    }
499
500    /// Returns the destination IP address of the packet.
501    ///
502    /// Returns None if the packet structure doesn't match an IPv4 or IPv6 datagram.
503    pub fn get_dst_addr(&self) -> Option<IpAddr> {
504        match self.get_ip_family() {
505            Some(4) => self.ipv4_at(16),
506            Some(6) => self.ipv6_at(24),
507            _ => None,
508        }
509    }
510}
511
512impl fmt::Debug for PacketMut {
513    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
514        write!(f, "{self:X}")
515    }
516}
517
518impl AsMut<[u8]> for PacketMut {
519    fn as_mut(&mut self) -> &mut [u8] {
520        self.contents.as_mut()
521    }
522}
523
524impl AsRef<[u8]> for PacketMut {
525    fn as_ref(&self) -> &[u8] {
526        self.contents.as_ref()
527    }
528}
529
530impl Buf for PacketMut {
531    fn remaining(&self) -> usize {
532        self.contents.remaining_mut()
533    }
534
535    fn chunk(&self) -> &[u8] {
536        &self.contents
537    }
538
539    fn advance(&mut self, cnt: usize) {
540        self.contents.advance(cnt)
541    }
542}
543
544// SAFETY: `bytes::BufMut` is an `unsafe trait`, so `unsafe impl` is required by the language
545// regardless of body. Every method forwards verbatim to `self.contents: BytesMut`, whose own
546// `unsafe impl BufMut` upholds all trait invariants; we add no behavior, so those guarantees
547// carry through unchanged.
548unsafe impl BufMut for PacketMut {
549    fn remaining_mut(&self) -> usize {
550        self.contents.remaining_mut()
551    }
552
553    unsafe fn advance_mut(&mut self, cnt: usize) {
554        // SAFETY: the caller guarantees `cnt` bytes returned by `chunk_mut` were initialized; we forward
555        // that identical precondition to `BytesMut::advance_mut`, which requires exactly the same thing.
556        unsafe {
557            self.contents.advance_mut(cnt);
558        }
559    }
560
561    fn chunk_mut(&mut self) -> &mut UninitSlice {
562        self.contents.chunk_mut()
563    }
564}
565
566impl crypto_box::aead::Buffer for PacketMut {
567    fn extend_from_slice(&mut self, other: &[u8]) -> crypto_box::aead::Result<()> {
568        self.contents.extend_from_slice(other);
569        Ok(())
570    }
571
572    fn truncate(&mut self, len: usize) {
573        self.truncate(len);
574    }
575}
576
577impl From<&[u8]> for PacketMut {
578    fn from(value: &[u8]) -> Self {
579        Self {
580            contents: BytesMut::from(value),
581        }
582    }
583}
584
585impl<const N: usize> From<&[u8; N]> for PacketMut {
586    fn from(value: &[u8; N]) -> Self {
587        Self {
588            contents: BytesMut::from(value.as_ref()),
589        }
590    }
591}
592
593impl From<Vec<u8>> for PacketMut {
594    fn from(value: Vec<u8>) -> Self {
595        Self {
596            contents: BytesMut::from(value.as_slice()),
597        }
598    }
599}
600
601impl From<BytesMut> for PacketMut {
602    fn from(value: BytesMut) -> Self {
603        Self { contents: value }
604    }
605}
606
607impl<T> Index<T> for PacketMut
608where
609    // This instance is provided by implicit deref to [u8] on BytesMut
610    [u8]: Index<T>,
611{
612    type Output = <[u8] as Index<T>>::Output;
613
614    #[inline]
615    fn index(&self, index: T) -> &Self::Output {
616        self.contents.index(index)
617    }
618}
619
620impl<T> IndexMut<T> for PacketMut
621where
622    [u8]: IndexMut<T>,
623{
624    #[inline]
625    fn index_mut(&mut self, index: T) -> &mut Self::Output {
626        self.contents.index_mut(index)
627    }
628}
629
630impl LowerHex for PacketMut {
631    #[inline]
632    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
633        hex_fmt(self.iter(), Case::Lower, f)
634    }
635}
636
637impl UpperHex for PacketMut {
638    #[inline]
639    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
640        hex_fmt(self.iter(), Case::Upper, f)
641    }
642}
643
644#[cfg(test)]
645mod tests {
646    use alloc::string::String;
647    use core::fmt::Write;
648
649    use super::*;
650
651    /// Simple byte sequence for testing hexdumps, etc.
652    const BYTE_SEQUENCE_1: &[u8] = &[
653        0x00u8, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
654        0x0F, 0x10, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
655    ];
656
657    /// Resembles a 5-byte DERP KeepAlive frame; the 4-byte length field doesn't include the type/
658    /// length fields themselves, so is zero.
659    const BYTE_SEQUENCE_2: &[u8] = &[0x06, 0x00, 0x00, 0x00, 0x00];
660
661    #[test]
662    fn test_packet_mut_hexdump() {
663        let pkt = PacketMut::from(BYTE_SEQUENCE_1);
664
665        let mut buf = String::new();
666        write!(
667            buf,
668            "{}",
669            pkt.iter()
670                .hexdump(Case::Lower)
671                .flatten()
672                .collect::<String>()
673        )
674        .unwrap();
675        assert_eq!(
676            buf,
677            "00 01 02 03 04 05 06 07   08 09 0a 0b 0c 0d 0e 0f   ................\n10 aa bb cc dd ee ff                                .......\n"
678        );
679
680        buf.clear();
681        write!(
682            buf,
683            "{}",
684            pkt.iter()
685                .hexdump(Case::Upper)
686                .flatten()
687                .collect::<String>()
688        )
689        .unwrap();
690        assert_eq!(
691            buf,
692            "00 01 02 03 04 05 06 07   08 09 0A 0B 0C 0D 0E 0F   ................\n10 AA BB CC DD EE FF                                .......\n"
693        );
694    }
695
696    #[test]
697    fn test_packet_mut_iter() {
698        let pkt = PacketMut::from(BYTE_SEQUENCE_1);
699        for (idx, byte) in pkt.iter().enumerate() {
700            assert_eq!(
701                *byte, BYTE_SEQUENCE_1[idx],
702                "packet and original bytes should have identical values in same order"
703            );
704        }
705    }
706
707    #[test]
708    fn test_packet_mut_iter_mut() {
709        let mut pkt1 = PacketMut::from(BYTE_SEQUENCE_1);
710        let pkt2 = PacketMut::from(BYTE_SEQUENCE_1);
711        for byte in pkt1.iter_mut() {
712            *byte = byte.wrapping_sub(0xFF);
713        }
714
715        for (idx, byte) in pkt1.iter().enumerate() {
716            assert_eq!(
717                *byte,
718                BYTE_SEQUENCE_1[idx].wrapping_sub(0xFF),
719                "pkt1 and original bytes should have values offset by 0xFF"
720            );
721            assert_eq!(
722                pkt2[idx], BYTE_SEQUENCE_1[idx],
723                "pkt2 and original bytes should have identical values in same order"
724            );
725            assert_eq!(
726                pkt1[idx],
727                pkt2[idx].wrapping_sub(0xFF),
728                "pkt1 and pkt2 should have values offset by 0xFF"
729            );
730        }
731    }
732
733    #[test]
734    fn test_packet_mut_prepend() {
735        let mut pkt = PacketMut::from(BYTE_SEQUENCE_1);
736        pkt.grow_front(5);
737        assert_eq!(pkt.len(), BYTE_SEQUENCE_1.len() + 5);
738        assert_eq!(pkt[..5], [0; 5]);
739        assert_eq!(&pkt[5..], BYTE_SEQUENCE_1);
740
741        let mut pkt = PacketMut::from(BYTE_SEQUENCE_1);
742        pkt.extend_front_from_slice(BYTE_SEQUENCE_2);
743        assert_eq!(pkt.len(), BYTE_SEQUENCE_1.len() + BYTE_SEQUENCE_2.len());
744        assert_eq!(&pkt[..BYTE_SEQUENCE_2.len()], BYTE_SEQUENCE_2);
745        assert_eq!(&pkt[BYTE_SEQUENCE_2.len()..], BYTE_SEQUENCE_1);
746    }
747}