summaryrefslogtreecommitdiffhomepage
path: root/windows
diff options
context:
space:
mode:
authorOdd Stranne <odd@mullvad.net>2019-11-08 17:19:51 +0100
committerOdd Stranne <odd@mullvad.net>2019-11-25 13:46:13 +0100
commitcfca573d8b8ee4ce50b9db2964381cbc1d01c26d (patch)
tree71ec5d50073b9eb4b093ffa6209c2b212e05e94d /windows
parent9a52ae1c7b04550a2a999a233a1d930a6e27cd36 (diff)
downloadmullvadvpn-cfca573d8b8ee4ce50b9db2964381cbc1d01c26d.tar.xz
mullvadvpn-cfca573d8b8ee4ce50b9db2964381cbc1d01c26d.zip
Add function to assign device IP addresses
Diffstat (limited to 'windows')
-rw-r--r--windows/winnet/src/winnet/interfaceutils.cpp20
-rw-r--r--windows/winnet/src/winnet/interfaceutils.h13
-rw-r--r--windows/winnet/src/winnet/winnet.cpp81
-rw-r--r--windows/winnet/src/winnet/winnet.def2
-rw-r--r--windows/winnet/src/winnet/winnet.h13
5 files changed, 122 insertions, 7 deletions
diff --git a/windows/winnet/src/winnet/interfaceutils.cpp b/windows/winnet/src/winnet/interfaceutils.cpp
index babe03eba6..202d9d0724 100644
--- a/windows/winnet/src/winnet/interfaceutils.cpp
+++ b/windows/winnet/src/winnet/interfaceutils.cpp
@@ -2,13 +2,8 @@
#include "interfaceutils.h"
#include "libcommon/error.h"
#include "libcommon/string.h"
-#include <vector>
#include <cstdint>
#include <algorithm>
-#include <winsock2.h>
-#include <iphlpapi.h>
-#include <windows.h>
-
//static
std::set<InterfaceUtils::NetworkAdapter> InterfaceUtils::GetAllAdapters()
@@ -112,3 +107,18 @@ std::wstring InterfaceUtils::GetTapInterfaceAlias()
throw std::runtime_error("Unable to find TAP adapter");
}
+
+//static
+void InterfaceUtils::AddDeviceIpAddresses(NET_LUID device, const std::vector<SOCKADDR_INET> &addresses)
+{
+ for (const auto &address : addresses)
+ {
+ MIB_UNICASTIPADDRESS_ROW row;
+ InitializeUnicastIpAddressEntry(&row);
+
+ row.InterfaceLuid = device;
+ row.Address = address;
+
+ THROW_UNLESS(NO_ERROR, CreateUnicastIpAddressEntry(&row), "Assign IP address on network interface");
+ }
+}
diff --git a/windows/winnet/src/winnet/interfaceutils.h b/windows/winnet/src/winnet/interfaceutils.h
index f5c31963c2..8ab1249a50 100644
--- a/windows/winnet/src/winnet/interfaceutils.h
+++ b/windows/winnet/src/winnet/interfaceutils.h
@@ -2,6 +2,17 @@
#include <string>
#include <set>
+#include <vector>
+
+// Secret include order to get most common networking structs/apis
+// And avoiding compilation errors
+#include <winsock2.h>
+#include <windows.h>
+#include <ws2def.h>
+#include <ws2ipdef.h>
+#include <iphlpapi.h>
+#include <netioapi.h>
+// end
class InterfaceUtils
{
@@ -35,4 +46,6 @@ public:
// Determines alias of primary TAP adapter.
//
static std::wstring GetTapInterfaceAlias();
+
+ static void AddDeviceIpAddresses(NET_LUID device, const std::vector<SOCKADDR_INET> &addresses);
};
diff --git a/windows/winnet/src/winnet/winnet.cpp b/windows/winnet/src/winnet/winnet.cpp
index 569df8f591..4240f6a706 100644
--- a/windows/winnet/src/winnet/winnet.cpp
+++ b/windows/winnet/src/winnet/winnet.cpp
@@ -141,6 +141,49 @@ void UnwindAndLog(MullvadLogSink logSink, void *logSinkContext, const std::excep
common::error::UnwindException(err, logger);
}
+std::vector<SOCKADDR_INET> ConvertAddresses(const WINNET_IP *addresses, uint32_t numAddresses)
+{
+ //
+ // This duplicates the same logic we have above.
+ // TODO: Fix when time permits.
+ //
+
+ std::vector<SOCKADDR_INET> out;
+ out.reserve(numAddresses);
+
+ for (uint32_t i = 0; i < numAddresses; ++i)
+ {
+ const WINNET_IP &from = addresses[i];
+ SOCKADDR_INET to{ 0 };
+
+ switch (from.type)
+ {
+ case WINNET_IP_TYPE_IPV4:
+ {
+ to.si_family = AF_INET;
+ to.Ipv4.sin_addr.s_addr = *reinterpret_cast<const uint32_t *>(from.bytes);
+
+ break;
+ }
+ case WINNET_IP_TYPE_IPV6:
+ {
+ to.si_family = AF_INET6;
+ memcpy(&to.Ipv6.sin6_addr.u.Byte, from.bytes, 16);
+
+ break;
+ }
+ default:
+ {
+ throw std::logic_error("Invalid address family in 'WINNET_IP' definition");
+ }
+ }
+
+ out.push_back(to);
+ }
+
+ return out;
+}
+
} //anonymous namespace
extern "C"
@@ -492,3 +535,41 @@ WinNet_DeactivateRouteManager(
}
}
+extern "C"
+WINNET_LINKAGE
+bool
+WINNET_API
+WinNet_AddDeviceIpAddresses(
+ const wchar_t *deviceAlias,
+ const WINNET_IP *addresses,
+ uint32_t numAddresses,
+ MullvadLogSink logSink,
+ void *logSinkContext
+)
+{
+ try
+ {
+ NET_LUID luid;
+
+ if (0 != ConvertInterfaceAliasToLuid(deviceAlias, &luid))
+ {
+ const auto ansiName = common::string::ToAnsi(deviceAlias);
+ const auto err = std::string("Unable to derive interface LUID from interface alias: ").append(ansiName);
+
+ throw std::runtime_error(err);
+ }
+
+ InterfaceUtils::AddDeviceIpAddresses(luid, ConvertAddresses(addresses, numAddresses));
+
+ return true;
+ }
+ catch (const std::exception &err)
+ {
+ UnwindAndLog(logSink, logSinkContext, err);
+ return false;
+ }
+ catch (...)
+ {
+ return false;
+ }
+}
diff --git a/windows/winnet/src/winnet/winnet.def b/windows/winnet/src/winnet/winnet.def
index 05738682e3..b23ae6c854 100644
--- a/windows/winnet/src/winnet/winnet.def
+++ b/windows/winnet/src/winnet/winnet.def
@@ -8,4 +8,4 @@ EXPORTS
WinNet_DeactivateConnectivityMonitor
WinNet_ActivateRouteManager
WinNet_DeactivateRouteManager
-
+ WinNet_AddDeviceIpAddresses
diff --git a/windows/winnet/src/winnet/winnet.h b/windows/winnet/src/winnet/winnet.h
index 1906e77ce6..7b4272fc72 100644
--- a/windows/winnet/src/winnet/winnet.h
+++ b/windows/winnet/src/winnet/winnet.h
@@ -91,7 +91,6 @@ WINNET_API
WinNet_DeactivateConnectivityMonitor(
);
-
enum WINNET_IP_TYPE
{
WINNET_IP_TYPE_IPV4 = 0,
@@ -177,3 +176,15 @@ WINNET_API
WinNet_DeactivateRouteManager(
);
+extern "C"
+WINNET_LINKAGE
+bool
+WINNET_API
+WinNet_AddDeviceIpAddresses(
+ const wchar_t *deviceAlias,
+ const WINNET_IP *addresses,
+ uint32_t numAddresses,
+ MullvadLogSink logSink,
+ void *logSinkContext
+);
+