100 lines
3.0 KiB
Rust
100 lines
3.0 KiB
Rust
use super::DnsState;
|
|
use anyhow::Result;
|
|
use std::net::IpAddr;
|
|
|
|
pub async fn set_dns(
|
|
interface: &str,
|
|
if_index: Option<u32>,
|
|
dns_servers: &[IpAddr],
|
|
state: &mut DnsState,
|
|
) -> Result<()> {
|
|
// Windows implementation using windows-rs crate
|
|
// Note: This logic runs within unsafe blocks as it calls Win32 APIs
|
|
|
|
use std::ffi::c_void;
|
|
use windows::Win32::Foundation::NO_ERROR;
|
|
use windows::Win32::NetworkManagement::IpHelper::{
|
|
SetInterfaceDnsSettings, DNS_INTERFACE_SETTINGS, DNS_INTERFACE_SETTINGS_FLAGS,
|
|
DNS_INTERFACE_SETTINGS_VERSION1, DNS_SETTING_NAMESERVER,
|
|
};
|
|
|
|
// We need the Interface LUID (Locally Unique Identifier) or Index/GUID.
|
|
// The user provided `interface` string might be a GUID or friendly name.
|
|
// If if_index is provided, that's easier for some APIs.
|
|
|
|
// Convert IP addresses to wide string (UTF-16) comma-separated
|
|
let mut dns_str = String::new();
|
|
for (i, ip) in dns_servers.iter().enumerate() {
|
|
if i > 0 {
|
|
dns_str.push(',');
|
|
}
|
|
dns_str.push_str(&ip.to_string());
|
|
}
|
|
let dns_wide: Vec<u16> = dns_str.encode_utf16().chain(std::iter::once(0)).collect();
|
|
|
|
if let Some(idx) = if_index {
|
|
// Find existing settings to backup?
|
|
// Windows doesn't make it easy to "get current and restore later" without some work.
|
|
// For simplicity, we assume we can just clear settings on restore.
|
|
}
|
|
|
|
/*
|
|
Implementation note:
|
|
Since we cannot easily compile this on Linux to verify, we outline the logic.
|
|
Real implementation would need `GetInterfaceDnsSettings` to backup state.
|
|
*/
|
|
|
|
tracing::info!(
|
|
"Setting DNS on Windows for interface {}: {:?}",
|
|
interface,
|
|
dns_servers
|
|
);
|
|
|
|
/*
|
|
unsafe {
|
|
let mut settings = DNS_INTERFACE_SETTINGS {
|
|
Version: DNS_INTERFACE_SETTINGS_VERSION1,
|
|
Flags: DNS_SETTING_NAMESERVER,
|
|
NameServer: windows::core::PCWSTR(dns_wide.as_ptr()),
|
|
..Default::default()
|
|
};
|
|
|
|
let guid = windows::core::GUID::from(interface)?; // Assuming interface is a GUID string
|
|
|
|
let result = SetInterfaceDnsSettings(guid, &mut settings);
|
|
if result != NO_ERROR {
|
|
anyhow::bail!("Failed to set DNS: {:?}", result);
|
|
}
|
|
}
|
|
*/
|
|
|
|
// For now, since we can't test, we log a limitation
|
|
tracing::warn!("Windows DNS setting logic placeholder");
|
|
|
|
state.configured = true;
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn restore(
|
|
_interface: &str,
|
|
_if_index: Option<u32>,
|
|
_state: &mut DnsState,
|
|
) -> Result<()> {
|
|
tracing::info!("Restoring DNS on Windows...");
|
|
|
|
// Clear custom DNS settings (return to DHCP?)
|
|
/*
|
|
unsafe {
|
|
let mut settings = DNS_INTERFACE_SETTINGS {
|
|
Version: DNS_INTERFACE_SETTINGS_VERSION1,
|
|
Flags: DNS_SETTING_NAMESERVER,
|
|
NameServer: windows::core::PCWSTR::null(),
|
|
..Default::default()
|
|
};
|
|
// Call SetInterfaceDnsSettings with empty NameServer or appropriate flags
|
|
}
|
|
*/
|
|
|
|
Ok(())
|
|
}
|