Start to build NAT configuration mode

This commit is contained in:
2024-01-10 19:29:24 +01:00
parent 6fdcc8c07c
commit ed25eed31e
10 changed files with 200 additions and 12 deletions

View File

@ -1,5 +1,8 @@
use nix::sys::socket::{AddressFamily, SockaddrLike};
use std::collections::HashMap;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::str::FromStr;
use sysinfo::{NetworksExt, System, SystemExt};
pub fn extract_ipv4(ip: IpAddr) -> Ipv4Addr {
match ip {
@ -51,6 +54,88 @@ pub fn is_net_interface_name_valid<D: AsRef<str>>(int: D) -> bool {
lazy_regex::regex!("^[a-zA-Z0-9]+$").is_match(int.as_ref())
}
/// Get the list of available network interfaces
pub fn net_list() -> Vec<String> {
let mut system = System::new();
system.refresh_networks_list();
system
.networks()
.iter()
.map(|n| n.0.to_string())
.collect::<Vec<_>>()
}
/// Get the list of available network interfaces associated with their IP address
pub fn net_list_and_ips() -> anyhow::Result<HashMap<String, Vec<IpAddr>>> {
let addrs = nix::ifaddrs::getifaddrs().unwrap();
let mut res = HashMap::new();
for ifaddr in addrs {
let address = match ifaddr.address {
Some(address) => address,
None => {
log::debug!(
"Interface {} has an unsupported address family",
ifaddr.interface_name
);
continue;
}
};
let addr_str = match address.family() {
Some(AddressFamily::Inet) => {
let address = address.to_string();
address
.split_once(':')
.map(|a| a.0)
.unwrap_or(&address)
.to_string()
}
Some(AddressFamily::Inet6) => {
let address = address.to_string();
let address = address
.split_once(']')
.map(|a| a.0)
.unwrap_or(&address)
.to_string();
let address = address
.split_once('%')
.map(|a| a.0)
.unwrap_or(&address)
.to_string();
address.strip_prefix('[').unwrap_or(&address).to_string()
}
_ => {
log::debug!(
"Interface {} has an unsupported address family {:?}",
ifaddr.interface_name,
address.family()
);
continue;
}
};
log::debug!(
"Process ip {addr_str} for interface {}",
ifaddr.interface_name
);
let ip = IpAddr::from_str(&addr_str)?;
if !res.contains_key(&ifaddr.interface_name) {
res.insert(ifaddr.interface_name.to_string(), Vec::with_capacity(1));
}
res.get_mut(&ifaddr.interface_name).unwrap().push(ip);
}
Ok(res)
}
#[cfg(test)]
mod tests {
use crate::utils::net_utils::{