69 lines
1.8 KiB
Rust
69 lines
1.8 KiB
Rust
use super::DnsState;
|
|
use anyhow::Result;
|
|
use std::net::IpAddr;
|
|
use std::os::windows::process::CommandExt;
|
|
use tracing::info;
|
|
|
|
const CREATE_NO_WINDOW: u32 = 0x0800_0000;
|
|
|
|
pub async fn set_dns(
|
|
interface: &str,
|
|
if_index: Option<u32>,
|
|
dns_servers: &[IpAddr],
|
|
state: &mut DnsState,
|
|
) -> Result<()> {
|
|
if dns_servers.is_empty() {
|
|
return Ok(());
|
|
}
|
|
|
|
let addrs: Vec<String> = dns_servers.iter().map(|ip| ip.to_string()).collect();
|
|
let addrs_str = addrs.join(",");
|
|
|
|
let iface_arg = if let Some(idx) = if_index {
|
|
format!("-InterfaceIndex {}", idx)
|
|
} else {
|
|
format!("-InterfaceAlias '{}'", interface)
|
|
};
|
|
|
|
info!("Setting DNS on {} to {}", interface, addrs_str);
|
|
|
|
let script = format!(
|
|
"Set-DnsClientServerAddress {} -ServerAddresses {}",
|
|
iface_arg, addrs_str
|
|
);
|
|
let status = std::process::Command::new("powershell")
|
|
.args(["-NoProfile", "-NonInteractive", "-Command", &script])
|
|
.creation_flags(CREATE_NO_WINDOW)
|
|
.status()?;
|
|
|
|
if !status.success() {
|
|
anyhow::bail!("PowerShell failed to set DNS on {}", interface);
|
|
}
|
|
|
|
state.configured = true;
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn restore(
|
|
interface: &str,
|
|
if_index: Option<u32>,
|
|
state: &mut DnsState,
|
|
) -> Result<()> {
|
|
info!("Restoring DNS on {} to automatic", interface);
|
|
|
|
let iface_arg = if let Some(idx) = if_index {
|
|
format!("-InterfaceIndex {}", idx)
|
|
} else {
|
|
format!("-InterfaceAlias '{}'", interface)
|
|
};
|
|
|
|
let script = format!("Set-DnsClientServerAddress {} -ResetServerAddresses", iface_arg);
|
|
let _ = std::process::Command::new("powershell")
|
|
.args(["-NoProfile", "-NonInteractive", "-Command", &script])
|
|
.creation_flags(CREATE_NO_WINDOW)
|
|
.status();
|
|
|
|
state.configured = false;
|
|
Ok(())
|
|
}
|