summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOdd Stranne <odd@mullvad.net>2018-06-04 14:57:46 +0200
committerOdd Stranne <odd@mullvad.net>2018-06-18 08:45:15 +0200
commit40802f371877f6050ec81c84d611dacb7c2298b8 (patch)
tree02fa7272988ec0d242991bc8f75b0822890427bc
parent73ee6af8a30640537ce329f52f67d6d4e0a15f1c (diff)
downloadmullvadvpn-40802f371877f6050ec81c84d611dacb7c2298b8.tar.xz
mullvadvpn-40802f371877f6050ec81c84d611dacb7c2298b8.zip
Add netsh class with methods to update DNS settings
-rw-r--r--windows/windns/src/windns/netsh.cpp159
-rw-r--r--windows/windns/src/windns/netsh.h26
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();
+};