diff --git a/Apple/NetworkExtension/PacketTunnelProvider.swift b/Apple/NetworkExtension/PacketTunnelProvider.swift index ff08261..5ca4e93 100644 --- a/Apple/NetworkExtension/PacketTunnelProvider.swift +++ b/Apple/NetworkExtension/PacketTunnelProvider.swift @@ -1,7 +1,22 @@ +import libburrow import NetworkExtension +import OSLog class PacketTunnelProvider: NEPacketTunnelProvider { + let logger = Logger(subsystem: "com.hackclub.burrow", category: "General") override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) { + let fild = libburrow.retrieve() + if fild == -1 { + // Not sure if this is the right way to return an error + logger.error("Failed to retrieve file descriptor for burrow.") + let err = NSError( + domain: "com.hackclub.burrow", + code: 1_010, + userInfo: [NSLocalizedDescriptionKey: "Failed to find TunInterface"] + ) + completionHandler(err) + } + logger.info("fd: \(fild)") completionHandler(nil) } diff --git a/Apple/NetworkExtension/libburrow/libburrow.h b/Apple/NetworkExtension/libburrow/libburrow.h index 8b13789..1057c90 100644 --- a/Apple/NetworkExtension/libburrow/libburrow.h +++ b/Apple/NetworkExtension/libburrow/libburrow.h @@ -1 +1 @@ - +int retrieve(); diff --git a/burrow/src/lib.rs b/burrow/src/lib.rs index 6abc28f..687d306 100644 --- a/burrow/src/lib.rs +++ b/burrow/src/lib.rs @@ -1 +1,32 @@ pub mod ensureroot; + +#[cfg(any(target_os = "linux", target_vendor = "apple"))] +use std::{ + mem, + os::fd::{AsRawFd, FromRawFd}, +}; + +use tun::TunInterface; + +// TODO Separate start and retrieve functions + +#[cfg(any(target_os = "linux", target_vendor = "apple"))] +#[no_mangle] +pub extern "C" fn retrieve() -> i32 { + let iface2 = (1..100) + .filter_map(|i| { + let iface = unsafe { TunInterface::from_raw_fd(i) }; + match iface.name() { + Ok(_name) => Some(iface), + Err(_) => { + mem::forget(iface); + None + } + } + }) + .next(); + match iface2 { + Some(iface) => iface.as_raw_fd(), + None => -1, + } +} diff --git a/burrow/src/main.rs b/burrow/src/main.rs index 40c54e6..4dace79 100644 --- a/burrow/src/main.rs +++ b/burrow/src/main.rs @@ -1,5 +1,11 @@ +use std::mem; +#[cfg(any(target_os = "linux", target_vendor = "apple"))] +use std::os::fd::FromRawFd; + use clap::{Args, Parser, Subcommand}; use tokio::io::Result; +#[cfg(any(target_os = "linux", target_vendor = "apple"))] +use burrow::retrieve; use tun::TunInterface; #[derive(Parser)] @@ -22,17 +28,41 @@ struct Cli { enum Commands { /// Start Burrow Start(StartArgs), + /// Retrieve the file descriptor of the tun interface + Retrieve(RetrieveArgs), } #[derive(Args)] struct StartArgs {} -async fn try_main() -> Result<()> { - burrow::ensureroot::ensure_root(); +#[derive(Args)] +struct RetrieveArgs {} +#[cfg(any(target_os = "linux", target_vendor = "apple"))] +async fn try_start() -> Result<()> { + burrow::ensureroot::ensure_root(); let iface = TunInterface::new()?; println!("{:?}", iface.name()); + let iface2 = retrieve(); + println!("{}", iface2); + Ok(()) +} +#[cfg(any(target_os = "linux", target_vendor = "apple"))] +async fn try_retrieve() -> Result<()> { + burrow::ensureroot::ensure_root(); + let iface2 = retrieve(); + println!("{}", iface2); + Ok(()) +} + +#[cfg(not(any(target_os = "linux", target_vendor = "apple")))] +async fn try_start() -> Result<()> { + Ok(()) +} + +#[cfg(not(any(target_os = "linux", target_vendor = "apple")))] +async fn try_retrieve() -> Result<()> { Ok(()) } @@ -43,7 +73,12 @@ async fn main() { let cli = Cli::parse(); match &cli.command { Commands::Start(..) => { - try_main().await.unwrap(); + try_start().await.unwrap(); + println!("FINISHED"); + } + Commands::Retrieve(..) => { + try_retrieve().await.unwrap(); + println!("FINISHED"); } } }