68 lines
2.2 KiB
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
|
|
}
|