1#![doc = include_str!("../README.md")]
2#![recursion_limit = "1024"]
3
4mod adapter;
5#[cfg(feature = "async")]
6mod async_session;
7mod error;
8mod ffi;
9mod fn_holder;
10mod handle;
11mod log;
12mod packet;
13mod session;
14mod util;
15#[cfg(feature = "verify_binary_signature")]
16mod verify_binary_signature;
17
18#[cfg(feature = "verify_binary_signature")]
19pub(crate) const WINTUN_PROVIDER: &str = "WireGuard LLC";
20
21#[allow(dead_code, unused_variables, deref_nullptr, clippy::all)]
23mod wintun_raw;
24
25#[cfg(feature = "async")]
26pub use crate::async_session::AsyncSession;
27
28pub use crate::{
29 adapter::Adapter,
30 error::{BoxError, Error, OutOfRangeData, Result},
31 handle::UnsafeHandle,
32 log::{default_logger, reset_logger, set_logger},
33 packet::Packet,
34 session::Session,
35 util::get_active_network_interface_gateways,
36};
37#[doc(hidden)]
38pub use util::{format_message, get_wintun_bin_pattern_path, run_command, set_adapter_mtu};
39
40pub use windows_sys::Win32::{Foundation::HANDLE, NetworkManagement::Ndis::NET_LUID_LH};
41
42pub const MAX_RING_CAPACITY: u32 = wintun_raw::WINTUN_MAX_RING_CAPACITY;
44
45pub const MIN_RING_CAPACITY: u32 = wintun_raw::WINTUN_MIN_RING_CAPACITY;
47
48pub const MAX_IP_PACKET_SIZE: u32 = wintun_raw::WINTUN_MAX_IP_PACKET_SIZE;
51
52pub const MAX_POOL: usize = 256;
54
55pub type Wintun = Arc<wintun_raw::wintun>;
56
57use std::sync::Arc;
58
59pub unsafe fn load() -> Result<Wintun, Error> {
74 unsafe { load_from_path("wintun") }
75}
76
77pub unsafe fn load_from_path<P>(path: P) -> Result<Wintun, Error>
90where
91 P: AsRef<::std::ffi::OsStr>,
92{
93 #[cfg(feature = "verify_binary_signature")]
94 {
95 use verify_binary_signature::{get_dll_absolute_path, get_signer_name, verify_signature};
96 let abs_path = unsafe { get_dll_absolute_path(&path) }?;
98 verify_signature(&abs_path)?;
99 let signer_name = get_signer_name(&abs_path)?;
100 let wp = WINTUN_PROVIDER;
101 if signer_name != wp {
102 return Err(format!("Signer \"{}\" not match \"{}\"", signer_name, wp).into());
103 }
104 }
105 let path2: std::path::PathBuf = path.as_ref().into();
106 unsafe { Ok(Arc::new(wintun_raw::wintun::new(&path2)?)) }
107}
108
109pub unsafe fn load_from_library<L>(library: L) -> Result<Wintun, Error>
120where
121 L: Into<libloading::Library>,
122{
123 unsafe { Ok(Arc::new(wintun_raw::wintun::from_library(library)?)) }
124}
125
126#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
127pub struct Version {
128 pub major: u16,
129 pub minor: u16,
130}
131
132impl std::fmt::Display for Version {
133 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134 write!(f, "{}.{}", self.major, self.minor)
135 }
136}
137
138pub fn get_running_driver_version(wintun: &Wintun) -> Result<Version> {
140 let version = unsafe { wintun.WintunGetRunningDriverVersion() };
141 if version == 0 {
142 Err(util::get_last_error()?.into())
143 } else {
144 let v = version.to_be_bytes();
145 Ok(Version {
146 major: u16::from_be_bytes([v[0], v[1]]),
147 minor: u16::from_be_bytes([v[2], v[3]]),
148 })
149 }
150}