wintun_bindings/
lib.rs

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//Generated by bingen
22#[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
42/// The maximum size of wintun's internal ring buffer (in bytes)
43pub const MAX_RING_CAPACITY: u32 = wintun_raw::WINTUN_MAX_RING_CAPACITY;
44
45/// The minimum size of wintun's internal ring buffer (in bytes)
46pub const MIN_RING_CAPACITY: u32 = wintun_raw::WINTUN_MIN_RING_CAPACITY;
47
48/// The maximum size of an IP packet (in bytes)
49/// <https://en.wikipedia.org/wiki/Maximum_transmission_unit>
50pub const MAX_IP_PACKET_SIZE: u32 = wintun_raw::WINTUN_MAX_IP_PACKET_SIZE;
51
52/// Maximum pool name length including zero terminator
53pub const MAX_POOL: usize = 256;
54
55pub type Wintun = Arc<wintun_raw::wintun>;
56
57use std::sync::Arc;
58
59/// Attempts to load the Wintun library from the current directory using the default name "wintun.dll".
60///
61/// Use [`load_from_path`] with an absolute path when more control is needed as to where wintun.dll is
62///
63///
64/// # Safety
65/// This function loads a dll file with the name wintun.dll using the default system search paths.
66/// This is inherently unsafe as a user could simply rename undefined_behavior.dll to wintun.dll
67/// and do nefarious things inside of its DllMain function. In most cases, a regular wintun.dll
68/// file which exports all of the required functions for these bindings to work is loaded. Because
69/// WinTun is a well-written and well-tested library, loading a _normal_ wintun.dll file should be safe.
70/// Hoverer one can never be too cautious when loading a dll file.
71///
72/// For more information see [`libloading`]'s dynamic library safety guarantees: [`libloading`][`libloading::Library::new`]
73pub unsafe fn load() -> Result<Wintun, Error> {
74    unsafe { load_from_path("wintun") }
75}
76
77/// Attempts to load the Wintun library as a dynamic library from the given path.
78///
79///
80/// # Safety
81/// This function loads a dll file with the path provided.
82/// This is inherently unsafe as a user could simply rename undefined_behavior.dll to wintun.dll
83/// and do nefarious things inside of its DllMain function. In most cases, a regular wintun.dll
84/// file which exports all of the required functions for these bindings to work is loaded. Because
85/// WinTun is a well-written and well-tested library, loading a _normal_ wintun.dll file should be safe.
86/// Hoverer one can never be too cautious when loading a dll file.
87///
88/// For more information see [`libloading`]'s dynamic library safety guarantees: [`libloading`][`libloading::Library::new`]
89pub 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        // Ensure the dll file has not been tampered with.
97        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
109/// Attempts to load the Wintun library from an existing [`libloading::Library`].
110///
111///
112/// # Safety
113/// This function loads the required WinTun functions using the provided library. Reading a symbol table
114/// of a dynamic library and transmuting the function pointers inside to have the parameters and return
115/// values expected by the functions documented at: <https://git.zx2c4.com/wintun/about/#reference>
116/// is inherently unsafe.
117///
118/// For more information see [`libloading`]'s dynamic library safety guarantees: [`libloading::Library::new`]
119pub 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
138/// Returns the major and minor version of the wintun driver
139pub 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}