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;
|
2017-08-30 03:35:09 +08:00
|
|
|
use std::os::unix::io::{RawFd, AsRawFd};
|
2016-12-12 20:30:35 +08:00
|
|
|
|
2017-07-27 21:51:02 +08:00
|
|
|
use {Error, Result};
|
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
|
|
|
}
|
|
|
|
|
2017-08-30 03:35:09 +08:00
|
|
|
impl AsRawFd for TapInterface {
|
|
|
|
fn as_raw_fd(&self) -> RawFd {
|
|
|
|
self.lower.borrow().as_raw_fd()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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> {
|
2017-06-25 00:34:32 +08:00
|
|
|
let mut lower = sys::TapInterfaceDesc::new(name)?;
|
|
|
|
lower.attach_interface()?;
|
2017-07-23 12:40:35 +08:00
|
|
|
let mtu = lower.interface_mtu()?;
|
2016-12-11 07:15:26 +08:00
|
|
|
Ok(TapInterface {
|
2016-12-12 20:30:35 +08:00
|
|
|
lower: Rc::new(RefCell::new(lower)),
|
2017-07-23 12:40:35 +08:00
|
|
|
mtu: mtu
|
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
|
|
|
|
2017-07-27 21:51:02 +08:00
|
|
|
fn receive(&mut self, _timestamp: u64) -> Result<Self::RxBuffer> {
|
2016-12-12 20:30:35 +08:00
|
|
|
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)
|
|
|
|
}
|
2017-08-30 03:35:09 +08:00
|
|
|
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => {
|
2017-03-05 13:20:33 +08:00
|
|
|
Err(Error::Exhausted)
|
|
|
|
}
|
2017-08-30 03:35:09 +08:00
|
|
|
Err(err) => panic!("{}", err)
|
2017-03-05 13:20:33 +08:00
|
|
|
}
|
2016-12-12 15:19:53 +08:00
|
|
|
}
|
2016-12-11 07:15:26 +08:00
|
|
|
|
2017-07-27 21:51:02 +08:00
|
|
|
fn transmit(&mut self, _timestamp: u64, length: usize) -> Result<Self::TxBuffer> {
|
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
|
|
|
}
|
|
|
|
}
|