use smoltcp::phy; use smoltcp::phy::{Device, DeviceCapabilities}; use smoltcp::time::Instant; #[derive(Default)] pub struct VirtualTunDevice { capabilities: DeviceCapabilities, inbuf: Vec>, outbuf: Vec>, } impl VirtualTunDevice { pub fn inject_packet(&mut self, buffer: &[u8]) { let vec = Vec::from(buffer); self.inbuf.push(vec); } pub fn exfiltrate_packet(&mut self) -> Option> { self.outbuf.pop() } } pub struct VirtRxToken { buffer: Vec, } impl phy::RxToken for VirtRxToken { fn consume(mut self, f: F) -> R where F: FnOnce(&mut [u8]) -> R, { f(&mut self.buffer[..]) } } pub struct VirtTxToken<'a>(&'a mut VirtualTunDevice); impl<'a> phy::TxToken for VirtTxToken<'a> { fn consume(self, len: usize, f: F) -> R where F: FnOnce(&mut [u8]) -> R, { let mut buffer = vec![0; len]; let result = f(&mut buffer); self.0.outbuf.push(buffer); result } } impl Device for VirtualTunDevice { type RxToken<'a> = VirtRxToken; type TxToken<'a> = VirtTxToken<'a>; fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { if let Some(buffer) = self.inbuf.pop() { let rx = Self::RxToken { buffer }; let tx = VirtTxToken(self); return Some((rx, tx)); } None } fn transmit(&mut self, _timestamp: Instant) -> Option> { return Some(VirtTxToken(self)); } fn capabilities(&self) -> DeviceCapabilities { self.capabilities.clone() } } impl VirtualTunDevice { pub fn new(capabilities: DeviceCapabilities) -> Self { Self { capabilities, ..Default::default() } } }