use super::*;
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum ElementFilter<T> {
Any,
No,
Some(T)
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum LinkFilter {
Ethernet2 {
source: Option<[u8;6]>,
destination: Option<[u8;6]>
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum VlanFilter {
Single(Option<u16>),
Double {
outer_identifier: Option<u16>,
inner_identifier: Option<u16>
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum IpFilter {
Ipv4 {
source: Option<[u8;4]>,
destination: Option<[u8;4]>
},
Ipv6 {
source: Option<[u8;16]>,
destination: Option<[u8;16]>
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum TransportFilter {
Udp {
source_port: Option<u16>,
destination_port: Option<u16>
},
Tcp {
source_port: Option<u16>,
destination_port: Option<u16>
}
}
#[derive(Debug, Clone, Default, Eq, PartialEq)]
pub struct Filter {
pub link: ElementFilter<LinkFilter>,
pub vlan: ElementFilter<VlanFilter>,
pub ip: ElementFilter<IpFilter>,
pub transport: ElementFilter<TransportFilter>,
}
impl<T> Default for ElementFilter<T> {
fn default() -> ElementFilter<T> {
ElementFilter::Any
}
}
impl LinkFilter {
pub fn applies_to_slice(&self, slice: &LinkSlice) -> bool {
use crate::LinkSlice::*;
match self {
LinkFilter::Ethernet2{
source: expected_source,
destination: expected_destination
} => match slice {
Ethernet2(header) => (match expected_source {
Some(e) => header.source() == *e,
None => true
}) && (match expected_destination {
Some(e) => header.destination() == *e,
None => true
})
}
}
}
}
impl VlanFilter {
pub fn applies_to_slice(&self, slice: &VlanSlice) -> bool {
use crate::VlanSlice::*;
match self {
VlanFilter::Single(expected_id) => {
match slice {
SingleVlan(header) => {
match expected_id {
Some(e) => header.vlan_identifier() == *e,
None => true
}
},
_ => false }
},
VlanFilter::Double { inner_identifier: expected_inner_id, outer_identifier: expecetd_outer_id } => {
match slice {
DoubleVlan(header) => {
(match expecetd_outer_id {
Some(e) => header.outer().vlan_identifier() == *e,
None => true
}) && (match expected_inner_id {
Some(e) => header.inner().vlan_identifier() == *e,
None => true
})
},
_ => false
}
}
}
}
}
impl IpFilter {
pub fn applies_to_slice(&self, slice: &InternetSlice) -> bool {
use crate::InternetSlice::*;
match self {
IpFilter::Ipv4 { source: expected_source, destination: expected_destination } => {
match slice {
Ipv4(header) => {
(match expected_source {
Some(e) => header.source() == &e[..],
None => true
}) && (match expected_destination {
Some(e) => header.destination() == &e[..],
None => true
})
},
_ => false
}
},
IpFilter::Ipv6 { source: expected_source, destination: expected_destination } => {
match slice {
Ipv6(header, _) => {
(match expected_source {
Some(e) => header.source() == &e[..],
None => true
}) && (match expected_destination {
Some(e) => header.destination() == &e[..],
None => true
})
},
_ => false
}
}
}
}
}
impl TransportFilter {
pub fn applies_to_slice(&self, slice: &TransportSlice) -> bool {
use crate::TransportSlice::*;
match self {
TransportFilter::Udp {
source_port: expected_source_port,
destination_port: expected_destination_port
} => {
match slice {
Udp(header) => {
(match expected_source_port {
Some(e) => header.source_port() == *e,
None => true
}) && (match expected_destination_port {
Some(e) => header.destination_port() == *e,
None => true
})
}
_ => false
}
},
TransportFilter::Tcp {
source_port: expected_source_port,
destination_port: expected_destination_port
} => {
match slice {
Tcp(header) => {
(match expected_source_port {
Some(e) => header.source_port() == *e,
None => true
}) && (match expected_destination_port {
Some(e) => header.destination_port() == *e,
None => true
})
}
_ => false
}
}
}
}
}
impl Filter {
pub fn applies_to_slice(&self, slice: &SlicedPacket) -> bool {
(match &self.link {
ElementFilter::Any => true,
ElementFilter::No => slice.link.is_none(),
ElementFilter::Some(filter) => {
match &slice.link {
Some(value) => filter.applies_to_slice(value),
None => false
}
}
}) && (match &self.vlan {
ElementFilter::Any => true,
ElementFilter::No => slice.vlan.is_none(),
ElementFilter::Some(filter) => {
match &slice.vlan {
Some(value) => filter.applies_to_slice(value),
None => false
}
}
}) && (match &self.ip {
ElementFilter::Any => true,
ElementFilter::No => slice.ip.is_none(),
ElementFilter::Some(filter) => {
match &slice.ip {
Some(value) => filter.applies_to_slice(value),
None => false
}
}
}) && (match &self.transport {
ElementFilter::Any => true,
ElementFilter::No => slice.transport.is_none(),
ElementFilter::Some(filter) => {
match &slice.transport {
Some(value) => filter.applies_to_slice(value),
None => false
}
}
})
}
}