mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-13 17:35:37 +00:00
128 lines
3.3 KiB
Rust
128 lines
3.3 KiB
Rust
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
|
mod darwin;
|
|
#[cfg(any(target_os = "linux"))]
|
|
mod netlink;
|
|
#[cfg(target_os = "windows")]
|
|
mod windows;
|
|
|
|
mod route;
|
|
|
|
use std::net::Ipv4Addr;
|
|
|
|
use async_trait::async_trait;
|
|
use tokio::process::Command;
|
|
|
|
use super::error::Error;
|
|
|
|
#[async_trait]
|
|
pub trait IfConfiguerTrait: Send + Sync {
|
|
async fn add_ipv4_route(
|
|
&self,
|
|
_name: &str,
|
|
_address: Ipv4Addr,
|
|
_cidr_prefix: u8,
|
|
) -> Result<(), Error> {
|
|
Ok(())
|
|
}
|
|
async fn remove_ipv4_route(
|
|
&self,
|
|
_name: &str,
|
|
_address: Ipv4Addr,
|
|
_cidr_prefix: u8,
|
|
) -> Result<(), Error> {
|
|
Ok(())
|
|
}
|
|
async fn add_ipv4_ip(
|
|
&self,
|
|
_name: &str,
|
|
_address: Ipv4Addr,
|
|
_cidr_prefix: u8,
|
|
) -> Result<(), Error> {
|
|
Ok(())
|
|
}
|
|
async fn set_link_status(&self, _name: &str, _up: bool) -> Result<(), Error> {
|
|
Ok(())
|
|
}
|
|
async fn remove_ip(&self, _name: &str, _ip: Option<Ipv4Addr>) -> Result<(), Error> {
|
|
Ok(())
|
|
}
|
|
async fn wait_interface_show(&self, _name: &str) -> Result<(), Error> {
|
|
return Ok(());
|
|
}
|
|
async fn set_mtu(&self, _name: &str, _mtu: u32) -> Result<(), Error> {
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
fn cidr_to_subnet_mask(prefix_length: u8) -> Ipv4Addr {
|
|
if prefix_length > 32 {
|
|
panic!("Invalid CIDR prefix length");
|
|
}
|
|
|
|
let subnet_mask: u32 = (!0u32)
|
|
.checked_shl(32 - u32::from(prefix_length))
|
|
.unwrap_or(0);
|
|
Ipv4Addr::new(
|
|
((subnet_mask >> 24) & 0xFF) as u8,
|
|
((subnet_mask >> 16) & 0xFF) as u8,
|
|
((subnet_mask >> 8) & 0xFF) as u8,
|
|
(subnet_mask & 0xFF) as u8,
|
|
)
|
|
}
|
|
|
|
async fn run_shell_cmd(cmd: &str) -> Result<(), Error> {
|
|
let cmd_out: std::process::Output;
|
|
let stdout: String;
|
|
let stderr: String;
|
|
#[cfg(target_os = "windows")]
|
|
{
|
|
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
|
cmd_out = Command::new("cmd")
|
|
.stdin(std::process::Stdio::null())
|
|
.arg("/C")
|
|
.arg(cmd)
|
|
.creation_flags(CREATE_NO_WINDOW)
|
|
.output()
|
|
.await?;
|
|
stdout = crate::utils::utf8_or_gbk_to_string(cmd_out.stdout.as_slice());
|
|
stderr = crate::utils::utf8_or_gbk_to_string(cmd_out.stderr.as_slice());
|
|
};
|
|
|
|
#[cfg(not(target_os = "windows"))]
|
|
{
|
|
cmd_out = Command::new("sh").arg("-c").arg(cmd).output().await?;
|
|
stdout = String::from_utf8_lossy(cmd_out.stdout.as_slice()).to_string();
|
|
stderr = String::from_utf8_lossy(cmd_out.stderr.as_slice()).to_string();
|
|
};
|
|
|
|
let ec = cmd_out.status.code();
|
|
let succ = cmd_out.status.success();
|
|
tracing::info!(?cmd, ?ec, ?succ, ?stdout, ?stderr, "run shell cmd");
|
|
|
|
if !cmd_out.status.success() {
|
|
return Err(Error::ShellCommandError(stdout + &stderr));
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub struct DummyIfConfiger {}
|
|
#[async_trait]
|
|
impl IfConfiguerTrait for DummyIfConfiger {}
|
|
|
|
#[cfg(any(target_os = "linux"))]
|
|
pub type IfConfiger = netlink::NetlinkIfConfiger;
|
|
|
|
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
|
pub type IfConfiger = darwin::MacIfConfiger;
|
|
|
|
#[cfg(target_os = "windows")]
|
|
pub type IfConfiger = windows::WindowsIfConfiger;
|
|
|
|
#[cfg(not(any(
|
|
target_os = "macos",
|
|
target_os = "linux",
|
|
target_os = "windows",
|
|
target_os = "freebsd",
|
|
)))]
|
|
pub type IfConfiger = DummyIfConfiger;
|