libpacket_core/
packet.rs

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