parent
a3e359cf2f
commit
460b723f1b
@ -0,0 +1,172 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2022-2023 Niko Bonnieure, Par le Peuple, NextGraph.org developers |
||||||
|
* All rights reserved. |
||||||
|
* Licensed under the Apache License, Version 2.0 |
||||||
|
* <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
|
||||||
|
* or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||||
|
* at your option. All files in the project carrying such |
||||||
|
* notice may not be copied, modified, or distributed except |
||||||
|
* according to those terms. |
||||||
|
*/ |
||||||
|
use p2p_net::utils::{is_ipv4_global, is_ipv4_private, is_ipv6_global, is_ipv6_private}; |
||||||
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; |
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)] |
||||||
|
pub enum InterfaceType { |
||||||
|
Loopback, |
||||||
|
Private, |
||||||
|
Public, |
||||||
|
Invalid, |
||||||
|
} |
||||||
|
|
||||||
|
impl InterfaceType { |
||||||
|
pub fn is_ipv4_valid_for_type(&self, ip: &Ipv4Addr) -> bool { |
||||||
|
match self { |
||||||
|
InterfaceType::Loopback => ip.is_loopback(), |
||||||
|
InterfaceType::Public => is_public_ipv4(ip), |
||||||
|
// we allow to bind to link-local for IPv4
|
||||||
|
InterfaceType::Private => is_ipv4_private(ip), |
||||||
|
_ => false, |
||||||
|
} |
||||||
|
} |
||||||
|
pub fn is_ipv6_valid_for_type(&self, ip: &Ipv6Addr) -> bool { |
||||||
|
match self { |
||||||
|
InterfaceType::Loopback => ip.is_loopback(), |
||||||
|
InterfaceType::Public => is_public_ipv6(ip), |
||||||
|
// we do NOT allow to bind to link-local for IPv6
|
||||||
|
InterfaceType::Private => is_ipv6_private(ip), |
||||||
|
_ => false, |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn print_ipv4(ip: &default_net::ip::Ipv4Net) -> String { |
||||||
|
format!("{}/{}", ip.addr, ip.prefix_len) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn print_ipv6(ip: &default_net::ip::Ipv6Net) -> String { |
||||||
|
format!("{}/{}", ip.addr, ip.prefix_len) |
||||||
|
} |
||||||
|
|
||||||
|
#[derive(Clone, Debug)] |
||||||
|
pub struct Interface { |
||||||
|
pub if_type: InterfaceType, |
||||||
|
pub name: String, |
||||||
|
pub mac_addr: Option<default_net::interface::MacAddr>, |
||||||
|
/// List of Ipv4Net for the network interface
|
||||||
|
pub ipv4: Vec<default_net::ip::Ipv4Net>, |
||||||
|
/// List of Ipv6Net for the network interface
|
||||||
|
pub ipv6: Vec<default_net::ip::Ipv6Net>, |
||||||
|
} |
||||||
|
|
||||||
|
pub fn find_first(list: &Vec<Interface>, iftype: InterfaceType) -> Option<Interface> { |
||||||
|
for inf in list { |
||||||
|
if inf.if_type == iftype { |
||||||
|
return Some(inf.clone()); |
||||||
|
} |
||||||
|
} |
||||||
|
None |
||||||
|
} |
||||||
|
|
||||||
|
pub fn find_first_or_name( |
||||||
|
list: &Vec<Interface>, |
||||||
|
iftype: InterfaceType, |
||||||
|
name: &String, |
||||||
|
) -> Option<Interface> { |
||||||
|
for inf in list { |
||||||
|
if (name == "default" || *name == inf.name) && inf.if_type == iftype { |
||||||
|
return Some(inf.clone()); |
||||||
|
} |
||||||
|
} |
||||||
|
None |
||||||
|
} |
||||||
|
|
||||||
|
pub fn find_name(list: &Vec<Interface>, name: &String) -> Option<Interface> { |
||||||
|
for inf in list { |
||||||
|
if *name == inf.name { |
||||||
|
return Some(inf.clone()); |
||||||
|
} |
||||||
|
} |
||||||
|
None |
||||||
|
} |
||||||
|
|
||||||
|
pub fn is_public_ipv4(ip: &Ipv4Addr) -> bool { |
||||||
|
// TODO, use core::net::Ipv6Addr.is_global when it will be stable
|
||||||
|
return is_ipv4_global(ip); |
||||||
|
} |
||||||
|
|
||||||
|
pub fn is_public_ipv6(ip: &Ipv6Addr) -> bool { |
||||||
|
// TODO, use core::net::Ipv6Addr.is_global when it will be stable
|
||||||
|
return is_ipv6_global(ip); |
||||||
|
} |
||||||
|
|
||||||
|
pub fn is_public_ip(ip: &IpAddr) -> bool { |
||||||
|
match ip { |
||||||
|
IpAddr::V4(v4) => is_public_ipv4(v4), |
||||||
|
IpAddr::V6(v6) => is_public_ipv6(v6), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn is_private_ip(ip: &IpAddr) -> bool { |
||||||
|
match ip { |
||||||
|
IpAddr::V4(v4) => is_ipv4_private(v4), |
||||||
|
IpAddr::V6(v6) => is_ipv6_private(v6), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pub fn get_interface() -> Vec<Interface> { |
||||||
|
let mut res: Vec<Interface> = vec![]; |
||||||
|
let interfaces = default_net::get_interfaces(); |
||||||
|
for interface in interfaces { |
||||||
|
if interface.ipv4.len() > 0 { |
||||||
|
let first_v4 = interface.ipv4[0].addr; |
||||||
|
let if_type = if first_v4.is_loopback() { |
||||||
|
InterfaceType::Loopback |
||||||
|
} else if is_ipv4_private(&first_v4) { |
||||||
|
InterfaceType::Private |
||||||
|
} else if is_public_ipv4(&first_v4) { |
||||||
|
InterfaceType::Public |
||||||
|
} else { |
||||||
|
continue; |
||||||
|
}; |
||||||
|
let interf = Interface { |
||||||
|
if_type, |
||||||
|
name: interface.name, |
||||||
|
mac_addr: interface.mac_addr, |
||||||
|
ipv4: interface.ipv4, |
||||||
|
ipv6: interface.ipv6, |
||||||
|
}; |
||||||
|
res.push(interf); |
||||||
|
} |
||||||
|
} |
||||||
|
res |
||||||
|
} |
||||||
|
|
||||||
|
pub fn print_interfaces() { |
||||||
|
let interfaces = get_interface(); |
||||||
|
for interface in interfaces { |
||||||
|
println!("{} \t{:?}", interface.name, interface.if_type); |
||||||
|
|
||||||
|
println!( |
||||||
|
"\tIPv4: {}", |
||||||
|
interface |
||||||
|
.ipv4 |
||||||
|
.iter() |
||||||
|
.map(|ip| print_ipv4(ip)) |
||||||
|
.collect::<Vec<String>>() |
||||||
|
.join(" ") |
||||||
|
); |
||||||
|
println!( |
||||||
|
"\tIPv6: {}", |
||||||
|
interface |
||||||
|
.ipv6 |
||||||
|
.iter() |
||||||
|
.map(|ip| print_ipv6(ip)) |
||||||
|
.collect::<Vec<String>>() |
||||||
|
.join(" ") |
||||||
|
); |
||||||
|
if let Some(mac_addr) = interface.mac_addr { |
||||||
|
println!("\tMAC: {}", mac_addr); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue