use super::super::*;
#[derive(Clone, Debug, Eq, PartialEq, Default)]
pub struct Ipv4Extensions {
pub auth: Option<IpAuthenticationHeader>,
}
#[derive(Clone, Debug, Eq, PartialEq, Default)]
pub struct Ipv4ExtensionsSlice<'a> {
pub auth: Option<IpAuthenticationHeaderSlice<'a>>,
}
impl Ipv4Extensions {
pub fn from_slice(start_protocol: u8, slice: &[u8]) -> Result<(Ipv4Extensions, u8, &[u8]), ReadError> {
Ipv4ExtensionsSlice::from_slice(start_protocol, slice).map(
|v| (v.0.to_header(), v.1, v.2)
)
}
pub fn read<T: io::Read + io::Seek + Sized>(reader: &mut T, start_ip_number: u8) -> Result<(Ipv4Extensions, u8), ReadError> {
use ip_number::*;
if AUTH == start_ip_number {
let header = IpAuthenticationHeader::read(reader)?;
let next_ip_number = header.next_header;
Ok((
Ipv4Extensions{
auth: Some(header)
},
next_ip_number,
))
} else {
Ok((Default::default(), start_ip_number))
}
}
pub fn write<T: io::Write + Sized>(&self, writer: &mut T, start_ip_number: u8) -> Result<(), WriteError> {
use ip_number::*;
use IpNumber::*;
use ValueError::*;
match self.auth {
Some(ref header) => if AUTH == start_ip_number {
header.write(writer)
} else {
Err(Ipv4ExtensionNotReferenced(AuthenticationHeader).into())
},
None => Ok(())
}
}
pub fn header_len(&self) -> usize {
if let Some(ref header) = self.auth {
header.header_len()
} else {
0
}
}
pub fn set_next_headers(&mut self, last_protocol_number: u8) -> u8 {
use ip_number::*;
let mut next = last_protocol_number;
if let Some(ref mut header) = self.auth {
header.next_header = next;
next = AUTH;
}
next
}
pub fn next_header(&self, first_next_header: u8) -> Result<u8, ValueError> {
use ip_number::*;
if let Some(ref auth) = self.auth {
if first_next_header == AUTH {
Ok(auth.next_header)
} else {
Err(
ValueError::Ipv4ExtensionNotReferenced(
IpNumber::AuthenticationHeader
)
)
}
} else {
Ok(first_next_header)
}
}
#[inline]
pub fn is_empty(&self) -> bool {
self.auth.is_none()
}
}
impl<'a> Ipv4ExtensionsSlice<'a> {
pub fn from_slice(start_ip_number: u8, start_slice: &'a [u8]) -> Result<(Ipv4ExtensionsSlice, u8, &[u8]), ReadError> {
use ip_number::*;
if AUTH == start_ip_number {
let header = IpAuthenticationHeaderSlice::from_slice(start_slice)?;
let rest = &start_slice[header.slice().len()..];
let next_header = header.next_header();
Ok((
Ipv4ExtensionsSlice{
auth: Some(header)
},
next_header,
rest
))
} else {
Ok((Default::default(), start_ip_number, start_slice))
}
}
pub fn to_header(&self) -> Ipv4Extensions {
Ipv4Extensions {
auth: self.auth.as_ref().map(|v| v.to_header())
}
}
#[inline]
pub fn is_empty(&self) -> bool {
self.auth.is_none()
}
}