mirror of https://github.com/ospab/ostp.git
57 lines
1.4 KiB
Rust
57 lines
1.4 KiB
Rust
use std::net::IpAddr;
|
|
|
|
pub type IpFilter<'a> = Box<dyn Fn(&IpAddr, &IpAddr) -> bool + Send + Sync + 'a>;
|
|
|
|
pub struct IpFilters<'a> {
|
|
filters: Vec<IpFilter<'a>>,
|
|
}
|
|
|
|
impl<'a> Default for IpFilters<'a> {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
impl<'a> IpFilters<'a> {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
filters: Default::default(),
|
|
}
|
|
}
|
|
|
|
pub fn with_non_broadcast() -> Self {
|
|
macro_rules! non_broadcast {
|
|
($addr:ident) => {
|
|
match $addr {
|
|
IpAddr::V4(a) => !(a.is_broadcast() || a.is_multicast() || a.is_unspecified()),
|
|
IpAddr::V6(a) => !(a.is_multicast() || a.is_unspecified()),
|
|
}
|
|
};
|
|
}
|
|
Self {
|
|
filters: vec![Box::new(|src, dst| {
|
|
non_broadcast!(src) && non_broadcast!(dst)
|
|
})],
|
|
}
|
|
}
|
|
|
|
pub fn add(&mut self, filter: IpFilter<'a>) {
|
|
self.filters.push(filter);
|
|
}
|
|
|
|
pub fn add_fn<F>(&mut self, filter: F)
|
|
where
|
|
F: Fn(&IpAddr, &IpAddr) -> bool + Send + Sync + 'a,
|
|
{
|
|
self.filters.push(Box::new(filter));
|
|
}
|
|
|
|
pub fn add_all<I: IntoIterator<Item = IpFilter<'a>>>(&mut self, filters: I) {
|
|
self.filters.extend(filters);
|
|
}
|
|
|
|
pub fn is_allowed(&self, src: &IpAddr, dst: &IpAddr) -> bool {
|
|
self.filters.iter().all(|filter| filter(src, dst))
|
|
}
|
|
}
|