Implement TunInterfaceOptions
This commit is contained in:
parent
da065b503f
commit
84f1d91d5c
6 changed files with 83 additions and 9 deletions
|
|
@ -6,4 +6,7 @@ mod imp;
|
|||
#[path = "unix/mod.rs"]
|
||||
pub(crate) mod imp;
|
||||
|
||||
mod options;
|
||||
|
||||
pub use imp::{TunInterface, TunQueue};
|
||||
pub use options::TunInterfaceOptions;
|
||||
|
|
|
|||
38
tun/src/options.rs
Normal file
38
tun/src/options.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
use fehler::throws;
|
||||
use std::io::Error;
|
||||
|
||||
use super::TunInterface;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct TunInterfaceOptions {
|
||||
/// (Windows + Linux) Name the tun interface.
|
||||
pub(crate) name: Option<String>,
|
||||
/// (Linux) Don't include packet information.
|
||||
pub(crate) no_pi: Option<()>,
|
||||
/// (Linux) Avoid opening an existing persistant device.
|
||||
pub(crate) tun_excl: Option<()>,
|
||||
}
|
||||
|
||||
impl TunInterfaceOptions {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn name(mut self, name: &str) -> Self {
|
||||
self.name = Some(name.to_owned());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn no_pi(mut self, enable: bool) {
|
||||
self.no_pi = enable.then_some(());
|
||||
}
|
||||
|
||||
pub fn tun_excl(mut self, enable: bool) {
|
||||
self.tun_excl = enable.then_some(());
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub fn open(self) -> TunInterface {
|
||||
TunInterface::new_with_options(self)?
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@ mod sys;
|
|||
|
||||
pub use super::queue::TunQueue;
|
||||
|
||||
use super::{ifname_to_string, string_to_ifname};
|
||||
use super::{ifname_to_string, string_to_ifname, TunInterfaceOptions};
|
||||
use kern_control::SysControlSocket;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -26,6 +26,11 @@ pub struct TunInterface {
|
|||
impl TunInterface {
|
||||
#[throws]
|
||||
pub fn new() -> TunInterface {
|
||||
Self::new_with_options(TunInterfaceOptions::new())?
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub fn new_with_options(_: TunInterfaceOptions) -> TunInterface {
|
||||
TunInterface::connect(0)?
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use log::info;
|
|||
|
||||
use libc::in6_ifreq;
|
||||
|
||||
use super::{ifname_to_string, string_to_ifname};
|
||||
use super::{ifname_to_string, string_to_ifname, TunInterfaceOptions};
|
||||
|
||||
mod sys;
|
||||
|
||||
|
|
@ -24,16 +24,33 @@ pub struct TunInterface {
|
|||
impl TunInterface {
|
||||
#[throws]
|
||||
pub fn new() -> TunInterface {
|
||||
Self::new_with_options(TunInterfaceOptions::new())?
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn new_with_options(options: TunInterfaceOptions) -> TunInterface {
|
||||
let file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.open("/dev/net/tun")?;
|
||||
|
||||
let mut flags = libc::IFF_TUN as i16;
|
||||
|
||||
if options.no_pi.is_some() {
|
||||
flags |= libc::IFF_NO_PI as i16;
|
||||
}
|
||||
if options.tun_excl.is_some() {
|
||||
flags |= libc::IFF_TUN_EXCL as i16;
|
||||
}
|
||||
|
||||
let name = options
|
||||
.name
|
||||
.map(|name| string_to_ifname(&name))
|
||||
.unwrap_or([0; libc::IFNAMSIZ]);
|
||||
|
||||
let iff = libc::ifreq {
|
||||
ifr_name: [0; libc::IFNAMSIZ],
|
||||
ifr_ifru: libc::__c_anonymous_ifr_ifru {
|
||||
ifru_flags: (libc::IFF_TUN | libc::IFF_TUN_EXCL | libc::IFF_NO_PI) as i16,
|
||||
},
|
||||
ifr_name: name,
|
||||
ifr_ifru: libc::__c_anonymous_ifr_ifru { ifru_flags: flags },
|
||||
};
|
||||
unsafe { sys::tun_set_iff(file.as_raw_fd(), &iff)? };
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ use std::{
|
|||
os::fd::{AsRawFd, FromRawFd, IntoRawFd, RawFd},
|
||||
};
|
||||
|
||||
use super::TunInterfaceOptions;
|
||||
|
||||
mod queue;
|
||||
|
||||
#[cfg(target_vendor = "apple")]
|
||||
|
|
@ -71,7 +73,7 @@ mod test {
|
|||
|
||||
use super::*;
|
||||
use std::io::Write;
|
||||
|
||||
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
#[throws]
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ use widestring::{u16cstr, U16CString};
|
|||
use windows::Win32::Foundation::GetLastError;
|
||||
mod queue;
|
||||
|
||||
use super::TunInterfaceOptions;
|
||||
|
||||
pub use queue::TunQueue;
|
||||
|
||||
pub struct TunInterface {
|
||||
|
|
@ -15,7 +17,14 @@ pub struct TunInterface {
|
|||
impl TunInterface {
|
||||
#[throws]
|
||||
pub fn new() -> TunInterface {
|
||||
let name = U16CString::from(u16cstr!("Burrow"));
|
||||
Self::new_with_options(TunInterfaceOptions::new())?
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn new_with_options(options: TunInterfaceOptions) -> TunInterface {
|
||||
let name_owned = options.name.unwrap_or("Burrow".to_owned());
|
||||
let name = U16CString::from_str(&name_owned).unwrap();
|
||||
|
||||
let handle =
|
||||
unsafe { sys::WINTUN.WintunCreateAdapter(name.as_ptr(), name.as_ptr(), ptr::null()) };
|
||||
if handle.is_null() {
|
||||
|
|
@ -23,7 +32,7 @@ impl TunInterface {
|
|||
}
|
||||
TunInterface {
|
||||
handle,
|
||||
name: String::from("Burrow"),
|
||||
name: name_owned,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue