Files
AetherForge/agent/client/dns_windows.go

68 lines
2.2 KiB
Go

//go:build windows
package client
import (
"strings"
)
// probeDNS returns the DNS servers and search domains currently active on
// this machine's non-loopback network interfaces (Windows).
//
// Uses Get-DnsClientServerAddress (fast, built into Windows 8+/2012+).
// Falls back to ipconfig /all parsing if the CIM call fails (older OSes).
func probeDNS() *DNSConfig {
cfg := &DNSConfig{}
// Primary: CIM-based — deduped, IPv4+IPv6, excludes loopback adapters
const script = `
$addrs = Get-DnsClientServerAddress -ErrorAction SilentlyContinue |
Where-Object { $_.InterfaceAlias -notmatch 'Loopback|Npcap|VirtualBox|VMware' } |
Select-Object -ExpandProperty ServerAddresses |
Where-Object { $_ -ne '' -and $_ -ne '::1' -and $_ -ne '127.0.0.1' } |
Sort-Object -Unique
$search = (Get-DnsClient -ErrorAction SilentlyContinue |
Where-Object { $_.ConnectionSpecificSuffix -ne '' } |
Select-Object -ExpandProperty ConnectionSpecificSuffix |
Sort-Object -Unique) -join ','
[PSCustomObject]@{ servers = ($addrs -join ','); search = $search } | ConvertTo-Json -Compress
`
if out, err := silentOutput("powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-WindowStyle", "Hidden", "-Command", script); err == nil {
raw := strings.TrimSpace(string(out))
if idx := strings.LastIndex(raw, "{"); idx >= 0 {
raw = raw[idx:]
}
cfg = parseDNSJSON(raw)
}
// Fallback: ipconfig /all if the CIM call returned nothing
if len(cfg.Servers) == 0 {
cfg = parseDNSIpconfig()
}
return cfg
}
// parseDNSIpconfig extracts DNS servers from ipconfig /all output.
func parseDNSIpconfig() *DNSConfig {
cfg := &DNSConfig{}
out, err := silentOutput("ipconfig", "/all")
if err != nil {
return cfg
}
seen := map[string]bool{}
for _, line := range strings.Split(string(out), "\n") {
line = strings.TrimSpace(line)
if strings.HasPrefix(strings.ToLower(line), "dns servers") {
parts := strings.SplitN(line, ":", 2)
if len(parts) == 2 {
addr := strings.TrimSpace(parts[1])
if addr != "" && addr != "127.0.0.1" && addr != "::1" && !seen[addr] {
seen[addr] = true
cfg.Servers = append(cfg.Servers, addr)
}
}
}
}
return cfg
}