Port forwarding is working

This commit is contained in:
2024-01-10 21:59:41 +01:00
parent ed25eed31e
commit d6c8964380
4 changed files with 246 additions and 35 deletions

View File

@ -1,6 +1,6 @@
use crate::constants;
use crate::utils::net_utils;
use std::net::{Ipv4Addr, Ipv6Addr};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
#[derive(thiserror::Error, Debug)]
enum NatDefError {
@ -10,18 +10,28 @@ enum NatDefError {
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum NatSource<IPv> {
pub enum NatSourceIP<IPv> {
Interface { name: String },
Ip { ip: IPv },
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
pub enum NatProtocol {
TCP,
UDP,
Both,
}
impl NatProtocol {
pub fn has_tcp(&self) -> bool {
!matches!(&self, NatProtocol::UDP)
}
pub fn has_udp(&self) -> bool {
!matches!(&self, NatProtocol::TCP)
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum NatHostPort {
@ -29,19 +39,28 @@ pub enum NatHostPort {
Range { start: u16, end: u16 },
}
impl NatHostPort {
pub fn as_seq(&self) -> Vec<u16> {
match self {
NatHostPort::Single { port } => vec![*port],
NatHostPort::Range { start, end } => (*start..(*end + 1)).collect(),
}
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Nat<IPv> {
pub protocol: NatProtocol,
pub host_addr: NatSource<IPv>,
pub host_ip: NatSourceIP<IPv>,
pub host_port: NatHostPort,
pub guest_addr: IPv,
pub guest_ip: IPv,
pub guest_port: u16,
pub comment: Option<String>,
}
impl<IPv> Nat<IPv> {
pub fn check(&self) -> anyhow::Result<()> {
if let NatSource::Interface { name } = &self.host_addr {
if let NatSourceIP::Interface { name } = &self.host_ip {
if !net_utils::is_net_interface_name_valid(name) {
return Err(NatDefError::InvalidNatDef("Invalid nat interface name!").into());
}
@ -75,6 +94,46 @@ impl<IPv> Nat<IPv> {
}
}
impl Nat<Ipv4Addr> {
pub fn generalize(&self) -> Nat<IpAddr> {
Nat {
protocol: self.protocol,
host_ip: match &self.host_ip {
NatSourceIP::Ip { ip } => NatSourceIP::Ip {
ip: IpAddr::V4(*ip),
},
NatSourceIP::Interface { name } => NatSourceIP::Interface {
name: name.to_string(),
},
},
host_port: self.host_port.clone(),
guest_ip: IpAddr::V4(self.guest_ip),
guest_port: self.guest_port,
comment: self.comment.clone(),
}
}
}
impl Nat<Ipv6Addr> {
pub fn generalize(&self) -> Nat<IpAddr> {
Nat {
protocol: self.protocol,
host_ip: match &self.host_ip {
NatSourceIP::Ip { ip } => NatSourceIP::Ip {
ip: IpAddr::V6(*ip),
},
NatSourceIP::Interface { name } => NatSourceIP::Interface {
name: name.to_string(),
},
},
host_port: self.host_port.clone(),
guest_ip: IpAddr::V6(self.guest_ip),
guest_port: self.guest_port,
comment: self.comment.clone(),
}
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
pub struct NetNat {
pub interface: String,