mirror of https://github.com/ospab/ostp.git
92 lines
3.1 KiB
Rust
92 lines
3.1 KiB
Rust
use anyhow::{anyhow, Result};
|
|
#[cfg(target_os = "windows")]
|
|
use std::sync::Arc;
|
|
use tokio::sync::watch;
|
|
|
|
#[cfg(target_os = "windows")]
|
|
pub async fn run_wintun_tunnel(
|
|
mut shutdown: watch::Receiver<bool>,
|
|
debug: bool,
|
|
) -> Result<()> {
|
|
if debug {
|
|
println!("[ostp-client] Initializing Wintun adapter 'ostp_tun'...");
|
|
}
|
|
|
|
// 1. Load Wintun DLL
|
|
let wintun = unsafe { wintun::load_from_path("wintun.dll") }
|
|
.map_err(|e| anyhow!("Failed to load wintun.dll: {:?}", e))?;
|
|
|
|
// 2. Create or Open Adapter with static name "ostp_tun"
|
|
let adapter = match wintun::Adapter::open(&wintun, "ostp_tun") {
|
|
Ok(a) => a,
|
|
Err(_) => wintun::Adapter::create(&wintun, "ostp_tun", "OSTP TUN Adapter", None)
|
|
.map_err(|e| anyhow!("Failed to create Wintun adapter: {:?}", e))?,
|
|
};
|
|
|
|
let adapter = Arc::new(adapter);
|
|
|
|
// Set IP, Subnet and Gateway natively using netsh for bulletproof routing
|
|
if debug {
|
|
println!("[ostp-client] Configuring Wintun network settings via netsh...");
|
|
}
|
|
let output = std::process::Command::new("netsh")
|
|
.args(["interface", "ipv4", "set", "address", "name=ostp_tun", "static", "10.1.0.2", "255.255.255.0", "10.1.0.1"])
|
|
.output()?;
|
|
|
|
if !output.status.success() {
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
println!("[ostp-client] Warning: netsh returned error: {}", stderr);
|
|
} else {
|
|
if debug {
|
|
println!("[ostp-client] Network configured. ostp_tun IP: 10.1.0.2, Gateway: 10.1.0.1");
|
|
}
|
|
}
|
|
|
|
// Start Wintun session
|
|
let session = adapter.start_session(wintun::MAX_RING_CAPACITY)
|
|
.map_err(|e| anyhow!("Failed to start Wintun session: {:?}", e))?;
|
|
let session = Arc::new(session);
|
|
|
|
if debug {
|
|
println!("[ostp-client] TUN tunnel 'ostp_tun' is active and intercepting packets!");
|
|
}
|
|
|
|
// Spawn Packet Receiver Loop to read packets from Windows stack
|
|
let rx_session = session.clone();
|
|
tokio::task::spawn_blocking(move || {
|
|
loop {
|
|
match rx_session.receive_blocking() {
|
|
Ok(packet) => {
|
|
let bytes = packet.bytes();
|
|
if bytes.len() >= 20 {
|
|
let proto = bytes[9];
|
|
let src_ip = format!("{}.{}.{}.{}", bytes[12], bytes[13], bytes[14], bytes[15]);
|
|
let dest_ip = format!("{}.{}.{}.{}", bytes[16], bytes[17], bytes[18], bytes[19]);
|
|
if debug {
|
|
println!("[TUN Packet] Proto={}, Src={}, Dest={}, Len={}", proto, src_ip, dest_ip, bytes.len());
|
|
}
|
|
}
|
|
}
|
|
Err(_) => break,
|
|
}
|
|
}
|
|
});
|
|
|
|
// Wait for shutdown signal
|
|
let _ = shutdown.changed().await;
|
|
|
|
if debug {
|
|
println!("[ostp-client] Shutting down Wintun adapter...");
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(not(target_os = "windows"))]
|
|
pub async fn run_wintun_tunnel(
|
|
_shutdown: watch::Receiver<bool>,
|
|
_debug: bool,
|
|
) -> Result<()> {
|
|
Err(anyhow!("Wintun is only supported on Windows!"))
|
|
}
|