Initial commit
This commit is contained in:
commit
c1e7415871
56 changed files with 3225 additions and 0 deletions
90
tun/src/apple/mod.rs
Normal file
90
tun/src/apple/mod.rs
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
use socket2::SockAddr;
|
||||
use std::io::Result;
|
||||
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
|
||||
|
||||
mod kern_control;
|
||||
mod queue;
|
||||
|
||||
pub use queue::TunQueue;
|
||||
|
||||
use crate::syscall;
|
||||
use crate::unix::copy_if_name;
|
||||
use kern_control::SysControlSocket;
|
||||
|
||||
pub struct TunInterface {
|
||||
socket: socket2::Socket,
|
||||
}
|
||||
|
||||
impl TunInterface {
|
||||
pub fn new() -> Result<TunInterface> {
|
||||
TunInterface::connect(None)
|
||||
}
|
||||
|
||||
fn connect(addr: Option<SockAddr>) -> Result<TunInterface> {
|
||||
use socket2::{Domain, Protocol, Socket, Type};
|
||||
|
||||
let socket = Socket::new(
|
||||
Domain::from(libc::AF_SYSTEM),
|
||||
Type::DGRAM,
|
||||
Some(Protocol::from(libc::SYSPROTO_CONTROL)),
|
||||
)?;
|
||||
let addr = match addr {
|
||||
Some(addr) => addr,
|
||||
None => socket.resolve(sys::UTUN_CONTROL_NAME, 0)?,
|
||||
};
|
||||
socket.connect(&addr)?;
|
||||
|
||||
Ok(TunInterface { socket })
|
||||
}
|
||||
|
||||
pub fn name(&self) -> Result<String> {
|
||||
let mut buf = [0u8; libc::IFNAMSIZ];
|
||||
let mut len = buf.len() as libc::socklen_t;
|
||||
syscall!(getsockopt(
|
||||
self.as_raw_fd(),
|
||||
libc::SYSPROTO_CONTROL,
|
||||
sys::UTUN_OPT_IFNAME,
|
||||
buf.as_mut_ptr() as *mut libc::c_void,
|
||||
&mut len,
|
||||
))?;
|
||||
let name = copy_if_name(buf);
|
||||
Ok(name)
|
||||
}
|
||||
|
||||
pub fn queue(&self) -> Result<TunQueue> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawFd for TunInterface {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.socket.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoRawFd for TunInterface {
|
||||
fn into_raw_fd(self) -> RawFd {
|
||||
self.socket.into_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
mod sys {
|
||||
pub const UTUN_CONTROL_NAME: &str = "com.apple.net.utun_control";
|
||||
|
||||
pub const UTUN_OPT_IFNAME: libc::c_int = 2;
|
||||
|
||||
/// Copied from https://github.com/rust-lang/socket2/blob/61314a231f73964b3db969ef72c0e9479df320f3/src/sys/unix.rs#L168-L178
|
||||
/// getsockopt is not exposed by socket2
|
||||
#[macro_export]
|
||||
macro_rules! syscall {
|
||||
($fn: ident ( $($arg: expr),* $(,)* ) ) => {{
|
||||
#[allow(unused_unsafe)]
|
||||
let res = unsafe { libc::$fn($($arg, )*) };
|
||||
if res == -1 {
|
||||
Err(std::io::Error::last_os_error())
|
||||
} else {
|
||||
Ok(res)
|
||||
}
|
||||
}};
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue