use crate::wire::{ip, udp, tcp, Checksum};
#[derive(Clone, Debug)]
pub struct Personality {
capabilities: Capabilities,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Capabilities {
ipv4: Protocol,
icmpv4: Protocol,
udp: Udp,
tcp: Tcp,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Protocol {
send: Checksum,
receive: Checksum,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Udp {
inner: Protocol,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Tcp {
inner: Protocol,
}
impl Personality {
pub fn baseline() -> Self {
Personality {
capabilities: Capabilities::no_support(),
}
}
pub fn capabilities(&self) -> &Capabilities {
&self.capabilities
}
pub fn capabilities_mut(&mut self) -> &mut Capabilities {
&mut self.capabilities
}
}
impl Capabilities {
pub fn no_support() -> Self {
Capabilities {
ipv4: Protocol::no_support(),
icmpv4: Protocol::no_support(),
udp: Udp::no_support(),
tcp: Tcp::no_support(),
}
}
pub fn icmpv4(&self) -> &Protocol {
&self.icmpv4
}
pub fn ipv4(&self) -> &Protocol {
&self.ipv4
}
pub fn ipv4_mut(&mut self) -> &mut Protocol {
&mut self.ipv4
}
pub fn udp(&self) -> &Udp {
&self.udp
}
pub fn udp_mut(&mut self) -> &mut Udp {
&mut self.udp
}
pub fn tcp(&self) -> &Tcp {
&self.tcp
}
pub fn tcp_mut(&mut self) -> &mut Tcp {
&mut self.tcp
}
}
impl Protocol {
pub fn no_support() -> Self {
Protocol {
send: Checksum::Manual,
receive: Checksum::Manual,
}
}
pub fn offloaded() -> Self {
Protocol {
send: Checksum::Ignored,
receive: Checksum::Ignored,
}
}
pub fn rx_checksum(&self) -> Checksum {
self.receive
}
pub fn rx_checksum_mut(&mut self) -> &mut Checksum {
&mut self.receive
}
pub fn tx_checksum(&self) -> Checksum {
self.send
}
pub fn tx_checksum_mut(&mut self) -> &mut Checksum {
&mut self.send
}
}
impl Udp {
pub fn no_support() -> Self {
Udp {
inner: Protocol::no_support(),
}
}
pub fn tx_checksum(&self, ip: ip::Repr) -> udp::Checksum {
match self.inner.tx_checksum() {
Checksum::Manual => udp::Checksum::Lazy {
src_addr: ip.src_addr(),
dst_addr: ip.dst_addr(),
},
Checksum::Ignored => udp::Checksum::Ignored,
}
}
pub fn rx_checksum(&self, ip: ip::Repr) -> udp::Checksum {
match self.inner.rx_checksum() {
Checksum::Manual => udp::Checksum::Lazy {
src_addr: ip.src_addr(),
dst_addr: ip.dst_addr(),
},
Checksum::Ignored => udp::Checksum::Ignored,
}
}
}
impl Tcp {
pub fn no_support() -> Self {
Tcp {
inner: Protocol::no_support(),
}
}
pub fn tx_checksum(&self, ip: ip::Repr) -> tcp::Checksum {
match self.inner.tx_checksum() {
Checksum::Manual => tcp::Checksum::Manual {
src_addr: ip.src_addr(),
dst_addr: ip.dst_addr(),
},
Checksum::Ignored => tcp::Checksum::Ignored,
}
}
pub fn rx_checksum(&self, ip: ip::Repr) -> tcp::Checksum {
match self.inner.rx_checksum() {
Checksum::Manual => tcp::Checksum::Manual {
src_addr: ip.src_addr(),
dst_addr: ip.dst_addr(),
},
Checksum::Ignored => tcp::Checksum::Ignored,
}
}
}
impl From<Protocol> for Udp {
fn from(inner: Protocol) -> Self {
Udp {
inner,
}
}
}
impl From<Protocol> for Tcp {
fn from(inner: Protocol) -> Self {
Tcp {
inner,
}
}
}