-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
105 additions
and
948 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,2 @@ | ||
pub mod file; | ||
pub mod search; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,5 @@ | ||
|
||
|
||
#[path = "fs.rs"] | ||
pub mod fs_api; | ||
pub mod settings; | ||
pub mod utils; | ||
pub mod wifi; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,214 +0,0 @@ | ||
use crate::utils::run_command; | ||
use crate::{Mode, Peer, PeerResource, WiFiInterface, UI}; | ||
use std::error::Error; | ||
use tokio::task; | ||
|
||
// stub | ||
pub struct WindowsHotspot { | ||
_inner: (), | ||
} | ||
|
||
fn is_hosting(peer: Peer, mode: Mode) -> bool { | ||
match peer { | ||
Peer::Android | Peer::IOS | Peer::MacOS => true, | ||
Peer::Windows => false, | ||
Peer::Linux => match mode { | ||
Mode::Send(_) => false, | ||
Mode::Receive(_) => true, | ||
}, | ||
} | ||
} | ||
|
||
pub async fn connect_to_peer<T: UI>( | ||
peer: Peer, | ||
mode: Mode, | ||
ssid: String, | ||
password: String, | ||
interface: WiFiInterface, | ||
ui: &T, | ||
) -> Result<PeerResource, Box<dyn Error>> { | ||
if is_hosting(peer, mode) { | ||
// start hotspot | ||
ui.output(&format!("Starting hotspot {}", ssid)); | ||
start_hotspot(&ssid, &password, &interface.0)?; | ||
Ok(PeerResource::LinuxHotspot) | ||
} else { | ||
// join hotspot and find gateway | ||
ui.output(&format!("Joining hotspot {}", ssid)); | ||
join_hotspot(&ssid, &password, &interface.0)?; | ||
loop { | ||
// println!("looking for gateway"); | ||
task::yield_now().await; | ||
match find_gateway(&interface.0) { | ||
Ok(gateway) => { | ||
if gateway != "" { | ||
return Ok(PeerResource::WifiClient(gateway)); | ||
} | ||
} | ||
Err(e) => Err(e)?, | ||
} | ||
tokio::time::sleep(tokio::time::Duration::from_millis(200)).await; | ||
} | ||
} | ||
} | ||
|
||
fn start_hotspot(ssid: &str, password: &str, interface: &str) -> Result<(), Box<dyn Error>> { | ||
let nmcli = "nmcli"; | ||
let commands = vec![ | ||
vec![ | ||
"con", | ||
"add", | ||
"type", | ||
"wifi", | ||
"ifname", | ||
&interface, | ||
"con-name", | ||
ssid, | ||
"autoconnect", | ||
"yes", | ||
"ssid", | ||
ssid, | ||
], | ||
vec![ | ||
"con", | ||
"modify", | ||
ssid, | ||
"802-11-wireless.mode", | ||
"ap", | ||
"ipv4.method", | ||
"shared", | ||
], | ||
vec!["con", "modify", ssid, "wifi-sec.key-mgmt", "wpa-psk"], | ||
// disable Protected Management Frames, which disables WPA3/SAE, which is necessary for M1 Macs to join Linux | ||
vec!["con", "modify", ssid, "wifi-sec.pmf", "disable"], | ||
// use AES, not TKIP | ||
vec!["con", "modify", ssid, "wifi-sec.pairwise", "ccmp"], | ||
vec!["con", "modify", ssid, "wifi-sec.group", "ccmp"], | ||
// use WPA2, not WPA | ||
vec!["con", "modify", ssid, "wifi-sec.proto", "rsn"], | ||
vec!["con", "modify", ssid, "wifi-sec.psk", password], | ||
vec!["con", "up", ssid], | ||
]; | ||
for command in commands { | ||
let res = run_command(nmcli, Some(command))?; | ||
if !res.status.success() { | ||
let stderr = String::from_utf8_lossy(&res.stderr); | ||
Err(format!("Could not start hotspot: {}", stderr))?; | ||
} | ||
// println!("output: {}", String::from_utf8_lossy(&res.stdout)); | ||
} | ||
Ok(()) | ||
} | ||
|
||
pub fn stop_hotspot(_peer_resource: Option<&PeerResource>, ssid: Option<&str>) -> Result<(), Box<dyn Error>> { | ||
if ssid.is_some() { | ||
let options = Some(vec!["connection", "delete", ssid.unwrap()]); | ||
let command_output = run_command("nmcli", options)?; | ||
if !command_output.status.success() { | ||
let stderr = String::from_utf8_lossy(&command_output.stderr); | ||
Err(format!("Error stopping hotspot: {}", stderr))?; | ||
} | ||
let output = String::from_utf8_lossy(&command_output.stdout); | ||
println!("Stop hotspot output: {}", output); | ||
} | ||
Ok(()) | ||
} | ||
|
||
fn join_hotspot(ssid: &str, password: &str, interface: &str) -> Result<(), Box<dyn Error>> { | ||
let nmcli = "nmcli"; | ||
let commands = vec![ | ||
vec![ | ||
"con", | ||
"add", | ||
"type", | ||
"wifi", | ||
"ifname", | ||
&interface, | ||
"con-name", | ||
ssid, | ||
"autoconnect", | ||
"yes", | ||
"ssid", | ||
ssid, | ||
], | ||
vec!["con", "modify", ssid, "wifi-sec.key-mgmt", "wpa-psk"], | ||
vec!["con", "modify", ssid, "wifi-sec.psk", password], | ||
vec!["con", "up", ssid], | ||
]; | ||
for command in commands { | ||
let res = run_command(nmcli, Some(command))?; | ||
if !res.status.success() { | ||
let stderr = String::from_utf8_lossy(&res.stderr); | ||
Err(format!("Error joining hotspot: {}", stderr))?; | ||
} | ||
// println!( | ||
// "join hotspot output: {}", | ||
// String::from_utf8_lossy(&res.stdout) | ||
// ); | ||
} | ||
Ok(()) | ||
} | ||
|
||
pub fn get_wifi_interfaces() -> Result<Vec<WiFiInterface>, Box<dyn Error>> { | ||
let command = "nmcli"; | ||
let options = vec!["-t", "device"]; | ||
let command_output = run_command(command, Some(options))?; | ||
let output = String::from_utf8_lossy(&command_output.stdout); | ||
let mut interfaces: Vec<WiFiInterface> = vec![]; | ||
output | ||
.lines() | ||
.map(|line| line.split(":").collect()) | ||
.for_each(|split_line: Vec<&str>| { | ||
if split_line[1] == "wifi" { | ||
interfaces.push(WiFiInterface(split_line[0].to_string(), "".to_string())); | ||
} | ||
}); | ||
Ok(interfaces) | ||
} | ||
|
||
fn find_gateway(interface: &str) -> Result<String, Box<dyn Error>> { | ||
let route_command = format!( | ||
"route -n | grep {} | grep UG | awk '{{print $2}}'", | ||
interface | ||
); // TODO: not the best but it will do? use regex in rust? | ||
let output = run_command("sh", Some(vec!["-c", &route_command]))?; | ||
let stdout = String::from_utf8_lossy(&output.stdout); | ||
Ok(stdout.trim().to_string()) | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use crate::PeerResource; | ||
|
||
use super::get_wifi_interfaces; | ||
|
||
#[test] | ||
fn start_and_stop_hotspot() { | ||
let ssid = "flyingCarpet_1234"; | ||
let password = "password"; | ||
let _pr = PeerResource::WifiClient("".to_string()); | ||
let interface = &get_wifi_interfaces().expect("no wifi interface present")[0].0; | ||
crate::network::start_hotspot(ssid, password, interface).unwrap(); | ||
std::thread::sleep(std::time::Duration::from_secs(5)); | ||
crate::network::stop_hotspot(Some(&_pr), Some(ssid)).unwrap(); | ||
} | ||
|
||
#[test] | ||
fn join_hotspot() { | ||
let ssid = ""; | ||
let password = ""; | ||
let pr = PeerResource::WifiClient("".to_string()); | ||
let interface = &get_wifi_interfaces().expect("no wifi interface present")[0].0; | ||
crate::network::join_hotspot(ssid, password, &interface).unwrap(); | ||
std::thread::sleep(std::time::Duration::from_secs(20)); | ||
crate::network::stop_hotspot(Some(&pr), Some(ssid)).unwrap(); | ||
} | ||
|
||
#[test] | ||
fn find_gateway() { | ||
let interface = &get_wifi_interfaces().expect("no wifi interface present")[0].0; | ||
let gateway = crate::network::find_gateway(interface).unwrap(); | ||
println!("interface: {}", interface); | ||
println!("gateway: {}", gateway); | ||
} | ||
} | ||
Oops, something went wrong.