use super::ipv4::Protocol;
use crate::parser::{ByteOrder, Invalid, Parser};
use crate::{Error, Head};
use core::net::{Ipv6Addr, SocketAddrV6};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Origin {
Manual = 0x00,
StatelessAutoConfiguration = 0x01,
StatefulConfiguration = 0x02,
}
impl Parser<Origin> for &[u8] {
type Arg = ();
fn parse(&mut self, arg: ()) -> Result<Origin, Invalid> {
match self.parse(arg)? {
0x00u8 => Ok(Origin::Manual),
0x01 => Ok(Origin::StatelessAutoConfiguration),
0x02 => Ok(Origin::StatefulConfiguration),
_ => Err(Invalid),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Ipv6 {
pub local: SocketAddrV6,
pub remote: SocketAddrV6,
pub protocol: Protocol,
pub origin: Origin,
pub prefix_length: u8,
pub gateway_ip: Ipv6Addr,
}
impl<'a> TryFrom<Head<'a>> for Ipv6 {
type Error = Error;
fn try_from(mut node: Head<'a>) -> Result<Self, Self::Error> {
let local_ip_bytes: [u8; 16] = node.data.parse(())?;
let local_ip = Ipv6Addr::from(local_ip_bytes);
let remote_ip_bytes: [u8; 16] = node.data.parse(())?;
let remote_ip = Ipv6Addr::from(remote_ip_bytes);
let local_port = node.data.parse(ByteOrder::Little)?;
let remote_port = node.data.parse(ByteOrder::Little)?;
let protocol = Protocol(node.data.parse(ByteOrder::Little)?);
let ip_address_origin = node.data.parse(())?;
let prefix_length = node.data.parse(())?;
let gateway_ip_bytes: [u8; 16] = node.data.finish(())?;
let gateway_ip = Ipv6Addr::from(gateway_ip_bytes);
Ok(Self {
local: SocketAddrV6::new(local_ip, local_port, 0, 0),
remote: SocketAddrV6::new(remote_ip, remote_port, 0, 0),
protocol,
origin: ip_address_origin,
prefix_length,
gateway_ip,
})
}
}