69 lines
1.7 KiB
Rust
69 lines
1.7 KiB
Rust
|
use std::collections::BTreeSet;
|
||
|
|
||
|
use anyhow::Context as _;
|
||
|
use common::proc::Command;
|
||
|
use serde::Deserialize;
|
||
|
|
||
|
#[derive(Debug, Deserialize)]
|
||
|
struct Link {
|
||
|
ifname: String,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Deserialize)]
|
||
|
struct Addr {
|
||
|
addr_info: Vec<AddrInfo>,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Deserialize)]
|
||
|
struct AddrInfo {
|
||
|
local: String,
|
||
|
prefixlen: usize,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Deserialize)]
|
||
|
struct Route {
|
||
|
dst: String,
|
||
|
gateway: Option<String>,
|
||
|
}
|
||
|
|
||
|
pub fn get_link_names() -> anyhow::Result<BTreeSet<String>> {
|
||
|
let mut proc = Command::new("ip");
|
||
|
proc.args(["-j", "link"]);
|
||
|
let out = proc.try_spawn_to_json::<Vec<Link>>()?;
|
||
|
|
||
|
Ok(out.into_iter().map(|l| l.ifname).collect())
|
||
|
}
|
||
|
|
||
|
pub fn has_ipv6_address(dev: &str, addr: &str) -> anyhow::Result<bool> {
|
||
|
let mut proc = Command::new("ip");
|
||
|
proc.args(["-j", "-6", "addr", "show", dev]);
|
||
|
|
||
|
let out: Vec<Addr> = proc.try_spawn_to_json()?;
|
||
|
|
||
|
let idx = addr
|
||
|
.char_indices()
|
||
|
.find_map(|(idx, ch)| if ch == '/' { Some(idx) } else { None })
|
||
|
.expect("Address should contain prefixlen");
|
||
|
let prefixlen = &addr[idx + 1..];
|
||
|
let addr = &addr[..idx];
|
||
|
let prefixlen: usize = prefixlen
|
||
|
.parse()
|
||
|
.context("Ipv6 prefixlen was not a usize")?;
|
||
|
Ok(out.iter().any(|a| {
|
||
|
a.addr_info
|
||
|
.iter()
|
||
|
.any(|a| a.local == addr && a.prefixlen == prefixlen)
|
||
|
}))
|
||
|
}
|
||
|
|
||
|
pub fn has_default_route(dev: &str, gateway: &str) -> anyhow::Result<bool> {
|
||
|
let mut proc = Command::new("ip");
|
||
|
proc.args(["-j", "-6", "route", "show", "dev", dev]);
|
||
|
|
||
|
let out: Vec<Route> = proc.try_spawn_to_json()?;
|
||
|
|
||
|
Ok(out
|
||
|
.iter()
|
||
|
.any(|r| r.dst == "default" && r.gateway.as_deref().is_some_and(|gw| gw == gateway)))
|
||
|
}
|