Skip to content

Commit 16cdf18

Browse files
committed
Add macOS utun support
Signed-off-by: Emīls <[email protected]>
1 parent 8bddba9 commit 16cdf18

File tree

8 files changed

+1100
-2
lines changed

8 files changed

+1100
-2
lines changed

Cargo.lock

Lines changed: 20 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ version = "0.5.0"
3737
[target.'cfg(unix)'.dependencies]
3838
libc = "^0.2"
3939

40+
[target.'cfg(target_os = "macos")'.dependencies]
41+
ioctl-sys = "0.6"
42+
page_size = "0.4"
43+
4044
[dependencies.x25519-dalek]
4145
version = "^1.1"
4246

src/main.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
extern crate alloc;
44

5+
#[cfg(target_os = "macos")]
6+
extern crate ioctl_sys;
7+
#[cfg(target_os = "macos")]
8+
extern crate page_size;
9+
510
#[cfg(feature = "profiler")]
611
extern crate cpuprofiler;
712

src/platform/macos/fd.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use std::{io, os::unix::io::RawFd, sync::Arc};
2+
3+
struct FdInner {
4+
fd: RawFd,
5+
}
6+
7+
impl Drop for FdInner {
8+
fn drop(&mut self) {
9+
unsafe { libc::close(self.fd) };
10+
}
11+
}
12+
13+
#[derive(Clone)]
14+
pub(super) struct Fd {
15+
fd: Arc<FdInner>,
16+
}
17+
18+
impl Fd {
19+
pub fn new(fd: RawFd) -> Self {
20+
Self {
21+
fd: Arc::new(FdInner { fd }),
22+
}
23+
}
24+
25+
pub unsafe fn raw_fd(&self) -> RawFd {
26+
self.fd.fd
27+
}
28+
29+
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
30+
let bytes_read = unsafe { libc::write(self.raw_fd(), buf.as_ptr() as _, buf.len()) };
31+
if bytes_read < 0 {
32+
return Err(io::Error::from_raw_os_error(-bytes_read as i32));
33+
}
34+
Ok(bytes_read as usize)
35+
}
36+
37+
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
38+
let bytes_written = unsafe { libc::read(self.raw_fd(), buf.as_mut_ptr() as _, buf.len()) };
39+
if bytes_written < 0 {
40+
return Err(io::Error::last_os_error());
41+
}
42+
Ok(bytes_written as usize)
43+
}
44+
}

src/platform/macos/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
mod fd;
2+
mod sys;
3+
mod tun;
4+
5+
pub use crate::platform::unix::uapi::UnixUAPI as UAPI;
6+
pub use tun::MacosTun as Tun;

src/platform/macos/sys.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#![allow(non_camel_case_types)]
2+
#[repr(C)]
3+
pub struct ctl_info {
4+
pub ctl_id: u32,
5+
pub ctl_name: [u8; 96],
6+
}
7+
ioctl_sys::ioctl!(readwrite ctliocginfo with 'N', 3; ctl_info);
8+
9+
#[repr(C)]
10+
pub struct rt_msghdr {
11+
pub rtm_msglen: u16,
12+
pub rtm_version: u8,
13+
pub rtm_type: u8,
14+
pub rtm_index: u16,
15+
pub rtm_flags: i32,
16+
pub rtm_addrs: i32,
17+
pub rtm_pid: libc::pid_t,
18+
pub rtm_seq: i32,
19+
pub rtm_errno: i32,
20+
pub rtm_use: i32,
21+
pub rtm_inits: u32,
22+
pub rtm_rmx: rt_metrics,
23+
}
24+
25+
#[repr(C)]
26+
pub struct rt_metrics {
27+
pub rmx_locks: u32, /* Kernel must leave these values alone */
28+
pub rmx_mtu: u32, /* MTU for this path */
29+
pub rmx_hopcount: u32, /* max hops expected */
30+
pub rmx_expire: i32, /* lifetime for route, e.g. redirect */
31+
pub rmx_recvpipe: u32, /* inbound delay-bandwidth product */
32+
pub rmx_sendpipe: u32, /* outbound delay-bandwidth product */
33+
pub rmx_ssthresh: u32, /* outbound gateway buffer limit */
34+
pub rmx_rtt: u32, /* estimated round trip time */
35+
pub rmx_rttvar: u32, /* estimated rtt variance */
36+
pub rmx_pksent: u32, /* packets sent using this route */
37+
pub rmx_filler: [u32; 4], /* will be used for T/TCP later */
38+
}

0 commit comments

Comments
 (0)