Add ARP / RARP selectors extraction
This commit is contained in:
parent
8182ecd7f6
commit
b3f89309c4
@ -45,7 +45,7 @@ pub struct NetworkFilterRuleProtocolMac {
|
|||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||||
#[serde(rename = "arp")]
|
#[serde(rename = "arp")]
|
||||||
pub struct NetworkFilterRuleProtocolArp {
|
pub struct NetworkFilterRuleProtocolArpXML {
|
||||||
#[serde(
|
#[serde(
|
||||||
rename(serialize = "@srcmacaddr"),
|
rename(serialize = "@srcmacaddr"),
|
||||||
skip_serializing_if = "Option::is_none"
|
skip_serializing_if = "Option::is_none"
|
||||||
@ -247,11 +247,11 @@ pub struct NetworkFilterRuleXML {
|
|||||||
|
|
||||||
/// Match arp protocol
|
/// Match arp protocol
|
||||||
#[serde(default, rename = "arp", skip_serializing_if = "Vec::is_empty")]
|
#[serde(default, rename = "arp", skip_serializing_if = "Vec::is_empty")]
|
||||||
pub arp_selectors: Vec<NetworkFilterRuleProtocolArp>,
|
pub arp_selectors: Vec<NetworkFilterRuleProtocolArpXML>,
|
||||||
|
|
||||||
/// Match rarp protocol
|
/// Match rarp protocol
|
||||||
#[serde(default, rename = "arp", skip_serializing_if = "Vec::is_empty")]
|
#[serde(default, rename = "rarp", skip_serializing_if = "Vec::is_empty")]
|
||||||
pub rarp_selectors: Vec<NetworkFilterRuleProtocolArp>,
|
pub rarp_selectors: Vec<NetworkFilterRuleProtocolArpXML>,
|
||||||
|
|
||||||
/// Match IPv4 protocol
|
/// Match IPv4 protocol
|
||||||
#[serde(default, rename = "ip", skip_serializing_if = "Vec::is_empty")]
|
#[serde(default, rename = "ip", skip_serializing_if = "Vec::is_empty")]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::libvirt_lib_structures::nwfilter::{
|
use crate::libvirt_lib_structures::nwfilter::{
|
||||||
NetworkFilterRefXML, NetworkFilterRuleProtocolAll, NetworkFilterRuleProtocolArp,
|
NetworkFilterRefXML, NetworkFilterRuleProtocolAll, NetworkFilterRuleProtocolArpXML,
|
||||||
NetworkFilterRuleProtocolIpvx, NetworkFilterRuleProtocolLayer4, NetworkFilterRuleProtocolMac,
|
NetworkFilterRuleProtocolIpvx, NetworkFilterRuleProtocolLayer4, NetworkFilterRuleProtocolMac,
|
||||||
NetworkFilterRuleXML, NetworkFilterXML,
|
NetworkFilterRuleXML, NetworkFilterXML,
|
||||||
};
|
};
|
||||||
@ -56,6 +56,35 @@ fn extract_mac_address_or_var(
|
|||||||
Ok(n.as_ref().map(|n| n.0.to_string()))
|
Ok(n.as_ref().map(|n| n.0.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||||
|
pub struct NetworkFilterIPv4OrVar(pub String);
|
||||||
|
|
||||||
|
impl NetworkFilterIPv4OrVar {
|
||||||
|
pub fn is_valid(&self) -> bool {
|
||||||
|
is_var_def(&self.0) || net_utils::is_ipv4_address_valid(&self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&String> for NetworkFilterIPv4OrVar {
|
||||||
|
fn from(value: &String) -> Self {
|
||||||
|
Self(value.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extract_ipv4_or_var(n: &Option<NetworkFilterIPv4OrVar>) -> anyhow::Result<Option<String>> {
|
||||||
|
if let Some(ip) = n {
|
||||||
|
if !ip.is_valid() {
|
||||||
|
return Err(NetworkFilterExtraction(format!(
|
||||||
|
"Invalid IPv4 address or variable! {}",
|
||||||
|
ip.0
|
||||||
|
))
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(n.as_ref().map(|n| n.0.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
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') {
|
||||||
@ -169,15 +198,15 @@ impl NetworkFilter {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lib2rest_process_arp_rule(n: &NetworkFilterRuleProtocolArp) -> NetworkSelectorARP {
|
fn lib2rest_process_arp_rule(n: &NetworkFilterRuleProtocolArpXML) -> NetworkSelectorARP {
|
||||||
NetworkSelectorARP {
|
NetworkSelectorARP {
|
||||||
srcmacaddr: n.srcmacaddr.as_ref().map(|v| v.into()),
|
srcmacaddr: n.srcmacaddr.as_ref().map(|v| v.into()),
|
||||||
srcmacmask: n.srcmacmask.as_ref().map(|v| v.into()),
|
srcmacmask: n.srcmacmask.as_ref().map(|v| v.into()),
|
||||||
dstmacaddr: n.dstmacaddr.as_ref().map(|v| v.into()),
|
dstmacaddr: n.dstmacaddr.as_ref().map(|v| v.into()),
|
||||||
dstmacmask: n.dstmacmask.as_ref().map(|v| v.into()),
|
dstmacmask: n.dstmacmask.as_ref().map(|v| v.into()),
|
||||||
arpsrcipaddr: n.arpsrcipaddr.clone(),
|
arpsrcipaddr: n.arpsrcipaddr.as_ref().map(|v| v.into()),
|
||||||
arpsrcipmask: n.arpsrcipmask,
|
arpsrcipmask: n.arpsrcipmask,
|
||||||
arpdstipaddr: n.arpdstipaddr.clone(),
|
arpdstipaddr: n.arpdstipaddr.as_ref().map(|v| v.into()),
|
||||||
arpdstipmask: n.arpdstipmask,
|
arpdstipmask: n.arpdstipmask,
|
||||||
comment: n.comment.clone(),
|
comment: n.comment.clone(),
|
||||||
}
|
}
|
||||||
@ -391,6 +420,22 @@ impl NetworkFilter {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rest2lib_process_arp_selector(
|
||||||
|
selector: &NetworkSelectorARP,
|
||||||
|
) -> anyhow::Result<NetworkFilterRuleProtocolArpXML> {
|
||||||
|
Ok(NetworkFilterRuleProtocolArpXML {
|
||||||
|
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)?,
|
||||||
|
arpsrcipaddr: extract_ipv4_or_var(&selector.arpsrcipaddr)?,
|
||||||
|
arpsrcipmask: selector.arpsrcipmask,
|
||||||
|
arpdstipaddr: extract_ipv4_or_var(&selector.arpdstipaddr)?,
|
||||||
|
arpdstipmask: selector.arpdstipmask,
|
||||||
|
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(),
|
||||||
@ -428,10 +473,20 @@ impl NetworkFilter {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkFilterSelector::Arp(_) => todo!(),
|
NetworkFilterSelector::Arp(a) => {
|
||||||
NetworkFilterSelector::Rarp(_) => todo!(),
|
rule_xml
|
||||||
|
.arp_selectors
|
||||||
|
.push(Self::rest2lib_process_arp_selector(a)?);
|
||||||
|
}
|
||||||
|
NetworkFilterSelector::Rarp(a) => {
|
||||||
|
rule_xml
|
||||||
|
.rarp_selectors
|
||||||
|
.push(Self::rest2lib_process_arp_selector(a)?);
|
||||||
|
}
|
||||||
|
|
||||||
NetworkFilterSelector::IPv4(_) => todo!(),
|
NetworkFilterSelector::IPv4(_) => todo!(),
|
||||||
NetworkFilterSelector::IPv6(_) => todo!(),
|
NetworkFilterSelector::IPv6(_) => todo!(),
|
||||||
|
|
||||||
NetworkFilterSelector::TCP(_) => todo!(),
|
NetworkFilterSelector::TCP(_) => todo!(),
|
||||||
NetworkFilterSelector::UDP(_) => todo!(),
|
NetworkFilterSelector::UDP(_) => todo!(),
|
||||||
NetworkFilterSelector::SCTP(_) => todo!(),
|
NetworkFilterSelector::SCTP(_) => todo!(),
|
||||||
@ -608,19 +663,6 @@ impl Layer4State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
|
||||||
pub struct NetworkFilterSelectorIP {
|
|
||||||
srcmacaddr: Option<String>,
|
|
||||||
srcmacmask: Option<String>,
|
|
||||||
dstmacaddr: Option<String>,
|
|
||||||
dstmacmask: Option<String>,
|
|
||||||
srcipaddr: Option<String>,
|
|
||||||
srcipmask: Option<u8>,
|
|
||||||
dstipaddr: Option<String>,
|
|
||||||
dstipmask: Option<u8>,
|
|
||||||
comment: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||||
pub struct NetworkSelectorMac {
|
pub struct NetworkSelectorMac {
|
||||||
src_mac_addr: Option<NetworkFilterMacAddressOrVar>,
|
src_mac_addr: Option<NetworkFilterMacAddressOrVar>,
|
||||||
@ -636,13 +678,26 @@ pub struct NetworkSelectorARP {
|
|||||||
srcmacmask: Option<NetworkFilterMacAddressOrVar>,
|
srcmacmask: Option<NetworkFilterMacAddressOrVar>,
|
||||||
dstmacaddr: Option<NetworkFilterMacAddressOrVar>,
|
dstmacaddr: Option<NetworkFilterMacAddressOrVar>,
|
||||||
dstmacmask: Option<NetworkFilterMacAddressOrVar>,
|
dstmacmask: Option<NetworkFilterMacAddressOrVar>,
|
||||||
arpsrcipaddr: Option<String>,
|
arpsrcipaddr: Option<NetworkFilterIPv4OrVar>,
|
||||||
arpsrcipmask: Option<u8>,
|
arpsrcipmask: Option<u8>,
|
||||||
arpdstipaddr: Option<String>,
|
arpdstipaddr: Option<NetworkFilterIPv4OrVar>,
|
||||||
arpdstipmask: Option<u8>,
|
arpdstipmask: Option<u8>,
|
||||||
comment: Option<String>,
|
comment: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||||
|
pub struct NetworkFilterSelectorIP {
|
||||||
|
srcmacaddr: Option<String>,
|
||||||
|
srcmacmask: Option<String>,
|
||||||
|
dstmacaddr: Option<String>,
|
||||||
|
dstmacmask: Option<String>,
|
||||||
|
srcipaddr: Option<String>,
|
||||||
|
srcipmask: Option<u8>,
|
||||||
|
dstipaddr: Option<String>,
|
||||||
|
dstipmask: Option<u8>,
|
||||||
|
comment: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||||
pub struct NetworkSelectorLayer4<IPv> {
|
pub struct NetworkSelectorLayer4<IPv> {
|
||||||
srcmacaddr: Option<NetworkFilterMacAddressOrVar>,
|
srcmacaddr: Option<NetworkFilterMacAddressOrVar>,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
pub fn extract_ipv4(ip: IpAddr) -> Ipv4Addr {
|
pub fn extract_ipv4(ip: IpAddr) -> Ipv4Addr {
|
||||||
match ip {
|
match ip {
|
||||||
@ -18,16 +19,20 @@ pub fn extract_ipv6(ip: IpAddr) -> Ipv6Addr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_ipv4_address_valid<D: AsRef<str>>(ip: D) -> bool {
|
||||||
|
Ipv4Addr::from_str(ip.as_ref()).is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
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_mac_address_valid;
|
use crate::utils::net_utils::{is_ipv4_address_valid, is_mac_address_valid};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn mac_addresses() {
|
fn test_is_mac_address_valid() {
|
||||||
assert!(is_mac_address_valid("FF:FF:FF:FF:FF:FF"));
|
assert!(is_mac_address_valid("FF:FF:FF:FF:FF:FF"));
|
||||||
assert!(is_mac_address_valid("02:42:a4:6e:f2:be"));
|
assert!(is_mac_address_valid("02:42:a4:6e:f2:be"));
|
||||||
|
|
||||||
@ -35,4 +40,14 @@ mod tests {
|
|||||||
assert!(!is_mac_address_valid("FF:FF:FF:FF:FF:FZ"));
|
assert!(!is_mac_address_valid("FF:FF:FF:FF:FF:FZ"));
|
||||||
assert!(!is_mac_address_valid("FF:FF:FF:FF:FF:FF:FF"));
|
assert!(!is_mac_address_valid("FF:FF:FF:FF:FF:FF:FF"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_ipv4_address_valid() {
|
||||||
|
assert!(is_ipv4_address_valid("10.0.0.1"));
|
||||||
|
assert!(is_ipv4_address_valid("2.56.58.156"));
|
||||||
|
|
||||||
|
assert!(!is_ipv4_address_valid("tata"));
|
||||||
|
assert!(!is_ipv4_address_valid("1.25.25.288"));
|
||||||
|
assert!(!is_ipv4_address_valid("5.5.5.5.5"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user