#[cfg(target_os = "linux")]
pub fn is_root() -> bool {
std::fs::read_to_string("/proc/self/status")
.map(|s| {
s.lines()
.find(|l| l.starts_with("Uid:"))
.and_then(|l| l.split_whitespace().nth(2))
.map(|uid| uid == "0")
.unwrap_or(false)
})
.unwrap_or(false)
}
#[cfg(target_os = "linux")]
pub fn iface_exists(iface: &str) -> bool {
let needle = format!("{iface}:");
std::fs::read_to_string("/proc/net/dev")
.map(|s| s.lines().any(|line| line.trim_start().starts_with(&needle)))
.unwrap_or(false)
}
#[cfg(target_os = "linux")]
pub fn has_route(ip: &str, dev: &str) -> bool {
std::process::Command::new("/usr/sbin/ip")
.args(["route", "show", ip])
.output()
.map(|o| {
let out = String::from_utf8_lossy(&o.stdout);
out.contains(dev)
})
.unwrap_or(false)
}
#[cfg(target_os = "linux")]
pub fn get_peer_addr(iface: &str) -> Option<String> {
let output = std::process::Command::new("/usr/sbin/ip")
.args(["addr", "show", "dev", iface])
.output()
.ok()?;
let out = String::from_utf8_lossy(&output.stdout);
for line in out.lines() {
if let Some(idx) = line.find("peer ") {
let rest = &line[idx + 5..];
return rest.split('/').next().map(String::from);
}
}
None
}