Start to build NAT configuration mode
This commit is contained in:
		@@ -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::{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user