提示虚拟网卡创建失败的信息

This commit is contained in:
lbl8603
2024-08-07 21:29:55 +08:00
parent afff49e61a
commit dc4e472f20
14 changed files with 198 additions and 19 deletions
Generated
+1
View File
@@ -2195,6 +2195,7 @@ dependencies = [
"anyhow",
"chrono",
"common",
"console",
"log",
"rand",
"signal-hook",
+2 -1
View File
@@ -37,7 +37,8 @@ impl VntCallback for VntHandler {
| ErrorType::AddressExhausted
| ErrorType::IpAlreadyExists
| ErrorType::InvalidIp
| ErrorType::LocalIpExists => {
| ErrorType::LocalIpExists
| ErrorType::FailedToCrateDevice => {
self.stop();
}
_ => {}
+2 -8
View File
@@ -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);
+1 -1
View File
@@ -17,7 +17,7 @@ fn main() {
e,
std::env::args().collect::<Vec<String>>()
);
println!("{}", e);
println!("Error {:?}", e);
return;
}
};
+1 -1
View File
@@ -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
View File
@@ -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;
}
};
+8
View File
@@ -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");
+2
View File
@@ -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,
}
}
+3 -3
View File
@@ -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),
));
}
+1 -1
View File
@@ -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
View File
@@ -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"
]}
] }
+167
View File
@@ -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(())
}
+3
View File
@@ -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 {
+1
View File
@@ -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;