diff --git a/quicktap-cli/src/device.rs b/quicktap-cli/src/device.rs new file mode 100644 index 0000000..b9cd9c7 --- /dev/null +++ b/quicktap-cli/src/device.rs @@ -0,0 +1,28 @@ +use std::error::Error; +use std::io; +use std::net::Ipv4Addr; + +use quicktap::cidr::{IpInet, Ipv4Inet}; +use quicktap::drivers::tun::TunDevice; +use quicktap::drivers::tungeneric::{GenericDriver, GenericInterface}; + +pub fn packet_eventloop() -> Result<(), Box> { + let mut device = TunDevice::new(&GenericInterface { + addresses: vec![IpInet::V4(Ipv4Inet::new(Ipv4Addr::new(10, 19, 2, 2), 16).unwrap())], + mtu: None, + name: "ela1".to_string(), + }).unwrap(); + loop { + let packet = match device.read() { + Ok(p) => Some(p), + Err(e) => match e.kind() { + io::ErrorKind::WouldBlock => None, + _ => return Err(e.into()) + } + }; + + if let Some(p) = packet { + println!("{:?}", p.header); + } + } +} \ No newline at end of file diff --git a/quicktap-cli/src/main.rs b/quicktap-cli/src/main.rs index 8c74578..26c9483 100644 --- a/quicktap-cli/src/main.rs +++ b/quicktap-cli/src/main.rs @@ -1,15 +1,13 @@ -use std::net::{Ipv4Addr}; +use std::net::Ipv4Addr; + use quicktap::cidr::{IpInet, Ipv4Inet}; use quicktap::drivers::tun::TunDevice; use quicktap::drivers::tungeneric::{GenericDriver, GenericInterface}; +use crate::device::packet_eventloop; + +pub mod device; + fn main() { - let mut device = TunDevice::new(&GenericInterface { - addresses: vec![IpInet::V4(Ipv4Inet::new(Ipv4Addr::new(10, 19, 2, 2), 16).unwrap())], - mtu: None, - name: "ela1".to_string(), - }).unwrap(); - loop { - println!("{:?}", device.read().unwrap().header) - } + packet_eventloop().unwrap(); } diff --git a/quicktap/src/drivers/linux.rs b/quicktap/src/drivers/linux.rs index 2d25bbf..111ae53 100644 --- a/quicktap/src/drivers/linux.rs +++ b/quicktap/src/drivers/linux.rs @@ -3,8 +3,10 @@ use std::error::Error; use std::io; use std::io::{Read, Write}; + use etherparse::IpHeader; use tun::platform::Device; + use crate::drivers::tungeneric::{GenericDriver, GenericInterface, TunPacket}; #[allow(clippy::module_name_repetitions)] @@ -31,15 +33,18 @@ impl GenericDriver for TunDevice { if let Some(mtu) = config.mtu { device_config.mtu(mtu); } + let device = tun::create(&device_config)?; + device.set_nonblock()?; + Ok(Self { - device: tun::create(&device_config)?, + device, read_buf: [0u8; 4096], read_offset: 0, packet_buf: [0u8; 4096], }) } - fn read(&mut self) -> Result> { + fn read(&mut self) -> Result { self.packet_buf = [0u8; 4096]; let _ = self.device.read(&mut self.packet_buf)?; let ip_header = IpHeader::from_slice(&self.packet_buf); @@ -53,7 +58,7 @@ impl GenericDriver for TunDevice { }) } - Err(io::Error::new(io::ErrorKind::WouldBlock, "No packets detected yet").into()) + Err(io::Error::new(io::ErrorKind::WouldBlock, "No packets detected yet")) } fn clear(&mut self) { @@ -61,8 +66,8 @@ impl GenericDriver for TunDevice { self.read_offset = 0; } - fn write(&mut self, packet: TunPacket) -> Result<(), Box> { + fn write(&mut self, packet: TunPacket) -> Result<(), io::Error> { let _ = self.device.write(&packet.packet)?; Ok(()) } -} \ No newline at end of file +} diff --git a/quicktap/src/drivers/tungeneric.rs b/quicktap/src/drivers/tungeneric.rs index a4fedef..f34ff7d 100644 --- a/quicktap/src/drivers/tungeneric.rs +++ b/quicktap/src/drivers/tungeneric.rs @@ -1,8 +1,10 @@ //! Generic traits and modules to represent a tun/tap device use std::error::Error; +use std::io; + use cidr::IpInet; -use etherparse::{IpHeader}; +use etherparse::IpHeader; #[derive(Debug)] /// A parsed packet from an interface @@ -24,7 +26,7 @@ pub trait GenericDriver { /// Upon finding a successful packet inside the internal buffer, or the .clear() method being called, the internal buffer will be cleared. /// # Errors /// This function will return `WouldBlock` if a packet could not be read. This function may error if there is an error reading the interface. - fn read(&mut self) -> Result>; + fn read(&mut self) -> Result; /// Clear any internal state of this interface. fn clear(&mut self); @@ -32,7 +34,7 @@ pub trait GenericDriver { /// Attempt to write a packet to the interface. /// # Errors /// This function will error if an error occured writing to the device. - fn write(&mut self, packet: TunPacket) -> Result<(), Box>; + fn write(&mut self, packet: TunPacket) -> Result<(), io::Error>; } /// Generic interface config