use crate::error::*;
use crate::packet::{Packet as P, PacketMut as PM, AsPacket, AsPacketMut};
use crate::size;
use crate::ip::{v4, v6};
#[derive(Debug)]
pub enum Packet<B: AsRef<[u8]>> {
V4(v4::Packet<B>),
V6(v6::Packet<B>),
}
impl<B: AsRef<[u8]>> Packet<B> {
pub fn unchecked(buffer: B) -> Packet<B> {
match buffer.as_ref()[0] >> 4 {
4 =>
Packet::V4(v4::Packet::unchecked(buffer)),
6 =>
Packet::V6(v6::Packet::unchecked(buffer)),
_ =>
panic!("not an IPv4 or IPv6 packet")
}
}
pub fn no_payload(buffer: B) -> Result<Packet<B>> {
match buffer.as_ref()[0] >> 4 {
4 =>
v4::Packet::no_payload(buffer).map(Packet::V4),
6 =>
v6::Packet::no_payload(buffer).map(Packet::V6),
_ =>
Err(Error::InvalidPacket)
}
}
pub fn new(buffer: B) -> Result<Packet<B>> {
match buffer.as_ref()[0] >> 4 {
4 =>
v4::Packet::new(buffer).map(Packet::V4),
6 =>
v6::Packet::new(buffer).map(Packet::V6),
_ =>
Err(Error::InvalidPacket)
}
}
}
impl<B: AsRef<[u8]>> From<v4::Packet<B>> for Packet<B> {
fn from(value: v4::Packet<B>) -> Packet<B> {
Packet::V4(value)
}
}
impl<B: AsRef<[u8]>> From<v6::Packet<B>> for Packet<B> {
fn from(value: v6::Packet<B>) -> Packet<B> {
Packet::V6(value)
}
}
impl<'a, B: AsRef<[u8]> + Clone> From<&'a v4::Packet<B>> for Packet<B> {
fn from(value: &'a v4::Packet<B>) -> Packet<B> {
Packet::V4(value.clone())
}
}
impl<'a, B: AsRef<[u8]> + Clone> From<&'a v6::Packet<B>> for Packet<B> {
fn from(value: &'a v6::Packet<B>) -> Packet<B> {
Packet::V6(value.clone())
}
}
impl<B: AsRef<[u8]>> Packet<B> {
pub fn to_owned(&self) -> Packet<Vec<u8>> {
match *self {
Packet::V4(ref packet) =>
Packet::V4(packet.to_owned()),
Packet::V6(ref packet) =>
Packet::V6(packet.to_owned()),
}
}
}
impl<B: AsRef<[u8]>> AsRef<[u8]> for Packet<B> {
fn as_ref(&self) -> &[u8] {
match *self {
Packet::V4(ref packet) =>
packet.as_ref(),
Packet::V6(ref packet) =>
packet.as_ref(),
}
}
}
impl<B: AsRef<[u8]> + AsMut<[u8]>> AsMut<[u8]> for Packet<B> {
fn as_mut(&mut self) -> &mut [u8] {
match *self {
Packet::V4(ref mut packet) =>
packet.as_mut(),
Packet::V6(ref mut packet) =>
packet.as_mut(),
}
}
}
impl<'a, B: AsRef<[u8]>> AsPacket<'a, Packet<&'a [u8]>> for B {
fn as_packet(&self) -> Result<Packet<&[u8]>> {
Packet::new(self.as_ref())
}
}
impl<'a, B: AsRef<[u8]> + AsMut<[u8]>> AsPacketMut<'a, Packet<&'a mut [u8]>> for B {
fn as_packet_mut(&mut self) -> Result<Packet<&mut [u8]>> {
Packet::new(self.as_mut())
}
}
impl<B: AsRef<[u8]>> P for Packet<B> {
fn split(&self) -> (&[u8], &[u8]) {
match *self {
Packet::V4(ref packet) =>
packet.split(),
Packet::V6(ref packet) =>
packet.split(),
}
}
}
impl<B: AsRef<[u8]> + AsMut<[u8]>> PM for Packet<B> {
fn split_mut(&mut self) -> (&mut [u8], &mut [u8]) {
match *self {
Packet::V4(ref mut packet) =>
packet.split_mut(),
Packet::V6(ref mut packet) =>
packet.split_mut(),
}
}
}
impl<B: AsRef<[u8]>> size::header::Size for Packet<B> {
fn size(&self) -> usize {
match *self {
Packet::V4(ref packet) =>
size::header::Size::size(packet),
Packet::V6(ref packet) =>
size::header::Size::size(packet),
}
}
}
impl<B: AsRef<[u8]>> size::payload::Size for Packet<B> {
fn size(&self) -> usize {
match *self {
Packet::V4(ref packet) =>
size::payload::Size::size(packet),
Packet::V6(ref packet) =>
size::payload::Size::size(packet),
}
}
}