diff --git a/vnt-cli/src/command/entity.rs b/vnt-cli/src/command/entity.rs index 154127f..5c06d18 100644 --- a/vnt-cli/src/command/entity.rs +++ b/vnt-cli/src/command/entity.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use std::net::{Ipv4Addr, SocketAddr}; #[derive(Serialize, Deserialize, Debug)] pub struct Info { pub name: String, @@ -13,6 +14,9 @@ pub struct Info { pub ipv6_addr: String, pub up: u64, pub down: u64, + pub port_mapping_list: Vec<(bool, SocketAddr, String)>, + pub in_ips: Vec<(u32, u32, Ipv4Addr)>, + pub out_ips: Vec<(u32, u32)>, } #[derive(Serialize, Deserialize, Debug)] diff --git a/vnt-cli/src/command/mod.rs b/vnt-cli/src/command/mod.rs index e059c2c..eee969c 100644 --- a/vnt-cli/src/command/mod.rs +++ b/vnt-cli/src/command/mod.rs @@ -185,6 +185,9 @@ pub fn command_info(vnt: &Vnt) -> Info { .unwrap_or("None".to_string()); let up = vnt.up_stream(); let down = vnt.down_stream(); + let port_mapping_list = vnt.config().port_mapping_list.clone(); + let in_ips = vnt.config().in_ips.clone(); + let out_ips = vnt.config().out_ips.clone(); Info { name, virtual_ip, @@ -198,5 +201,8 @@ pub fn command_info(vnt: &Vnt) -> Info { ipv6_addr, up, down, + port_mapping_list, + in_ips, + out_ips, } } diff --git a/vnt-cli/src/console_out/mod.rs b/vnt-cli/src/console_out/mod.rs index 557987d..44bde16 100644 --- a/vnt-cli/src/console_out/mod.rs +++ b/vnt-cli/src/console_out/mod.rs @@ -1,4 +1,5 @@ use console::{style, Style}; +use std::net::Ipv4Addr; use crate::command::entity::{DeviceItem, Info, RouteItem}; @@ -9,10 +10,15 @@ pub fn console_info(status: Info) { println!("Virtual ip: {}", style(status.virtual_ip).green()); println!("Virtual gateway: {}", style(status.virtual_gateway).green()); println!("Virtual netmask: {}", style(status.virtual_netmask).green()); - println!( - "Connection status: {}", - style(status.connect_status).green() - ); + if status.connect_status.eq_ignore_ascii_case("Connected") { + println!( + "Connection status: {}", + style(status.connect_status).green() + ); + } else { + println!("Connection status: {}", style(status.connect_status).red()); + } + println!("NAT type: {}", style(status.nat_type).green()); println!("Relay server: {}", style(status.relay_server).green()); println!("Public ips: {}", style(status.public_ips).green()); @@ -20,6 +26,38 @@ pub fn console_info(status: Info) { println!("IPv6: {}", style(status.ipv6_addr).green()); println!("Up: {}", style(convert(status.up)).green()); println!("Down: {}", style(convert(status.down)).green()); + + if !status.port_mapping_list.is_empty() { + println!("------------------------------------------"); + println!("Port mapping {}", status.port_mapping_list.len()); + for (is_tcp, addr, dest) in status.port_mapping_list { + if is_tcp { + println!(" TCP: {} -> {}", addr, dest) + } else { + println!(" UDP: {} -> {}", addr, dest) + } + } + } + if !status.in_ips.is_empty() || !status.out_ips.is_empty() { + println!("------------------------------------------"); + } + if !status.in_ips.is_empty() { + println!("IP forwarding {}", status.in_ips.len()); + for (dest, mask, ip) in status.in_ips { + println!( + " -- {} --> {}/{}", + ip, + Ipv4Addr::from(dest), + mask.count_ones() + ) + } + } + if !status.out_ips.is_empty() { + println!("Allows network {}", status.out_ips.len()); + for (dest, mask) in status.out_ips { + println!(" {}/{}", Ipv4Addr::from(dest), mask.count_ones()) + } + } } fn convert(num: u64) -> String { diff --git a/vnt/src/channel/punch.rs b/vnt/src/channel/punch.rs index 004b80a..6c424a5 100644 --- a/vnt/src/channel/punch.rs +++ b/vnt/src/channel/punch.rs @@ -103,7 +103,7 @@ impl NatInfo { if port != 0 { if let Some(public_port) = self.public_ports.get_mut(index) { if *public_port != port { - log::info!("端口变化={}:{}", ip, port) + log::info!("端口变化={}:{} index={}", ip, port, index) } *public_port = port; } diff --git a/vnt/src/core/mod.rs b/vnt/src/core/mod.rs index 4c0d728..bd1da8e 100644 --- a/vnt/src/core/mod.rs +++ b/vnt/src/core/mod.rs @@ -57,7 +57,7 @@ impl Config { server_address_str: String, mut name_servers: Vec, mut stun_server: Vec, - in_ips: Vec<(u32, u32, Ipv4Addr)>, + mut in_ips: Vec<(u32, u32, Ipv4Addr)>, out_ips: Vec<(u32, u32)>, password: Option, mtu: Option, @@ -103,6 +103,11 @@ impl Config { address_choose(dns_query_all(&server_address_str, name_servers.clone())?)?; #[cfg(feature = "port_mapping")] let port_mapping_list = crate::port_mapping::convert(port_mapping_list)?; + + for (dest, mask, _) in &mut in_ips { + *dest = *mask & *dest; + } + in_ips.sort_by(|(dest1, _, _), (dest2, _, _)| dest2.cmp(dest1)); Ok(Self { #[cfg(target_os = "windows")] tap,