Add IPv4 / IPv6 selectors extraction
This commit is contained in:
parent
b3f89309c4
commit
c6c1ce26d3
@ -57,25 +57,36 @@ fn extract_mac_address_or_var(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||||
pub struct NetworkFilterIPv4OrVar(pub String);
|
pub struct NetworkFilterIPOrVar<const V: usize>(pub String);
|
||||||
|
pub type NetworkFilterIPv4OrVar = NetworkFilterIPOrVar<4>;
|
||||||
|
|
||||||
impl NetworkFilterIPv4OrVar {
|
impl<const V: usize> NetworkFilterIPOrVar<V> {
|
||||||
pub fn is_valid(&self) -> bool {
|
pub fn is_valid(&self) -> bool {
|
||||||
is_var_def(&self.0) || net_utils::is_ipv4_address_valid(&self.0)
|
is_var_def(&self.0)
|
||||||
|
|| match V {
|
||||||
|
4 => net_utils::is_ipv4_address_valid(&self.0),
|
||||||
|
6 => net_utils::is_ipv6_address_valid(&self.0),
|
||||||
|
_ => panic!("Unsupported IP version!"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&String> for NetworkFilterIPv4OrVar {
|
impl<const V: usize> From<&String> for NetworkFilterIPOrVar<V> {
|
||||||
fn from(value: &String) -> Self {
|
fn from(value: &String) -> Self {
|
||||||
|
if V != 4 && V != 6 {
|
||||||
|
panic!("Unsupported IP version!");
|
||||||
|
}
|
||||||
Self(value.to_string())
|
Self(value.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_ipv4_or_var(n: &Option<NetworkFilterIPv4OrVar>) -> anyhow::Result<Option<String>> {
|
fn extract_ip_or_var<const V: usize>(
|
||||||
|
n: &Option<NetworkFilterIPOrVar<V>>,
|
||||||
|
) -> anyhow::Result<Option<String>> {
|
||||||
if let Some(ip) = n {
|
if let Some(ip) = n {
|
||||||
if !ip.is_valid() {
|
if !ip.is_valid() {
|
||||||
return Err(NetworkFilterExtraction(format!(
|
return Err(NetworkFilterExtraction(format!(
|
||||||
"Invalid IPv4 address or variable! {}",
|
"Invalid IPv{V} address or variable! {}",
|
||||||
ip.0
|
ip.0
|
||||||
))
|
))
|
||||||
.into());
|
.into());
|
||||||
@ -85,6 +96,16 @@ fn extract_ipv4_or_var(n: &Option<NetworkFilterIPv4OrVar>) -> anyhow::Result<Opt
|
|||||||
Ok(n.as_ref().map(|n| n.0.to_string()))
|
Ok(n.as_ref().map(|n| n.0.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn extract_ip_mask<const V: usize>(n: &Option<u8>) -> anyhow::Result<Option<u8>> {
|
||||||
|
if let Some(mask) = n {
|
||||||
|
if !net_utils::is_mask_valid(V, *mask) {
|
||||||
|
return Err(NetworkFilterExtraction(format!("Invalid IPv{V} mask! {}", mask)).into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(*n)
|
||||||
|
}
|
||||||
|
|
||||||
fn extract_nw_filter_comment(n: &Option<String>) -> anyhow::Result<Option<String>> {
|
fn extract_nw_filter_comment(n: &Option<String>) -> anyhow::Result<Option<String>> {
|
||||||
if let Some(comment) = n {
|
if let Some(comment) = n {
|
||||||
if comment.len() > 256 || comment.contains('\"') || comment.contains('\n') {
|
if comment.len() > 256 || comment.contains('\"') || comment.contains('\n') {
|
||||||
@ -212,15 +233,17 @@ impl NetworkFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lib2rest_process_ip_rule(n: &NetworkFilterRuleProtocolIpvx) -> NetworkFilterSelectorIP {
|
fn lib2rest_process_ip_rule<const V: usize>(
|
||||||
|
n: &NetworkFilterRuleProtocolIpvx,
|
||||||
|
) -> NetworkFilterSelectorIP<V> {
|
||||||
NetworkFilterSelectorIP {
|
NetworkFilterSelectorIP {
|
||||||
srcmacaddr: n.srcmacaddr.clone(),
|
srcmacaddr: n.srcmacaddr.as_ref().map(|v| v.into()),
|
||||||
srcmacmask: n.srcmacmask.clone(),
|
srcmacmask: n.srcmacmask.as_ref().map(|v| v.into()),
|
||||||
dstmacaddr: n.dstmacaddr.clone(),
|
dstmacaddr: n.dstmacaddr.as_ref().map(|v| v.into()),
|
||||||
dstmacmask: n.dstmacmask.clone(),
|
dstmacmask: n.dstmacmask.as_ref().map(|v| v.into()),
|
||||||
srcipaddr: n.srcipaddr.clone(),
|
srcipaddr: n.srcipaddr.as_ref().map(|v| v.into()),
|
||||||
srcipmask: n.srcipmask,
|
srcipmask: n.srcipmask,
|
||||||
dstipaddr: n.dstipaddr.clone(),
|
dstipaddr: n.dstipaddr.as_ref().map(|v| v.into()),
|
||||||
dstipmask: n.dstipmask,
|
dstipmask: n.dstipmask,
|
||||||
comment: n.comment.clone(),
|
comment: n.comment.clone(),
|
||||||
}
|
}
|
||||||
@ -428,14 +451,30 @@ impl NetworkFilter {
|
|||||||
srcmacmask: extract_mac_address_or_var(&selector.srcmacmask)?,
|
srcmacmask: extract_mac_address_or_var(&selector.srcmacmask)?,
|
||||||
dstmacaddr: extract_mac_address_or_var(&selector.dstmacaddr)?,
|
dstmacaddr: extract_mac_address_or_var(&selector.dstmacaddr)?,
|
||||||
dstmacmask: extract_mac_address_or_var(&selector.dstmacmask)?,
|
dstmacmask: extract_mac_address_or_var(&selector.dstmacmask)?,
|
||||||
arpsrcipaddr: extract_ipv4_or_var(&selector.arpsrcipaddr)?,
|
arpsrcipaddr: extract_ip_or_var(&selector.arpsrcipaddr)?,
|
||||||
arpsrcipmask: selector.arpsrcipmask,
|
arpsrcipmask: selector.arpsrcipmask,
|
||||||
arpdstipaddr: extract_ipv4_or_var(&selector.arpdstipaddr)?,
|
arpdstipaddr: extract_ip_or_var(&selector.arpdstipaddr)?,
|
||||||
arpdstipmask: selector.arpdstipmask,
|
arpdstipmask: selector.arpdstipmask,
|
||||||
comment: extract_nw_filter_comment(&selector.comment)?,
|
comment: extract_nw_filter_comment(&selector.comment)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rest2lib_process_ip_selector<const V: usize>(
|
||||||
|
selector: &NetworkFilterSelectorIP<V>,
|
||||||
|
) -> anyhow::Result<NetworkFilterRuleProtocolIpvx> {
|
||||||
|
Ok(NetworkFilterRuleProtocolIpvx {
|
||||||
|
srcmacaddr: extract_mac_address_or_var(&selector.srcmacaddr)?,
|
||||||
|
srcmacmask: extract_mac_address_or_var(&selector.srcmacmask)?,
|
||||||
|
dstmacaddr: extract_mac_address_or_var(&selector.dstmacaddr)?,
|
||||||
|
dstmacmask: extract_mac_address_or_var(&selector.dstmacmask)?,
|
||||||
|
srcipaddr: extract_ip_or_var(&selector.srcipaddr)?,
|
||||||
|
srcipmask: extract_ip_mask::<V>(&selector.srcipmask)?,
|
||||||
|
dstipaddr: extract_ip_or_var(&selector.dstipaddr)?,
|
||||||
|
dstipmask: extract_ip_mask::<V>(&selector.dstipmask)?,
|
||||||
|
comment: extract_nw_filter_comment(&selector.comment)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn rest2lib_process_rule(rule: &NetworkFilterRule) -> anyhow::Result<NetworkFilterRuleXML> {
|
fn rest2lib_process_rule(rule: &NetworkFilterRule) -> anyhow::Result<NetworkFilterRuleXML> {
|
||||||
let mut rule_xml = NetworkFilterRuleXML {
|
let mut rule_xml = NetworkFilterRuleXML {
|
||||||
action: rule.action.to_xml(),
|
action: rule.action.to_xml(),
|
||||||
@ -484,8 +523,13 @@ impl NetworkFilter {
|
|||||||
.push(Self::rest2lib_process_arp_selector(a)?);
|
.push(Self::rest2lib_process_arp_selector(a)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkFilterSelector::IPv4(_) => todo!(),
|
NetworkFilterSelector::IPv4(ip) => rule_xml
|
||||||
NetworkFilterSelector::IPv6(_) => todo!(),
|
.ipv4_selectors
|
||||||
|
.push(Self::rest2lib_process_ip_selector(ip)?),
|
||||||
|
|
||||||
|
NetworkFilterSelector::IPv6(ip) => rule_xml
|
||||||
|
.ipv6_selectors
|
||||||
|
.push(Self::rest2lib_process_ip_selector(ip)?),
|
||||||
|
|
||||||
NetworkFilterSelector::TCP(_) => todo!(),
|
NetworkFilterSelector::TCP(_) => todo!(),
|
||||||
NetworkFilterSelector::UDP(_) => todo!(),
|
NetworkFilterSelector::UDP(_) => todo!(),
|
||||||
@ -686,14 +730,14 @@ pub struct NetworkSelectorARP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||||
pub struct NetworkFilterSelectorIP {
|
pub struct NetworkFilterSelectorIP<const V: usize> {
|
||||||
srcmacaddr: Option<String>,
|
srcmacaddr: Option<NetworkFilterMacAddressOrVar>,
|
||||||
srcmacmask: Option<String>,
|
srcmacmask: Option<NetworkFilterMacAddressOrVar>,
|
||||||
dstmacaddr: Option<String>,
|
dstmacaddr: Option<NetworkFilterMacAddressOrVar>,
|
||||||
dstmacmask: Option<String>,
|
dstmacmask: Option<NetworkFilterMacAddressOrVar>,
|
||||||
srcipaddr: Option<String>,
|
srcipaddr: Option<NetworkFilterIPOrVar<V>>,
|
||||||
srcipmask: Option<u8>,
|
srcipmask: Option<u8>,
|
||||||
dstipaddr: Option<String>,
|
dstipaddr: Option<NetworkFilterIPOrVar<V>>,
|
||||||
dstipmask: Option<u8>,
|
dstipmask: Option<u8>,
|
||||||
comment: Option<String>,
|
comment: Option<String>,
|
||||||
}
|
}
|
||||||
@ -728,8 +772,8 @@ pub enum NetworkFilterSelector {
|
|||||||
Mac(NetworkSelectorMac),
|
Mac(NetworkSelectorMac),
|
||||||
Arp(NetworkSelectorARP),
|
Arp(NetworkSelectorARP),
|
||||||
Rarp(NetworkSelectorARP),
|
Rarp(NetworkSelectorARP),
|
||||||
IPv4(NetworkFilterSelectorIP),
|
IPv4(NetworkFilterSelectorIP<4>),
|
||||||
IPv6(NetworkFilterSelectorIP),
|
IPv6(NetworkFilterSelectorIP<6>),
|
||||||
TCP(NetworkSelectorLayer4<Ipv4Addr>),
|
TCP(NetworkSelectorLayer4<Ipv4Addr>),
|
||||||
UDP(NetworkSelectorLayer4<Ipv4Addr>),
|
UDP(NetworkSelectorLayer4<Ipv4Addr>),
|
||||||
SCTP(NetworkSelectorLayer4<Ipv4Addr>),
|
SCTP(NetworkSelectorLayer4<Ipv4Addr>),
|
||||||
|
@ -23,13 +23,35 @@ pub fn is_ipv4_address_valid<D: AsRef<str>>(ip: D) -> bool {
|
|||||||
Ipv4Addr::from_str(ip.as_ref()).is_ok()
|
Ipv4Addr::from_str(ip.as_ref()).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_ipv6_address_valid<D: AsRef<str>>(ip: D) -> bool {
|
||||||
|
Ipv6Addr::from_str(ip.as_ref()).is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_ipv4_mask_valid(mask: u8) -> bool {
|
||||||
|
mask <= 32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_ipv6_mask_valid(mask: u8) -> bool {
|
||||||
|
mask <= 64
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_mask_valid(ipv: usize, mask: u8) -> bool {
|
||||||
|
match ipv {
|
||||||
|
4 => is_ipv4_mask_valid(mask),
|
||||||
|
6 => is_ipv6_mask_valid(mask),
|
||||||
|
_ => panic!("Unsupported IP version"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_mac_address_valid<D: AsRef<str>>(mac: D) -> bool {
|
pub fn is_mac_address_valid<D: AsRef<str>>(mac: D) -> bool {
|
||||||
lazy_regex::regex!("^([a-fA-F0-9]{2}[:-]){5}[a-fA-F0-9]{2}$").is_match(mac.as_ref())
|
lazy_regex::regex!("^([a-fA-F0-9]{2}[:-]){5}[a-fA-F0-9]{2}$").is_match(mac.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::utils::net_utils::{is_ipv4_address_valid, is_mac_address_valid};
|
use crate::utils::net_utils::{
|
||||||
|
is_ipv4_address_valid, is_ipv6_address_valid, is_mac_address_valid, is_mask_valid,
|
||||||
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_mac_address_valid() {
|
fn test_is_mac_address_valid() {
|
||||||
@ -49,5 +71,28 @@ mod tests {
|
|||||||
assert!(!is_ipv4_address_valid("tata"));
|
assert!(!is_ipv4_address_valid("tata"));
|
||||||
assert!(!is_ipv4_address_valid("1.25.25.288"));
|
assert!(!is_ipv4_address_valid("1.25.25.288"));
|
||||||
assert!(!is_ipv4_address_valid("5.5.5.5.5"));
|
assert!(!is_ipv4_address_valid("5.5.5.5.5"));
|
||||||
|
assert!(!is_ipv4_address_valid("fe80::"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_ipv6_address_valid() {
|
||||||
|
assert!(is_ipv6_address_valid("fe80::"));
|
||||||
|
assert!(is_ipv6_address_valid("fe80:dd::"));
|
||||||
|
assert!(is_ipv6_address_valid("00:00:00:00:00::"));
|
||||||
|
|
||||||
|
assert!(!is_ipv6_address_valid("tata"));
|
||||||
|
assert!(!is_ipv6_address_valid("2.56.58.156"));
|
||||||
|
assert!(!is_ipv6_address_valid("fe::dd::dd"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_mask_valid() {
|
||||||
|
assert!(is_mask_valid(4, 25));
|
||||||
|
assert!(is_mask_valid(4, 32));
|
||||||
|
assert!(is_mask_valid(6, 32));
|
||||||
|
assert!(is_mask_valid(6, 34));
|
||||||
|
|
||||||
|
assert!(!is_mask_valid(4, 34));
|
||||||
|
assert!(!is_mask_valid(6, 69));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user