From 0fdfcccec1a2e6cbd70ec47a57a255fbe1e285e0 Mon Sep 17 00:00:00 2001 From: Thomas Karpiniec Date: Thu, 6 Jun 2024 21:14:17 +1000 Subject: [PATCH] Groundwork for watching iface changes on Apple via Network.framework --- Cargo.lock | 32 ++++++++++++++++++++++++++++++++ Cargo.toml | 3 ++- src/imp_mac.rs | 27 +++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 9af9c1b..632fe83 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,15 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -45,6 +54,7 @@ dependencies = [ name = "netwatcher" version = "0.1.0" dependencies = [ + "block2", "nix", "windows", ] @@ -62,6 +72,28 @@ dependencies = [ "memoffset", ] +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" + [[package]] name = "proc-macro2" version = "1.0.84" diff --git a/Cargo.toml b/Cargo.toml index 2615972..a1feb3c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,8 +5,9 @@ edition = "2021" [dependencies] -[target.'cfg(unix)'.dependencies] +[target.'cfg(target_vendor = "apple")'.dependencies] nix = { version = "0.29.0", features = ["net"] } +block2 = "0.5.1" [target.'cfg(windows)'.dependencies.windows] version = "0.56.0" diff --git a/src/imp_mac.rs b/src/imp_mac.rs index c4fc8d6..4ae0fc7 100644 --- a/src/imp_mac.rs +++ b/src/imp_mac.rs @@ -1,5 +1,7 @@ use std::{collections::HashMap, net::IpAddr}; +use block2::Block; +use nix::libc::c_long; use nix::{ifaddrs::getifaddrs, net::if_::if_nametoindex}; use crate::util::format_mac; @@ -60,6 +62,31 @@ pub(crate) fn list_interfaces() -> Result, Error> { Ok(ifs) } +// The "objc2" project aims to provide bindings for all frameworks but Network.framework +// isn't ready yet so let's kick it old-school + +struct nw_path_monitor; +type nw_path_monitor_t = *mut nw_path_monitor; +struct nw_path; +type nw_path_t = *mut nw_path; +struct dispatch_queue; +type dispatch_queue_t = *mut dispatch_queue; +const QOS_CLASS_BACKGROUND: usize = 0x09; + +#[link(name = "Network", kind = "framework")] +extern "C" { + fn nw_path_monitor_create() -> nw_path_monitor_t; + fn nw_path_monitor_set_update_handler( + monitor: nw_path_monitor_t, + update_handler: &Block, + ); + fn nw_path_monitor_set_queue(monitor: nw_path_monitor_t, queue: dispatch_queue_t); + fn nw_path_monitor_start(monitor: nw_path_monitor_t); + fn nw_path_monitor_cancel(monitor: nw_path_monitor_t); + + fn dispatch_get_global_queue(identifier: usize, flag: usize) -> dispatch_queue_t; +} + #[cfg(test)] mod test { use super::list_interfaces; -- 2.39.5