wintun-bindings 0.7.35

Safe idiomatic bindings to the WinTun C library and more enhancements
Documentation
#![doc = include_str!("../README.md")]
#![recursion_limit = "1024"]

mod adapter;
#[cfg(feature = "async")]
mod async_session;
mod dns_via_reg;
mod error;
mod ffi;
mod fn_holder;
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, set_adapter_mtu};

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> {
    unsafe { 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 = unsafe { 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());
        }
    }
    let path2: std::path::PathBuf = path.as_ref().into();
    unsafe { Ok(Arc::new(wintun_raw::wintun::new(&path2)?)) }
}

/// 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]]),
        })
    }
}