summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--osnet/WindowsEthernetTap.cpp9
-rw-r--r--osnet/WindowsRoutingTable.cpp176
-rw-r--r--osnet/WindowsRoutingTable.hpp49
-rw-r--r--windows/ZeroTierOne/ZeroTierOne.vcxproj6
-rw-r--r--windows/ZeroTierOne/ZeroTierOne.vcxproj.filters18
5 files changed, 253 insertions, 5 deletions
diff --git a/osnet/WindowsEthernetTap.cpp b/osnet/WindowsEthernetTap.cpp
index 8541ce7c..4408dc46 100644
--- a/osnet/WindowsEthernetTap.cpp
+++ b/osnet/WindowsEthernetTap.cpp
@@ -25,8 +25,6 @@
* LLC. Start here: http://www.zerotier.com/
*/
-#include "../Constants.hpp"
-
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@@ -42,9 +40,10 @@
#include <nldef.h>
#include <netioapi.h>
-#include "../EthernetTap.hpp"
-#include "../Utils.hpp"
-#include "../Mutex.hpp"
+#include "../node/Constants.hpp"
+#include "../node/EthernetTap.hpp"
+#include "../node/Utils.hpp"
+#include "../node/Mutex.hpp"
#include "WindowsEthernetTap.hpp"
#include "..\windows\TapDriver\tap-windows.h"
diff --git a/osnet/WindowsRoutingTable.cpp b/osnet/WindowsRoutingTable.cpp
index e69de29b..aa215fb0 100644
--- a/osnet/WindowsRoutingTable.cpp
+++ b/osnet/WindowsRoutingTable.cpp
@@ -0,0 +1,176 @@
+/*
+ * ZeroTier One - Global Peer to Peer Ethernet
+ * Copyright (C) 2011-2014 ZeroTier Networks LLC
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * --
+ *
+ * ZeroTier may be used and distributed under the terms of the GPLv3, which
+ * are available at: http://www.gnu.org/licenses/gpl-3.0.html
+ *
+ * If you would like to embed ZeroTier into a commercial application or
+ * redistribute it in a modified binary form, please contact ZeroTier Networks
+ * LLC. Start here: http://www.zerotier.com/
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <WinSock2.h>
+#include <Windows.h>
+#include <netioapi.h>
+#include <IPHlpApi.h>
+
+#include <vector>
+
+#include "../node/Constants.hpp"
+#include "WindowsRoutingTable.hpp"
+
+namespace ZeroTier {
+
+static void _copyInetAddressToSockaddrInet(const InetAddress &a,SOCKADDR_INET &sinet)
+{
+ memset(&sinet,0,sizeof(sinet));
+ if (a.isV4()) {
+ sinet.Ipv4.sin_addr.S_un.S_addr = *((const uint32_t *)a.rawIpData());
+ sinet.Ipv4.sin_family = AF_INET;
+ sinet.Ipv4.sin_port = htons(a.port());
+ } else if (a.isV6()) {
+ memcpy(sinet.Ipv6.sin6_addr.u.Byte,a.rawIpData(),16);
+ sinet.Ipv6.sin6_family = AF_INET6;
+ sinet.Ipv6.sin6_port = htons(a.port());
+ }
+}
+
+WindowsRoutingTable::WindowsRoutingTable()
+{
+}
+
+WindowsRoutingTable::~WindowsRoutingTable()
+{
+}
+
+std::vector<RoutingTable::Entry> WindowsRoutingTable::get(bool includeLinkLocal,bool includeLoopback) const
+{
+ std::vector<RoutingTable::Entry> entries;
+ PMIB_IPFORWARD_TABLE2 rtbl = NULL;
+
+ if (GetIpForwardTable2(AF_UNSPEC,&rtbl) != NO_ERROR)
+ return entries;
+ if (!rtbl)
+ return entries;
+
+ for(ULONG r=0;r<rtbl->NumEntries;++r) {
+ RoutingTable::Entry e;
+ switch(rtbl->Table[r].DestinationPrefix.Prefix.si_family) {
+ case AF_INET:
+ e.destination.set(&(rtbl->Table[r].DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr),4,rtbl->Table[r].DestinationPrefix.PrefixLength);
+ break;
+ case AF_INET6:
+ e.destination.set(rtbl->Table[r].DestinationPrefix.Prefix.Ipv6.sin6_addr.u.Byte,16,rtbl->Table[r].DestinationPrefix.PrefixLength);
+ break;
+ }
+ switch(rtbl->Table[r].NextHop.si_family) {
+ case AF_INET:
+ e.gateway.set(&(rtbl->Table[r].NextHop.Ipv4.sin_addr.S_un.S_addr),4,0);
+ break;
+ case AF_INET6:
+ e.gateway.set(rtbl->Table[r].NextHop.Ipv6.sin6_addr.u.Byte,16,0);
+ break;
+ }
+ e.deviceIndex = (int)rtbl->Table[r].InterfaceIndex;
+ e.metric = (int)rtbl->Table[r].Metric;
+ ConvertInterfaceLuidToNameA(&(rtbl->Table[r].InterfaceLuid),e.device,sizeof(e.device));
+ if ((e.destination)&&((includeLinkLocal)||(!e.destination.isLinkLocal()))&&((includeLoopback)||((!e.destination.isLoopback())&&(!e.gateway.isLoopback()))))
+ entries.push_back(e);
+ }
+
+ FreeMibTable(rtbl);
+ std::sort(entries.begin(),entries.end());
+ return entries;
+}
+
+RoutingTable::Entry WindowsRoutingTable::set(const InetAddress &destination,const InetAddress &gateway,const char *device,int metric)
+{
+ NET_LUID luid;
+ luid.Value = 0;
+ if (ConvertInterfaceNameToLuidA(device,&luid) != NO_ERROR)
+ return RoutingTable::Entry();
+
+ bool needCreate = true;
+ PMIB_IPFORWARD_TABLE2 rtbl = NULL;
+ if (GetIpForwardTable2(AF_UNSPEC,&rtbl) != NO_ERROR)
+ return RoutingTable::Entry();
+ if (!rtbl)
+ return RoutingTable::Entry();
+ for(ULONG r=0;r<rtbl->NumEntries;++r) {
+ if (rtbl->Table[r].InterfaceLuid.Value == luid.Value) {
+ InetAddress rdest;
+ switch(rtbl->Table[r].DestinationPrefix.Prefix.si_family) {
+ case AF_INET:
+ rdest.set(&(rtbl->Table[r].DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr),4,rtbl->Table[r].DestinationPrefix.PrefixLength);
+ break;
+ case AF_INET6:
+ rdest.set(rtbl->Table[r].DestinationPrefix.Prefix.Ipv6.sin6_addr.u.Byte,16,rtbl->Table[r].DestinationPrefix.PrefixLength);
+ break;
+ }
+ if (rdest == destination) {
+ if (metric >= 0) {
+ _copyInetAddressToSockaddrInet(gateway,rtbl->Table[r].NextHop);
+ rtbl->Table[r].Metric = metric;
+ SetIpForwardEntry2(&(rtbl->Table[r]));
+ needCreate = false;
+ } else {
+ DeleteIpForwardEntry2(&(rtbl->Table[r]));
+ FreeMibTable(rtbl);
+ return RoutingTable::Entry();
+ }
+ }
+ }
+ }
+ FreeMibTable(rtbl);
+
+ if ((metric >= 0)&&(needCreate)) {
+ MIB_IPFORWARD_ROW2 nr;
+ InitializeIpForwardEntry(&nr);
+ nr.InterfaceLuid.Value = luid.Value;
+ _copyInetAddressToSockaddrInet(destination,nr.DestinationPrefix.Prefix);
+ nr.DestinationPrefix.PrefixLength = destination.netmaskBits();
+ _copyInetAddressToSockaddrInet(gateway,nr.NextHop);
+ nr.Metric = metric;
+ nr.Protocol = MIB_IPPROTO_NETMGMT;
+ CreateIpForwardEntry2(&nr);
+ }
+
+ std::vector<RoutingTable::Entry> rtab(get(true,true));
+ std::vector<RoutingTable::Entry>::iterator bestEntry(rtab.end());
+ for(std::vector<RoutingTable::Entry>::iterator e(rtab.begin());e!=rtab.end();++e) {
+ if ((e->destination == destination)&&(e->gateway.ipsEqual(gateway))) {
+ if ((device)&&(device[0])) {
+ if (!strcmp(device,e->device)) {
+ if (metric == e->metric)
+ bestEntry = e;
+ }
+ }
+ if (bestEntry == rtab.end())
+ bestEntry = e;
+ }
+ }
+ if (bestEntry != rtab.end())
+ return *bestEntry;
+ return RoutingTable::Entry();
+}
+
+} // namespace ZeroTier
diff --git a/osnet/WindowsRoutingTable.hpp b/osnet/WindowsRoutingTable.hpp
index e69de29b..e371637a 100644
--- a/osnet/WindowsRoutingTable.hpp
+++ b/osnet/WindowsRoutingTable.hpp
@@ -0,0 +1,49 @@
+/*
+ * ZeroTier One - Global Peer to Peer Ethernet
+ * Copyright (C) 2011-2014 ZeroTier Networks LLC
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * --
+ *
+ * ZeroTier may be used and distributed under the terms of the GPLv3, which
+ * are available at: http://www.gnu.org/licenses/gpl-3.0.html
+ *
+ * If you would like to embed ZeroTier into a commercial application or
+ * redistribute it in a modified binary form, please contact ZeroTier Networks
+ * LLC. Start here: http://www.zerotier.com/
+ */
+
+#ifndef ZT_WINDOWSROUTINGTABLE_HPP
+#define ZT_WINDOWSROUTINGTABLE_HPP
+
+#include "../node/RoutingTable.hpp"
+
+namespace ZeroTier {
+
+/**
+ * Interface to Microsoft Windows (Vista or newer) routing table
+ */
+class WindowsRoutingTable : public RoutingTable
+{
+public:
+ WindowsRoutingTable();
+ virtual ~WindowsRoutingTable();
+ virtual std::vector<RoutingTable::Entry> get(bool includeLinkLocal = false,bool includeLoopback = false) const;
+ virtual RoutingTable::Entry set(const InetAddress &destination,const InetAddress &gateway,const char *device,int metric);
+};
+
+} // namespace ZeroTier
+
+#endif
diff --git a/windows/ZeroTierOne/ZeroTierOne.vcxproj b/windows/ZeroTierOne/ZeroTierOne.vcxproj
index fb67cec6..2a1b0325 100644
--- a/windows/ZeroTierOne/ZeroTierOne.vcxproj
+++ b/windows/ZeroTierOne/ZeroTierOne.vcxproj
@@ -52,6 +52,9 @@
<ClCompile Include="..\..\node\Topology.cpp" />
<ClCompile Include="..\..\node\UdpSocket.cpp" />
<ClCompile Include="..\..\node\Utils.cpp" />
+ <ClCompile Include="..\..\osnet\WindowsEthernetTap.cpp" />
+ <ClCompile Include="..\..\osnet\WindowsEthernetTapFactory.cpp" />
+ <ClCompile Include="..\..\osnet\WindowsRoutingTable.cpp" />
<ClCompile Include="ServiceBase.cpp" />
<ClCompile Include="ServiceInstaller.cpp" />
<ClCompile Include="ZeroTierOneService.cpp" />
@@ -109,6 +112,9 @@
<ClInclude Include="..\..\node\Topology.hpp" />
<ClInclude Include="..\..\node\UdpSocket.hpp" />
<ClInclude Include="..\..\node\Utils.hpp" />
+ <ClInclude Include="..\..\osnet\WindowsEthernetTap.hpp" />
+ <ClInclude Include="..\..\osnet\WindowsEthernetTapFactory.hpp" />
+ <ClInclude Include="..\..\osnet\WindowsRoutingTable.hpp" />
<ClInclude Include="..\..\version.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="ServiceBase.h" />
diff --git a/windows/ZeroTierOne/ZeroTierOne.vcxproj.filters b/windows/ZeroTierOne/ZeroTierOne.vcxproj.filters
index 4002bcec..b68854a1 100644
--- a/windows/ZeroTierOne/ZeroTierOne.vcxproj.filters
+++ b/windows/ZeroTierOne/ZeroTierOne.vcxproj.filters
@@ -123,6 +123,15 @@
<ClCompile Include="..\..\node\RoutingTable.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\osnet\WindowsEthernetTap.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\osnet\WindowsEthernetTapFactory.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\osnet\WindowsRoutingTable.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\ext\lz4\lz4.h">
@@ -296,6 +305,15 @@
<ClInclude Include="..\..\node\RoutingTable.hpp">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\osnet\WindowsEthernetTap.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\osnet\WindowsEthernetTapFactory.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\osnet\WindowsRoutingTable.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ZeroTierOne.rc">