wintun_bindings/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#![doc = include_str!("../README.md")]
#![recursion_limit = "1024"]

mod adapter;
#[cfg(feature = "async")]
mod async_session;
mod error;
mod ffi;
mod handle;
mod log;
mod packet;
mod session;
mod util;
#[cfg(feature = "verify_binary_signature")]
mod verify_binary_signature;

#[cfg(feature = "verify_binary_signature")]
pub(crate) const WINTUN_PROVIDER: &str = "WireGuard LLC";

//Generated by bingen
#[allow(dead_code, unused_variables, deref_nullptr, clippy::all)]
mod wintun_raw;

#[cfg(feature = "async")]
pub use crate::async_session::AsyncSession;

pub use crate::{
    adapter::Adapter,
    error::{BoxError, Error, OutOfRangeData, Result},
    handle::UnsafeHandle,
    log::{default_logger, reset_logger, set_logger},
    packet::Packet,
    session::Session,
    util::get_active_network_interface_gateways,
};
#[doc(hidden)]
pub use util::{format_message, get_wintun_bin_pattern_path, run_command};

pub use windows_sys::Win32::{Foundation::HANDLE, NetworkManagement::Ndis::NET_LUID_LH};

/// The maximum size of wintun's internal ring buffer (in bytes)
pub const MAX_RING_CAPACITY: u32 = wintun_raw::WINTUN_MAX_RING_CAPACITY;

/// The minimum size of wintun's internal ring buffer (in bytes)
pub const MIN_RING_CAPACITY: u32 = wintun_raw::WINTUN_MIN_RING_CAPACITY;

/// The maximum size of an IP packet (in bytes)
/// <https://en.wikipedia.org/wiki/Maximum_transmission_unit>
pub const MAX_IP_PACKET_SIZE: u32 = wintun_raw::WINTUN_MAX_IP_PACKET_SIZE;

/// Maximum pool name length including zero terminator
pub const MAX_POOL: usize = 256;

pub type Wintun = Arc<wintun_raw::wintun>;

use std::sync::Arc;

/// Attempts to load the Wintun library from the current directory using the default name "wintun.dll".
///
/// Use [`load_from_path`] with an absolute path when more control is needed as to where wintun.dll is
///
///
/// # Safety
/// This function loads a dll file with the name wintun.dll using the default system search paths.
/// This is inherently unsafe as a user could simply rename undefined_behavior.dll to wintun.dll
/// and do nefarious things inside of its DllMain function. In most cases, a regular wintun.dll
/// file which exports all of the required functions for these bindings to work is loaded. Because
/// WinTun is a well-written and well-tested library, loading a _normal_ wintun.dll file should be safe.
/// Hoverer one can never be too cautious when loading a dll file.
///
/// For more information see [`libloading`]'s dynamic library safety guarantees: [`libloading`][`libloading::Library::new`]
pub unsafe fn load() -> Result<Wintun, Error> {
    load_from_path("wintun")
}

/// Attempts to load the Wintun library as a dynamic library from the given path.
///
///
/// # Safety
/// This function loads a dll file with the path provided.
/// This is inherently unsafe as a user could simply rename undefined_behavior.dll to wintun.dll
/// and do nefarious things inside of its DllMain function. In most cases, a regular wintun.dll
/// file which exports all of the required functions for these bindings to work is loaded. Because
/// WinTun is a well-written and well-tested library, loading a _normal_ wintun.dll file should be safe.
/// Hoverer one can never be too cautious when loading a dll file.
///
/// For more information see [`libloading`]'s dynamic library safety guarantees: [`libloading`][`libloading::Library::new`]
pub unsafe fn load_from_path<P>(path: P) -> Result<Wintun, Error>
where
    P: AsRef<::std::ffi::OsStr>,
{
    #[cfg(feature = "verify_binary_signature")]
    {
        use verify_binary_signature::{get_dll_absolute_path, get_signer_name, verify_signature};
        // Ensure the dll file has not been tampered with.
        let abs_path = get_dll_absolute_path(&path)?;
        verify_signature(&abs_path)?;
        let signer_name = get_signer_name(&abs_path)?;
        let wp = WINTUN_PROVIDER;
        if signer_name != wp {
            return Err(format!("Signer \"{}\" not match \"{}\"", signer_name, wp).into());
        }
    }
    unsafe { Ok(Arc::new(wintun_raw::wintun::new(path)?)) }
}

/// Attempts to load the Wintun library from an existing [`libloading::Library`].
///
///
/// # Safety
/// This function loads the required WinTun functions using the provided library. Reading a symbol table
/// of a dynamic library and transmuting the function pointers inside to have the parameters and return
/// values expected by the functions documented at: <https://git.zx2c4.com/wintun/about/#reference>
/// is inherently unsafe.
///
/// For more information see [`libloading`]'s dynamic library safety guarantees: [`libloading::Library::new`]
pub unsafe fn load_from_library<L>(library: L) -> Result<Wintun, Error>
where
    L: Into<libloading::Library>,
{
    unsafe { Ok(Arc::new(wintun_raw::wintun::from_library(library)?)) }
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct Version {
    pub major: u16,
    pub minor: u16,
}

impl std::fmt::Display for Version {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}.{}", self.major, self.minor)
    }
}

/// Returns the major and minor version of the wintun driver
pub fn get_running_driver_version(wintun: &Wintun) -> Result<Version> {
    let version = unsafe { wintun.WintunGetRunningDriverVersion() };
    if version == 0 {
        Err(util::get_last_error()?.into())
    } else {
        let v = version.to_be_bytes();
        Ok(Version {
            major: u16::from_be_bytes([v[0], v[1]]),
            minor: u16::from_be_bytes([v[2], v[3]]),
        })
    }
}