diff --git a/vnt/rust-tun/Cargo.toml b/vnt/rust-tun/Cargo.toml deleted file mode 100644 index 7568382..0000000 --- a/vnt/rust-tun/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -name = "tun" -version = "0.5.4" -edition = "2018" - -authors = ["meh. "] -license = "WTFPL" - -description = "TUN device creation and handling." -repository = "https://github.com/meh/rust-tun" -keywords = ["tun", "network", "tunnel", "bindings"] - -[dependencies] -libc = "0.2" -thiserror = "1" - -[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "ios", target_os = "android"))'.dependencies] -bytes = { version = "1", optional = true } -byteorder = { version = "1", optional = true } - - -[target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies] -ioctl = { version = "0.6", package = "ioctl-sys" } - - diff --git a/vnt/rust-tun/src/address.rs b/vnt/rust-tun/src/address.rs deleted file mode 100644 index fd85fd4..0000000 --- a/vnt/rust-tun/src/address.rs +++ /dev/null @@ -1,128 +0,0 @@ -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// Version 2, December 2004 -// -// Copyleft (ↄ) meh. | http://meh.schizofreni.co -// -// Everyone is permitted to copy and distribute verbatim or modified -// copies of this license document, and changing it is allowed as long -// as the name is changed. -// -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -// -// 0. You just DO WHAT THE FUCK YOU WANT TO. - -use std::net::{IpAddr, Ipv4Addr}; -use std::net::{SocketAddr, SocketAddrV4}; - -use crate::error::*; - -/// Helper trait to convert things into IPv4 addresses. -#[allow(clippy::wrong_self_convention)] -pub trait IntoAddress { - /// Convert the type to an `Ipv4Addr`. - fn into_address(&self) -> Result; -} - -impl IntoAddress for u32 { - fn into_address(&self) -> Result { - Ok(Ipv4Addr::new( - ((*self) & 0xff) as u8, - ((*self >> 8) & 0xff) as u8, - ((*self >> 16) & 0xff) as u8, - ((*self >> 24) & 0xff) as u8, - )) - } -} - -impl IntoAddress for i32 { - fn into_address(&self) -> Result { - (*self as u32).into_address() - } -} - -impl IntoAddress for (u8, u8, u8, u8) { - fn into_address(&self) -> Result { - Ok(Ipv4Addr::new(self.0, self.1, self.2, self.3)) - } -} - -impl IntoAddress for str { - fn into_address(&self) -> Result { - self.parse().map_err(|_| Error::InvalidAddress) - } -} - -impl<'a> IntoAddress for &'a str { - fn into_address(&self) -> Result { - (*self).into_address() - } -} - -impl IntoAddress for String { - fn into_address(&self) -> Result { - (&**self).into_address() - } -} - -impl<'a> IntoAddress for &'a String { - fn into_address(&self) -> Result { - (&**self).into_address() - } -} - -impl IntoAddress for Ipv4Addr { - fn into_address(&self) -> Result { - Ok(*self) - } -} - -impl<'a> IntoAddress for &'a Ipv4Addr { - fn into_address(&self) -> Result { - (&**self).into_address() - } -} - -impl IntoAddress for IpAddr { - fn into_address(&self) -> Result { - match *self { - IpAddr::V4(ref value) => Ok(*value), - - IpAddr::V6(_) => Err(Error::InvalidAddress), - } - } -} - -impl<'a> IntoAddress for &'a IpAddr { - fn into_address(&self) -> Result { - (&**self).into_address() - } -} - -impl IntoAddress for SocketAddrV4 { - fn into_address(&self) -> Result { - Ok(*self.ip()) - } -} - -impl<'a> IntoAddress for &'a SocketAddrV4 { - fn into_address(&self) -> Result { - (&**self).into_address() - } -} - -impl IntoAddress for SocketAddr { - fn into_address(&self) -> Result { - match *self { - SocketAddr::V4(ref value) => Ok(*value.ip()), - - SocketAddr::V6(_) => Err(Error::InvalidAddress), - } - } -} - -impl<'a> IntoAddress for &'a SocketAddr { - fn into_address(&self) -> Result { - (&**self).into_address() - } -} diff --git a/vnt/rust-tun/src/configuration.rs b/vnt/rust-tun/src/configuration.rs deleted file mode 100644 index 6c6652c..0000000 --- a/vnt/rust-tun/src/configuration.rs +++ /dev/null @@ -1,126 +0,0 @@ -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// Version 2, December 2004 -// -// Copyleft (ↄ) meh. | http://meh.schizofreni.co -// -// Everyone is permitted to copy and distribute verbatim or modified -// copies of this license document, and changing it is allowed as long -// as the name is changed. -// -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -// -// 0. You just DO WHAT THE FUCK YOU WANT TO. - -use std::net::Ipv4Addr; -use std::os::unix::io::RawFd; - -use crate::address::IntoAddress; -use crate::platform; - -/// TUN interface OSI layer of operation. -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Layer { - L2, - L3, -} - -impl Default for Layer { - fn default() -> Self { - Layer::L3 - } -} - -/// Configuration builder for a TUN interface. -#[derive(Clone, Default, Debug)] -pub struct Configuration { - pub(crate) name: Option, - pub(crate) platform: platform::Configuration, - - pub(crate) address: Option, - pub(crate) destination: Option, - pub(crate) broadcast: Option, - pub(crate) netmask: Option, - pub(crate) mtu: Option, - pub(crate) enabled: Option, - pub(crate) layer: Option, - pub(crate) queues: Option, - pub(crate) raw_fd: Option, -} - -impl Configuration { - /// Access the platform dependant configuration. - pub fn platform(&mut self, f: F) -> &mut Self - where - F: FnOnce(&mut platform::Configuration), - { - f(&mut self.platform); - self - } - - /// Set the name. - pub fn name>(&mut self, name: S) -> &mut Self { - self.name = Some(name.as_ref().into()); - self - } - - /// Set the address. - pub fn address(&mut self, value: A) -> &mut Self { - self.address = Some(value.into_address().unwrap()); - self - } - - /// Set the destination address. - pub fn destination(&mut self, value: A) -> &mut Self { - self.destination = Some(value.into_address().unwrap()); - self - } - - /// Set the broadcast address. - pub fn broadcast(&mut self, value: A) -> &mut Self { - self.broadcast = Some(value.into_address().unwrap()); - self - } - - /// Set the netmask. - pub fn netmask(&mut self, value: A) -> &mut Self { - self.netmask = Some(value.into_address().unwrap()); - self - } - - /// Set the MTU. - pub fn mtu(&mut self, value: i32) -> &mut Self { - self.mtu = Some(value); - self - } - - /// Set the interface to be enabled once created. - pub fn up(&mut self) -> &mut Self { - self.enabled = Some(true); - self - } - - /// Set the interface to be disabled once created. - pub fn down(&mut self) -> &mut Self { - self.enabled = Some(false); - self - } - - /// Set the OSI layer of operation. - pub fn layer(&mut self, value: Layer) -> &mut Self { - self.layer = Some(value); - self - } - - /// Set the number of queues. - pub fn queues(&mut self, value: usize) -> &mut Self { - self.queues = Some(value); - self - } - - /// Set the raw fd. - pub fn raw_fd(&mut self, fd: RawFd) -> &mut Self { - self.raw_fd = Some(fd); - self - } -} diff --git a/vnt/rust-tun/src/device.rs b/vnt/rust-tun/src/device.rs deleted file mode 100644 index b3f3bc7..0000000 --- a/vnt/rust-tun/src/device.rs +++ /dev/null @@ -1,94 +0,0 @@ -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// Version 2, December 2004 -// -// Copyleft (ↄ) meh. | http://meh.schizofreni.co -// -// Everyone is permitted to copy and distribute verbatim or modified -// copies of this license document, and changing it is allowed as long -// as the name is changed. -// -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -// -// 0. You just DO WHAT THE FUCK YOU WANT TO. - -use std::net::Ipv4Addr; - -use crate::configuration::Configuration; -use crate::error::*; - -/// A TUN device. -pub trait Device { - type Queue; - - /// Reconfigure the device. - fn configure(&mut self, config: &Configuration) -> Result<()> { - if let Some(ip) = config.address { - self.set_address(ip)?; - } - - if let Some(ip) = config.destination { - self.set_destination(ip)?; - } - - if let Some(ip) = config.broadcast { - self.set_broadcast(ip)?; - } - - if let Some(ip) = config.netmask { - self.set_netmask(ip)?; - } - - if let Some(mtu) = config.mtu { - self.set_mtu(mtu)?; - } - - if let Some(enabled) = config.enabled { - self.enabled(enabled)?; - } - - Ok(()) - } - - /// Get the device name. - fn name(&self) -> &str; - - /// Set the device name. - fn set_name(&mut self, name: &str) -> Result<()>; - - /// Turn on or off the interface. - fn enabled(&mut self, value: bool) -> Result<()>; - - /// Get the address. - fn address(&self) -> Result; - - /// Set the address. - fn set_address(&mut self, value: Ipv4Addr) -> Result<()>; - - /// Get the destination address. - fn destination(&self) -> Result; - - /// Set the destination address. - fn set_destination(&mut self, value: Ipv4Addr) -> Result<()>; - - /// Get the broadcast address. - fn broadcast(&self) -> Result; - - /// Set the broadcast address. - fn set_broadcast(&mut self, value: Ipv4Addr) -> Result<()>; - - /// Get the netmask. - fn netmask(&self) -> Result; - - /// Set the netmask. - fn set_netmask(&mut self, value: Ipv4Addr) -> Result<()>; - - /// Get the MTU. - fn mtu(&self) -> Result; - - /// Set the MTU. - fn set_mtu(&mut self, value: i32) -> Result<()>; - - /// Get a device queue. - fn queue(&self, index: usize) -> Option<&Self::Queue>; -} diff --git a/vnt/rust-tun/src/error.rs b/vnt/rust-tun/src/error.rs deleted file mode 100644 index fb41960..0000000 --- a/vnt/rust-tun/src/error.rs +++ /dev/null @@ -1,54 +0,0 @@ -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// Version 2, December 2004 -// -// Copyleft (ↄ) meh. | http://meh.schizofreni.co -// -// Everyone is permitted to copy and distribute verbatim or modified -// copies of this license document, and changing it is allowed as long -// as the name is changed. -// -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -// -// 0. You just DO WHAT THE FUCK YOU WANT TO. - -use std::{ffi, io, num}; -use thiserror::Error; - -#[derive(Error, Debug)] -pub enum Error { - #[error("invalid configuration")] - InvalidConfig, - - #[error("not implementated")] - NotImplemented, - - #[error("device name too long")] - NameTooLong, - - #[error("invalid device name")] - InvalidName, - - #[error("invalid address")] - InvalidAddress, - - #[error("invalid file descriptor")] - InvalidDescriptor, - - #[error("unsuported network layer of operation")] - UnsupportedLayer, - - #[error("invalid queues number")] - InvalidQueuesNumber, - - #[error(transparent)] - Io(#[from] io::Error), - - #[error(transparent)] - Nul(#[from] ffi::NulError), - - #[error(transparent)] - ParseNum(#[from] num::ParseIntError), -} - -pub type Result = ::std::result::Result; diff --git a/vnt/rust-tun/src/lib.rs b/vnt/rust-tun/src/lib.rs deleted file mode 100644 index 482e2c6..0000000 --- a/vnt/rust-tun/src/lib.rs +++ /dev/null @@ -1,32 +0,0 @@ -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// Version 2, December 2004 -// -// Copyleft (ↄ) meh. | http://meh.schizofreni.co -// -// Everyone is permitted to copy and distribute verbatim or modified -// copies of this license document, and changing it is allowed as long -// as the name is changed. -// -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -// -// 0. You just DO WHAT THE FUCK YOU WANT TO. -#![cfg(unix)] -mod error; -pub use crate::error::*; - -mod address; -pub use crate::address::IntoAddress; - -mod device; -pub use crate::device::Device; - -mod configuration; -pub use crate::configuration::{Configuration, Layer}; - -pub mod platform; -pub use crate::platform::create; - -pub fn configure() -> Configuration { - Configuration::default() -} diff --git a/vnt/rust-tun/src/platform/linux/device.rs b/vnt/rust-tun/src/platform/linux/device.rs deleted file mode 100644 index 1503a3a..0000000 --- a/vnt/rust-tun/src/platform/linux/device.rs +++ /dev/null @@ -1,384 +0,0 @@ -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// Version 2, December 2004 -// -// Copyleft (ↄ) meh. | http://meh.schizofreni.co -// -// Everyone is permitted to copy and distribute verbatim or modified -// copies of this license document, and changing it is allowed as long -// as the name is changed. -// -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -// -// 0. You just DO WHAT THE FUCK YOU WANT TO. - -use std::ffi::{CStr, CString}; -use std::io; -use std::mem; -use std::net::Ipv4Addr; -use std::os::unix::io::AsRawFd; -use std::ptr; -use std::sync::Arc; -use std::vec::Vec; - -use libc; -use libc::{c_char, c_short}; -use libc::{AF_INET, O_RDWR, SOCK_DGRAM}; - -use crate::configuration::{Configuration, Layer}; -use crate::device::Device as D; -use crate::error::*; -use crate::platform::linux::sys::*; -use crate::platform::posix::{self, Fd, SockAddr}; - -/// A TUN device using the TUN/TAP Linux driver. -pub struct Device { - name: String, - queues: Vec, - ctl: Fd, -} - -impl Device { - /// Create a new `Device` for the given `Configuration`. - pub fn new(config: &Configuration) -> Result { - let mut device = unsafe { - let dev = match config.name.as_ref() { - Some(name) => { - let name = CString::new(name.clone())?; - - if name.as_bytes_with_nul().len() > IFNAMSIZ { - return Err(Error::NameTooLong); - } - - Some(name) - } - - None => None, - }; - - let mut queues = Vec::new(); - - let mut req: ifreq = mem::zeroed(); - - if let Some(dev) = dev.as_ref() { - ptr::copy_nonoverlapping( - dev.as_ptr() as *const c_char, - req.ifrn.name.as_mut_ptr(), - dev.as_bytes().len(), - ); - } - - let device_type: c_short = config.layer.unwrap_or(Layer::L3).into(); - - let queues_num = config.queues.unwrap_or(1); - if queues_num < 1 { - return Err(Error::InvalidQueuesNumber); - } - - req.ifru.flags = device_type - | if config.platform.packet_information { - 0 - } else { - IFF_NO_PI - } - | if queues_num > 1 { IFF_MULTI_QUEUE } else { 0 }; - - for _ in 0..queues_num { - let tun = Fd::new(libc::open(b"/dev/net/tun\0".as_ptr() as *const _, O_RDWR)) - .map_err(|_| io::Error::last_os_error())?; - - if tunsetiff(tun.0, &mut req as *mut _ as *mut _) < 0 { - return Err(io::Error::last_os_error().into()); - } - - queues.push(Queue { - tun: Arc::new(tun), - pi_enabled: config.platform.packet_information, - }); - } - - let ctl = Fd::new(libc::socket(AF_INET, SOCK_DGRAM, 0)) - .map_err(|_| io::Error::last_os_error())?; - - Device { - name: CStr::from_ptr(req.ifrn.name.as_ptr()) - .to_string_lossy() - .into(), - queues, - ctl, - } - }; - - device.configure(config)?; - - Ok(device) - } - - /// Prepare a new request. - unsafe fn request(&self) -> ifreq { - let mut req: ifreq = mem::zeroed(); - ptr::copy_nonoverlapping( - self.name.as_ptr() as *const c_char, - req.ifrn.name.as_mut_ptr(), - self.name.len(), - ); - - req - } - - // /// Make the device persistent. - // pub fn persist(&mut self) -> Result<()> { - // unsafe { - // if tunsetpersist(self.as_raw_fd(), &1) < 0 { - // Err(io::Error::last_os_error().into()) - // } else { - // Ok(()) - // } - // } - // } - - // /// Set the owner of the device. - // pub fn user(&mut self, value: i32) -> Result<()> { - // unsafe { - // if tunsetowner(self.as_raw_fd(), &value) < 0 { - // Err(io::Error::last_os_error().into()) - // } else { - // Ok(()) - // } - // } - // } - // - // /// Set the group of the device. - // pub fn group(&mut self, value: i32) -> Result<()> { - // unsafe { - // if tunsetgroup(self.as_raw_fd(), &value) < 0 { - // Err(io::Error::last_os_error().into()) - // } else { - // Ok(()) - // } - // } - // } - /// Return whether the device has packet information - pub fn has_packet_information(&self) -> bool { - self.queues[0].has_packet_information() - } - - /// Set non-blocking mode - pub fn set_nonblock(&self) -> io::Result<()> { - self.queues[0].set_nonblock() - } -} - -impl D for Device { - type Queue = Queue; - - fn name(&self) -> &str { - &self.name - } - - fn set_name(&mut self, value: &str) -> Result<()> { - unsafe { - let name = CString::new(value)?; - - if name.as_bytes_with_nul().len() > IFNAMSIZ { - return Err(Error::NameTooLong); - } - - let mut req = self.request(); - ptr::copy_nonoverlapping( - name.as_ptr() as *const c_char, - req.ifru.newname.as_mut_ptr(), - value.len(), - ); - - if siocsifname(self.ctl.as_raw_fd(), &req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - self.name = value.into(); - - Ok(()) - } - } - - fn enabled(&mut self, value: bool) -> Result<()> { - unsafe { - let mut req = self.request(); - - if siocgifflags(self.ctl.as_raw_fd(), &mut req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - if value { - req.ifru.flags |= IFF_UP | IFF_RUNNING; - } else { - req.ifru.flags &= !IFF_UP; - } - - if siocsifflags(self.ctl.as_raw_fd(), &req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - Ok(()) - } - } - - fn address(&self) -> Result { - unsafe { - let mut req = self.request(); - - if siocgifaddr(self.ctl.as_raw_fd(), &mut req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - SockAddr::new(&req.ifru.addr).map(Into::into) - } - } - - fn set_address(&mut self, value: Ipv4Addr) -> Result<()> { - unsafe { - let mut req = self.request(); - req.ifru.addr = SockAddr::from(value).into(); - - if siocsifaddr(self.ctl.as_raw_fd(), &req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - Ok(()) - } - } - - fn destination(&self) -> Result { - unsafe { - let mut req = self.request(); - - if siocgifdstaddr(self.ctl.as_raw_fd(), &mut req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - SockAddr::new(&req.ifru.dstaddr).map(Into::into) - } - } - - fn set_destination(&mut self, value: Ipv4Addr) -> Result<()> { - unsafe { - let mut req = self.request(); - req.ifru.dstaddr = SockAddr::from(value).into(); - - if siocsifdstaddr(self.ctl.as_raw_fd(), &req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - Ok(()) - } - } - - fn broadcast(&self) -> Result { - unsafe { - let mut req = self.request(); - - if siocgifbrdaddr(self.ctl.as_raw_fd(), &mut req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - SockAddr::new(&req.ifru.broadaddr).map(Into::into) - } - } - - fn set_broadcast(&mut self, value: Ipv4Addr) -> Result<()> { - unsafe { - let mut req = self.request(); - req.ifru.broadaddr = SockAddr::from(value).into(); - - if siocsifbrdaddr(self.ctl.as_raw_fd(), &req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - Ok(()) - } - } - - fn netmask(&self) -> Result { - unsafe { - let mut req = self.request(); - - if siocgifnetmask(self.ctl.as_raw_fd(), &mut req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - SockAddr::new(&req.ifru.netmask).map(Into::into) - } - } - - fn set_netmask(&mut self, value: Ipv4Addr) -> Result<()> { - unsafe { - let mut req = self.request(); - req.ifru.netmask = SockAddr::from(value).into(); - - if siocsifnetmask(self.ctl.as_raw_fd(), &req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - Ok(()) - } - } - - fn mtu(&self) -> Result { - unsafe { - let mut req = self.request(); - - if siocgifmtu(self.ctl.as_raw_fd(), &mut req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - Ok(req.ifru.mtu) - } - } - - fn set_mtu(&mut self, value: i32) -> Result<()> { - unsafe { - let mut req = self.request(); - req.ifru.mtu = value; - - if siocsifmtu(self.ctl.as_raw_fd(), &req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - Ok(()) - } - } - - fn queue(&self, index: usize) -> Option<&Self::Queue> { - self.queues.get(index) - } -} - -pub struct Queue { - tun: Arc, - pi_enabled: bool, -} - -impl Queue { - pub fn has_packet_information(&self) -> bool { - self.pi_enabled - } - - pub fn set_nonblock(&self) -> io::Result<()> { - self.tun.set_nonblock() - } - pub fn reader(&self) -> posix::Reader { - posix::Reader(self.tun.clone()) - } - pub fn writer(&self) -> posix::Writer { - posix::Writer(self.tun.clone()) - } -} - -impl From for c_short { - fn from(layer: Layer) -> Self { - match layer { - Layer::L2 => IFF_TAP, - Layer::L3 => IFF_TUN, - } - } -} diff --git a/vnt/rust-tun/src/platform/linux/mod.rs b/vnt/rust-tun/src/platform/linux/mod.rs deleted file mode 100644 index 455a279..0000000 --- a/vnt/rust-tun/src/platform/linux/mod.rs +++ /dev/null @@ -1,43 +0,0 @@ -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// Version 2, December 2004 -// -// Copyleft (ↄ) meh. | http://meh.schizofreni.co -// -// Everyone is permitted to copy and distribute verbatim or modified -// copies of this license document, and changing it is allowed as long -// as the name is changed. -// -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -// -// 0. You just DO WHAT THE FUCK YOU WANT TO. - -//! Linux specific functionality. - -pub mod sys; - -mod device; -pub use self::device::{Device, Queue}; - -use crate::configuration::Configuration as C; -use crate::error::*; - -/// Linux-only interface configuration. -#[derive(Copy, Clone, Default, Debug)] -pub struct Configuration { - pub(crate) packet_information: bool, -} - -impl Configuration { - /// Enable or disable packet information, when enabled the first 4 bytes of - /// each packet is a header with flags and protocol type. - pub fn packet_information(&mut self, value: bool) -> &mut Self { - self.packet_information = value; - self - } -} - -/// Create a TUN device with the given name. -pub fn create(configuration: &C) -> Result { - Device::new(configuration) -} diff --git a/vnt/rust-tun/src/platform/linux/sys.rs b/vnt/rust-tun/src/platform/linux/sys.rs deleted file mode 100644 index cf35c93..0000000 --- a/vnt/rust-tun/src/platform/linux/sys.rs +++ /dev/null @@ -1,111 +0,0 @@ -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// Version 2, December 2004 -// -// Copyleft (ↄ) meh. | http://meh.schizofreni.co -// -// Everyone is permitted to copy and distribute verbatim or modified -// copies of this license document, and changing it is allowed as long -// as the name is changed. -// -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -// -// 0. You just DO WHAT THE FUCK YOU WANT TO. - -//! Bindings to internal Linux stuff. - -use ioctl::*; -use libc::sockaddr; -use libc::{c_char, c_int, c_short, c_uchar, c_uint, c_ulong, c_ushort, c_void}; - -pub const IFNAMSIZ: usize = 16; - -pub const IFF_UP: c_short = 0x1; -pub const IFF_RUNNING: c_short = 0x40; - -pub const IFF_TUN: c_short = 0x0001; -pub const IFF_TAP: c_short = 0x0002; -pub const IFF_NO_PI: c_short = 0x1000; -pub const IFF_MULTI_QUEUE: c_short = 0x0100; - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct ifmap { - pub mem_start: c_ulong, - pub mem_end: c_ulong, - pub base_addr: c_ushort, - pub irq: c_uchar, - pub dma: c_uchar, - pub port: c_uchar, -} - -#[repr(C)] -#[derive(Copy, Clone)] -pub union ifsu { - pub raw_hdlc_proto: *mut c_void, - pub cisco: *mut c_void, - pub fr: *mut c_void, - pub fr_pvc: *mut c_void, - pub fr_pvc_info: *mut c_void, - pub sync: *mut c_void, - pub te1: *mut c_void, -} - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct if_settings { - pub type_: c_uint, - pub size: c_uint, - pub ifsu: ifsu, -} - -#[repr(C)] -#[derive(Copy, Clone)] -pub union ifrn { - pub name: [c_char; IFNAMSIZ], -} - -#[repr(C)] -#[derive(Copy, Clone)] -pub union ifru { - pub addr: sockaddr, - pub dstaddr: sockaddr, - pub broadaddr: sockaddr, - pub netmask: sockaddr, - pub hwaddr: sockaddr, - - pub flags: c_short, - pub ivalue: c_int, - pub mtu: c_int, - pub map: ifmap, - pub slave: [c_char; IFNAMSIZ], - pub newname: [c_char; IFNAMSIZ], - pub data: *mut c_void, - pub settings: if_settings, -} - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct ifreq { - pub ifrn: ifrn, - pub ifru: ifru, -} - -ioctl!(bad read siocgifflags with 0x8913; ifreq); -ioctl!(bad write siocsifflags with 0x8914; ifreq); -ioctl!(bad read siocgifaddr with 0x8915; ifreq); -ioctl!(bad write siocsifaddr with 0x8916; ifreq); -ioctl!(bad read siocgifdstaddr with 0x8917; ifreq); -ioctl!(bad write siocsifdstaddr with 0x8918; ifreq); -ioctl!(bad read siocgifbrdaddr with 0x8919; ifreq); -ioctl!(bad write siocsifbrdaddr with 0x891a; ifreq); -ioctl!(bad read siocgifnetmask with 0x891b; ifreq); -ioctl!(bad write siocsifnetmask with 0x891c; ifreq); -ioctl!(bad read siocgifmtu with 0x8921; ifreq); -ioctl!(bad write siocsifmtu with 0x8922; ifreq); -ioctl!(bad write siocsifname with 0x8923; ifreq); - -ioctl!(write tunsetiff with b'T', 202; c_int); -ioctl!(write tunsetpersist with b'T', 203; c_int); -ioctl!(write tunsetowner with b'T', 204; c_int); -ioctl!(write tunsetgroup with b'T', 206; c_int); diff --git a/vnt/rust-tun/src/platform/macos/device.rs b/vnt/rust-tun/src/platform/macos/device.rs deleted file mode 100644 index 54f0b9b..0000000 --- a/vnt/rust-tun/src/platform/macos/device.rs +++ /dev/null @@ -1,445 +0,0 @@ -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// Version 2, December 2004 -// -// Copyleft (ↄ) meh. | http://meh.schizofreni.co -// -// Everyone is permitted to copy and distribute verbatim or modified -// copies of this license document, and changing it is allowed as long -// as the name is changed. -// -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -// -// 0. You just DO WHAT THE FUCK YOU WANT TO. -#![allow(unused_variables)] - -use std::ffi::CStr; -use std::io; -use std::mem; -use std::net::Ipv4Addr; -use std::os::unix::io::AsRawFd; -use std::ptr; -use std::sync::Arc; - -use libc; -use libc::{c_char, c_uint, c_void, sockaddr, socklen_t, AF_INET, SOCK_DGRAM}; - -use crate::configuration::{Configuration, Layer}; -use crate::device::Device as D; -use crate::error::*; -use crate::platform::macos::sys::*; -use crate::platform::posix::{self, Fd, SockAddr}; - -/// A TUN device using the TUN macOS driver. -pub struct Device { - name: String, - queue: Queue, - ctl: Fd, -} - -impl Device { - /// Create a new `Device` for the given `Configuration`. - pub fn new(config: &Configuration) -> Result { - let id = if let Some(name) = config.name.as_ref() { - if name.len() > IFNAMSIZ { - return Err(Error::NameTooLong); - } - - if !name.starts_with("utun") { - return Err(Error::InvalidName); - } - - name[4..].parse()? - } else { - 0 - }; - - if config.layer.filter(|l| *l != Layer::L3).is_some() { - return Err(Error::UnsupportedLayer); - } - - let queues_number = config.queues.unwrap_or(1); - if queues_number != 1 { - return Err(Error::InvalidQueuesNumber); - } - - let mut device = unsafe { - let tun = Fd::new(libc::socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL)) - .map_err(|_| io::Error::last_os_error())?; - - let mut info = ctl_info { - ctl_id: 0, - ctl_name: { - let mut buffer = [0; 96]; - for (i, o) in UTUN_CONTROL_NAME.as_bytes().iter().zip(buffer.iter_mut()) { - *o = *i as _; - } - buffer - }, - }; - - if ctliocginfo(tun.0, &mut info as *mut _ as *mut _) < 0 { - return Err(io::Error::last_os_error().into()); - } - - let addr = sockaddr_ctl { - sc_id: info.ctl_id, - sc_len: mem::size_of::() as _, - sc_family: AF_SYSTEM, - ss_sysaddr: AF_SYS_CONTROL, - sc_unit: id as c_uint, - sc_reserved: [0; 5], - }; - - if libc::connect( - tun.0, - &addr as *const sockaddr_ctl as *const sockaddr, - mem::size_of_val(&addr) as socklen_t, - ) < 0 - { - return Err(io::Error::last_os_error().into()); - } - - let mut name = [0u8; 64]; - let mut name_len: socklen_t = 64; - - if libc::getsockopt( - tun.0, - SYSPROTO_CONTROL, - UTUN_OPT_IFNAME, - &mut name as *mut _ as *mut c_void, - &mut name_len as *mut socklen_t, - ) < 0 - { - return Err(io::Error::last_os_error().into()); - } - - let ctl = Fd::new(libc::socket(AF_INET, SOCK_DGRAM, 0)) - .map_err(|_| io::Error::last_os_error())?; - - Device { - name: CStr::from_ptr(name.as_ptr() as *const c_char) - .to_string_lossy() - .into(), - queue: Queue { tun: Arc::new(tun) }, - ctl: ctl, - } - }; - - device.configure(&config)?; - - Ok(device) - } - - /// Prepare a new request. - pub unsafe fn request(&self) -> ifreq { - let mut req: ifreq = mem::zeroed(); - ptr::copy_nonoverlapping( - self.name.as_ptr() as *const c_char, - req.ifrn.name.as_mut_ptr(), - self.name.len(), - ); - - req - } - - /// Set the IPv4 alias of the device. - pub fn set_alias(&mut self, addr: Ipv4Addr, broadaddr: Ipv4Addr, mask: Ipv4Addr) -> Result<()> { - unsafe { - let mut req: ifaliasreq = mem::zeroed(); - ptr::copy_nonoverlapping( - self.name.as_ptr() as *const c_char, - req.ifran.as_mut_ptr(), - self.name.len(), - ); - - req.addr = SockAddr::from(addr).into(); - req.broadaddr = SockAddr::from(broadaddr).into(); - req.mask = SockAddr::from(mask).into(); - - if siocaifaddr(self.ctl.as_raw_fd(), &req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - Ok(()) - } - } - - // /// Split the interface into a `Reader` and `Writer`. - // pub fn split(self) -> (posix::Reader, posix::Writer) { - // let fd = Arc::new(self.queue.tun); - // (posix::Reader(fd.clone()), posix::Writer(fd.clone())) - // } - - /// Return whether the device has packet information - pub fn has_packet_information(&self) -> bool { - self.queue.has_packet_information() - } - - /// Set non-blocking mode - pub fn set_nonblock(&self) -> io::Result<()> { - self.queue.set_nonblock() - } -} - -// impl Read for Device { -// fn read(&mut self, buf: &mut [u8]) -> io::Result { -// self.queue.tun.read(buf) -// } -// -// fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result { -// self.queue.tun.read_vectored(bufs) -// } -// } -// -// impl Write for Device { -// fn write(&mut self, buf: &[u8]) -> io::Result { -// self.queue.tun.write(buf) -// } -// -// fn flush(&mut self) -> io::Result<()> { -// self.queue.tun.flush() -// } -// -// fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { -// self.queue.tun.write_vectored(bufs) -// } -// } - -impl D for Device { - type Queue = Queue; - - fn name(&self) -> &str { - &self.name - } - - // XXX: Cannot set interface name on Darwin. - fn set_name(&mut self, value: &str) -> Result<()> { - Err(Error::InvalidName) - } - - fn enabled(&mut self, value: bool) -> Result<()> { - unsafe { - let mut req = self.request(); - - if siocgifflags(self.ctl.as_raw_fd(), &mut req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - if value { - req.ifru.flags |= IFF_UP | IFF_RUNNING; - } else { - req.ifru.flags &= !IFF_UP; - } - - if siocsifflags(self.ctl.as_raw_fd(), &req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - Ok(()) - } - } - - fn address(&self) -> Result { - unsafe { - let mut req = self.request(); - - if siocgifaddr(self.ctl.as_raw_fd(), &mut req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - SockAddr::new(&req.ifru.addr).map(Into::into) - } - } - - fn set_address(&mut self, value: Ipv4Addr) -> Result<()> { - unsafe { - let mut req = self.request(); - req.ifru.addr = SockAddr::from(value).into(); - - if siocsifaddr(self.ctl.as_raw_fd(), &req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - Ok(()) - } - } - - fn destination(&self) -> Result { - unsafe { - let mut req = self.request(); - - if siocgifdstaddr(self.ctl.as_raw_fd(), &mut req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - SockAddr::new(&req.ifru.dstaddr).map(Into::into) - } - } - - fn set_destination(&mut self, value: Ipv4Addr) -> Result<()> { - unsafe { - let mut req = self.request(); - req.ifru.dstaddr = SockAddr::from(value).into(); - - if siocsifdstaddr(self.ctl.as_raw_fd(), &req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - Ok(()) - } - } - - fn broadcast(&self) -> Result { - unsafe { - let mut req = self.request(); - - if siocgifbrdaddr(self.ctl.as_raw_fd(), &mut req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - SockAddr::new(&req.ifru.broadaddr).map(Into::into) - } - } - - fn set_broadcast(&mut self, value: Ipv4Addr) -> Result<()> { - unsafe { - let mut req = self.request(); - req.ifru.broadaddr = SockAddr::from(value).into(); - - if siocsifbrdaddr(self.ctl.as_raw_fd(), &req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - Ok(()) - } - } - - fn netmask(&self) -> Result { - unsafe { - let mut req = self.request(); - - if siocgifnetmask(self.ctl.as_raw_fd(), &mut req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - SockAddr::unchecked(&req.ifru.addr).map(Into::into) - } - } - - fn set_netmask(&mut self, value: Ipv4Addr) -> Result<()> { - unsafe { - let mut req = self.request(); - req.ifru.addr = SockAddr::from(value).into(); - - if siocsifnetmask(self.ctl.as_raw_fd(), &req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - Ok(()) - } - } - - fn mtu(&self) -> Result { - unsafe { - let mut req = self.request(); - - if siocgifmtu(self.ctl.as_raw_fd(), &mut req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - Ok(req.ifru.mtu) - } - } - - fn set_mtu(&mut self, value: i32) -> Result<()> { - unsafe { - let mut req = self.request(); - req.ifru.mtu = value; - - if siocsifmtu(self.ctl.as_raw_fd(), &req) < 0 { - return Err(io::Error::last_os_error().into()); - } - - Ok(()) - } - } - - fn queue(&self, index: usize) -> Option<&Self::Queue> { - if index > 0 { - return None; - } - - Some(&self.queue) - } -} - -// impl AsRawFd for Device { -// fn as_raw_fd(&self) -> RawFd { -// self.queue.as_raw_fd() -// } -// } -// -// impl IntoRawFd for Device { -// fn into_raw_fd(self) -> RawFd { -// self.queue.into_raw_fd() -// } -// } - -pub struct Queue { - tun: Arc, -} - -impl Queue { - pub fn has_packet_information(&self) -> bool { - // on macos this is always the case - true - } - - pub fn set_nonblock(&self) -> io::Result<()> { - self.tun.set_nonblock() - } - - pub fn reader(&self) -> posix::Reader { - posix::Reader(self.tun.clone()) - } - pub fn writer(&self) -> posix::Writer { - posix::Writer(self.tun.clone()) - } -} - -// impl AsRawFd for Queue { -// fn as_raw_fd(&self) -> RawFd { -// self.tun.as_raw_fd() -// } -// } -// -// impl IntoRawFd for Queue { -// fn into_raw_fd(self) -> RawFd { -// self.tun.into_raw_fd() -// } -// } - -// impl Read for Queue { -// fn read(&mut self, buf: &mut [u8]) -> io::Result { -// self.tun.read(buf) -// } -// -// fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result { -// self.tun.read_vectored(bufs) -// } -// } -// -// impl Write for Queue { -// fn write(&mut self, buf: &[u8]) -> io::Result { -// self.tun.write(buf) -// } -// -// fn flush(&mut self) -> io::Result<()> { -// self.tun.flush() -// } -// -// fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { -// self.tun.write_vectored(bufs) -// } -// } diff --git a/vnt/rust-tun/src/platform/macos/mod.rs b/vnt/rust-tun/src/platform/macos/mod.rs deleted file mode 100644 index 36c82bb..0000000 --- a/vnt/rust-tun/src/platform/macos/mod.rs +++ /dev/null @@ -1,32 +0,0 @@ -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// Version 2, December 2004 -// -// Copyleft (ↄ) meh. | http://meh.schizofreni.co -// -// Everyone is permitted to copy and distribute verbatim or modified -// copies of this license document, and changing it is allowed as long -// as the name is changed. -// -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -// -// 0. You just DO WHAT THE FUCK YOU WANT TO. - -//! macOS specific functionality. - -pub mod sys; - -mod device; -pub use self::device::{Device, Queue}; - -use crate::configuration::Configuration as C; -use crate::error::*; - -/// macOS-only interface configuration. -#[derive(Copy, Clone, Default, Debug)] -pub struct Configuration {} - -/// Create a TUN device with the given name. -pub fn create(configuration: &C) -> Result { - Device::new(&configuration) -} diff --git a/vnt/rust-tun/src/platform/mod.rs b/vnt/rust-tun/src/platform/mod.rs deleted file mode 100644 index 14d477b..0000000 --- a/vnt/rust-tun/src/platform/mod.rs +++ /dev/null @@ -1,60 +0,0 @@ -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// Version 2, December 2004 -// -// Copyleft (ↄ) meh. | http://meh.schizofreni.co -// -// Everyone is permitted to copy and distribute verbatim or modified -// copies of this license document, and changing it is allowed as long -// as the name is changed. -// -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -// -// 0. You just DO WHAT THE FUCK YOU WANT TO. - -//! Platform specific modules. - -#[cfg(unix)] -pub mod posix; - -#[cfg(target_os = "linux")] -pub mod linux; -#[cfg(target_os = "linux")] -pub use self::linux::{create, Configuration, Device, Queue}; - -#[cfg(target_os = "macos")] -pub mod macos; -#[cfg(target_os = "macos")] -pub use self::macos::{create, Configuration, Device, Queue}; - -#[cfg(test)] -mod test { - use crate::configuration::Configuration; - use crate::device::Device; - use std::net::Ipv4Addr; - - #[test] - fn create() { - let dev = super::create( - Configuration::default() - .name("utun6") - .address("192.168.50.1") - .netmask("255.255.0.0") - .mtu(1400) - .up(), - ) - .unwrap(); - - assert_eq!( - "192.168.50.1".parse::().unwrap(), - dev.address().unwrap() - ); - - assert_eq!( - "255.255.0.0".parse::().unwrap(), - dev.netmask().unwrap() - ); - - assert_eq!(1400, dev.mtu().unwrap()); - } -} diff --git a/vnt/rust-tun/src/platform/posix/fd.rs b/vnt/rust-tun/src/platform/posix/fd.rs deleted file mode 100644 index 89ea161..0000000 --- a/vnt/rust-tun/src/platform/posix/fd.rs +++ /dev/null @@ -1,124 +0,0 @@ -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// Version 2, December 2004 -// -// Copyleft (ↄ) meh. | http://meh.schizofreni.co -// -// Everyone is permitted to copy and distribute verbatim or modified -// copies of this license document, and changing it is allowed as long -// as the name is changed. -// -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -// -// 0. You just DO WHAT THE FUCK YOU WANT TO. - -use std::io::{self, Read, Write}; -use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd}; - -use crate::error::*; -use libc::{self, fcntl, F_GETFL, F_SETFL, O_NONBLOCK}; - -/// POSIX file descriptor support for `io` traits. -pub struct Fd(pub RawFd); - -impl Fd { - pub fn new(value: RawFd) -> Result { - if value < 0 { - return Err(Error::InvalidDescriptor); - } - - Ok(Fd(value)) - } - - /// Enable non-blocking mode - pub fn set_nonblock(&self) -> io::Result<()> { - match unsafe { fcntl(self.0, F_SETFL, fcntl(self.0, F_GETFL) | O_NONBLOCK) } { - 0 => Ok(()), - _ => Err(io::Error::last_os_error()), - } - } -} - -impl Read for Fd { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - unsafe { - let amount = libc::read(self.0, buf.as_mut_ptr() as *mut _, buf.len()); - - if amount < 0 { - return Err(io::Error::last_os_error()); - } - - Ok(amount as usize) - } - } - - fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result { - unsafe { - let iov = bufs.as_ptr().cast(); - let iovcnt = bufs.len().min(libc::c_int::MAX as usize) as _; - - let n = libc::readv(self.0, iov, iovcnt); - if n < 0 { - return Err(io::Error::last_os_error()); - } - - Ok(n as usize) - } - } -} - -impl Write for Fd { - fn write(&mut self, buf: &[u8]) -> io::Result { - unsafe { - let amount = libc::write(self.0, buf.as_ptr() as *const _, buf.len()); - - if amount < 0 { - return Err(io::Error::last_os_error()); - } - - Ok(amount as usize) - } - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } - - fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { - unsafe { - let iov = bufs.as_ptr().cast(); - let iovcnt = bufs.len().min(libc::c_int::MAX as usize) as _; - - let n = libc::writev(self.0, iov, iovcnt); - if n < 0 { - return Err(io::Error::last_os_error()); - } - - Ok(n as usize) - } - } -} - -impl AsRawFd for Fd { - fn as_raw_fd(&self) -> RawFd { - self.0 - } -} - -impl IntoRawFd for Fd { - fn into_raw_fd(mut self) -> RawFd { - let fd = self.0; - self.0 = -1; - fd - } -} - -impl Drop for Fd { - fn drop(&mut self) { - unsafe { - if self.0 >= 0 { - libc::close(self.0); - } - } - } -} diff --git a/vnt/rust-tun/src/platform/posix/mod.rs b/vnt/rust-tun/src/platform/posix/mod.rs deleted file mode 100644 index 6b972b5..0000000 --- a/vnt/rust-tun/src/platform/posix/mod.rs +++ /dev/null @@ -1,24 +0,0 @@ -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// Version 2, December 2004 -// -// Copyleft (ↄ) meh. | http://meh.schizofreni.co -// -// Everyone is permitted to copy and distribute verbatim or modified -// copies of this license document, and changing it is allowed as long -// as the name is changed. -// -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -// -// 0. You just DO WHAT THE FUCK YOU WANT TO. - -//! POSIX compliant support. - -mod sockaddr; -pub use self::sockaddr::SockAddr; - -mod fd; -pub use self::fd::Fd; - -mod split; -pub use self::split::{Reader, Writer}; diff --git a/vnt/rust-tun/src/platform/posix/split.rs b/vnt/rust-tun/src/platform/posix/split.rs deleted file mode 100644 index ec1a6b4..0000000 --- a/vnt/rust-tun/src/platform/posix/split.rs +++ /dev/null @@ -1,124 +0,0 @@ -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// Version 2, December 2004 -// -// Copyleft (ↄ) meh. | http://meh.schizofreni.co -// -// Everyone is permitted to copy and distribute verbatim or modified -// copies of this license document, and changing it is allowed as long -// as the name is changed. -// -// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -// -// 0. You just DO WHAT THE FUCK YOU WANT TO. - -use std::io; -use std::mem; -use std::os::unix::io::{AsRawFd, RawFd}; -use std::sync::Arc; - -use crate::platform::posix::Fd; -use libc; - -/// Read-only end for a file descriptor. -#[derive(Clone)] -pub struct Reader(pub(crate) Arc); - -/// Write-only end for a file descriptor. -#[derive(Clone)] -pub struct Writer(pub(crate) Arc); - -impl Reader { - pub fn read(&self, buf: &mut [u8]) -> io::Result { - unsafe { - let amount = libc::read(self.0.as_raw_fd(), buf.as_mut_ptr() as *mut _, buf.len()); - - if amount < 0 { - return Err(io::Error::last_os_error()); - } - - Ok(amount as usize) - } - } - - pub fn read_vectored(&self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result { - unsafe { - let mut msg: libc::msghdr = mem::zeroed(); - // msg.msg_name: NULL - // msg.msg_namelen: 0 - msg.msg_iov = bufs.as_mut_ptr().cast(); - msg.msg_iovlen = bufs.len().min(libc::c_int::MAX as usize) as _; - - let n = libc::recvmsg(self.0.as_raw_fd(), &mut msg, 0); - if n < 0 { - return Err(io::Error::last_os_error()); - } - - Ok(n as usize) - } - } -} - -impl Writer { - pub fn write(&self, buf: &[u8]) -> io::Result { - unsafe { - let amount = libc::write(self.0.as_raw_fd(), buf.as_ptr() as *const _, buf.len()); - - if amount < 0 { - return Err(io::Error::last_os_error()); - } - - Ok(amount as usize) - } - } - - pub fn write_vectored(&self, bufs: &[io::IoSlice<'_>]) -> io::Result { - unsafe { - let mut msg: libc::msghdr = mem::zeroed(); - // msg.msg_name = NULL - // msg.msg_namelen = 0 - msg.msg_iov = bufs.as_ptr() as *mut _; - msg.msg_iovlen = bufs.len().min(libc::c_int::MAX as usize) as _; - - let n = libc::sendmsg(self.0.as_raw_fd(), &msg, 0); - if n < 0 { - return Err(io::Error::last_os_error()); - } - - Ok(n as usize) - } - } - pub fn write_all(&self, mut buf: &[u8]) -> io::Result<()> { - while !buf.is_empty() { - match self.write(buf) { - Ok(0) => { - return Err(io::Error::new( - io::ErrorKind::WriteZero, - "failed to write whole buffer", - )); - } - Ok(n) => buf = &buf[n..], - Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} - Err(e) => return Err(e), - } - } - Ok(()) - } -} - -impl AsRawFd for Reader { - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() - } -} -impl AsRawFd for Writer { - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() - } -} -// -// impl AsRawFd for Writer { -// fn as_raw_fd(&self) -> RawFd { -// self.0.as_raw_fd() -// } -// } diff --git a/vnt/src/error/mod.rs b/vnt/src/error/mod.rs deleted file mode 100644 index f7032aa..0000000 --- a/vnt/src/error/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -use std::io; - -use thiserror::Error; - -#[derive(Error, Debug)] -pub enum Error { - #[error("Io error")] - Io(#[from] io::Error), - #[error("Protobuf error")] - Protobuf(#[from] protobuf::Error), - #[error("Invalid packet")] - InvalidPacket, - #[error("Not support")] - NotSupport, - #[error("Stop")] - Stop(String), - #[error("Warn")] - Warn(String), -} - -pub type Result = std::result::Result; diff --git a/vnt/src/lib.rs b/vnt/src/lib.rs index 55c426b..65d4a95 100644 --- a/vnt/src/lib.rs +++ b/vnt/src/lib.rs @@ -1,14 +1,10 @@ -use crate::error::Error; pub const VNT_VERSION: &'static str = env!("CARGO_PKG_VERSION"); -pub type Result = std::result::Result; pub mod channel; pub mod cipher; pub mod core; -pub mod error; pub mod external_route; pub mod handle; -pub mod igmp_server; #[cfg(feature = "ip_proxy")] pub mod ip_proxy; pub mod nat; @@ -16,3 +12,5 @@ pub mod proto; pub mod protocol; pub mod tun_tap_device; pub mod util; + +pub use handle::callback::{DeviceInfo, ErrorInfo, HandshakeInfo, RegisterInfo, VntCallback}; diff --git a/vnt/src/tun_tap_device/android.rs b/vnt/src/tun_tap_device/android.rs deleted file mode 100644 index 0f95d2f..0000000 --- a/vnt/src/tun_tap_device/android.rs +++ /dev/null @@ -1,48 +0,0 @@ -use std::io; -use std::os::unix::io::RawFd; - -#[derive(Clone)] -pub struct DeviceWriter(RawFd); - -pub struct DeviceReader(RawFd); - -impl DeviceWriter { - pub fn write_ipv4_tun(&self, buf: &[u8]) -> io::Result<()> { - unsafe { - let amount = libc::write(self.0, buf.as_ptr() as *const _, buf.len()); - if amount < 0 { - return Err(io::Error::last_os_error()); - } - Ok(()) - } - } - ///写入ipv4数据,为了兼容其他代码,头部空了14个字节 - pub fn write_ipv4(&self, buf: &[u8]) -> io::Result<()> { - let buf = &buf[14..]; - self.write_ipv4_tun(buf) - } - pub fn close(&self) -> io::Result<()> { - // unsafe { - // libc::close(self.0); - // } - Ok(()) - } -} - -impl DeviceReader { - pub fn read(&self, buf: &mut [u8]) -> io::Result { - unsafe { - let amount = libc::read(self.0, buf.as_mut_ptr() as *mut _, buf.len()); - - if amount < 0 { - return Err(io::Error::last_os_error()); - } - - Ok(amount as usize) - } - } -} - -pub fn create(fd: i32) -> (DeviceWriter, DeviceReader) { - (DeviceWriter(fd as _), DeviceReader(fd as _)) -} diff --git a/vnt/src/tun_tap_device/linux.rs b/vnt/src/tun_tap_device/linux.rs deleted file mode 100644 index 0d4e951..0000000 --- a/vnt/src/tun_tap_device/linux.rs +++ /dev/null @@ -1,175 +0,0 @@ -use crate::tun_tap_device::linux_mac::DeviceW; -use crate::tun_tap_device::{DeviceReader, DeviceType, DeviceWriter, DriverInfo}; -use parking_lot::Mutex; -use std::io; -use std::net::Ipv4Addr; -use std::process::Command; -use std::sync::Arc; -use tun::Device; - -pub const TUN_INTERFACE_NAME: &str = "vnt-tun"; -pub const TAP_INTERFACE_NAME: &str = "vnt-tap"; - -impl DeviceWriter { - pub fn change_ip( - &self, - address: Ipv4Addr, - netmask: Ipv4Addr, - gateway: Ipv4Addr, - _old_netmask: Ipv4Addr, - _old_gateway: Ipv4Addr, - ) -> io::Result<()> { - let mut config = tun::Configuration::default(); - let broadcast_address = - (!u32::from_be_bytes(netmask.octets())) | u32::from_be_bytes(gateway.octets()); - let broadcast_address = Ipv4Addr::from(broadcast_address); - config - .destination(gateway) - .address(address) - .netmask(netmask) - .broadcast(broadcast_address) - // .queues(2) - .up(); - let mut dev = self.lock.lock(); - if let Err(e) = dev.configure(&config) { - return Err(io::Error::new(io::ErrorKind::Other, format!("{:?}", e))); - } - let name = dev.name(); - for (address, netmask) in &self.in_ips { - add_route(name, *address, *netmask)?; - } - // 当前网段路由 - // add_route(name, address, netmask)?; - // 广播和组播路由 - add_route(name, Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST)?; - add_route( - name, - Ipv4Addr::from([224, 0, 0, 0]), - Ipv4Addr::from([240, 0, 0, 0]), - )?; - return Ok(()); - } -} - -pub fn add_route(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> io::Result<()> { - let route_add_str: String = format!("ip route add {:?}/{:?} dev {}", address, netmask, name); - let route_add_out = Command::new("sh") - .arg("-c") - .arg(&route_add_str) - .output() - .expect("sh exec error!"); - if !route_add_out.status.success() { - return Err(io::Error::new( - io::ErrorKind::Other, - format!( - "添加路由失败: cmd:{},out:{:?}", - route_add_str, route_add_out - ), - )); - } - Ok(()) -} - -pub fn create_device( - device_type: DeviceType, - address: Ipv4Addr, - netmask: Ipv4Addr, - gateway: Ipv4Addr, - in_ips: Vec<(Ipv4Addr, Ipv4Addr)>, - mtu: u16, -) -> io::Result<(DeviceWriter, DeviceReader, DriverInfo)> { - let mut config = tun::Configuration::default(); - let broadcast_address = - (!u32::from_be_bytes(netmask.octets())) | u32::from_be_bytes(gateway.octets()); - let broadcast_address = Ipv4Addr::from(broadcast_address); - config - .destination(gateway) - .address(address) - .netmask(netmask) - .mtu(mtu.into()) - .broadcast(broadcast_address) - // .queues(2) 用多个队列有兼容性问题 - .up(); - match device_type { - DeviceType::Tun => { - config.name(TUN_INTERFACE_NAME); - } - DeviceType::Tap => { - config.name(TAP_INTERFACE_NAME); - config.layer(tun::Layer::L2); - } - } - let dev = tun::create(&config).expect("tun/tap failed to create"); - let packet_information = dev.has_packet_information(); - let queue = dev.queue(0).unwrap(); - let reader = queue.reader(); - let writer = queue.writer(); - let name = dev.name(); - for (address, netmask) in &in_ips { - add_route(name, *address, *netmask)?; - } - // 当前网段路由 - // add_route(name, address, netmask)?; - // 广播和组播路由 - add_route(name, Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST)?; - add_route( - name, - Ipv4Addr::from([224, 0, 0, 0]), - Ipv4Addr::from([240, 0, 0, 0]), - )?; - let device_w = match device_type { - DeviceType::Tun => DeviceW::Tun(writer), - DeviceType::Tap => { - let get_mac_cmd = format!("cat /sys/class/net/{}/address", name); - let mac_out = Command::new("sh") - .arg("-c") - .arg(get_mac_cmd) - .output() - .expect("sh exec error!"); - if !mac_out.status.success() { - return Err(io::Error::new( - io::ErrorKind::Other, - format!("获取mac地址错误: {:?}", mac_out), - )); - } - let mac_str = String::from_utf8(mac_out.stdout).unwrap(); - let mut mac = [0; 6]; - let mut split = mac_str.split(":"); - for i in 0..6 { - mac[i] = u8::from_str_radix(&split.next().unwrap()[..2], 16).unwrap(); - } - DeviceW::Tap((writer, mac)) - } - }; - let driver_info = DriverInfo { - device_type, - name: name.to_string(), - version: String::new(), - mac: None, - }; - Ok(( - DeviceWriter::new( - device_w, - Arc::new(Mutex::new(dev)), - in_ips, - address, - packet_information, - ), - DeviceReader::new(reader), - driver_info, - )) -} - -pub fn delete_device(_device_type: DeviceType) { - for name in [TUN_INTERFACE_NAME, TAP_INTERFACE_NAME] { - let cmd = format!("ip link delete {}", name); - let delete_tun = Command::new("sh") - .arg("-c") - .arg(&cmd) - .output() - .expect("sh exec error!"); - if !delete_tun.status.success() { - log::warn!("删除网卡失败:{:?}", delete_tun); - } - } -} diff --git a/vnt/src/tun_tap_device/linux_mac.rs b/vnt/src/tun_tap_device/linux_mac.rs deleted file mode 100644 index 6159334..0000000 --- a/vnt/src/tun_tap_device/linux_mac.rs +++ /dev/null @@ -1,144 +0,0 @@ -use std::io; -use std::sync::Arc; - -use bytes::BufMut; -use packet::ethernet; -use parking_lot::Mutex; -use std::net::Ipv4Addr; -#[cfg(any(target_os = "linux"))] -use tun::platform::linux::Device; -#[cfg(any(target_os = "macos"))] -use tun::platform::macos::Device; -use tun::platform::posix::{Reader, Writer}; - -use packet::ethernet::packet::EthernetPacket; - -#[derive(Clone)] -pub enum DeviceW { - Tun(Writer), - Tap((Writer, [u8; 6])), -} - -impl DeviceW { - pub fn is_tun(&self) -> bool { - match self { - DeviceW::Tun(_) => true, - DeviceW::Tap(_) => false, - } - } -} - -#[derive(Clone)] -pub struct DeviceWriter { - writer: DeviceW, - pub lock: Arc>, - pub in_ips: Vec<(Ipv4Addr, Ipv4Addr)>, - packet_information: bool, -} - -impl DeviceWriter { - pub fn new( - writer: DeviceW, - lock: Arc>, - in_ips: Vec<(Ipv4Addr, Ipv4Addr)>, - _ip: Ipv4Addr, - packet_information: bool, - ) -> Self { - Self { - writer, - lock, - in_ips, - packet_information, - } - } -} - -impl DeviceWriter { - pub fn write(packet_information: bool, writer: &Writer, packet: &[u8]) -> io::Result<()> { - if packet_information { - let mut buf = Vec::::with_capacity(4 + packet.len()); - buf.put_u16(0); - #[cfg(any(target_os = "macos", target_os = "ios"))] - buf.put_u16(libc::PF_INET as u16); - #[cfg(any(target_os = "linux", target_os = "android"))] - buf.put_u16(libc::ETH_P_IP as u16); - buf.extend_from_slice(packet); - let len = writer.write(&buf)?; - if len != buf.len() { - log::error!("tun write error"); - } - } else { - let len = writer.write(packet)?; - if len != packet.len() { - log::error!("tun write error"); - } - } - Ok(()) - } - ///tun网卡写入ipv4数据 - pub fn write_ipv4_tun(&self, buf: &[u8]) -> io::Result<()> { - match &self.writer { - DeviceW::Tun(writer) => Self::write(self.packet_information, writer, buf), - DeviceW::Tap(_) => Err(io::Error::from(io::ErrorKind::Unsupported)), - } - } - /// tap网卡写入以太网帧 - pub fn write_ethernet_tap(&self, buf: &[u8]) -> io::Result<()> { - match &self.writer { - DeviceW::Tun(_) => Err(io::Error::from(io::ErrorKind::Unsupported)), - DeviceW::Tap((writer, _)) => Self::write(self.packet_information, writer, buf), - } - } - ///写入ipv4数据,头部必须留14字节,给tap写入以太网帧头 - pub fn write_ipv4(&self, buf: &mut [u8]) -> io::Result<()> { - match &self.writer { - DeviceW::Tun(writer) => Self::write(self.packet_information, writer, &buf[14..]), - DeviceW::Tap((writer, mac)) => { - let source_mac = [ - buf[14 + 12], - buf[14 + 13], - buf[14 + 14], - buf[14 + 15], - !mac[5], - 234, - ]; - let mut ethernet_packet = EthernetPacket::unchecked(buf); - ethernet_packet.set_source(&source_mac); - ethernet_packet.set_destination(mac); - ethernet_packet.set_protocol(ethernet::protocol::Protocol::Ipv4); - Self::write(self.packet_information, writer, ðernet_packet.buffer) - } - } - } - pub fn close(&self) -> io::Result<()> { - //早期使用close直接切断网卡,现在并不需要这么做也能正常关闭 - // unsafe { - // match &self.writer { - // DeviceW::Tun(writer) => { - // libc::close(writer.as_raw_fd()); - // } - // DeviceW::Tap((writer, _)) => { - // libc::close(writer.as_raw_fd()); - // } - // } - // } - Ok(()) - } - pub fn is_tun(&self) -> bool { - self.writer.is_tun() - } -} - -pub struct DeviceReader(Reader); - -impl DeviceReader { - pub fn new(device: Reader) -> Self { - DeviceReader(device) - } -} - -impl DeviceReader { - pub fn read(&self, buf: &mut [u8]) -> io::Result { - self.0.read(buf) - } -} diff --git a/vnt/src/tun_tap_device/mac.rs b/vnt/src/tun_tap_device/mac.rs deleted file mode 100644 index 37e1e3c..0000000 --- a/vnt/src/tun_tap_device/mac.rs +++ /dev/null @@ -1,153 +0,0 @@ -use crate::tun_tap_device::linux_mac::DeviceW; -use crate::tun_tap_device::{DeviceReader, DeviceType, DeviceWriter, DriverInfo}; -use parking_lot::Mutex; -use std::io; -use std::net::Ipv4Addr; -use std::process::Command; -use std::sync::Arc; -use tun::Device; - -impl DeviceWriter { - pub fn change_ip( - &self, - address: Ipv4Addr, - netmask: Ipv4Addr, - gateway: Ipv4Addr, - _old_netmask: Ipv4Addr, - _old_gateway: Ipv4Addr, - ) -> io::Result<()> { - let mut config = tun::Configuration::default(); - config - .destination(gateway) - .address(address) - .netmask(netmask) - .up(); - let mut dev = self.lock.lock(); - if let Err(e) = dev.configure(&config) { - return Err(io::Error::new(io::ErrorKind::Other, format!("{:?}", e))); - } - if let Err(e) = config_ip(dev.name(), address, netmask, gateway) { - log::error!("{}", e); - } - let name = dev.name(); - for (address, netmask) in &self.in_ips { - add_route(name, *address, *netmask)?; - } - // 当前网段路由 - add_route(name, address, netmask)?; - // 广播和组播路由 - add_route(name, Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST)?; - add_route( - name, - Ipv4Addr::from([224, 0, 0, 0]), - Ipv4Addr::from([240, 0, 0, 0]), - )?; - return Ok(()); - } -} - -pub fn create_device( - device_type: DeviceType, - address: Ipv4Addr, - netmask: Ipv4Addr, - gateway: Ipv4Addr, - in_ips: Vec<(Ipv4Addr, Ipv4Addr)>, - mtu: u16, -) -> io::Result<(DeviceWriter, DeviceReader, DriverInfo)> { - match device_type { - DeviceType::Tun => {} - DeviceType::Tap => { - unimplemented!() - } - } - let mut config = tun::Configuration::default(); - - config - .destination(gateway) - .address(address) - .netmask(netmask) - .mtu(mtu.into()) - .up(); - - let dev = tun::create(&config).unwrap(); - let name = dev.name(); - config_ip(name, address, netmask, gateway)?; - for (address, netmask) in &in_ips { - add_route(name, *address, *netmask)?; - } - // 当前网段路由 - add_route(name, address, netmask)?; - // 广播和组播路由 - add_route(name, Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST)?; - add_route( - name, - Ipv4Addr::from([224, 0, 0, 0]), - Ipv4Addr::from([240, 0, 0, 0]), - )?; - let packet_information = dev.has_packet_information(); - let queue = dev.queue(0).unwrap(); - let reader = queue.reader(); - let writer = queue.writer(); - let driver_info = DriverInfo { - device_type, - name: name.to_string(), - version: String::new(), - mac: None, - }; - Ok(( - DeviceWriter::new( - DeviceW::Tun(writer), - Arc::new(Mutex::new(dev)), - in_ips, - address, - packet_information, - ), - DeviceReader::new(reader), - driver_info, - )) -} - -fn add_route(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> io::Result<()> { - let route_add_str: String = format!( - "route -n add {} -netmask {} -interface {}", - address, netmask, name - ); - let route_add_out = Command::new("sh") - .arg("-c") - .arg(&route_add_str) - .output() - .expect("sh exec error!"); - if !route_add_out.status.success() { - return Err(io::Error::new( - io::ErrorKind::Other, - format!( - "添加路由失败: cmd:{},out:{:?}", - route_add_str, route_add_out - ), - )); - } - Ok(()) -} - -fn config_ip( - name: &str, - address: Ipv4Addr, - _netmask: Ipv4Addr, - gateway: Ipv4Addr, -) -> io::Result<()> { - let up_eth_str: String = format!("ifconfig {} {:?} {:?} up ", name, address, gateway); - let up_eth_out = Command::new("sh") - .arg("-c") - .arg(&up_eth_str) - .output() - .expect("sh exec error!"); - if !up_eth_out.status.success() { - return Err(io::Error::new( - io::ErrorKind::Other, - format!("设置网络地址失败: cmd:{},out:{:?}", up_eth_str, up_eth_out), - )); - } - Ok(()) -} - -pub fn delete_device(_device_type: DeviceType) {} diff --git a/vnt/src/tun_tap_device/windows.rs b/vnt/src/tun_tap_device/windows.rs deleted file mode 100644 index b7bb47d..0000000 --- a/vnt/src/tun_tap_device/windows.rs +++ /dev/null @@ -1,363 +0,0 @@ -use crate::tun_tap_device::{DeviceType, DriverInfo}; -use libloading::Library; -use packet::ethernet; -use packet::ethernet::packet::EthernetPacket; -use parking_lot::Mutex; -use std::net::Ipv4Addr; -use std::os::windows::process::CommandExt; -use std::sync::Arc; -use std::time::Duration; -use std::{io, thread}; -use win_tun_tap::{IFace, TapDevice, TunDevice}; - -pub const TUN_INTERFACE_NAME: &str = "Vnt-Tun-V1"; -pub const TUN_POOL_NAME: &str = "Vnt-Tun-V1"; -pub const TAP_INTERFACE_NAME: &str = "Vnt-Tap-V1"; - -pub enum Device { - Tun(TunDevice), - Tap((TapDevice, [u8; 6])), -} - -impl Device { - pub fn is_tun(&self) -> bool { - match self { - Device::Tun(_) => true, - Device::Tap(_) => false, - } - } -} - -#[derive(Clone)] -pub struct DeviceWriter { - device: Arc, - lock: Arc>, - in_ips: Vec<(Ipv4Addr, Ipv4Addr)>, -} - -impl DeviceWriter { - pub fn new(device: Arc, in_ips: Vec<(Ipv4Addr, Ipv4Addr)>, _ip: Ipv4Addr) -> Self { - Self { - device, - lock: Arc::new(Default::default()), - in_ips, - } - } -} - -impl DeviceWriter { - ///tun网卡写入ipv4数据 - pub fn write_ipv4_tun(&self, buf: &[u8]) -> io::Result<()> { - match self.device.as_ref() { - Device::Tun(dev) => { - let mut packet = dev.allocate_send_packet(buf.len() as u16)?; - packet.bytes_mut().copy_from_slice(buf); - dev.send_packet(packet); - Ok(()) - } - Device::Tap(_) => Err(io::Error::from(io::ErrorKind::Unsupported)), - } - } - /// tap网卡写入以太网帧 - pub fn write_ethernet_tap(&self, buf: &[u8]) -> io::Result<()> { - match self.device.as_ref() { - Device::Tun(_) => Err(io::Error::from(io::ErrorKind::Unsupported)), - Device::Tap((dev, _)) => { - dev.write(buf)?; - Ok(()) - } - } - } - ///写入ipv4数据,头部必须留14字节,给tap写入以太网帧头 - pub fn write_ipv4(&self, buf: &mut [u8]) -> io::Result<()> { - match self.device.as_ref() { - Device::Tun(dev) => { - let mut packet = dev.allocate_send_packet((buf.len() - 14) as u16)?; - packet.bytes_mut().copy_from_slice(&buf[14..]); - dev.send_packet(packet); - } - Device::Tap((dev, mac)) => { - let source_mac = [ - buf[14 + 12], - buf[14 + 13], - buf[14 + 14], - buf[14 + 15], - !mac[5], - 234, - ]; - let mut ethernet_packet = EthernetPacket::unchecked(buf); - ethernet_packet.set_source(&source_mac); - ethernet_packet.set_destination(mac); - ethernet_packet.set_protocol(ethernet::protocol::Protocol::Ipv4); - dev.write(ðernet_packet.buffer)?; - } - } - Ok(()) - } - pub fn change_ip( - &self, - address: Ipv4Addr, - netmask: Ipv4Addr, - gateway: Ipv4Addr, - old_netmask: Ipv4Addr, - old_gateway: Ipv4Addr, - ) -> io::Result<()> { - let _guard = self.lock.lock(); - let dev: &dyn IFace = match self.device.as_ref() { - Device::Tun(dev) => dev as &dyn IFace, - Device::Tap((dev, _)) => dev as &dyn IFace, - }; - if let Err(e) = dev.delete_route(dest(old_gateway, old_gateway), old_netmask, old_gateway) { - log::warn!("{:?}", e); - } - dev.set_ip(address, netmask)?; - for (address, netmask) in &self.in_ips { - dev.add_route(*address, *netmask, gateway, 1)?; - } - // 当前网段路由 - dev.add_route(address, netmask, gateway, 1)?; - // 广播和组播路由 - // dev.add_route(Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST, gateway, 1)?; - dev.add_route( - Ipv4Addr::from([224, 0, 0, 0]), - Ipv4Addr::from([240, 0, 0, 0]), - gateway, - 1, - )?; - delete_cache(); - Ok(()) - } - pub fn close(&self) -> io::Result<()> { - match self.device.as_ref() { - Device::Tun(dev) => dev.shutdown(), - Device::Tap((dev, _)) => dev.shutdown(), - } - } - pub fn is_tun(&self) -> bool { - self.device.is_tun() - } -} - -fn dest(ip: Ipv4Addr, mask: Ipv4Addr) -> Ipv4Addr { - let ip = ip.octets(); - let mask = mask.octets(); - Ipv4Addr::from([ - ip[0] & mask[0], - ip[1] & mask[1], - ip[2] & mask[2], - ip[3] & mask[3], - ]) -} - -pub struct DeviceReader { - device: Arc, -} - -impl DeviceReader { - pub fn new(device: Arc) -> Self { - Self { device } - } -} - -impl DeviceReader { - pub fn read(&self, buf: &mut [u8]) -> io::Result { - match self.device.as_ref() { - Device::Tun(dev) => { - let packet = dev.receive_blocking()?; - let packet = packet.bytes(); - let len = packet.len(); - if len > buf.len() { - return Err(io::Error::new(io::ErrorKind::InvalidData, "data too long")); - } - buf[..len].copy_from_slice(packet); - Ok(len) - } - Device::Tap((dev, _)) => dev.read(buf), - } - } -} - -fn create_tun( - address: Ipv4Addr, - netmask: Ipv4Addr, - gateway: Ipv4Addr, - in_ips: Vec<(Ipv4Addr, Ipv4Addr)>, - mtu: u16, -) -> io::Result<(DeviceWriter, DeviceReader, DriverInfo)> { - unsafe { - match Library::new("wintun.dll") { - Ok(lib) => match TunDevice::delete_for_name(lib, TUN_INTERFACE_NAME) { - Ok(_) => { - thread::sleep(Duration::from_millis(5)); - } - Err(_) => {} - }, - Err(e) => { - return Err(io::Error::new( - io::ErrorKind::Other, - format!("wintun.dll not found {:?}", e), - )); - } - } - let tun_device = match TunDevice::create( - Library::new("wintun.dll").unwrap(), - TUN_POOL_NAME, - TUN_INTERFACE_NAME, - ) { - Ok(tun_device) => tun_device, - Err(_) => { - thread::sleep(Duration::from_millis(200)); - match TunDevice::create( - Library::new("wintun.dll").unwrap(), - TUN_POOL_NAME, - TUN_INTERFACE_NAME, - ) { - Ok(tun_device) => tun_device, - Err(e) => { - return Err(io::Error::new(io::ErrorKind::Other, format!("{:?}", e))); - } - } - } - }; - let name = tun_device.get_name()?; - let version = format!("{:?}", tun_device.version()?); - tun_device.set_ip(address, netmask)?; - tun_device.set_metric(1)?; - tun_device.set_mtu(mtu)?; - // ip代理路由 - for (address, netmask) in &in_ips { - tun_device.add_route(*address, *netmask, gateway, 1)?; - } - // 当前网段路由 - tun_device.add_route(address, netmask, gateway, 1)?; - // 广播和组播路由 修改了广播路由会导致发不出广播 - // tun_device.add_route(Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST, gateway, 1)?; - tun_device.add_route( - Ipv4Addr::from([224, 0, 0, 0]), - Ipv4Addr::from([240, 0, 0, 0]), - gateway, - 1, - )?; - delete_cache(); - let device = Arc::new(Device::Tun(tun_device)); - let driver_info = DriverInfo { - device_type: DeviceType::Tun, - name, - version, - mac: None, - }; - Ok(( - DeviceWriter::new(device.clone(), in_ips, address), - DeviceReader::new(device), - driver_info, - )) - } -} - -fn delete_cache() { - //清除路由缓存 - let delete_cache = "netsh interface ip delete destinationcache"; - let out = std::process::Command::new("cmd") - .creation_flags(0x08000000) - .arg("/C") - .arg(delete_cache) - .output() - .unwrap(); - if !out.status.success() { - log::warn!("删除缓存失败:{:?}", out); - } -} - -fn delete_tun() { - unsafe { - match Library::new("wintun.dll") { - Ok(lib) => match TunDevice::delete_for_name(lib, TUN_INTERFACE_NAME) { - Ok(_) => {} - Err(_) => {} - }, - Err(_) => {} - } - } -} - -fn create_tap( - address: Ipv4Addr, - netmask: Ipv4Addr, - gateway: Ipv4Addr, - in_ips: Vec<(Ipv4Addr, Ipv4Addr)>, - mtu: u16, -) -> io::Result<(DeviceWriter, DeviceReader, DriverInfo)> { - let tap_device = match TapDevice::open(TAP_INTERFACE_NAME) { - Ok(tap_device) => tap_device, - Err(e) => { - log::warn!("{:?}", e); - let tap_device = TapDevice::create()?; - tap_device.set_name(TAP_INTERFACE_NAME)?; - tap_device - } - }; - let mac = tap_device.get_mac()?; - let name = tap_device.get_name()?; - let version = format!("{:?}", tap_device.get_version()?); - let mac_str = format!("mac:{:x?}", mac); - tap_device.set_ip(address, netmask)?; - tap_device.set_metric(1)?; - tap_device.set_mtu(mtu)?; - tap_device.set_status(true)?; - tap_device.add_route(address, netmask, gateway, 1)?; - for (address, netmask) in &in_ips { - tap_device.add_route(*address, *netmask, gateway, 1)?; - } - // 广播和组播路由 - // tap_device.add_route(Ipv4Addr::BROADCAST, Ipv4Addr::BROADCAST, gateway, 1)?; - tap_device.add_route( - Ipv4Addr::from([224, 0, 0, 0]), - Ipv4Addr::from([240, 0, 0, 0]), - gateway, - 1, - )?; - delete_cache(); - let tap = Arc::new(Device::Tap((tap_device, mac))); - let driver_info = DriverInfo { - device_type: DeviceType::Tap, - name, - version, - mac: Some(mac_str), - }; - Ok(( - DeviceWriter::new(tap.clone(), in_ips, address), - DeviceReader::new(tap), - driver_info, - )) -} - -fn delete_tap() { - let tap_device = match TapDevice::open(TAP_INTERFACE_NAME) { - Ok(tap_device) => tap_device, - Err(_) => { - return; - } - }; - let _ = tap_device.delete(); -} - -pub fn create_device( - device_type: DeviceType, - address: Ipv4Addr, - netmask: Ipv4Addr, - gateway: Ipv4Addr, - in_ips: Vec<(Ipv4Addr, Ipv4Addr)>, - mtu: u16, -) -> io::Result<(DeviceWriter, DeviceReader, DriverInfo)> { - match device_type { - DeviceType::Tun => create_tun(address, netmask, gateway, in_ips, mtu), - DeviceType::Tap => create_tap(address, netmask, gateway, in_ips, mtu), - } -} - -pub fn delete_device(device_type: DeviceType) { - match device_type { - DeviceType::Tun => delete_tun(), - DeviceType::Tap => delete_tap(), - } -} diff --git a/vnt/win-tun-tap/Cargo.toml b/vnt/win-tun-tap/Cargo.toml deleted file mode 100644 index fbed85c..0000000 --- a/vnt/win-tun-tap/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "win-tun-tap" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -log = "0.4.17" -winreg = "0.51.0" -scopeguard = "1.1" -libloading = "0.8.0" -widestring = "1.0.2" -once_cell = "1.8" -itertools = "0.11.0" -rand = "0.8.5" -[dependencies.winapi] -version = "0.3" -features = [ - "errhandlingapi", - "combaseapi", - "ioapiset", - "winioctl", - "setupapi", - "synchapi", - "netioapi", - "fileapi", - "winbase", - "winerror", - "ipexport", - "iphlpapi", - "handleapi", - "ifdef", - "minwinbase", - "basetsd", - "impl-default" -] \ No newline at end of file diff --git a/vnt/win-tun-tap/src/lib.rs b/vnt/win-tun-tap/src/lib.rs deleted file mode 100644 index a889334..0000000 --- a/vnt/win-tun-tap/src/lib.rs +++ /dev/null @@ -1,49 +0,0 @@ -#![cfg(windows)] - -mod ffi; -mod netsh; -mod route; -mod tap; -mod tun; -use std::io; -use std::net::Ipv4Addr; -pub use tap::TapDevice; -pub use tun::*; - -/// Encode a string as a utf16 buffer -fn encode_utf16(string: &str) -> Vec { - use std::iter::once; - string.encode_utf16().chain(once(0)).collect() -} - -/// Decode a string from a utf16 buffer -fn decode_utf16(string: &[u16]) -> String { - let end = string.iter().position(|b| *b == 0).unwrap_or(string.len()); - String::from_utf16_lossy(&string[..end]) -} - -pub trait IFace { - fn shutdown(&self) -> io::Result<()>; - /// 获取接口索引 - fn get_index(&self) -> io::Result; - /// 获取名称 - fn get_name(&self) -> io::Result; - /// 设置名称 - fn set_name(&self, new_name: &str) -> io::Result<()>; - /// 设置ip - fn set_ip(&self, address: Ipv4Addr, mask: Ipv4Addr) -> io::Result<()>; - /// 设置路由 - fn add_route( - &self, - dest: Ipv4Addr, - netmask: Ipv4Addr, - gateway: Ipv4Addr, - metric: u16, - ) -> io::Result<()>; - /// 删除路由 - fn delete_route(&self, dest: Ipv4Addr, netmask: Ipv4Addr, gateway: Ipv4Addr) -> io::Result<()>; - /// 设置最大传输单元 - fn set_mtu(&self, mtu: u16) -> io::Result<()>; - /// 设置跃点 - fn set_metric(&self, metric: u16) -> io::Result<()>; -} diff --git a/vnt/win-tun-tap/src/netsh.rs b/vnt/win-tun-tap/src/netsh.rs deleted file mode 100644 index ee16399..0000000 --- a/vnt/win-tun-tap/src/netsh.rs +++ /dev/null @@ -1,80 +0,0 @@ -use std::io; -use std::net::Ipv4Addr; -use std::os::windows::process::CommandExt; - -/// 设置网卡名称 -pub fn set_interface_name(old_name: &str, new_name: &str) -> io::Result<()> { - let cmd = format!( - " netsh interface set interface name={:?} newname={:?}", - old_name, new_name - ); - let out = std::process::Command::new("cmd") - .creation_flags(0x08000000) //winapi-0.3.9/src/um/winbase.rs:283 - .arg("/C") - .arg(&cmd) - .output()?; - if !out.status.success() { - log::warn!("修改网卡名称失败:cmd={:?},out={:?}", cmd, out); - return Err(io::Error::new(io::ErrorKind::Other, "修改网卡名称失败")); - } - Ok(()) -} -/// 设置网卡ip -pub fn set_interface_ip(index: u32, address: &Ipv4Addr, netmask: &Ipv4Addr) -> io::Result<()> { - let set_address = format!( - "netsh interface ip set address {} static {:?} {:?} ", - index, address, netmask, - ); - let out = std::process::Command::new("cmd") - .creation_flags(0x08000000) - .arg("/C") - .arg(&set_address) - .output()?; - if !out.status.success() { - log::error!("cmd={:?},out={:?}", set_address, out); - return Err(io::Error::new( - io::ErrorKind::Other, - format!("设置网络地址失败: {:?}", out), - )); - } - Ok(()) -} - -pub fn set_interface_mtu(index: u32, mtu: u16) -> io::Result<()> { - let set_mtu = format!( - "netsh interface ipv4 set subinterface {} mtu={} store=persistent", - index, mtu - ); - let out = std::process::Command::new("cmd") - .creation_flags(0x08000000) - .arg("/C") - .arg(&set_mtu) - .output()?; - if !out.status.success() { - log::error!("cmd={:?},out={:?}", set_mtu, out); - return Err(io::Error::new( - io::ErrorKind::Other, - format!("设置mtu失败: {:?}", out), - )); - } - Ok(()) -} -pub fn set_interface_metric(index: u32, metric: u16) -> io::Result<()> { - let set_metric = format!( - "netsh interface ip set interface {} metric={}", - index, metric - ); - let out = std::process::Command::new("cmd") - .creation_flags(0x08000000) - .arg("/C") - .arg(&set_metric) - .output()?; - if !out.status.success() { - log::error!("cmd={:?},out={:?}", set_metric, out); - return Err(io::Error::new( - io::ErrorKind::Other, - format!("设置metric失败: {:?}", out), - )); - } - Ok(()) -} diff --git a/vnt/win-tun-tap/src/route.rs b/vnt/win-tun-tap/src/route.rs deleted file mode 100644 index 97d2e5b..0000000 --- a/vnt/win-tun-tap/src/route.rs +++ /dev/null @@ -1,65 +0,0 @@ -use std::io; -use std::net::Ipv4Addr; -use std::os::windows::process::CommandExt; - -/// 添加路由 -pub fn add_route( - index: u32, - dest: Ipv4Addr, - netmask: Ipv4Addr, - gateway: Ipv4Addr, - metric: u16, -) -> io::Result<()> { - let set_route = format!( - "route add {:?} mask {:?} {:?} metric {} if {}", - dest, netmask, gateway, metric, index - ); - // 执行添加路由命令 - let out = std::process::Command::new("cmd") - .creation_flags(0x08000000) - .arg("/C") - .arg(&set_route) - .output() - .unwrap(); - if !out.status.success() { - log::error!("cmd={:?},out={:?}", set_route, out); - return Err(io::Error::new( - io::ErrorKind::Other, - format!("添加路由失败: {:?}", out), - )); - } - Ok(()) -} - -/// 删除路由 -pub fn delete_route( - index: u32, - dest: Ipv4Addr, - netmask: Ipv4Addr, - gateway: Ipv4Addr, -) -> io::Result<()> { - if index == 0 { - return Err(io::Error::new( - io::ErrorKind::Other, - format!("网络接口索引错误: {:?}", index), - )); - } - let delete_route = format!( - "route delete {:?} mask {:?} {:?} if {}", - dest, netmask, gateway, index - ); - // 删除路由 - let out = std::process::Command::new("cmd") - .creation_flags(0x08000000) - .arg("/C") - .arg(delete_route) - .output() - .unwrap(); - if !out.status.success() { - return Err(io::Error::new( - io::ErrorKind::Other, - format!("删除路由失败: {:?}", out), - )); - } - Ok(()) -} diff --git a/vnt/win-tun-tap/src/tap/iface.rs b/vnt/win-tun-tap/src/tap/iface.rs deleted file mode 100644 index 201a366..0000000 --- a/vnt/win-tun-tap/src/tap/iface.rs +++ /dev/null @@ -1,297 +0,0 @@ -use winapi::shared::ifdef::NET_LUID; -use winapi::shared::minwindef::*; - -use winapi::um::fileapi::*; -use winapi::um::setupapi::*; -use winapi::um::winnt::*; - -use scopeguard::{guard, ScopeGuard}; -use winreg::RegKey; - -use std::io; -use winapi::um::winbase::FILE_FLAG_OVERLAPPED; - -use crate::{decode_utf16, encode_utf16, ffi}; - -/// tap-windows hardware ID -const HARDWARE_ID: &str = "tap0901"; - -winapi::DEFINE_GUID! { - GUID_NETWORK_ADAPTER, - 0x4d36e972, 0xe325, 0x11ce, - 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 -} - -/// Create a new interface and returns its NET_LUID -pub fn create_interface() -> io::Result { - let devinfo = ffi::create_device_info_list(&GUID_NETWORK_ADAPTER)?; - - let _guard = guard((), |_| { - let _ = ffi::destroy_device_info_list(devinfo); - }); - - let class_name = ffi::class_name_from_guid(&GUID_NETWORK_ADAPTER)?; - - let devinfo_data = ffi::create_device_info( - devinfo, - &class_name, - &GUID_NETWORK_ADAPTER, - &encode_utf16(""), - DICD_GENERATE_ID, - )?; - - ffi::set_selected_device(devinfo, &devinfo_data)?; - ffi::set_device_registry_property( - devinfo, - &devinfo_data, - SPDRP_HARDWAREID, - &encode_utf16(HARDWARE_ID), - )?; - - ffi::build_driver_info_list(devinfo, &devinfo_data, SPDIT_COMPATDRIVER)?; - - let _guard = guard((), |_| { - let _ = ffi::destroy_driver_info_list(devinfo, &devinfo_data, SPDIT_COMPATDRIVER); - }); - - let mut driver_version = 0; - let mut member_index = 0; - - while let Some(drvinfo_data) = - ffi::enum_driver_info(devinfo, &devinfo_data, SPDIT_COMPATDRIVER, member_index) - { - member_index += 1; - - let drvinfo_data = match drvinfo_data { - Ok(drvinfo_data) => drvinfo_data, - _ => continue, - }; - - if drvinfo_data.DriverVersion <= driver_version { - continue; - } - - let drvinfo_detail = - match ffi::get_driver_info_detail(devinfo, &devinfo_data, &drvinfo_data) { - Ok(drvinfo_detail) => drvinfo_detail, - _ => continue, - }; - - let is_compatible = drvinfo_detail - .HardwareID - .split(|b| *b == 0) - .map(|id| decode_utf16(id)) - .any(|id| id.eq_ignore_ascii_case(HARDWARE_ID)); - - if !is_compatible { - continue; - } - - match ffi::set_selected_driver(devinfo, &devinfo_data, &drvinfo_data) { - Ok(_) => (), - _ => continue, - } - - driver_version = drvinfo_data.DriverVersion; - } - - if driver_version == 0 { - return Err(io::Error::new(io::ErrorKind::NotFound, "No driver found")); - } - - let uninstaller = guard((), |_| { - let _ = ffi::call_class_installer(devinfo, &devinfo_data, DIF_REMOVE); - }); - - ffi::call_class_installer(devinfo, &devinfo_data, DIF_REGISTERDEVICE)?; - - let _ = ffi::call_class_installer(devinfo, &devinfo_data, DIF_REGISTER_COINSTALLERS); - let _ = ffi::call_class_installer(devinfo, &devinfo_data, DIF_INSTALLINTERFACES); - - ffi::call_class_installer(devinfo, &devinfo_data, DIF_INSTALLDEVICE)?; - - let key = ffi::open_dev_reg_key( - devinfo, - &devinfo_data, - DICS_FLAG_GLOBAL, - 0, - DIREG_DRV, - KEY_QUERY_VALUE | KEY_NOTIFY, - )?; - - let key = RegKey::predef(key as _); - - while let Err(_) = key.get_value::("*IfType") { - ffi::notify_change_key_value(key.raw_handle() as _, TRUE, REG_NOTIFY_CHANGE_NAME, 2000)?; - } - - while let Err(_) = key.get_value::("NetLuidIndex") { - ffi::notify_change_key_value(key.raw_handle() as _, TRUE, REG_NOTIFY_CHANGE_NAME, 2000)?; - } - - let if_type: DWORD = key.get_value("*IfType")?; - let luid_index: DWORD = key.get_value("NetLuidIndex")?; - - // Defuse the uninstaller - ScopeGuard::into_inner(uninstaller); - - let mut luid = NET_LUID { Value: 0 }; - - luid.set_IfType(if_type as _); - luid.set_NetLuidIndex(luid_index as _); - - Ok(luid) -} - -/// Check if the given interface exists and is a valid tap-windows device -pub fn check_interface(luid: &NET_LUID) -> io::Result<()> { - let devinfo = ffi::get_class_devs(&GUID_NETWORK_ADAPTER, DIGCF_PRESENT)?; - - let _guard = guard((), |_| { - let _ = ffi::destroy_device_info_list(devinfo); - }); - - let mut member_index = 0; - - while let Some(devinfo_data) = ffi::enum_device_info(devinfo, member_index) { - member_index += 1; - - let devinfo_data = match devinfo_data { - Ok(devinfo_data) => devinfo_data, - Err(_) => continue, - }; - - let hardware_id = - match ffi::get_device_registry_property(devinfo, &devinfo_data, SPDRP_HARDWAREID) { - Ok(hardware_id) => hardware_id, - Err(_) => continue, - }; - - if !decode_utf16(&hardware_id).eq_ignore_ascii_case(HARDWARE_ID) { - continue; - } - - let key = match ffi::open_dev_reg_key( - devinfo, - &devinfo_data, - DICS_FLAG_GLOBAL, - 0, - DIREG_DRV, - KEY_QUERY_VALUE | KEY_NOTIFY, - ) { - Ok(key) => RegKey::predef(key as _), - Err(_) => continue, - }; - - let if_type: DWORD = match key.get_value("*IfType") { - Ok(if_type) => if_type, - Err(_) => continue, - }; - - let luid_index: DWORD = match key.get_value("NetLuidIndex") { - Ok(luid_index) => luid_index, - Err(_) => continue, - }; - - let mut luid2 = NET_LUID { Value: 0 }; - - luid2.set_IfType(if_type as _); - luid2.set_NetLuidIndex(luid_index as _); - - if luid.Value != luid2.Value { - continue; - } - - // Found it! - return Ok(()); - } - - Err(io::Error::new( - io::ErrorKind::NotFound, - "TAP Device not found", - )) -} - -/// Deletes an existing interface -pub fn delete_interface(luid: &NET_LUID) -> io::Result<()> { - let devinfo = ffi::get_class_devs(&GUID_NETWORK_ADAPTER, DIGCF_PRESENT)?; - - let _guard = guard((), |_| { - let _ = ffi::destroy_device_info_list(devinfo); - }); - - let mut member_index = 0; - - while let Some(devinfo_data) = ffi::enum_device_info(devinfo, member_index) { - member_index += 1; - - let devinfo_data = match devinfo_data { - Ok(devinfo_data) => devinfo_data, - Err(_) => continue, - }; - - let hardware_id = - match ffi::get_device_registry_property(devinfo, &devinfo_data, SPDRP_HARDWAREID) { - Ok(hardware_id) => hardware_id, - Err(_) => continue, - }; - - if !decode_utf16(&hardware_id).eq_ignore_ascii_case(HARDWARE_ID) { - continue; - } - - let key = match ffi::open_dev_reg_key( - devinfo, - &devinfo_data, - DICS_FLAG_GLOBAL, - 0, - DIREG_DRV, - KEY_QUERY_VALUE | KEY_NOTIFY, - ) { - Ok(key) => RegKey::predef(key as _), - Err(_) => continue, - }; - - let if_type: DWORD = match key.get_value("*IfType") { - Ok(if_type) => if_type, - Err(_) => continue, - }; - - let luid_index: DWORD = match key.get_value("NetLuidIndex") { - Ok(luid_index) => luid_index, - Err(_) => continue, - }; - - let mut luid2 = NET_LUID { Value: 0 }; - - luid2.set_IfType(if_type as _); - luid2.set_NetLuidIndex(luid_index as _); - - if luid.Value != luid2.Value { - continue; - } - - // Found it! - return ffi::call_class_installer(devinfo, &devinfo_data, DIF_REMOVE); - } - - Err(io::Error::new( - io::ErrorKind::NotFound, - "TAP Device not found", - )) -} - -/// Open an handle to an interface -pub fn open_interface(luid: &NET_LUID) -> io::Result { - let guid = ffi::luid_to_guid(luid).and_then(|guid| ffi::string_from_guid(&guid))?; - - let path = format!(r"\\.\Global\{}.tap", &decode_utf16(&guid)); - - ffi::create_file( - &encode_utf16(&path), - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - OPEN_EXISTING, - FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, //FILE_ATTRIBUTE_SYSTEM, - ) -} diff --git a/vnt/win-tun-tap/src/tap/mod.rs b/vnt/win-tun-tap/src/tap/mod.rs deleted file mode 100644 index 823d7ec..0000000 --- a/vnt/win-tun-tap/src/tap/mod.rs +++ /dev/null @@ -1,191 +0,0 @@ -use std::net::Ipv4Addr; -use std::{io, time}; - -use winapi::shared::ifdef::NET_LUID; -use winapi::um::winioctl::*; -use winapi::um::winnt::HANDLE; - -use crate::{decode_utf16, encode_utf16, ffi, netsh, route, IFace}; - -mod iface; - -pub struct TapDevice { - index: u32, - luid: NET_LUID, - handle: HANDLE, -} - -unsafe impl Send for TapDevice {} - -unsafe impl Sync for TapDevice {} - -impl TapDevice { - /// Retieve the mac of the interface - pub fn get_mac(&self) -> io::Result<[u8; 6]> { - let mut mac = [0; 6]; - - ffi::device_io_control( - self.handle, - CTL_CODE(FILE_DEVICE_UNKNOWN, 1, METHOD_BUFFERED, FILE_ANY_ACCESS), - &(), - &mut mac, - ) - .map(|_| mac) - } - - /// Retrieve the version of the driver - pub fn get_version(&self) -> io::Result<[u32; 3]> { - let mut version = [0; 3]; - - ffi::device_io_control( - self.handle, - CTL_CODE(FILE_DEVICE_UNKNOWN, 2, METHOD_BUFFERED, FILE_ANY_ACCESS), - &(), - &mut version, - ) - .map(|_| version) - } - - /// Retieve the mtu of the interface - pub fn get_mtu(&self) -> io::Result { - let mut mtu = 0; - - ffi::device_io_control( - self.handle, - CTL_CODE(FILE_DEVICE_UNKNOWN, 3, METHOD_BUFFERED, FILE_ANY_ACCESS), - &(), - &mut mtu, - ) - .map(|_| mtu) - } - - /// Set the status of the interface, true for connected, - /// false for disconnected. - pub fn set_status(&self, status: bool) -> io::Result<()> { - let status: u32 = if status { 1 } else { 0 }; - ffi::device_io_control( - self.handle, - CTL_CODE(FILE_DEVICE_UNKNOWN, 6, METHOD_BUFFERED, FILE_ANY_ACCESS), - &status, - &mut (), - ) - } -} - -impl TapDevice { - pub fn create() -> io::Result { - let luid = iface::create_interface()?; - // Even after retrieving the luid, we might need to wait - let start = time::Instant::now(); - let handle = loop { - // If we surpassed 2 seconds just return - let now = time::Instant::now(); - if now - start > time::Duration::from_secs(3) { - return Err(io::Error::new( - io::ErrorKind::TimedOut, - "Interface timed out", - )); - } - - match iface::open_interface(&luid) { - Err(_) => { - std::thread::yield_now(); - continue; - } - Ok(handle) => break handle, - }; - }; - let index = ffi::luid_to_index(&luid).map(|index| index as u32)?; - Ok(Self { - index, - luid, - handle, - }) - } - - pub fn open(name: &str) -> io::Result { - let name = encode_utf16(name); - - let luid = ffi::alias_to_luid(&name)?; - iface::check_interface(&luid)?; - - let handle = iface::open_interface(&luid)?; - let index = ffi::luid_to_index(&luid).map(|index| index as u32)?; - Ok(Self { - index, - luid, - handle, - }) - } - - pub fn delete(self) -> io::Result<()> { - // iface::delete_interface(&self.luid) - Ok(()) - } -} - -impl IFace for TapDevice { - fn shutdown(&self) -> io::Result<()> { - self.set_status(false) - } - - fn get_index(&self) -> io::Result { - Ok(self.index) - } - - fn get_name(&self) -> io::Result { - ffi::luid_to_alias(&self.luid).map(|name| decode_utf16(&name)) - } - - fn set_name(&self, new_name: &str) -> io::Result<()> { - let name = self.get_name()?; - netsh::set_interface_name(&name, new_name) - } - - fn set_ip(&self, address: Ipv4Addr, mask: Ipv4Addr) -> io::Result<()> { - let index = self.get_index()?; - netsh::set_interface_ip(index, &address, &mask) - } - - fn add_route( - &self, - dest: Ipv4Addr, - netmask: Ipv4Addr, - gateway: Ipv4Addr, - metric: u16, - ) -> io::Result<()> { - let index = self.get_index()?; - route::add_route(index, dest, netmask, gateway, metric) - } - - fn delete_route(&self, dest: Ipv4Addr, netmask: Ipv4Addr, gateway: Ipv4Addr) -> io::Result<()> { - let index = self.get_index()?; - route::delete_route(index, dest, netmask, gateway) - } - - fn set_mtu(&self, mtu: u16) -> io::Result<()> { - let index = self.get_index()?; - netsh::set_interface_mtu(index, mtu) - } - - fn set_metric(&self, metric: u16) -> io::Result<()> { - let index = self.get_index()?; - netsh::set_interface_metric(index, metric) - } -} - -impl TapDevice { - pub fn read(&self, buf: &mut [u8]) -> io::Result { - ffi::read_file(self.handle, buf).map(|res| res as _) - } - pub fn write(&self, buf: &[u8]) -> io::Result { - ffi::write_file(self.handle, buf).map(|res| res as _) - } -} - -impl Drop for TapDevice { - fn drop(&mut self) { - let _ = ffi::close_handle(self.handle); - let _ = iface::delete_interface(&self.luid); - } -}