提示虚拟网卡创建失败的信息
This commit is contained in:
Generated
+1
@@ -2195,6 +2195,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
"common",
|
||||
"console",
|
||||
"log",
|
||||
"rand",
|
||||
"signal-hook",
|
||||
|
||||
@@ -37,7 +37,8 @@ impl VntCallback for VntHandler {
|
||||
| ErrorType::AddressExhausted
|
||||
| ErrorType::IpAlreadyExists
|
||||
| ErrorType::InvalidIp
|
||||
| ErrorType::LocalIpExists => {
|
||||
| ErrorType::LocalIpExists
|
||||
| ErrorType::FailedToCrateDevice => {
|
||||
self.stop();
|
||||
}
|
||||
_ => {}
|
||||
|
||||
+2
-8
@@ -302,7 +302,7 @@ pub fn parse_args_config() -> anyhow::Result<Option<(Config, Vec<String>, bool)>
|
||||
} else {
|
||||
Compressor::None
|
||||
};
|
||||
let config = match Config::new(
|
||||
let config = Config::new(
|
||||
#[cfg(feature = "integrated_tun")]
|
||||
#[cfg(target_os = "windows")]
|
||||
tap,
|
||||
@@ -337,13 +337,7 @@ pub fn parse_args_config() -> anyhow::Result<Option<(Config, Vec<String>, bool)>
|
||||
!disable_stats,
|
||||
allow_wire_guard,
|
||||
local_ipv4,
|
||||
) {
|
||||
Ok(config) => config,
|
||||
Err(e) => {
|
||||
println!("config error: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
)?;
|
||||
(config, vnt_mapping_list, cmd)
|
||||
};
|
||||
println!("version {}", vnt::VNT_VERSION);
|
||||
|
||||
@@ -17,7 +17,7 @@ fn main() {
|
||||
e,
|
||||
std::env::args().collect::<Vec<String>>()
|
||||
);
|
||||
println!("{}", e);
|
||||
println!("Error {:?}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ vnt = { path = "../vnt", package = "vnt", default-features = false, features = [
|
||||
common = { path = "../common", default-features = false, features = ["integrated_tun"] }
|
||||
log = "0.4.17"
|
||||
anyhow = "1.0.82"
|
||||
|
||||
console = "0.15.2"
|
||||
|
||||
[target.'cfg(any(target_os = "linux",target_os = "macos"))'.dependencies]
|
||||
sudo = "0.6.0"
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
use common::callback;
|
||||
use console::style;
|
||||
use vnt::core::{Config, Vnt};
|
||||
mod root_check;
|
||||
fn main() {
|
||||
@@ -16,7 +17,7 @@ fn main() {
|
||||
e,
|
||||
std::env::args().collect::<Vec<String>>()
|
||||
);
|
||||
println!("{}", e);
|
||||
println!("{}", style(format!("Error {:?}", e)).red());
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -94,6 +94,14 @@ impl Config {
|
||||
allow_wire_guard: bool,
|
||||
local_ipv4: Option<Ipv4Addr>,
|
||||
) -> anyhow::Result<Self> {
|
||||
#[cfg(windows)]
|
||||
if !tap {
|
||||
if let Err(e) = tun::Device::check_tun_dll() {
|
||||
log::warn!("校验平台dll {:?}", e);
|
||||
// Err(e)?;
|
||||
}
|
||||
}
|
||||
|
||||
for x in stun_server.iter_mut() {
|
||||
if !x.contains(":") {
|
||||
x.push_str(":3478");
|
||||
|
||||
@@ -172,6 +172,7 @@ pub enum ErrorType {
|
||||
IpAlreadyExists,
|
||||
InvalidIp,
|
||||
LocalIpExists,
|
||||
FailedToCrateDevice,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
@@ -184,6 +185,7 @@ impl Into<u8> for ErrorType {
|
||||
ErrorType::IpAlreadyExists => 4,
|
||||
ErrorType::InvalidIp => 5,
|
||||
ErrorType::LocalIpExists => 6,
|
||||
ErrorType::FailedToCrateDevice => 101,
|
||||
ErrorType::Unknown => 255,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,7 +385,7 @@ impl<Call: VntCallback, Device: DeviceWrite> ServerPacketHandler<Call, Device> {
|
||||
let device_fd = self.callback.generate_tun(device_config);
|
||||
if device_fd == 0 {
|
||||
self.callback.error(ErrorInfo::new_msg(
|
||||
ErrorType::Unknown,
|
||||
ErrorType::FailedToCrateDevice,
|
||||
"device_fd == 0".into(),
|
||||
));
|
||||
} else {
|
||||
@@ -396,14 +396,14 @@ impl<Call: VntCallback, Device: DeviceWrite> ServerPacketHandler<Call, Device> {
|
||||
self.config_info.allow_wire_guard,
|
||||
) {
|
||||
self.callback.error(ErrorInfo::new_msg(
|
||||
ErrorType::Unknown,
|
||||
ErrorType::FailedToCrateDevice,
|
||||
format!("{:?}", e),
|
||||
));
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
self.callback.error(ErrorInfo::new_msg(
|
||||
ErrorType::Unknown,
|
||||
ErrorType::FailedToCrateDevice,
|
||||
format!("{:?}", e),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ pub fn create_device(config: DeviceConfig) -> Result<Arc<Device>, ErrorInfo> {
|
||||
Ok(device) => device,
|
||||
Err(e) => {
|
||||
return Err(ErrorInfo::new_msg(
|
||||
ErrorType::Unknown,
|
||||
ErrorType::FailedToCrateDevice,
|
||||
format!("create device {:?}", e),
|
||||
));
|
||||
}
|
||||
|
||||
+4
-3
@@ -19,15 +19,16 @@ ioctl = { version = "0.8", package = "ioctl-sys" }
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
libloading = "0.8.0"
|
||||
widestring = "1.0.2"
|
||||
winapi = {version = "0.3",features = [
|
||||
winapi = { version = "0.3", features = [
|
||||
"errhandlingapi",
|
||||
"libloaderapi",
|
||||
"combaseapi",
|
||||
"ioapiset",
|
||||
"winioctl",
|
||||
"setupapi",
|
||||
"synchapi",
|
||||
"netioapi",
|
||||
"fileapi","handleapi","winerror","minwindef","ifdef","basetsd","winnt","winreg","winbase","minwinbase",
|
||||
"fileapi", "handleapi", "winerror", "minwindef", "ifdef", "basetsd", "winnt", "winreg", "winbase", "minwinbase",
|
||||
"impl-default"
|
||||
]}
|
||||
] }
|
||||
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
use libloading::Library;
|
||||
use std::ffi::{c_char, CStr, CString};
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read, Seek};
|
||||
use std::path::PathBuf;
|
||||
use winapi::shared::minwindef::HINSTANCE;
|
||||
use winapi::um::libloaderapi::{GetModuleFileNameA, GetModuleHandleA};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
struct DosHeader {
|
||||
e_magic: u16,
|
||||
e_cblp: u16,
|
||||
e_cp: u16,
|
||||
e_crlc: u16,
|
||||
e_cparhdr: u16,
|
||||
e_minalloc: u16,
|
||||
e_maxalloc: u16,
|
||||
e_ss: u16,
|
||||
e_sp: u16,
|
||||
e_csum: u16,
|
||||
e_ip: u16,
|
||||
e_cs: u16,
|
||||
e_lfarlc: u16,
|
||||
e_ovno: u16,
|
||||
e_res: [u16; 4],
|
||||
e_oemid: u16,
|
||||
e_oeminfo: u16,
|
||||
e_res2: [u16; 10],
|
||||
e_lfanew: i32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
struct FileHeader {
|
||||
machine: u16,
|
||||
number_of_sections: u16,
|
||||
time_date_stamp: u32,
|
||||
pointer_to_symbol_table: u32,
|
||||
number_of_symbols: u32,
|
||||
size_of_optional_header: u16,
|
||||
characteristics: u16,
|
||||
}
|
||||
|
||||
const IMAGE_FILE_MACHINE_I386: u16 = 0x014C;
|
||||
const IMAGE_FILE_MACHINE_AMD64: u16 = 0x8664;
|
||||
const IMAGE_FILE_MACHINE_ARM: u16 = 0x01C4;
|
||||
const IMAGE_FILE_MACHINE_ARM64: u16 = 0xAA64;
|
||||
|
||||
fn get_dll_path(dll_name: &str) -> Result<PathBuf, String> {
|
||||
unsafe {
|
||||
// 使用libloading加载DLL
|
||||
|
||||
// 转换DLL名称为C字符串
|
||||
let dll_name_c =
|
||||
CString::new(dll_name).map_err(|e| format!("Failed to convert to CString: {}", e))?;
|
||||
|
||||
// 获取DLL的模块句柄
|
||||
let h_instance: HINSTANCE = GetModuleHandleA(dll_name_c.as_ptr() as *const c_char);
|
||||
|
||||
if h_instance.is_null() {
|
||||
return Err("Failed to get module handle".to_string());
|
||||
}
|
||||
|
||||
// 获取DLL文件路径
|
||||
let mut buffer: [c_char; 260] = [0; 260];
|
||||
let length = GetModuleFileNameA(h_instance, buffer.as_mut_ptr(), buffer.len() as u32);
|
||||
|
||||
if length == 0 {
|
||||
return Err("Failed to get module file name".to_string());
|
||||
}
|
||||
|
||||
let path = CStr::from_ptr(buffer.as_ptr());
|
||||
let path_str = path
|
||||
.to_str()
|
||||
.map_err(|e| format!("Failed to convert to &str: {}", e))?;
|
||||
Ok(PathBuf::from(path_str))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_win_tun_dll() -> io::Result<()> {
|
||||
let _lib = unsafe {
|
||||
Library::new("wintun.dll").map_err(|_| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::NotFound,
|
||||
"wintun.dll not found,Please download https://www.wintun.net",
|
||||
)
|
||||
})
|
||||
};
|
||||
match get_dll_path("wintun.dll") {
|
||||
Ok(path) => match_platform(path),
|
||||
Err(e) => {
|
||||
// 能加载说明存在wintun,这里获取不到路径是代码的问题
|
||||
log::info!("{:?}", e);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn match_platform(path: PathBuf) -> io::Result<()> {
|
||||
let current_arch = if cfg!(target_arch = "x86") {
|
||||
"x86"
|
||||
} else if cfg!(target_arch = "x86_64") {
|
||||
"AMD64"
|
||||
} else if cfg!(target_arch = "arm") {
|
||||
"ARM"
|
||||
} else if cfg!(target_arch = "aarch64") {
|
||||
"ARM64"
|
||||
} else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let mut file = File::open(&path)?;
|
||||
|
||||
// 读取 DOS 头部
|
||||
let mut dos_header = [0u8; std::mem::size_of::<DosHeader>()];
|
||||
file.read_exact(&mut dos_header)?;
|
||||
let dos_header: DosHeader = unsafe { std::ptr::read(dos_header.as_ptr() as *const _) };
|
||||
|
||||
if dos_header.e_magic != 0x5A4D {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("Not a valid PE file {:?}", path),
|
||||
));
|
||||
}
|
||||
|
||||
// 跳转到 PE 头部
|
||||
file.seek(io::SeekFrom::Start(dos_header.e_lfanew as u64))?;
|
||||
|
||||
// 读取 PE 头部
|
||||
let mut pe_signature = [0u8; 4];
|
||||
file.read_exact(&mut pe_signature)?;
|
||||
if &pe_signature != b"PE\0\0" {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("Not a valid PE file {:?}", path),
|
||||
));
|
||||
}
|
||||
|
||||
// 读取文件头部
|
||||
let mut file_header = [0u8; std::mem::size_of::<FileHeader>()];
|
||||
file.read_exact(&mut file_header)?;
|
||||
let file_header: FileHeader = unsafe { std::ptr::read(file_header.as_ptr() as *const _) };
|
||||
let dll_arch = match file_header.machine {
|
||||
IMAGE_FILE_MACHINE_I386 => "x86",
|
||||
IMAGE_FILE_MACHINE_AMD64 => "AMD64",
|
||||
IMAGE_FILE_MACHINE_ARM => "ARM",
|
||||
IMAGE_FILE_MACHINE_ARM64 => "ARM64",
|
||||
_ => {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("Unknown machine type: {}", file_header.machine),
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
if dll_arch != current_arch {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!(
|
||||
"wintun.dll architecture ({}) does not match the current platform architecture ({}).",
|
||||
dll_arch, current_arch
|
||||
),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -16,6 +16,9 @@ impl Device {
|
||||
Ok(Device::Tun(tun::Device::new(name)?))
|
||||
}
|
||||
}
|
||||
pub fn check_tun_dll() -> io::Result<()> {
|
||||
crate::windows::check::check_win_tun_dll()
|
||||
}
|
||||
}
|
||||
|
||||
impl IFace for Device {
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::os::windows::process::CommandExt;
|
||||
use winapi::shared::minwindef::DWORD;
|
||||
use winapi::um::winbase::CREATE_NO_WINDOW;
|
||||
|
||||
mod check;
|
||||
mod device;
|
||||
mod ffi;
|
||||
mod netsh;
|
||||
|
||||
Reference in New Issue
Block a user