From 6daa75d2f270c5304e9d54d148cb02c9adb610f5 Mon Sep 17 00:00:00 2001 From: lubeilin <1791778603@qq.com> Date: Fri, 2 Jun 2023 18:28:02 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=BD=91=E5=8D=A1=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=EF=BC=8C=E5=A2=9E=E5=8A=A0metric=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- switch/src/tap_device/windows.rs | 1 + switch/src/tun_device/windows.rs | 12 ++++------ switch/win-tun-tap/src/lib.rs | 2 ++ switch/win-tun-tap/src/netsh.rs | 12 ++++++++++ switch/win-tun-tap/src/tap/mod.rs | 23 ++++++++++++------ switch/win-tun-tap/src/tun/mod.rs | 39 ++++++++++++++++++++----------- 6 files changed, 62 insertions(+), 27 deletions(-) diff --git a/switch/src/tap_device/windows.rs b/switch/src/tap_device/windows.rs index da0c62b..80606c3 100644 --- a/switch/src/tap_device/windows.rs +++ b/switch/src/tap_device/windows.rs @@ -77,6 +77,7 @@ pub fn create_tap( println!("version:{:x?}", tap_device.get_version()?); println!("mac:{:x?}", mac); tap_device.set_ip(address, netmask)?; + tap_device.set_metric(1)?; tap_device.set_mtu(1420)?; tap_device.set_status(true)?; tap_device.add_route(address, netmask, gateway)?; diff --git a/switch/src/tun_device/windows.rs b/switch/src/tun_device/windows.rs index 811da2f..611f02e 100644 --- a/switch/src/tun_device/windows.rs +++ b/switch/src/tun_device/windows.rs @@ -73,9 +73,8 @@ pub fn create_tun( unsafe { println!("========TUN网卡配置========"); match Library::new("wintun.dll") { - Ok(lib) => match TunDevice::open(lib, TUN_INTERFACE_NAME) { - Ok(tun_device) => { - let _ = tun_device.delete(); + Ok(lib) => match TunDevice::delete_for_name(lib, TUN_INTERFACE_NAME) { + Ok(_) => { thread::sleep(Duration::from_millis(5)); } Err(_) => {} @@ -113,8 +112,8 @@ pub fn create_tun( }; println!("name:{:?}", tun_device.get_name()?); println!("version:{:?}", tun_device.version()?); - log::error!("创建tun成功 {:?}",tun_device.get_name()?); tun_device.set_ip(address, netmask)?; + tun_device.set_metric(1)?; tun_device.set_mtu(1420)?; for (address, netmask) in in_ips { tun_device.add_route(address, netmask, gateway)?; @@ -132,9 +131,8 @@ pub fn create_tun( pub fn delete_tun() { unsafe { match Library::new("wintun.dll") { - Ok(lib) => match TunDevice::open(lib, TUN_INTERFACE_NAME) { - Ok(tun_device) => { - let _ = tun_device.delete(); + Ok(lib) => match TunDevice::delete_for_name(lib, TUN_INTERFACE_NAME) { + Ok(_) => { } Err(_) => {} }, diff --git a/switch/win-tun-tap/src/lib.rs b/switch/win-tun-tap/src/lib.rs index 9a589c6..f8b69d1 100644 --- a/switch/win-tun-tap/src/lib.rs +++ b/switch/win-tun-tap/src/lib.rs @@ -45,4 +45,6 @@ pub trait IFace { where IP: Into; /// 设置最大传输单元 fn set_mtu(&self, mtu: u16) -> io::Result<()>; + /// 设置跃点 + fn set_metric(&self, metric: u16) -> io::Result<()>; } diff --git a/switch/win-tun-tap/src/netsh.rs b/switch/win-tun-tap/src/netsh.rs index 12031ed..ab83580 100644 --- a/switch/win-tun-tap/src/netsh.rs +++ b/switch/win-tun-tap/src/netsh.rs @@ -45,4 +45,16 @@ pub fn set_interface_mtu(index: u32, mtu: u16) -> io::Result<()> { return Err(io::Error::new(io::ErrorKind::Other, format!("设置mtu失败: {:?}", out))); } Ok(()) +} +pub fn set_interface_metric(index: u32, metric: u16) -> io::Result<()> { + let set_metric = format!("netsh interface ip set interface {} metric={}", index,metric); + let out = std::process::Command::new("cmd") + .arg("/C") + .arg(&set_metric) + .output()?; + if !out.status.success() { + log::error!("cmd={:?},out={:?}",set_metric,out); + return Err(io::Error::new(io::ErrorKind::Other, format!("设置metric失败: {:?}", out))); + } + Ok(()) } \ No newline at end of file diff --git a/switch/win-tun-tap/src/tap/mod.rs b/switch/win-tun-tap/src/tap/mod.rs index fe25bc4..27b05f2 100644 --- a/switch/win-tun-tap/src/tap/mod.rs +++ b/switch/win-tun-tap/src/tap/mod.rs @@ -1,8 +1,7 @@ -use std::{io, net, time}; +use std::{io, time}; use std::net::Ipv4Addr; use winapi::shared::ifdef::NET_LUID; -use winapi::shared::minwindef::*; use winapi::um::winioctl::*; use winapi::um::winnt::HANDLE; @@ -11,12 +10,15 @@ use crate::{decode_utf16, encode_utf16, ffi, IFace, netsh, route}; mod iface; pub struct TapDevice { + index: u32, luid: NET_LUID, handle: HANDLE, } -unsafe impl Send for TapDevice{} -unsafe impl Sync for TapDevice{} + +unsafe impl Send for TapDevice {} + +unsafe impl Sync for TapDevice {} impl TapDevice { /// Retieve the mac of the interface @@ -95,7 +97,8 @@ impl TapDevice { Ok(handle) => break handle, }; }; - Ok(Self { luid, handle }) + let index = ffi::luid_to_index(&luid).map(|index| index as u32)?; + Ok(Self { index, luid, handle }) } pub fn open(name: &str) -> io::Result { @@ -105,7 +108,8 @@ impl TapDevice { iface::check_interface(&luid)?; let handle = iface::open_interface(&luid)?; - Ok(Self { luid, handle }) + let index = ffi::luid_to_index(&luid).map(|index| index as u32)?; + Ok(Self { index, luid, handle }) } pub fn delete(self) -> io::Result<()> { @@ -119,7 +123,7 @@ impl IFace for TapDevice { } fn get_index(&self) -> io::Result { - ffi::luid_to_index(&self.luid).map(|index| index as u32) + Ok(self.index) } fn get_name(&self) -> io::Result { @@ -150,6 +154,11 @@ impl IFace for TapDevice { let index = self.get_index()?; netsh::set_interface_mtu(index, mtu) } + + fn set_metric(&self, metric: u16) -> io::Result<()> { + let index = self.get_index()?; + netsh::set_interface_metric(index, metric) + } } diff --git a/switch/win-tun-tap/src/tun/mod.rs b/switch/win-tun-tap/src/tun/mod.rs index 37cff44..f6f03e6 100644 --- a/switch/win-tun-tap/src/tun/mod.rs +++ b/switch/win-tun-tap/src/tun/mod.rs @@ -4,6 +4,7 @@ use std::net::Ipv4Addr; use winapi::um::{handleapi, synchapi, winbase, winnt}; use crate::{decode_utf16, encode_utf16, ffi, IFace, netsh, route}; + mod wintun_raw; mod log; pub mod packet; @@ -19,6 +20,8 @@ pub const MAX_POOL: usize = 256; pub struct TunDevice { + pub(crate) luid:u64, + pub(crate) index: u32, /// The session handle given to us by WintunStartSession pub(crate) session: wintun_raw::WINTUN_SESSION_HANDLE, @@ -90,8 +93,12 @@ impl TunDevice { let shutdown_event = synchapi::CreateEventA(std::ptr::null_mut(), 0, 0, std::ptr::null_mut()); let read_event = win_tun.WintunGetReadWaitEvent(session) as winnt::HANDLE; - + let mut luid: wintun_raw::NET_LUID = std::mem::zeroed(); + win_tun.WintunGetAdapterLUID(adapter, &mut luid as *mut wintun_raw::NET_LUID); + let index = ffi::luid_to_index(&std::mem::transmute(luid)).map(|index| index as u32)?; Ok(TunDevice { + luid:std::mem::transmute(luid), + index, session, win_tun, read_event, @@ -99,7 +106,7 @@ impl TunDevice { adapter, }) } - pub unsafe fn open(library: L, name: &str) -> io::Result + pub unsafe fn delete_for_name(library: L, name: &str) -> io::Result<()> where L: Into, { let win_tun = match wintun_raw::wintun::from_library(library) { Ok(win_tun) => win_tun, @@ -113,7 +120,9 @@ impl TunDevice { if adapter.is_null() { return Err(io::Error::new(io::ErrorKind::Other, "Failed to open adapter")); } - Self::init(win_tun, adapter) + win_tun.WintunCloseAdapter(adapter); + win_tun.WintunDeleteDriver(); + Ok(()) } pub fn delete(self) -> io::Result<()> { drop(self); @@ -138,13 +147,13 @@ pub struct Version { pub minor: u16, } -impl TunDevice { - fn get_adapter_luid(&self) -> u64 { - let mut luid: wintun_raw::NET_LUID = unsafe { std::mem::zeroed() }; - unsafe { self.win_tun.WintunGetAdapterLUID(self.adapter, &mut luid as *mut wintun_raw::NET_LUID) }; - unsafe { std::mem::transmute(luid) } - } -} +// impl TunDevice { +// fn get_adapter_luid(&self) -> u64 { +// let mut luid: wintun_raw::NET_LUID = unsafe { std::mem::zeroed() }; +// unsafe { self.win_tun.WintunGetAdapterLUID(self.adapter, &mut luid as *mut wintun_raw::NET_LUID) }; +// unsafe { std::mem::transmute(luid) } +// } +// } impl IFace for TunDevice { fn shutdown(&self) -> io::Result<()> { @@ -154,12 +163,11 @@ impl IFace for TunDevice { } fn get_index(&self) -> io::Result { - let luid = self.get_adapter_luid(); - ffi::luid_to_index(&unsafe { std::mem::transmute(luid) }).map(|index| index as u32) + Ok(self.index) } fn get_name(&self) -> io::Result { - let luid = self.get_adapter_luid(); + let luid = self.luid; ffi::luid_to_alias(&unsafe { std::mem::transmute(luid) }).map(|name| { decode_utf16(&name) }) @@ -185,6 +193,11 @@ impl IFace for TunDevice { fn set_mtu(&self, mtu: u16) -> io::Result<()> { netsh::set_interface_mtu(self.get_index()?, mtu) } + + fn set_metric(&self, metric: u16) -> io::Result<()> { + let index = self.get_index()?; + netsh::set_interface_metric(index, metric) + } } impl TunDevice {