提示虚拟网卡创建失败的信息
This commit is contained in:
Generated
+1
@@ -2195,6 +2195,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
"common",
|
"common",
|
||||||
|
"console",
|
||||||
"log",
|
"log",
|
||||||
"rand",
|
"rand",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ impl VntCallback for VntHandler {
|
|||||||
| ErrorType::AddressExhausted
|
| ErrorType::AddressExhausted
|
||||||
| ErrorType::IpAlreadyExists
|
| ErrorType::IpAlreadyExists
|
||||||
| ErrorType::InvalidIp
|
| ErrorType::InvalidIp
|
||||||
| ErrorType::LocalIpExists => {
|
| ErrorType::LocalIpExists
|
||||||
|
| ErrorType::FailedToCrateDevice => {
|
||||||
self.stop();
|
self.stop();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|||||||
+2
-8
@@ -302,7 +302,7 @@ pub fn parse_args_config() -> anyhow::Result<Option<(Config, Vec<String>, bool)>
|
|||||||
} else {
|
} else {
|
||||||
Compressor::None
|
Compressor::None
|
||||||
};
|
};
|
||||||
let config = match Config::new(
|
let config = Config::new(
|
||||||
#[cfg(feature = "integrated_tun")]
|
#[cfg(feature = "integrated_tun")]
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
tap,
|
tap,
|
||||||
@@ -337,13 +337,7 @@ pub fn parse_args_config() -> anyhow::Result<Option<(Config, Vec<String>, bool)>
|
|||||||
!disable_stats,
|
!disable_stats,
|
||||||
allow_wire_guard,
|
allow_wire_guard,
|
||||||
local_ipv4,
|
local_ipv4,
|
||||||
) {
|
)?;
|
||||||
Ok(config) => config,
|
|
||||||
Err(e) => {
|
|
||||||
println!("config error: {}", e);
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
(config, vnt_mapping_list, cmd)
|
(config, vnt_mapping_list, cmd)
|
||||||
};
|
};
|
||||||
println!("version {}", vnt::VNT_VERSION);
|
println!("version {}", vnt::VNT_VERSION);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ fn main() {
|
|||||||
e,
|
e,
|
||||||
std::env::args().collect::<Vec<String>>()
|
std::env::args().collect::<Vec<String>>()
|
||||||
);
|
);
|
||||||
println!("{}", e);
|
println!("Error {:?}", e);
|
||||||
return;
|
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"] }
|
common = { path = "../common", default-features = false, features = ["integrated_tun"] }
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
anyhow = "1.0.82"
|
anyhow = "1.0.82"
|
||||||
|
console = "0.15.2"
|
||||||
|
|
||||||
[target.'cfg(any(target_os = "linux",target_os = "macos"))'.dependencies]
|
[target.'cfg(any(target_os = "linux",target_os = "macos"))'.dependencies]
|
||||||
sudo = "0.6.0"
|
sudo = "0.6.0"
|
||||||
|
|||||||
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
use common::callback;
|
use common::callback;
|
||||||
|
use console::style;
|
||||||
use vnt::core::{Config, Vnt};
|
use vnt::core::{Config, Vnt};
|
||||||
mod root_check;
|
mod root_check;
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -16,7 +17,7 @@ fn main() {
|
|||||||
e,
|
e,
|
||||||
std::env::args().collect::<Vec<String>>()
|
std::env::args().collect::<Vec<String>>()
|
||||||
);
|
);
|
||||||
println!("{}", e);
|
println!("{}", style(format!("Error {:?}", e)).red());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -94,6 +94,14 @@ impl Config {
|
|||||||
allow_wire_guard: bool,
|
allow_wire_guard: bool,
|
||||||
local_ipv4: Option<Ipv4Addr>,
|
local_ipv4: Option<Ipv4Addr>,
|
||||||
) -> anyhow::Result<Self> {
|
) -> 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() {
|
for x in stun_server.iter_mut() {
|
||||||
if !x.contains(":") {
|
if !x.contains(":") {
|
||||||
x.push_str(":3478");
|
x.push_str(":3478");
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ pub enum ErrorType {
|
|||||||
IpAlreadyExists,
|
IpAlreadyExists,
|
||||||
InvalidIp,
|
InvalidIp,
|
||||||
LocalIpExists,
|
LocalIpExists,
|
||||||
|
FailedToCrateDevice,
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,6 +185,7 @@ impl Into<u8> for ErrorType {
|
|||||||
ErrorType::IpAlreadyExists => 4,
|
ErrorType::IpAlreadyExists => 4,
|
||||||
ErrorType::InvalidIp => 5,
|
ErrorType::InvalidIp => 5,
|
||||||
ErrorType::LocalIpExists => 6,
|
ErrorType::LocalIpExists => 6,
|
||||||
|
ErrorType::FailedToCrateDevice => 101,
|
||||||
ErrorType::Unknown => 255,
|
ErrorType::Unknown => 255,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -385,7 +385,7 @@ impl<Call: VntCallback, Device: DeviceWrite> ServerPacketHandler<Call, Device> {
|
|||||||
let device_fd = self.callback.generate_tun(device_config);
|
let device_fd = self.callback.generate_tun(device_config);
|
||||||
if device_fd == 0 {
|
if device_fd == 0 {
|
||||||
self.callback.error(ErrorInfo::new_msg(
|
self.callback.error(ErrorInfo::new_msg(
|
||||||
ErrorType::Unknown,
|
ErrorType::FailedToCrateDevice,
|
||||||
"device_fd == 0".into(),
|
"device_fd == 0".into(),
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
@@ -396,14 +396,14 @@ impl<Call: VntCallback, Device: DeviceWrite> ServerPacketHandler<Call, Device> {
|
|||||||
self.config_info.allow_wire_guard,
|
self.config_info.allow_wire_guard,
|
||||||
) {
|
) {
|
||||||
self.callback.error(ErrorInfo::new_msg(
|
self.callback.error(ErrorInfo::new_msg(
|
||||||
ErrorType::Unknown,
|
ErrorType::FailedToCrateDevice,
|
||||||
format!("{:?}", e),
|
format!("{:?}", e),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
self.callback.error(ErrorInfo::new_msg(
|
self.callback.error(ErrorInfo::new_msg(
|
||||||
ErrorType::Unknown,
|
ErrorType::FailedToCrateDevice,
|
||||||
format!("{:?}", e),
|
format!("{:?}", e),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub fn create_device(config: DeviceConfig) -> Result<Arc<Device>, ErrorInfo> {
|
|||||||
Ok(device) => device,
|
Ok(device) => device,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(ErrorInfo::new_msg(
|
return Err(ErrorInfo::new_msg(
|
||||||
ErrorType::Unknown,
|
ErrorType::FailedToCrateDevice,
|
||||||
format!("create device {:?}", e),
|
format!("create device {:?}", e),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -19,15 +19,16 @@ ioctl = { version = "0.8", package = "ioctl-sys" }
|
|||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
libloading = "0.8.0"
|
libloading = "0.8.0"
|
||||||
widestring = "1.0.2"
|
widestring = "1.0.2"
|
||||||
winapi = {version = "0.3",features = [
|
winapi = { version = "0.3", features = [
|
||||||
"errhandlingapi",
|
"errhandlingapi",
|
||||||
|
"libloaderapi",
|
||||||
"combaseapi",
|
"combaseapi",
|
||||||
"ioapiset",
|
"ioapiset",
|
||||||
"winioctl",
|
"winioctl",
|
||||||
"setupapi",
|
"setupapi",
|
||||||
"synchapi",
|
"synchapi",
|
||||||
"netioapi",
|
"netioapi",
|
||||||
"fileapi","handleapi","winerror","minwindef","ifdef","basetsd","winnt","winreg","winbase","minwinbase",
|
"fileapi", "handleapi", "winerror", "minwindef", "ifdef", "basetsd", "winnt", "winreg", "winbase", "minwinbase",
|
||||||
"impl-default"
|
"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)?))
|
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 {
|
impl IFace for Device {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::os::windows::process::CommandExt;
|
|||||||
use winapi::shared::minwindef::DWORD;
|
use winapi::shared::minwindef::DWORD;
|
||||||
use winapi::um::winbase::CREATE_NO_WINDOW;
|
use winapi::um::winbase::CREATE_NO_WINDOW;
|
||||||
|
|
||||||
|
mod check;
|
||||||
mod device;
|
mod device;
|
||||||
mod ffi;
|
mod ffi;
|
||||||
mod netsh;
|
mod netsh;
|
||||||
|
|||||||
Reference in New Issue
Block a user