From 93ae9755444c0475ffb59e5d8455d7c71dc6c2bf Mon Sep 17 00:00:00 2001 From: chlebon Date: Sat, 23 Nov 2024 02:58:41 +0100 Subject: [PATCH] feat: update wifiscanner for macOS v14.4> --- libs/wifiscanner/Cargo.lock | 189 +++++++++++++++++++++++++++++- libs/wifiscanner/Cargo.toml | 2 + libs/wifiscanner/src/sys/macos.rs | 65 +++++++++- 3 files changed, 252 insertions(+), 4 deletions(-) diff --git a/libs/wifiscanner/Cargo.lock b/libs/wifiscanner/Cargo.lock index b5aa180..c2f9fa8 100644 --- a/libs/wifiscanner/Cargo.lock +++ b/libs/wifiscanner/Cargo.lock @@ -26,6 +26,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "anyhow" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" + [[package]] name = "backtrace" version = "0.3.74" @@ -41,6 +47,12 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bytes" version = "1.7.2" @@ -53,24 +65,55 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "either" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "gimli" version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +[[package]] +name = "hashbrown" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" + [[package]] name = "hermit-abi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "itertools" version = "0.10.5" @@ -80,6 +123,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + [[package]] name = "libc" version = "0.2.159" @@ -113,6 +162,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "object" version = "0.36.4" @@ -122,12 +177,43 @@ dependencies = [ "memchr", ] +[[package]] +name = "os-version" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a8a1fed76ac765e39058ca106b6229a93c5a60292a1bd4b602ce2be11e1c020" +dependencies = [ + "anyhow", + "plist", + "uname", + "winapi", +] + [[package]] name = "pin-project-lite" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +[[package]] +name = "plist" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" +dependencies = [ + "base64", + "indexmap", + "quick-xml", + "serde", + "time", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "proc-macro2" version = "1.0.86" @@ -137,6 +223,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quick-xml" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.37" @@ -181,6 +276,26 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "serde" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -192,15 +307,46 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tokio" version = "1.40.0" @@ -233,8 +379,19 @@ name = "tokio-wifiscanner" version = "0.2.1" dependencies = [ "itertools", + "os-version", "regex", "tokio", + "version-compare", +] + +[[package]] +name = "uname" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8" +dependencies = [ + "libc", ] [[package]] @@ -243,12 +400,40 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-sys" version = "0.52.0" diff --git a/libs/wifiscanner/Cargo.toml b/libs/wifiscanner/Cargo.toml index 7c00f76..14948fd 100644 --- a/libs/wifiscanner/Cargo.toml +++ b/libs/wifiscanner/Cargo.toml @@ -18,6 +18,8 @@ path = "src/examples/main.rs" regex = "1" itertools = "0.10.0" tokio = { version = "1.40.0", features = ["process"] } +os-version = "0.2.0" +version-compare = "0.2.0" [dev-dependencies] regex = "1" diff --git a/libs/wifiscanner/src/sys/macos.rs b/libs/wifiscanner/src/sys/macos.rs index 80780e6..8ce5eae 100644 --- a/libs/wifiscanner/src/sys/macos.rs +++ b/libs/wifiscanner/src/sys/macos.rs @@ -1,14 +1,75 @@ use crate::{Error, Result, Wifi}; +use os_version::{self, MacOS}; +use regex::Regex; +use tokio::process::Command; +use version_compare::{compare_to, Cmp}; /// Returns a list of WiFi hotspots in your area - (OSX/MacOS) uses `airport` pub(crate) async fn scan() -> Result> { - use tokio::process::Command; + let mac_version = match os_version::MacOS::detect() { + Ok(version) => version, + Err(_) => MacOS { + version: "0.0.0".to_string(), + }, + }; + + let r = match compare_to(mac_version.version, "14.4", Cmp::Ge) { + Ok(cmp) => { + if cmp { + scan_system_profile().await + } else { + scan_airport().await + } + } + Err(_) => scan_airport().await, + }; + + return r; +} + +async fn scan_system_profile() -> Result> { + let output = Command::new("system_profiler") + .arg("SPAirPortDataType") + .output() + .await + .map_err(|_| Error::CommandNotFound)?; + let data = String::from_utf8_lossy(&output.stdout); + parse_system_profile(&data) +} + +fn parse_system_profile(network_list: &str) -> Result> { + let mut wifis: Vec = Vec::new(); + + let re = Regex::new(r"(?m)^\s+([^\n]+):\n\s+PHY Mode: [^\n]+\n\s+Channel: ([^\n]+)\n\s+.*?\n\s+Security: ([^\n]+)\n\s+Signal / Noise: ([^\n]+)") + .unwrap(); + for w in re.captures_iter(network_list) { + + let ssid = w[1].trim().to_string(); + let channel = w[2].split('(').next().unwrap().trim().to_string(); + let security = w[3].trim().to_string(); + let signal = w[4].split('/').next().unwrap().trim().to_string(); + + let wifi = Wifi{ + ssid, + channel, + signal_level: signal.split(' ').next().unwrap().trim().to_string(), + security, + mac: String::new(), + }; + wifis.push(wifi); + } + + Ok(wifis) +} + +async fn scan_airport() -> Result> { let output = Command::new( "/System/Library/PrivateFrameworks/Apple80211.\ framework/Versions/Current/Resources/airport", ) .arg("-s") - .output().await + .output() + .await .map_err(|_| Error::CommandNotFound)?; let data = String::from_utf8_lossy(&output.stdout);