tap_interface.rs 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. use libc;
  2. use std::io;
  3. use super::*;
  4. #[cfg(target_os = "linux")]
  5. #[derive(Debug)]
  6. pub struct TapInterfaceDesc {
  7. lower: libc::c_int,
  8. ifreq: ifreq
  9. }
  10. impl TapInterfaceDesc {
  11. pub fn new(name: &str) -> io::Result<TapInterfaceDesc> {
  12. let lower = unsafe {
  13. let lower = libc::open("/dev/net/tun".as_ptr() as *const libc::c_char,
  14. libc::O_RDWR);
  15. if lower == -1 { return Err(io::Error::last_os_error()) }
  16. lower
  17. };
  18. Ok(TapInterfaceDesc {
  19. lower: lower,
  20. ifreq: ifreq_for(name)
  21. })
  22. }
  23. pub fn attach_interface(&mut self) -> io::Result<()> {
  24. self.ifreq.ifr_data = imp::IFF_TAP | imp::IFF_NO_PI;
  25. ifreq_ioctl(self.lower, &mut self.ifreq, imp::TUNSETIFF).map(|_| ())
  26. }
  27. pub fn recv(&mut self, buffer: &mut [u8]) -> io::Result<usize> {
  28. unsafe {
  29. let len = libc::read(self.lower, buffer.as_mut_ptr() as *mut libc::c_void,
  30. buffer.len());
  31. if len == -1 { return Err(io::Error::last_os_error()) }
  32. Ok(len as usize)
  33. }
  34. }
  35. pub fn send(&mut self, buffer: &[u8]) -> io::Result<usize> {
  36. unsafe {
  37. let len = libc::write(self.lower, buffer.as_ptr() as *const libc::c_void,
  38. buffer.len());
  39. if len == -1 { Err(io::Error::last_os_error()).unwrap() }
  40. Ok(len as usize)
  41. }
  42. }
  43. }
  44. impl Drop for TapInterfaceDesc {
  45. fn drop(&mut self) {
  46. unsafe { libc::close(self.lower); }
  47. }
  48. }