2016-12-12 15:19:53 +08:00
|
|
|
use std::cell::RefCell;
|
|
|
|
use std::vec::Vec;
|
2016-12-12 20:30:35 +08:00
|
|
|
use std::rc::Rc;
|
2016-12-12 15:19:53 +08:00
|
|
|
use std::io;
|
2016-12-12 20:30:35 +08:00
|
|
|
|
|
|
|
use Error;
|
2017-03-07 18:56:48 +08:00
|
|
|
use super::{sys, DeviceLimits, Device};
|
2016-12-11 07:15:26 +08:00
|
|
|
|
|
|
|
/// A virtual Ethernet interface.
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct TapInterface {
|
2016-12-12 20:30:35 +08:00
|
|
|
lower: Rc<RefCell<sys::TapInterfaceDesc>>,
|
|
|
|
mtu: usize
|
2016-12-11 07:15:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl TapInterface {
|
|
|
|
/// Attaches to a TAP interface called `name`, or creates it if it does not exist.
|
|
|
|
///
|
|
|
|
/// If `name` is a persistent interface configured with UID of the current user,
|
|
|
|
/// no special privileges are needed. Otherwise, this requires superuser privileges
|
|
|
|
/// or a corresponding capability set on the executable.
|
|
|
|
pub fn new(name: &str) -> io::Result<TapInterface> {
|
|
|
|
let mut lower = try!(sys::TapInterfaceDesc::new(name));
|
|
|
|
try!(lower.attach_interface());
|
|
|
|
Ok(TapInterface {
|
2016-12-12 20:30:35 +08:00
|
|
|
lower: Rc::new(RefCell::new(lower)),
|
|
|
|
mtu: 1536 // FIXME: get the real value somehow
|
2016-12-11 07:15:26 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Device for TapInterface {
|
2016-12-12 20:30:35 +08:00
|
|
|
type RxBuffer = Vec<u8>;
|
|
|
|
type TxBuffer = TxBuffer;
|
|
|
|
|
2017-03-07 18:56:48 +08:00
|
|
|
fn limits(&self) -> DeviceLimits {
|
|
|
|
DeviceLimits {
|
|
|
|
max_transmission_unit: self.mtu,
|
|
|
|
..DeviceLimits::default()
|
|
|
|
}
|
|
|
|
}
|
2016-12-12 20:30:35 +08:00
|
|
|
|
|
|
|
fn receive(&mut self) -> Result<Self::RxBuffer, Error> {
|
|
|
|
let mut lower = self.lower.borrow_mut();
|
|
|
|
let mut buffer = vec![0; self.mtu];
|
2017-03-05 13:20:33 +08:00
|
|
|
match lower.recv(&mut buffer[..]) {
|
|
|
|
Ok(size) => {
|
|
|
|
buffer.resize(size, 0);
|
|
|
|
Ok(buffer)
|
|
|
|
}
|
|
|
|
Err(ref err) if err.kind() == io::ErrorKind::TimedOut => {
|
|
|
|
Err(Error::Exhausted)
|
|
|
|
}
|
|
|
|
Err(err) => panic!(err)
|
|
|
|
}
|
2016-12-12 15:19:53 +08:00
|
|
|
}
|
2016-12-11 07:15:26 +08:00
|
|
|
|
2016-12-31 09:10:46 +08:00
|
|
|
fn transmit(&mut self, length: usize) -> Result<Self::TxBuffer, Error> {
|
2016-12-12 20:30:35 +08:00
|
|
|
Ok(TxBuffer {
|
|
|
|
lower: self.lower.clone(),
|
2016-12-31 09:10:46 +08:00
|
|
|
buffer: vec![0; length]
|
2016-12-12 20:30:35 +08:00
|
|
|
})
|
2016-12-11 07:15:26 +08:00
|
|
|
}
|
2016-12-12 20:30:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
|
|
|
pub struct TxBuffer {
|
|
|
|
lower: Rc<RefCell<sys::TapInterfaceDesc>>,
|
|
|
|
buffer: Vec<u8>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AsRef<[u8]> for TxBuffer {
|
|
|
|
fn as_ref(&self) -> &[u8] { self.buffer.as_ref() }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AsMut<[u8]> for TxBuffer {
|
|
|
|
fn as_mut(&mut self) -> &mut [u8] { self.buffer.as_mut() }
|
|
|
|
}
|
2016-12-11 07:15:26 +08:00
|
|
|
|
2016-12-12 20:30:35 +08:00
|
|
|
impl Drop for TxBuffer {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
let mut lower = self.lower.borrow_mut();
|
|
|
|
lower.send(&mut self.buffer[..]).unwrap();
|
2016-12-11 07:15:26 +08:00
|
|
|
}
|
|
|
|
}
|