diff options
| author | Odd Stranne <odd@mullvad.net> | 2018-06-04 14:57:46 +0200 |
|---|---|---|
| committer | Odd Stranne <odd@mullvad.net> | 2018-06-18 08:45:15 +0200 |
| commit | 40802f371877f6050ec81c84d611dacb7c2298b8 (patch) | |
| tree | 02fa7272988ec0d242991bc8f75b0822890427bc | |
| parent | 73ee6af8a30640537ce329f52f67d6d4e0a15f1c (diff) | |
| download | mullvadvpn-40802f371877f6050ec81c84d611dacb7c2298b8.tar.xz mullvadvpn-40802f371877f6050ec81c84d611dacb7c2298b8.zip | |
Add netsh class with methods to update DNS settings
| -rw-r--r-- | windows/windns/src/windns/netsh.cpp | 159 | ||||
| -rw-r--r-- | windows/windns/src/windns/netsh.h | 26 |
2 files changed, 185 insertions, 0 deletions
diff --git a/windows/windns/src/windns/netsh.cpp b/windows/windns/src/windns/netsh.cpp new file mode 100644 index 0000000000..af65ace2a9 --- /dev/null +++ b/windows/windns/src/windns/netsh.cpp @@ -0,0 +1,159 @@ +#include "stdafx.h" +#include "netsh.h" +#include "libcommon/applicationrunner.h" +#include <sstream> +#include <stdexcept> + +namespace +{ + +void ValidateShellOut(common::ApplicationRunner &netsh) +{ + static const uint32_t TIMEOUT_TWO_SECONDS = 2000; + + DWORD returnCode; + + if (false == netsh.join(returnCode, TIMEOUT_TWO_SECONDS)) + { + throw std::runtime_error("'netsh' did not complete in a timely manner"); + } + + if (returnCode != 0) + { + std::stringstream ss; + + ss << "'netsh' failed the requested operation. Error: " << returnCode; + + throw std::runtime_error(ss.str()); + } +} + +} // anonymous namespace + +//static +void NetSh::SetIpv4PrimaryDns(uint32_t interfaceIndex, std::wstring server) +{ + // + // netsh interface ipv4 set dnsservers name="Ethernet 2" source=static address=8.8.8.8 validate=no + // + // Note: we're specifying the interface by index instead. + // + + std::wstringstream ss; + + ss << L"interface ipv4 set dnsservers name=" + << interfaceIndex + << L" source=static address=" + << server + << L" validate=no"; + + auto netsh = common::ApplicationRunner::StartWithoutConsole(L"netsh.exe", ss.str()); + + ValidateShellOut(*netsh); +} + +//static +void NetSh::SetIpv4SecondaryDns(uint32_t interfaceIndex, std::wstring server) +{ + // + // netsh interface ipv4 add dnsservers name="Ethernet 2" address=8.8.4.4 index=2 validate=no + // + // Note: we're specifying the interface by index instead. + // + + std::wstringstream ss; + + ss << L"interface ipv4 add dnsservers name=" + << interfaceIndex + << L" address=" + << server + << L" index=2 validate=no"; + + auto netsh = common::ApplicationRunner::StartWithoutConsole(L"netsh.exe", ss.str()); + + ValidateShellOut(*netsh); +} + +//static +void NetSh::SetIpv4Dhcp(uint32_t interfaceIndex) +{ + // + // netsh interface ipv4 set dnsservers name="Ethernet 2" source=dhcp + // + // Note: we're specifying the interface by index instead. + // + + std::wstringstream ss; + + ss << L"interface ipv4 set dnsservers name=" + << interfaceIndex + << L" source=dhcp"; + + auto netsh = common::ApplicationRunner::StartWithoutConsole(L"netsh.exe", ss.str()); + + ValidateShellOut(*netsh); +} + +//static +void NetSh::SetIpv6PrimaryDns(uint32_t interfaceIndex, std::wstring server) +{ + // + // netsh interface ipv6 set dnsservers name="Ethernet 2" source=static address=2001:4860:4860::8888 validate=no + // + // Note: we're specifying the interface by index instead. + // + + std::wstringstream ss; + + ss << L"interface ipv6 set dnsservers name=" + << interfaceIndex + << L" source=static address=" + << server + << L" validate=no"; + + auto netsh = common::ApplicationRunner::StartWithoutConsole(L"netsh.exe", ss.str()); + + ValidateShellOut(*netsh); +} + +//static +void NetSh::SetIpv6SecondaryDns(uint32_t interfaceIndex, std::wstring server) +{ + // + // netsh interface ipv6 add dnsservers name="Ethernet 2" address=2001:4860:4860::8844 index=2 validate=no + // + // Note: we're specifying the interface by index instead. + // + + std::wstringstream ss; + + ss << L"interface ipv6 add dnsservers name=" + << interfaceIndex + << L"address =" + << server + << L" index=2 validate=no"; + + auto netsh = common::ApplicationRunner::StartWithoutConsole(L"netsh.exe", ss.str()); + + ValidateShellOut(*netsh); +} + +//static +void NetSh::SetIpv6Dhcp(uint32_t interfaceIndex) +{ + // + // netsh interface ipv6 set dnsservers name="Ethernet 2" source=dhcp + // + // Note: we're specifying the interface by index instead. + // + + std::wstringstream ss; + + ss << L"interface ipv6 set dnsservers name=" + << interfaceIndex + << L" source=dhcp"; + + auto netsh = common::ApplicationRunner::StartWithoutConsole(L"netsh.exe", ss.str()); + + ValidateShellOut(*netsh); +} diff --git a/windows/windns/src/windns/netsh.h b/windows/windns/src/windns/netsh.h new file mode 100644 index 0000000000..d299cf6f87 --- /dev/null +++ b/windows/windns/src/windns/netsh.h @@ -0,0 +1,26 @@ +#pragma once + +#include <string> +#include <cstdint> + +class NetSh +{ +public: + + static void SetIpv4PrimaryDns(uint32_t interfaceIndex, std::wstring server); + + // + // Caveat: This sets the primary DNS server if there isn't already one. + // + static void SetIpv4SecondaryDns(uint32_t interfaceIndex, std::wstring server); + + static void SetIpv4Dhcp(uint32_t interfaceIndex); + + static void SetIpv6PrimaryDns(uint32_t interfaceIndex, std::wstring server); + static void SetIpv6SecondaryDns(uint32_t interfaceIndex, std::wstring server); + static void SetIpv6Dhcp(uint32_t interfaceIndex); + +private: + + NetSh(); +}; |
