Merge pull request 'Removed hardcoded interfaces from peach-network' (#47) from iface_agnostic into main
Reviewed-on: #47
This commit is contained in:
commit
b5ce677a5b
|
@ -2532,7 +2532,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "peach-network"
|
name = "peach-network"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"get_if_addrs",
|
"get_if_addrs",
|
||||||
"miniserde",
|
"miniserde",
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
[package]
|
[package]
|
||||||
name = "peach-network"
|
name = "peach-network"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
authors = ["Andrew Reid <glyph@mycelial.technology>"]
|
authors = ["Andrew Reid <glyph@mycelial.technology>"]
|
||||||
edition = "2018"
|
edition = "2021"
|
||||||
description = "Query and configure network interfaces."
|
description = "Query and configure network interfaces."
|
||||||
homepage = "https://opencollective.com/peachcloud"
|
homepage = "https://opencollective.com/peachcloud"
|
||||||
repository = "ihttps://git.coopcloud.tech/PeachCloud/peach-workspace/src/branch/main/peach-network"
|
repository = "ihttps://git.coopcloud.tech/PeachCloud/peach-workspace/src/branch/main/peach-network"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# peach-network
|
# peach-network
|
||||||
|
|
||||||
![Generic badge](https://img.shields.io/badge/version-0.3.0-<COLOR>.svg)
|
![Generic badge](https://img.shields.io/badge/version-0.4.0-<COLOR>.svg)
|
||||||
|
|
||||||
Network interface state query and modification library.
|
Network interface state query and modification library.
|
||||||
|
|
||||||
|
|
|
@ -156,10 +156,13 @@ pub enum NetworkError {
|
||||||
/// Interface.
|
/// Interface.
|
||||||
iface: String,
|
iface: String,
|
||||||
},
|
},
|
||||||
/// Failed to start ap0 service.
|
/// Failed to start systemctl service for a network interface.
|
||||||
StartAp0(IoError),
|
StartInterface {
|
||||||
/// Failed to start wlan0 service.
|
/// Underlying error source.
|
||||||
StartWlan0(IoError),
|
source: IoError,
|
||||||
|
/// Interface.
|
||||||
|
iface: String,
|
||||||
|
},
|
||||||
/// Failed to execute wpa-ctrl command.
|
/// Failed to execute wpa-ctrl command.
|
||||||
WpaCtrl(WpaError),
|
WpaCtrl(WpaError),
|
||||||
}
|
}
|
||||||
|
@ -196,8 +199,7 @@ impl std::error::Error for NetworkError {
|
||||||
NetworkError::WlanOperstate(ref source) => Some(source),
|
NetworkError::WlanOperstate(ref source) => Some(source),
|
||||||
NetworkError::Save => None,
|
NetworkError::Save => None,
|
||||||
NetworkError::Connect { .. } => None,
|
NetworkError::Connect { .. } => None,
|
||||||
NetworkError::StartWlan0(ref source) => Some(source),
|
NetworkError::StartInterface { ref source, .. } => Some(source),
|
||||||
NetworkError::StartAp0(ref source) => Some(source),
|
|
||||||
NetworkError::WpaCtrl(ref source) => Some(source),
|
NetworkError::WpaCtrl(ref source) => Some(source),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,8 +334,11 @@ impl std::fmt::Display for NetworkError {
|
||||||
id, iface
|
id, iface
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
NetworkError::StartWlan0(_) => write!(f, "Failed to start ap0 service"),
|
NetworkError::StartInterface { ref iface, .. } => write!(
|
||||||
NetworkError::StartAp0(_) => write!(f, "Failed to start wlan0 service"),
|
f,
|
||||||
|
"Failed to start systemctl service for {} interface",
|
||||||
|
iface
|
||||||
|
),
|
||||||
NetworkError::WpaCtrl(_) => write!(f, "WpaCtrl command failed"),
|
NetworkError::WpaCtrl(_) => write!(f, "WpaCtrl command failed"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
//! Switching between client mode and access point mode is achieved by making
|
//! Switching between client mode and access point mode is achieved by making
|
||||||
//! system calls to systemd (via `systemctl`). Further networking functionality
|
//! system calls to systemd (via `systemctl`). Further networking functionality
|
||||||
//! is provided by making system calls to retrieve interface state and write
|
//! is provided by making system calls to retrieve interface state and write
|
||||||
//! access point credentials to `wpa_supplicant-wlan0.conf`.
|
//! access point credentials to `wpa_supplicant-<wlan_iface>.conf`.
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
fs::OpenOptions,
|
fs::OpenOptions,
|
||||||
|
@ -478,36 +478,22 @@ pub fn traffic(iface: &str) -> Result<Option<Traffic>, NetworkError> {
|
||||||
|
|
||||||
/* SET - Methods for modifying state */
|
/* SET - Methods for modifying state */
|
||||||
|
|
||||||
/// Activate wireless access point.
|
/// Start network interface service.
|
||||||
///
|
///
|
||||||
/// A `systemctl `command is invoked which starts the `ap0` interface service.
|
/// A `systemctl `command is invoked which starts the service for the given
|
||||||
/// If the command executes successfully, an `Ok` `Result` type is returned.
|
/// network interface. If the command executes successfully, an `Ok` `Result`
|
||||||
/// In the event of an error, a `NetworkError` is returned in the `Result`.
|
/// type is returned. In the event of an error, a `NetworkError` is returned
|
||||||
pub fn activate_ap() -> Result<(), NetworkError> {
|
/// in the `Result`.
|
||||||
// start the ap0 interface service
|
pub fn start_iface_service(iface: String) -> Result<(), NetworkError> {
|
||||||
|
let iface_service = format!("wpa_supplicant@{}.service", &iface);
|
||||||
|
|
||||||
|
// start the interface service
|
||||||
Command::new("sudo")
|
Command::new("sudo")
|
||||||
.arg("/usr/bin/systemctl")
|
.arg("/usr/bin/systemctl")
|
||||||
.arg("start")
|
.arg("start")
|
||||||
.arg("wpa_supplicant@ap0.service")
|
.arg(iface_service)
|
||||||
.output()
|
.output()
|
||||||
.map_err(NetworkError::StartAp0)?;
|
.map_err(|source| NetworkError::StartInterface { source, iface })?;
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Activate wireless client.
|
|
||||||
///
|
|
||||||
/// A `systemctl` command is invoked which starts the `wlan0` interface service.
|
|
||||||
/// If the command executes successfully, an `Ok` `Result` type is returned.
|
|
||||||
/// In the event of an error, a `NetworkError` is returned in the `Result`.
|
|
||||||
pub fn activate_client() -> Result<(), NetworkError> {
|
|
||||||
// start the wlan0 interface service
|
|
||||||
Command::new("sudo")
|
|
||||||
.arg("/usr/bin/systemctl")
|
|
||||||
.arg("start")
|
|
||||||
.arg("wpa_supplicant@wlan0.service")
|
|
||||||
.output()
|
|
||||||
.map_err(NetworkError::StartWlan0)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -516,13 +502,15 @@ pub fn activate_client() -> Result<(), NetworkError> {
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
|
/// * `wlan_iface` - A local wireless interface.
|
||||||
/// * `wifi` - An instance of the `WiFi` `struct` with fields `ssid` and `pass`
|
/// * `wifi` - An instance of the `WiFi` `struct` with fields `ssid` and `pass`
|
||||||
///
|
///
|
||||||
/// If configuration parameters are successfully generated from the provided
|
/// If configuration parameters are successfully generated from the provided
|
||||||
/// SSID and password and appended to `wpa_supplicant-wlan0.conf`, an `Ok`
|
/// SSID and password and appended to `wpa_supplicant-<wlan_iface>.conf` (where
|
||||||
/// `Result` type is returned. In the event of an error, a `NetworkError` is
|
/// `<wlan_iface>` is the provided interface parameter), an `Ok` `Result` type
|
||||||
/// returned in the `Result`.
|
/// is returned. In the event of an error, a `NetworkError` is returned in the
|
||||||
pub fn add(wifi: &WiFi) -> Result<(), NetworkError> {
|
/// `Result`.
|
||||||
|
pub fn add(wlan_iface: String, wifi: &WiFi) -> Result<(), NetworkError> {
|
||||||
// generate configuration based on provided ssid & password
|
// generate configuration based on provided ssid & password
|
||||||
let output = Command::new("wpa_passphrase")
|
let output = Command::new("wpa_passphrase")
|
||||||
.arg(&wifi.ssid)
|
.arg(&wifi.ssid)
|
||||||
|
@ -538,12 +526,12 @@ pub fn add(wifi: &WiFi) -> Result<(), NetworkError> {
|
||||||
let mut wpa_details = "\n".as_bytes().to_vec();
|
let mut wpa_details = "\n".as_bytes().to_vec();
|
||||||
wpa_details.extend(&*(output.stdout));
|
wpa_details.extend(&*(output.stdout));
|
||||||
|
|
||||||
// append wpa_passphrase output to wpa_supplicant-wlan0.conf if successful
|
let wlan_config = format!("/etc/wpa_supplicant/wpa_supplicant-{}.conf", wlan_iface);
|
||||||
|
|
||||||
|
// append wpa_passphrase output to wpa_supplicant-<wlan_iface>.conf if successful
|
||||||
if output.status.success() {
|
if output.status.success() {
|
||||||
// open file in append mode
|
// open file in append mode
|
||||||
let file = OpenOptions::new()
|
let file = OpenOptions::new().append(true).open(wlan_config);
|
||||||
.append(true)
|
|
||||||
.open("/etc/wpa_supplicant/wpa_supplicant-wlan0.conf");
|
|
||||||
|
|
||||||
let _file = match file {
|
let _file = match file {
|
||||||
// if file exists & open succeeds, write wifi configuration
|
// if file exists & open succeeds, write wifi configuration
|
||||||
|
@ -563,33 +551,35 @@ pub fn add(wifi: &WiFi) -> Result<(), NetworkError> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deploy the access point if the `wlan0` interface is `up` without an active
|
/// Deploy an access point if the wireless interface is `up` without an active
|
||||||
/// connection.
|
/// connection.
|
||||||
///
|
///
|
||||||
/// The status of the `wlan0` service and the state of the `wlan0` interface
|
/// The status of the wireless service and the state of the wireless interface
|
||||||
/// are checked. If the service is active but the interface is down (ie. not
|
/// are checked. If the service is active but the interface is down (ie. not
|
||||||
/// currently connected to an access point), then the access point is activated
|
/// currently connected to an access point), then the access point is activated
|
||||||
/// by calling the `activate_ap()` function.
|
/// by calling the `activate_ap()` function.
|
||||||
pub fn check_iface() -> Result<(), NetworkError> {
|
pub fn check_iface(wlan_iface: String, ap_iface: String) -> Result<(), NetworkError> {
|
||||||
|
let wpa_service = format!("wpa_supplicant@{}.service", &wlan_iface);
|
||||||
|
|
||||||
// returns 0 if the service is currently active
|
// returns 0 if the service is currently active
|
||||||
let wlan0_status = Command::new("/usr/bin/systemctl")
|
let wlan_status = Command::new("/usr/bin/systemctl")
|
||||||
.arg("is-active")
|
.arg("is-active")
|
||||||
.arg("wpa_supplicant@wlan0.service")
|
.arg(wpa_service)
|
||||||
.status()
|
.status()
|
||||||
.map_err(NetworkError::WlanState)?;
|
.map_err(NetworkError::WlanState)?;
|
||||||
|
|
||||||
// returns the current state of the wlan0 interface
|
// returns the current state of the wlan interface
|
||||||
let iface_state = state("wlan0")?;
|
let iface_state = state(&wlan_iface)?;
|
||||||
|
|
||||||
// returns down if the interface is not currently connected to an ap
|
// returns down if the interface is not currently connected to an ap
|
||||||
let wlan0_state = match iface_state {
|
let wlan_state = match iface_state {
|
||||||
Some(state) => state,
|
Some(state) => state,
|
||||||
None => "error".to_string(),
|
None => "error".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// if wlan0 is active but not connected, start the ap0 service
|
// if wlan is active but not connected, start the ap service
|
||||||
if wlan0_status.success() && wlan0_state == "down" {
|
if wlan_status.success() && wlan_state == "down" {
|
||||||
activate_ap()?
|
start_iface_service(ap_iface)?
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in New Issue