mod.rs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #![allow(unsafe_code)]
  2. use libc;
  3. use std::{mem, ptr, io};
  4. use std::os::unix::io::RawFd;
  5. #[cfg(target_os = "linux")]
  6. #[path = "linux.rs"]
  7. mod imp;
  8. #[cfg(feature = "phy-raw_socket")]
  9. pub mod raw_socket;
  10. #[cfg(all(feature = "phy-tap_interface", target_os = "linux"))]
  11. pub mod tap_interface;
  12. #[cfg(feature = "phy-raw_socket")]
  13. pub use self::raw_socket::RawSocketDesc;
  14. #[cfg(all(feature = "phy-tap_interface", target_os = "linux"))]
  15. pub use self::tap_interface::TapInterfaceDesc;
  16. /// Wait until given file descriptor becomes readable, but no longer than given timeout.
  17. pub fn wait(fd: RawFd, millis: Option<u64>) -> io::Result<()> {
  18. unsafe {
  19. let mut readfds = mem::uninitialized::<libc::fd_set>();
  20. libc::FD_ZERO(&mut readfds);
  21. libc::FD_SET(fd, &mut readfds);
  22. let mut writefds = mem::uninitialized::<libc::fd_set>();
  23. libc::FD_ZERO(&mut writefds);
  24. let mut exceptfds = mem::uninitialized::<libc::fd_set>();
  25. libc::FD_ZERO(&mut exceptfds);
  26. let mut timeout = libc::timeval { tv_sec: 0, tv_usec: 0 };
  27. let timeout_ptr =
  28. if let Some(millis) = millis {
  29. timeout.tv_usec = (millis * 1_000) as libc::suseconds_t;
  30. &mut timeout as *mut _
  31. } else {
  32. ptr::null_mut()
  33. };
  34. let res = libc::select(fd + 1, &mut readfds, &mut writefds, &mut exceptfds, timeout_ptr);
  35. if res == -1 { return Err(io::Error::last_os_error()) }
  36. Ok(())
  37. }
  38. }
  39. #[repr(C)]
  40. #[derive(Debug)]
  41. struct ifreq {
  42. ifr_name: [libc::c_char; libc::IF_NAMESIZE],
  43. ifr_data: libc::c_int /* ifr_ifindex or ifr_mtu */
  44. }
  45. fn ifreq_for(name: &str) -> ifreq {
  46. let mut ifreq = ifreq {
  47. ifr_name: [0; libc::IF_NAMESIZE],
  48. ifr_data: 0
  49. };
  50. for (i, byte) in name.as_bytes().iter().enumerate() {
  51. ifreq.ifr_name[i] = *byte as libc::c_char
  52. }
  53. ifreq
  54. }
  55. fn ifreq_ioctl(lower: libc::c_int, ifreq: &mut ifreq,
  56. cmd: libc::c_ulong) -> io::Result<libc::c_int> {
  57. unsafe {
  58. let res = libc::ioctl(lower, cmd, ifreq as *mut ifreq);
  59. if res == -1 { return Err(io::Error::last_os_error()) }
  60. }
  61. Ok(ifreq.ifr_data)
  62. }