diff options
author | Adam Ierymenko <adam.ierymenko@zerotier.com> | 2014-07-28 09:08:56 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@zerotier.com> | 2014-07-28 09:08:56 -0700 |
commit | f0199d67703277ee9891115bb618d7665ff7c32a (patch) | |
tree | 14ef947da9d8029223aa17cbb67c1a064e3a254a | |
parent | f2d372545a9ba8fae54f0da4bf40569dff81f6b3 (diff) | |
download | infinitytier-f0199d67703277ee9891115bb618d7665ff7c32a.tar.gz infinitytier-f0199d67703277ee9891115bb618d7665ff7c32a.zip |
Windows routing table interface (untested).
-rw-r--r-- | osnet/WindowsEthernetTap.cpp | 9 | ||||
-rw-r--r-- | osnet/WindowsRoutingTable.cpp | 176 | ||||
-rw-r--r-- | osnet/WindowsRoutingTable.hpp | 49 | ||||
-rw-r--r-- | windows/ZeroTierOne/ZeroTierOne.vcxproj | 6 | ||||
-rw-r--r-- | windows/ZeroTierOne/ZeroTierOne.vcxproj.filters | 18 |
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"> |