53 lines
1.4 KiB
Rust
53 lines
1.4 KiB
Rust
use crate::{
|
|
config::Config,
|
|
netns::{DockerExecTransport, NsTransport, NsenterTransport, nsenter_available},
|
|
};
|
|
|
|
pub fn detect_interface(cfg: &Config, pid: u32, container: &str) -> anyhow::Result<String> {
|
|
let boxed: Box<dyn NsTransport> = if nsenter_available() {
|
|
Box::new(NsenterTransport { pid })
|
|
} else {
|
|
Box::new(DockerExecTransport {
|
|
container: container.to_string(),
|
|
})
|
|
};
|
|
|
|
detect_interface_with_transport(cfg, boxed.as_ref())
|
|
}
|
|
|
|
pub fn detect_interface_with_transport(
|
|
cfg: &Config,
|
|
transport: &dyn NsTransport,
|
|
) -> anyhow::Result<String> {
|
|
for ifname in &cfg.amnezia.interface_candidates {
|
|
if transport
|
|
.run(&["ip", "link", "show", ifname])
|
|
.is_ok()
|
|
{
|
|
return Ok(ifname.clone());
|
|
}
|
|
}
|
|
|
|
let links = transport.run(&["sh", "-c", "ip -o link show | awk -F': ' '{print $2}'"])?;
|
|
|
|
for raw in links.lines() {
|
|
let name = raw.trim();
|
|
for p in &cfg.amnezia.interface_patterns {
|
|
if glob_like_match(p, name) {
|
|
return Ok(name.to_string());
|
|
}
|
|
}
|
|
}
|
|
|
|
anyhow::bail!("unable to detect amnezia interface")
|
|
}
|
|
|
|
fn glob_like_match(pattern: &str, value: &str) -> bool {
|
|
if let Some(prefix) = pattern.strip_suffix('*') {
|
|
value.starts_with(prefix)
|
|
} else {
|
|
pattern == value
|
|
}
|
|
}
|
|
|