xenet_macro_helper/
packet.rs

1//! Packet helpers for `xenet-macro`.
2
3extern crate alloc;
4use alloc::vec;
5
6use core::ops::{Deref, DerefMut, Index, IndexMut, Range, RangeFrom, RangeFull, RangeTo};
7use xenet_core;
8
9/// Represents a generic network packet.
10pub trait Packet {
11    /// Retrieve the underlying buffer for the packet.
12    fn packet(&self) -> &[u8];
13    /// Retrieve the payload for the packet.
14    fn payload(&self) -> &[u8];
15}
16
17/// Blanket impl for Boxed objects
18impl<T: Packet> Packet for alloc::boxed::Box<T> {
19    /// Retrieve the underlying buffer for the packet.
20    fn packet(&self) -> &[u8] {
21        self.deref().packet()
22    }
23    /// Retrieve the payload for the packet.
24    fn payload(&self) -> &[u8] {
25        self.deref().payload()
26    }
27}
28
29impl<T: Packet> Packet for &T {
30    /// Retrieve the underlying buffer for the packet.
31    fn packet(&self) -> &[u8] {
32        (*self).packet()
33    }
34    /// Retrieve the payload for the packet.
35    fn payload(&self) -> &[u8] {
36        (*self).payload()
37    }
38}
39
40/// Represents a generic, mutable, network packet.
41pub trait MutablePacket: Packet {
42    /// Retrieve the underlying, mutable, buffer for the packet.
43    fn packet_mut(&mut self) -> &mut [u8];
44    /// Retrieve the mutable payload for the packet.
45    fn payload_mut(&mut self) -> &mut [u8];
46    /// Initialize this packet by cloning another.
47    fn clone_from<T: Packet>(&mut self, other: &T) {
48        use core::ptr;
49
50        assert!(self.packet().len() >= other.packet().len());
51        unsafe {
52            ptr::copy_nonoverlapping(
53                other.packet().as_ptr(),
54                self.packet_mut().as_mut_ptr(),
55                other.packet().len(),
56            );
57        }
58    }
59}
60
61/// Used to convert on-the-wire packets to their #\[packet\] equivalent.
62pub trait FromPacket: Packet {
63    /// The type of the packet to convert from.
64    type T;
65    /// Converts a wire-format packet to #\[packet\] struct format.
66    fn from_packet(&self) -> Self::T;
67}
68
69/// Used to find the calculated size of the packet. This is used for occasions where the underlying
70/// buffer is not the same length as the packet itself.
71pub trait PacketSize: Packet {
72    /// Get the calculated size of the packet.
73    fn packet_size(&self) -> usize;
74}
75
76macro_rules! impl_index {
77    ($t:ident, $index_t:ty, $output_t:ty) => {
78        impl<'p> Index<$index_t> for $t<'p> {
79            type Output = $output_t;
80
81            #[inline]
82            fn index(&self, index: $index_t) -> &$output_t {
83                &self.as_slice().index(index)
84            }
85        }
86    };
87}
88
89macro_rules! impl_index_mut {
90    ($t:ident, $index_t:ty, $output_t:ty) => {
91        impl<'p> IndexMut<$index_t> for $t<'p> {
92            #[inline]
93            fn index_mut(&mut self, index: $index_t) -> &mut $output_t {
94                self.as_mut_slice().index_mut(index)
95            }
96        }
97    };
98}
99
100/// Packet data.
101#[derive(PartialEq)]
102pub enum PacketData<'p> {
103    /// A packet owns its contents.
104    Owned(vec::Vec<u8>),
105    /// A packet borrows its contents.
106    Borrowed(&'p [u8]),
107}
108
109impl<'p> PacketData<'p> {
110    /// Get a slice of the packet data.
111    #[inline]
112    pub fn as_slice(&self) -> &[u8] {
113        match self {
114            &PacketData::Owned(ref data) => data.deref(),
115            &PacketData::Borrowed(ref data) => data,
116        }
117    }
118    /// No-op - returns `self`.
119    #[inline]
120    pub fn to_immutable(self) -> PacketData<'p> {
121        self
122    }
123    /// A length of the packet data.
124    #[inline]
125    pub fn len(&self) -> usize {
126        self.as_slice().len()
127    }
128}
129
130impl_index!(PacketData, usize, u8);
131impl_index!(PacketData, Range<usize>, [u8]);
132impl_index!(PacketData, RangeTo<usize>, [u8]);
133impl_index!(PacketData, RangeFrom<usize>, [u8]);
134impl_index!(PacketData, RangeFull, [u8]);
135
136/// Mutable packet data.
137#[derive(PartialEq)]
138pub enum MutPacketData<'p> {
139    /// Owned mutable packet data.
140    Owned(vec::Vec<u8>),
141    /// Borrowed mutable packet data.
142    Borrowed(&'p mut [u8]),
143}
144
145impl<'p> MutPacketData<'p> {
146    /// Get packet data as a slice.
147    #[inline]
148    pub fn as_slice(&self) -> &[u8] {
149        match self {
150            &MutPacketData::Owned(ref data) => data.deref(),
151            &MutPacketData::Borrowed(ref data) => data,
152        }
153    }
154    /// Get packet data as a mutable slice.
155    #[inline]
156    pub fn as_mut_slice(&mut self) -> &mut [u8] {
157        match self {
158            &mut MutPacketData::Owned(ref mut data) => data.deref_mut(),
159            &mut MutPacketData::Borrowed(ref mut data) => data,
160        }
161    }
162    /// Get an immutable version of packet data.
163    #[inline]
164    pub fn to_immutable(self) -> PacketData<'p> {
165        match self {
166            MutPacketData::Owned(data) => PacketData::Owned(data),
167            MutPacketData::Borrowed(data) => PacketData::Borrowed(data),
168        }
169    }
170    /// Get a length of data in the packet.
171    #[inline]
172    pub fn len(&self) -> usize {
173        self.as_slice().len()
174    }
175}
176
177impl_index!(MutPacketData, usize, u8);
178impl_index!(MutPacketData, Range<usize>, [u8]);
179impl_index!(MutPacketData, RangeTo<usize>, [u8]);
180impl_index!(MutPacketData, RangeFrom<usize>, [u8]);
181impl_index!(MutPacketData, RangeFull, [u8]);
182
183impl_index_mut!(MutPacketData, usize, u8);
184impl_index_mut!(MutPacketData, Range<usize>, [u8]);
185impl_index_mut!(MutPacketData, RangeTo<usize>, [u8]);
186impl_index_mut!(MutPacketData, RangeFrom<usize>, [u8]);
187impl_index_mut!(MutPacketData, RangeFull, [u8]);
188
189/// Used to convert a type to primitive values representing it.
190pub trait PrimitiveValues {
191    /// A tuple of types, to represent the current value.
192    type T;
193    /// Convert a value to primitive types representing it.
194    fn to_primitive_values(&self) -> Self::T;
195}
196
197impl PrimitiveValues for xenet_core::mac::MacAddr {
198    type T = (u8, u8, u8, u8, u8, u8);
199    #[inline]
200    fn to_primitive_values(&self) -> (u8, u8, u8, u8, u8, u8) {
201        (self.0, self.1, self.2, self.3, self.4, self.5)
202    }
203}
204
205impl PrimitiveValues for std::net::Ipv4Addr {
206    type T = (u8, u8, u8, u8);
207    #[inline]
208    fn to_primitive_values(&self) -> (u8, u8, u8, u8) {
209        let octets = self.octets();
210
211        (octets[0], octets[1], octets[2], octets[3])
212    }
213}
214
215impl PrimitiveValues for std::net::Ipv6Addr {
216    type T = (u16, u16, u16, u16, u16, u16, u16, u16);
217    #[inline]
218    fn to_primitive_values(&self) -> (u16, u16, u16, u16, u16, u16, u16, u16) {
219        let segments = self.segments();
220        (
221            segments[0],
222            segments[1],
223            segments[2],
224            segments[3],
225            segments[4],
226            segments[5],
227            segments[6],
228            segments[7],
229        )
230    }
231}