use crate::macaddr::MacAddr;
use std::net::{Ipv4Addr, Ipv6Addr};
use std::ops::{Deref, DerefMut, Index, IndexMut, Range, RangeFrom, RangeFull, RangeTo};
pub trait Packet {
fn packet(&self) -> &[u8];
fn payload(&self) -> &[u8];
}
pub trait MutablePacket: Packet {
fn packet_mut(&mut self) -> &mut [u8];
fn payload_mut(&mut self) -> &mut [u8];
fn clone_from<T: Packet>(&mut self, other: &T) {
use std::ptr;
assert!(self.packet().len() >= other.packet().len());
unsafe {
ptr::copy_nonoverlapping(
other.packet().as_ptr(),
self.packet_mut().as_mut_ptr(),
other.packet().len(),
);
}
}
}
pub trait FromPacket: Packet {
type T;
fn from_packet(&self) -> Self::T;
}
pub trait PacketSize: Packet {
fn packet_size(&self) -> usize;
}
macro_rules! impl_index {
($t:ident, $index_t:ty, $output_t:ty) => {
impl<'p> Index<$index_t> for $t<'p> {
type Output = $output_t;
fn index(&self, index: $index_t) -> &$output_t {
&self.as_slice().index(index)
}
}
};
}
macro_rules! impl_index_mut {
($t:ident, $index_t:ty, $output_t:ty) => {
impl<'p> IndexMut<$index_t> for $t<'p> {
fn index_mut(&mut self, index: $index_t) -> &mut $output_t {
self.as_mut_slice().index_mut(index)
}
}
};
}
#[derive(PartialEq)]
pub enum PacketData<'p> {
Owned(Vec<u8>),
Borrowed(&'p [u8]),
}
impl<'p> PacketData<'p> {
pub fn as_slice(&self) -> &[u8] {
match self {
&PacketData::Owned(ref data) => data.deref(),
&PacketData::Borrowed(ref data) => data,
}
}
pub fn to_immutable(self) -> PacketData<'p> {
self
}
pub fn len(&self) -> usize {
self.as_slice().len()
}
}
impl_index!(PacketData, usize, u8);
impl_index!(PacketData, Range<usize>, [u8]);
impl_index!(PacketData, RangeTo<usize>, [u8]);
impl_index!(PacketData, RangeFrom<usize>, [u8]);
impl_index!(PacketData, RangeFull, [u8]);
#[derive(PartialEq)]
pub enum MutPacketData<'p> {
Owned(Vec<u8>),
Borrowed(&'p mut [u8]),
}
impl<'p> MutPacketData<'p> {
pub fn as_slice(&self) -> &[u8] {
match self {
&MutPacketData::Owned(ref data) => data.deref(),
&MutPacketData::Borrowed(ref data) => data,
}
}
pub fn as_mut_slice(&mut self) -> &mut [u8] {
match self {
&mut MutPacketData::Owned(ref mut data) => data.deref_mut(),
&mut MutPacketData::Borrowed(ref mut data) => data,
}
}
pub fn to_immutable(self) -> PacketData<'p> {
match self {
MutPacketData::Owned(data) => PacketData::Owned(data),
MutPacketData::Borrowed(data) => PacketData::Borrowed(data),
}
}
pub fn len(&self) -> usize {
self.as_slice().len()
}
}
impl_index!(MutPacketData, usize, u8);
impl_index!(MutPacketData, Range<usize>, [u8]);
impl_index!(MutPacketData, RangeTo<usize>, [u8]);
impl_index!(MutPacketData, RangeFrom<usize>, [u8]);
impl_index!(MutPacketData, RangeFull, [u8]);
impl_index_mut!(MutPacketData, usize, u8);
impl_index_mut!(MutPacketData, Range<usize>, [u8]);
impl_index_mut!(MutPacketData, RangeTo<usize>, [u8]);
impl_index_mut!(MutPacketData, RangeFrom<usize>, [u8]);
impl_index_mut!(MutPacketData, RangeFull, [u8]);
pub trait PrimitiveValues {
type T;
fn to_primitive_values(&self) -> Self::T;
}
impl PrimitiveValues for MacAddr {
type T = (u8, u8, u8, u8, u8, u8);
fn to_primitive_values(&self) -> (u8, u8, u8, u8, u8, u8) {
(self.0, self.1, self.2, self.3, self.4, self.5)
}
}
impl PrimitiveValues for Ipv4Addr {
type T = (u8, u8, u8, u8);
fn to_primitive_values(&self) -> (u8, u8, u8, u8) {
let octets = self.octets();
(octets[0], octets[1], octets[2], octets[3])
}
}
impl PrimitiveValues for Ipv6Addr {
type T = (u16, u16, u16, u16, u16, u16, u16, u16);
fn to_primitive_values(&self) -> (u16, u16, u16, u16, u16, u16, u16, u16) {
let segments = self.segments();
(
segments[0],
segments[1],
segments[2],
segments[3],
segments[4],
segments[5],
segments[6],
segments[7],
)
}
}