v1.1
This commit is contained in:
@@ -5,9 +5,8 @@ use std::sync::Arc;
|
||||
use libloading::Library;
|
||||
use wintun::{Adapter, Packet, Session};
|
||||
|
||||
use crate::error::*;
|
||||
|
||||
pub struct TunWriter(Arc<Session>);
|
||||
#[derive(Clone)]
|
||||
pub struct TunWriter(Arc<Session>, u32);
|
||||
|
||||
impl TunWriter {
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<()> {
|
||||
@@ -21,10 +20,19 @@ impl TunWriter {
|
||||
}
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "send err"));
|
||||
}
|
||||
pub fn change_ip(&self, address: Ipv4Addr, netmask: Ipv4Addr,
|
||||
gateway: Ipv4Addr, old_netmask: Ipv4Addr, old_gateway: Ipv4Addr) -> io::Result<()> {
|
||||
if let Err(e) = delete_route(self.1, old_netmask, old_gateway) {
|
||||
log::warn!("{:?}",e);
|
||||
}
|
||||
config_ip(self.1, address, netmask, gateway)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TunReader(pub(crate) Arc<Session>);
|
||||
|
||||
|
||||
impl TunReader {
|
||||
pub fn next(&self) -> io::Result<Packet> {
|
||||
match self.0.receive_blocking() {
|
||||
@@ -35,36 +43,46 @@ impl TunReader {
|
||||
}
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "read err"));
|
||||
}
|
||||
pub fn close(&self) {
|
||||
self.0.shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_tun(
|
||||
address: Ipv4Addr,
|
||||
netmask: Ipv4Addr,
|
||||
gateway: Ipv4Addr,
|
||||
) -> Result<(TunWriter, TunReader)> {
|
||||
) -> io::Result<(TunWriter, TunReader)> {
|
||||
let win_tun = unsafe {
|
||||
match Library::new("wintun.dll") {
|
||||
Ok(library) => match wintun::load_from_library(library) {
|
||||
Ok(win_tun) => win_tun,
|
||||
Err(e) => {
|
||||
return Err(Error::Stop(format!("{:?}", e)));
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("{:?}", e)));
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("wintun.dll not found");
|
||||
return Err(Error::Stop(format!("wintun.dll not found {:?}", e)));
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("wintun.dll not found {:?}", e)));
|
||||
}
|
||||
}
|
||||
};
|
||||
let adapter = match Adapter::open(&win_tun, "Switch") {
|
||||
let adapter = match Adapter::open(&win_tun, "Switch-V1") {
|
||||
Ok(a) => a,
|
||||
Err(_) => match Adapter::create(&win_tun, "Switch", "Switch", None) {
|
||||
Err(_) => match Adapter::create(&win_tun, "Switch-V1", "Switch-V1", None) {
|
||||
Ok(adapter) => adapter,
|
||||
|
||||
Err(e) => return Err(Error::Stop(format!("{:?}", e))),
|
||||
Err(e) => return Err(io::Error::new(io::ErrorKind::Other, format!("{:?}", e))),
|
||||
},
|
||||
};
|
||||
let index = adapter.get_adapter_index().unwrap();
|
||||
config_ip(index, address, netmask, gateway)?;
|
||||
let session = Arc::new(adapter.start_session(wintun::MAX_RING_CAPACITY).unwrap());
|
||||
let reader_session = session.clone();
|
||||
Ok((TunWriter(session.clone(), index), TunReader(reader_session)))
|
||||
}
|
||||
|
||||
fn config_ip(index: u32, address: Ipv4Addr, netmask: Ipv4Addr, gateway: Ipv4Addr) -> io::Result<()> {
|
||||
let set_mtu = format!(
|
||||
"netsh interface ipv4 set subinterface {} mtu=1420 store=persistent",
|
||||
index
|
||||
@@ -74,9 +92,6 @@ pub fn create_tun(
|
||||
"netsh interface ip set address {} static {:?} {:?} ", // gateway={:?}
|
||||
index, address, netmask,
|
||||
);
|
||||
// println!("{}", set_mtu);
|
||||
// println!("{}", set_metric);
|
||||
// println!("{}", set_address);
|
||||
// 执行网卡初始化命令
|
||||
let out = std::process::Command::new("cmd")
|
||||
.arg("/C")
|
||||
@@ -84,7 +99,7 @@ pub fn create_tun(
|
||||
.output()
|
||||
.unwrap();
|
||||
if !out.status.success() {
|
||||
return Err(Error::Stop(format!("设置mtu失败:{:?}", out)));
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("设置mtu失败: {:?}", out)));
|
||||
}
|
||||
let out = std::process::Command::new("cmd")
|
||||
.arg("/C")
|
||||
@@ -92,7 +107,7 @@ pub fn create_tun(
|
||||
.output()
|
||||
.unwrap();
|
||||
if !out.status.success() {
|
||||
return Err(Error::Stop(format!("设置接口跃点失败:{:?}", out)));
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("设置接口跃点失败: {:?}", out)));
|
||||
}
|
||||
let out = std::process::Command::new("cmd")
|
||||
.arg("/C")
|
||||
@@ -100,7 +115,7 @@ pub fn create_tun(
|
||||
.output()
|
||||
.unwrap();
|
||||
if !out.status.success() {
|
||||
return Err(Error::Stop(format!("设置网络地址失败:{:?}", out)));
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("设置网络地址失败: {:?}", out)));
|
||||
}
|
||||
let dest = {
|
||||
let ip = address.octets();
|
||||
@@ -116,7 +131,6 @@ pub fn create_tun(
|
||||
"route add {:?} mask {:?} {:?} if {}",
|
||||
dest, netmask, gateway, index
|
||||
);
|
||||
// println!("{}", set_route);
|
||||
// 执行添加路由命令
|
||||
let out = std::process::Command::new("cmd")
|
||||
.arg("/C")
|
||||
@@ -124,9 +138,32 @@ pub fn create_tun(
|
||||
.output()
|
||||
.unwrap();
|
||||
if !out.status.success() {
|
||||
return Err(Error::Stop(format!("添加路由失败:{:?}", out)));
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("添加路由失败: {:?}", out)));
|
||||
}
|
||||
let session = Arc::new(adapter.start_session(wintun::MAX_RING_CAPACITY).unwrap());
|
||||
let reader_session = session.clone();
|
||||
Ok((TunWriter(session), TunReader(reader_session)))
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn delete_route(index: u32, netmask: Ipv4Addr, gateway: Ipv4Addr) -> io::Result<()> {
|
||||
let mask = netmask.octets();
|
||||
let ip = gateway.octets();
|
||||
let dest = Ipv4Addr::from([
|
||||
ip[0] & mask[0],
|
||||
ip[1] & mask[1],
|
||||
ip[2] & mask[2],
|
||||
ip[3] & mask[3],
|
||||
]);
|
||||
let delete_route = format!(
|
||||
"route delete {:?} mask {:?} {:?} if {}",
|
||||
dest, netmask, gateway, index
|
||||
);
|
||||
// 删除路由
|
||||
let out = std::process::Command::new("cmd")
|
||||
.arg("/C")
|
||||
.arg(delete_route)
|
||||
.output()
|
||||
.unwrap();
|
||||
if !out.status.success() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("删除路由失败: {:?}", out)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user