1

This question has been asked before here without any clear answer.

I am creating a Windows Service that needs to reconfigure the IPv4 and IPv6 DNS addresses for the active network interface. I got the following code from Kaj's answer to a similiar question which works fine for IPv4 addresses but WMI does not seem to support configuration of IPv6 DNS addresses:

private NetworkInterface GetActiveNetworkInterface()
{
    var Nic = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(
        a => a.OperationalStatus == OperationalStatus.Up &&
        (a.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || a.NetworkInterfaceType == NetworkInterfaceType.Ethernet) &&
        a.GetIPProperties().GatewayAddresses.Any(g => g.Address.AddressFamily.ToString() == "InterNetwork"));

    return Nic;
}

private void ConfigureDns(string[] dnsAddresses)
{
    var currentInterface = GetActiveNetworkInterface();
    if (currentInterface == null) return;

    ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
    ManagementObjectCollection moc = mc.GetInstances();
    foreach (ManagementObject mo in moc)
    {
        if ((bool)mo["IPEnabled"])
        {
            if (mo["Description"].ToString().Equals(currentInterface.Description))
            {
                ManagementBaseObject dnsMo = mo.GetMethodParameters("SetDNSServerSearchOrder");
                if (dnsMo != null)
                {
                    dnsMo["DNSServerSearchOrder"] = dnsAddresses;
                    mo.InvokeMethod("SetDNSServerSearchOrder", dnsMo, null);
                }
            }
        }
    }
}

public void SetDns(string ipv4PrimaryAddress, string ipv6PrimaryAddress)
{
    ConfigureDns(new string[] { ipv4PrimaryAddress, ipv6PrimaryAddress });
}

public void UnsetDns()
{
    ConfigureDns(null);
}

So instead I tried to execute netsh commands using System.Diagnostics.Process, as suggested by PaulB but this does not work due to the user privileges on my work pc:

public void SetDns(string ipv4PrimaryAddress, string ipv6PrimaryAddress)
{
    var currentNic = GetActiveNetworkInterface();
    string setIpv4DnsAddress = $"interface ipv4 set dns name=\"{currentNic.Name}\" static {ipv4PrimaryAddress}";
    string setIpv6DnsAddress = $"interface ipv6 set dns name=\"{currentNic.Name}\" static {ipv6PrimaryAddress}";

    RunCommand(setIpv4DnsAddress);
    RunCommand(setIpv6DnsAddress);
}

public void UnsetDns()
{
    var currentNic = GetActiveNetworkInterface();
    string setIpv4DnsAddress = $"interface ipv4 set dns name=\"{currentNic.Name}\" dhcp";
    string setIpv6DnsAddress = $"interface ipv6 set dns name=\"{currentNic.Name}\" dhcp";

    RunCommand(setIpv4DnsAddress);
    RunCommand(setIpv6DnsAddress);
}

private void RunCommand(string command)
{
    Process proc = new Process();
    proc.StartInfo.FileName = "netsh.exe";
    proc.StartInfo.UseShellExecute = true;
    proc.StartInfo.Verb = "runas";
    proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    proc.StartInfo.Arguments = command;
    proc.Start();
    proc.WaitForExit();
}

I am not able to set any network settings through the command line even if I start it as administrator, so this solution seems to be out of the question. The reason I am able to set the IPv4 settings with WMI is because I do it from within the Windows Service which is run using the LocalSystem account.

Is there any way to set both IPv4 and IPv6 DNS addresses from within my Windows Service?

Is there some new API for interacting Windows network adapter configurations?

Is there anything I have missed regarding WMI?

Is there a way to execute the netsh commands in a Process run as LocalSystem without having to enter any credentials?

Sources:

Setting Win32_NetworkAdapterConfiguration's "SetDNSServerSearchOrder" method using powershell in pure IPv6 machine

Win32_NetworkAdapterConfiguration class

SetDNSServerSearchOrder method of the Win32_NetworkAdapterConfiguration class

IPv6 and IPv4 Support in WMI

WMI/netsh to add DNS servers on network adapters

y.svanberg
  • 43
  • 5
  • 1
    A DNS server for IPv6 does not need an IPv6 address. A DNS server can serve both A and AAAA records, regardless if the IP version of the address.. – Ron Maupin Oct 08 '21 at 19:03
  • @RonMaupin Thank you for replying, the issue is that I am using a local DNS proxy that only seems to work reliably when configuring DNS with both IPv4 and IPv6 to localhost. – y.svanberg Oct 08 '21 at 20:02
  • A dual-stacked host needing an IPv6 name resolution is perfectly fine using a DNS server with only an IPv4 address to get the AAAA record, and vice versa. You probably want to ask about your proxy problem on [sf]. – Ron Maupin Oct 08 '21 at 20:15
  • @RonMaupin I have a webserver on a VPN with a domain name registered in a DNS on the same VPN. When I connect to the VPN and configure the DNS on my Windows 10 pc I am still not able to connect to the webserver because my browser wont use the configured DNS and therefore cant resolve the domain name. I am trying to resolve the issue by using a local DNS proxy with a rule that maps the domain name to the ip of the webserver. I have tried both Acrylic and DNSAgent but neither seem to work reliably without configuring IPv6 DNS to localhost. – y.svanberg Oct 09 '21 at 12:19
  • That sounds like a problem for [sf], not a programming problem. You should give the server jockeys a crack at it. – Ron Maupin Oct 09 '21 at 13:31

0 Answers0