[quicktap] work on linux tun drivers
This commit is contained in:
parent
9a3e367a4c
commit
bd9e953352
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
/Cargo.lock
|
|
@ -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
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="CPP_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/quicktap-cli/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/quicktap/src" isTestSource="false" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/elaeis4.iml" filepath="$PROJECT_DIR$/.idea/elaeis4.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
<mapping directory="$PROJECT_DIR$/wginterface" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -1,4 +1,5 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"wginterface"
|
"quicktap", # Fast WireGuard implementation library
|
||||||
|
"quicktap-cli", # A userspace Wireguard implementation (wrapper around quicktap)
|
||||||
]
|
]
|
||||||
|
|
|
@ -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).
|
|
@ -1,8 +1,9 @@
|
||||||
[package]
|
[package]
|
||||||
name = "wginterface"
|
name = "quicktap-cli"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
quicktap = { path = "../quicktap", version = "0.1.0" }
|
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
|
@ -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"
|
|
@ -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<Self, Box<dyn Error>> {
|
||||||
|
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<TunPacket, Box<dyn Error>> {
|
||||||
|
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<TunPacket>) -> Result<(), Box<dyn Error>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#[cfg(unix)]
|
||||||
|
#[path = "linux.rs"]
|
||||||
|
pub mod tun; // Tun/tap drivers for Linux
|
||||||
|
|
||||||
|
pub mod tungeneric;
|
|
@ -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<Self, Box<dyn Error>>;
|
||||||
|
|
||||||
|
fn read(&mut self) -> Result<TunPacket, Box<dyn Error>>;
|
||||||
|
fn clear(&mut self);
|
||||||
|
fn write(&mut self, packet: TunPacket) -> Result<(), Box<dyn Error>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GenericInterface {
|
||||||
|
pub address: IpInet,
|
||||||
|
pub mtu: Option<i32>,
|
||||||
|
pub name: String
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod drivers; // Baremetal network drivers for various platforms
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue