diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fffb2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/elaeis4.iml b/.idea/elaeis4.iml new file mode 100644 index 0000000..8387b97 --- /dev/null +++ b/.idea/elaeis4.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..951a73d --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..f379199 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 7399cdd..6241f4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,5 @@ [workspace] members = [ - "wginterface" + "quicktap", # Fast WireGuard implementation library + "quicktap-cli", # A userspace Wireguard implementation (wrapper around quicktap) ] diff --git a/README.md b/README.md new file mode 100644 index 0000000..6da1e95 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Elaeis 4.0 +Elaeis is a implementation of the WireGuard protocol (quicktap) and a management system built around it (elaeis itself). \ No newline at end of file diff --git a/wginterface/Cargo.toml b/quicktap-cli/Cargo.toml similarity index 67% rename from wginterface/Cargo.toml rename to quicktap-cli/Cargo.toml index 437a648..309d0b1 100644 --- a/wginterface/Cargo.toml +++ b/quicktap-cli/Cargo.toml @@ -1,8 +1,9 @@ [package] -name = "wginterface" +name = "quicktap-cli" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +quicktap = { path = "../quicktap", version = "0.1.0" } \ No newline at end of file diff --git a/quicktap-cli/src/main.rs b/quicktap-cli/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/quicktap-cli/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/quicktap/Cargo.toml b/quicktap/Cargo.toml new file mode 100644 index 0000000..ac0480d --- /dev/null +++ b/quicktap/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "quicktap" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +cidr = "0.2.1" +etherparse = "0.13.0" + +[target.'cfg(unix)'.dependencies] +tun = "0.5.4" \ No newline at end of file diff --git a/quicktap/src/drivers/linux.rs b/quicktap/src/drivers/linux.rs new file mode 100644 index 0000000..c0496f2 --- /dev/null +++ b/quicktap/src/drivers/linux.rs @@ -0,0 +1,79 @@ +use std::error::Error; +use std::io; +use std::io::Read; +use etherparse::IpHeader; +use tun::platform::Device; +use crate::drivers::tungeneric::{GenericDriver, GenericInterface, TunPacket}; + +pub struct TunDevice { + device: Device, + read_buf: [u8; 4096], + read_offset: usize, + packet_buf: [u8; 4096], +} +impl GenericDriver for TunDevice { + /// Create a new TunDevice with the provided generic interface configuration + fn new(config: &GenericInterface) -> Result> { + let mut device_config = tun::Configuration::default(); + device_config.address(config.address.address())?; + device_config.netmask(config.address.mask())?; + device_config.name(&config.name)?; + if let Some(mtu) = config.mtu { + device_config.mtu(mtu)?; + } + //config.platform(|config| { + // config.packet_information(true); + //}); + Ok(Self { + device: tun::create(&device_config)?, + read_buf: [0u8; 4096], + read_offset: 0, + packet_buf: [0u8; 4096], + }) + } + + /// Attempt to read a packet from the interface. If no packet is found, append it to an internal buffer and return WouldBlock. + /// Upon finding a successful packet inside the internal buffer, or the .clear() method being called, the internal buffer will be cleared. + fn read(&mut self) -> Result> { + self.packet_buf = [0u8; 4096]; + let read_amt = self.device.read(&mut self.packet_buf)?; + let ip_header = IpHeader::from_slice(&self.packet_buf); + if let Ok((packet_header, _, _)) = ip_header { + // Found a packet. Clear read buffers + self.read_offset = 0; + self.read_buf = [0u8; 4096]; + Ok(TunPacket { + header: packet_header, + packet: *self.packet_buf, + }) + } + if &self.read_offset + read_amt > 4096 { + // packet is too big + io::Error::new(io::ErrorKind::InvalidData, "Too much non-packet data recieved on network")?; + } + self.read_buf[&self.read_offset..] = &self.packet_buf; + &self.read_offset += read_amt; + + let ip_header = IpHeader::from_slice(&self.read_buf); + if let Ok((packet_header, _, _)) = ip_header { + // Found a packet. Clear read buffers + self.read_offset = 0; + self.read_buf = [0u8; 4096]; + Ok(TunPacket { + header: packet_header, + packet: *self.packet_buf, + }) + } + + io::Error::new(io::ErrorKind::WouldBlock, "No packets detected yet")? + } + + fn clear(&mut self) { + self.read_buf = [0u8; 4096]; + self.read_offset = 0; + } + + fn write(&mut self, packet: Box) -> Result<(), Box> { + todo!() + } +} \ No newline at end of file diff --git a/quicktap/src/drivers/mod.rs b/quicktap/src/drivers/mod.rs new file mode 100644 index 0000000..f12a700 --- /dev/null +++ b/quicktap/src/drivers/mod.rs @@ -0,0 +1,5 @@ +#[cfg(unix)] +#[path = "linux.rs"] +pub mod tun; // Tun/tap drivers for Linux + +pub mod tungeneric; \ No newline at end of file diff --git a/quicktap/src/drivers/tungeneric.rs b/quicktap/src/drivers/tungeneric.rs new file mode 100644 index 0000000..60bd0cd --- /dev/null +++ b/quicktap/src/drivers/tungeneric.rs @@ -0,0 +1,22 @@ +use std::error::Error; +use cidr::IpInet; +use etherparse::{IpHeader, SlicedPacket}; + +pub struct TunPacket { + pub header: IpHeader, + pub packet: [u8] +} + +pub trait GenericDriver { + fn new(config: &GenericInterface) -> Result>; + + fn read(&mut self) -> Result>; + fn clear(&mut self); + fn write(&mut self, packet: TunPacket) -> Result<(), Box>; +} + +pub struct GenericInterface { + pub address: IpInet, + pub mtu: Option, + pub name: String +} \ No newline at end of file diff --git a/quicktap/src/lib.rs b/quicktap/src/lib.rs new file mode 100644 index 0000000..a44f2df --- /dev/null +++ b/quicktap/src/lib.rs @@ -0,0 +1 @@ +pub mod drivers; // Baremetal network drivers for various platforms \ No newline at end of file diff --git a/wginterface/src/lib.rs b/wginterface/src/lib.rs deleted file mode 100644 index 7d12d9a..0000000 --- a/wginterface/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -}