From d76133046518e71025000ec6322f5b8f1c98529f Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 8 Apr 2015 18:47:06 -0700 Subject: No more tap factories. --- attic/BSDEthernetTapFactory.cpp | 78 +++++++++++++++++ attic/BSDEthernetTapFactory.hpp | 63 ++++++++++++++ attic/LinuxEthernetTapFactory.cpp | 74 ++++++++++++++++ attic/LinuxEthernetTapFactory.hpp | 63 ++++++++++++++ attic/OSXEthernetTapFactory.cpp | 122 +++++++++++++++++++++++++++ attic/OSXEthernetTapFactory.hpp | 76 +++++++++++++++++ attic/WindowsEthernetTapFactory.cpp | 162 ++++++++++++++++++++++++++++++++++++ attic/WindowsEthernetTapFactory.hpp | 90 ++++++++++++++++++++ make-freebsd.mk | 4 +- make-linux.mk | 4 +- make-mac.mk | 4 +- osdep/BSDEthernetTapFactory.cpp | 78 ----------------- osdep/BSDEthernetTapFactory.hpp | 63 -------------- osdep/LinuxEthernetTapFactory.cpp | 74 ---------------- osdep/LinuxEthernetTapFactory.hpp | 63 -------------- osdep/OSXEthernetTapFactory.cpp | 122 --------------------------- osdep/OSXEthernetTapFactory.hpp | 76 ----------------- osdep/WindowsEthernetTapFactory.cpp | 162 ------------------------------------ osdep/WindowsEthernetTapFactory.hpp | 90 -------------------- 19 files changed, 734 insertions(+), 734 deletions(-) create mode 100644 attic/BSDEthernetTapFactory.cpp create mode 100644 attic/BSDEthernetTapFactory.hpp create mode 100644 attic/LinuxEthernetTapFactory.cpp create mode 100644 attic/LinuxEthernetTapFactory.hpp create mode 100644 attic/OSXEthernetTapFactory.cpp create mode 100644 attic/OSXEthernetTapFactory.hpp create mode 100644 attic/WindowsEthernetTapFactory.cpp create mode 100644 attic/WindowsEthernetTapFactory.hpp delete mode 100644 osdep/BSDEthernetTapFactory.cpp delete mode 100644 osdep/BSDEthernetTapFactory.hpp delete mode 100644 osdep/LinuxEthernetTapFactory.cpp delete mode 100644 osdep/LinuxEthernetTapFactory.hpp delete mode 100644 osdep/OSXEthernetTapFactory.cpp delete mode 100644 osdep/OSXEthernetTapFactory.hpp delete mode 100644 osdep/WindowsEthernetTapFactory.cpp delete mode 100644 osdep/WindowsEthernetTapFactory.hpp diff --git a/attic/BSDEthernetTapFactory.cpp b/attic/BSDEthernetTapFactory.cpp new file mode 100644 index 00000000..79ae73f7 --- /dev/null +++ b/attic/BSDEthernetTapFactory.cpp @@ -0,0 +1,78 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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 . + * + * -- + * + * 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 +#include +#include + +#include "BSDEthernetTapFactory.hpp" +#include "BSDEthernetTap.hpp" + +namespace ZeroTier { + +BSDEthernetTapFactory::BSDEthernetTapFactory() +{ +} + +BSDEthernetTapFactory::~BSDEthernetTapFactory() +{ + Mutex::Lock _l(_devices_m); + for(std::vector::iterator d(_devices.begin());d!=_devices.end();++d) + delete *d; +} + +EthernetTap *BSDEthernetTapFactory::open( + const MAC &mac, + unsigned int mtu, + unsigned int metric, + uint64_t nwid, + const char *desiredDevice, + const char *friendlyName, + void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), + void *arg) +{ + Mutex::Lock _l(_devices_m); + EthernetTap *t = new BSDEthernetTap(mac,mtu,metric,nwid,desiredDevice,friendlyName,handler,arg); + _devices.push_back(t); + return t; +} + +void BSDEthernetTapFactory::close(EthernetTap *tap,bool destroyPersistentDevices) +{ + { + Mutex::Lock _l(_devices_m); + for(std::vector::iterator d(_devices.begin());d!=_devices.end();++d) { + if (*d == tap) { + _devices.erase(d); + break; + } + } + } + delete tap; +} + +} // namespace ZeroTier diff --git a/attic/BSDEthernetTapFactory.hpp b/attic/BSDEthernetTapFactory.hpp new file mode 100644 index 00000000..5c681fb4 --- /dev/null +++ b/attic/BSDEthernetTapFactory.hpp @@ -0,0 +1,63 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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 . + * + * -- + * + * 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_BSDETHERNETTAPFACTORY_HPP +#define ZT_BSDETHERNETTAPFACTORY_HPP + +#include +#include + +#include "EthernetTapFactory.hpp" +#include "../node/Mutex.hpp" + +namespace ZeroTier { + +class BSDEthernetTapFactory : public EthernetTapFactory +{ +public: + BSDEthernetTapFactory(); + virtual ~BSDEthernetTapFactory(); + + virtual EthernetTap *open( + const MAC &mac, + unsigned int mtu, + unsigned int metric, + uint64_t nwid, + const char *desiredDevice, + const char *friendlyName, + void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), + void *arg); + virtual void close(EthernetTap *tap,bool destroyPersistentDevices); + +private: + std::vector _devices; + Mutex _devices_m; +}; + +} // namespace ZeroTier + +#endif diff --git a/attic/LinuxEthernetTapFactory.cpp b/attic/LinuxEthernetTapFactory.cpp new file mode 100644 index 00000000..014c6514 --- /dev/null +++ b/attic/LinuxEthernetTapFactory.cpp @@ -0,0 +1,74 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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 . + * + * -- + * + * 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 "LinuxEthernetTapFactory.hpp" +#include "LinuxEthernetTap.hpp" + +namespace ZeroTier { + +LinuxEthernetTapFactory::LinuxEthernetTapFactory() +{ +} + +LinuxEthernetTapFactory::~LinuxEthernetTapFactory() +{ + Mutex::Lock _l(_devices_m); + for(std::vector::iterator d(_devices.begin());d!=_devices.end();++d) + delete *d; +} + +EthernetTap *LinuxEthernetTapFactory::open( + const MAC &mac, + unsigned int mtu, + unsigned int metric, + uint64_t nwid, + const char *desiredDevice, + const char *friendlyName, + void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), + void *arg) +{ + Mutex::Lock _l(_devices_m); + EthernetTap *t = new LinuxEthernetTap(mac,mtu,metric,nwid,desiredDevice,friendlyName,handler,arg); + _devices.push_back(t); + return t; +} + +void LinuxEthernetTapFactory::close(EthernetTap *tap,bool destroyPersistentDevices) +{ + { + Mutex::Lock _l(_devices_m); + for(std::vector::iterator d(_devices.begin());d!=_devices.end();++d) { + if (*d == tap) { + _devices.erase(d); + break; + } + } + } + delete tap; +} + +} // namespace ZeroTier diff --git a/attic/LinuxEthernetTapFactory.hpp b/attic/LinuxEthernetTapFactory.hpp new file mode 100644 index 00000000..e61863ed --- /dev/null +++ b/attic/LinuxEthernetTapFactory.hpp @@ -0,0 +1,63 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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 . + * + * -- + * + * 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_LINUXETHERNETTAPFACTORY_HPP +#define ZT_LINUXETHERNETTAPFACTORY_HPP + +#include +#include + +#include "../node/EthernetTapFactory.hpp" +#include "../node/Mutex.hpp" + +namespace ZeroTier { + +class LinuxEthernetTapFactory : public EthernetTapFactory +{ +public: + LinuxEthernetTapFactory(); + virtual ~LinuxEthernetTapFactory(); + + virtual EthernetTap *open( + const MAC &mac, + unsigned int mtu, + unsigned int metric, + uint64_t nwid, + const char *desiredDevice, + const char *friendlyName, + void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), + void *arg); + virtual void close(EthernetTap *tap,bool destroyPersistentDevices); + +private: + std::vector _devices; + Mutex _devices_m; +}; + +} // namespace ZeroTier + +#endif diff --git a/attic/OSXEthernetTapFactory.cpp b/attic/OSXEthernetTapFactory.cpp new file mode 100644 index 00000000..4cad8daa --- /dev/null +++ b/attic/OSXEthernetTapFactory.cpp @@ -0,0 +1,122 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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 . + * + * -- + * + * 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 +#include +#include +#include +#include + +#include "OSXEthernetTapFactory.hpp" +#include "OSXEthernetTap.hpp" + +#include "../node/Utils.hpp" + +namespace ZeroTier { + +OSXEthernetTapFactory::OSXEthernetTapFactory(const char *pathToTapKext,const char *tapKextName) : + _pathToTapKext((pathToTapKext) ? pathToTapKext : ""), + _tapKextName((tapKextName) ? tapKextName : "") +{ + struct stat stattmp; + + if ((_pathToTapKext.length())&&(_tapKextName.length())) { + if (stat("/dev/zt0",&stattmp)) { + long kextpid = (long)vfork(); + if (kextpid == 0) { + ::chdir(_pathToTapKext.c_str()); + Utils::redirectUnixOutputs("/dev/null",(const char *)0); + ::execl("/sbin/kextload","/sbin/kextload","-q","-repository",_pathToTapKext.c_str(),_tapKextName.c_str(),(const char *)0); + ::_exit(-1); + } else if (kextpid > 0) { + int exitcode = -1; + ::waitpid(kextpid,&exitcode,0); + } else throw std::runtime_error("unable to create subprocess with fork()"); + } + } + + if (stat("/dev/zt0",&stattmp)) { + ::usleep(500); // give tap device driver time to start up and try again + if (stat("/dev/zt0",&stattmp)) + throw std::runtime_error("/dev/zt# tap devices do not exist and unable to load kernel extension"); + } +} + +OSXEthernetTapFactory::~OSXEthernetTapFactory() +{ + Mutex::Lock _l(_devices_m); + for(std::vector::iterator d(_devices.begin());d!=_devices.end();++d) + delete *d; + + if ((_pathToTapKext.length())&&(_tapKextName.length())) { + // Attempt to unload kext. If anything else is using a /dev/zt# node, this + // fails and the kext stays in the kernel. + char tmp[16384]; + sprintf(tmp,"%s/%s",_pathToTapKext.c_str(),_tapKextName.c_str()); + long kextpid = (long)vfork(); + if (kextpid == 0) { + Utils::redirectUnixOutputs("/dev/null",(const char *)0); + ::execl("/sbin/kextunload","/sbin/kextunload",tmp,(const char *)0); + ::_exit(-1); + } else if (kextpid > 0) { + int exitcode = -1; + ::waitpid(kextpid,&exitcode,0); + } + } +} + +EthernetTap *OSXEthernetTapFactory::open( + const MAC &mac, + unsigned int mtu, + unsigned int metric, + uint64_t nwid, + const char *desiredDevice, + const char *friendlyName, + void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), + void *arg) +{ + Mutex::Lock _l(_devices_m); + EthernetTap *t = new OSXEthernetTap(mac,mtu,metric,nwid,desiredDevice,friendlyName,handler,arg); + _devices.push_back(t); + return t; +} + +void OSXEthernetTapFactory::close(EthernetTap *tap,bool destroyPersistentDevices) +{ + { + Mutex::Lock _l(_devices_m); + for(std::vector::iterator d(_devices.begin());d!=_devices.end();++d) { + if (*d == tap) { + _devices.erase(d); + break; + } + } + } + delete tap; +} + +} // namespace ZeroTier diff --git a/attic/OSXEthernetTapFactory.hpp b/attic/OSXEthernetTapFactory.hpp new file mode 100644 index 00000000..2f2ee527 --- /dev/null +++ b/attic/OSXEthernetTapFactory.hpp @@ -0,0 +1,76 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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 . + * + * -- + * + * 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_OSXETHERNETTAPFACTORY_HPP +#define ZT_OSXETHERNETTAPFACTORY_HPP + +#include +#include + +#include "../node/EthernetTapFactory.hpp" +#include "../node/Mutex.hpp" + +namespace ZeroTier { + +class OSXEthernetTapFactory : public EthernetTapFactory +{ +public: + /** + * Create OSX ethernet tap factory + * + * If kext paths are specified, an attempt will be made to load the kext + * on launch if not present and unload it on shutdown. + * + * @param pathToTapKext Full path to the location of the tap kext + * @param tapKextName Name of tap kext as found within tap kext path (usually "tap.kext") + * @throws std::runtime_error Tap not available and unable to load kext + */ + OSXEthernetTapFactory(const char *pathToTapKext,const char *tapKextName); + + virtual ~OSXEthernetTapFactory(); + + virtual EthernetTap *open( + const MAC &mac, + unsigned int mtu, + unsigned int metric, + uint64_t nwid, + const char *desiredDevice, + const char *friendlyName, + void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), + void *arg); + virtual void close(EthernetTap *tap,bool destroyPersistentDevices); + +private: + std::vector _devices; + Mutex _devices_m; + std::string _pathToTapKext; + std::string _tapKextName; +}; + +} // namespace ZeroTier + +#endif diff --git a/attic/WindowsEthernetTapFactory.cpp b/attic/WindowsEthernetTapFactory.cpp new file mode 100644 index 00000000..996460a1 --- /dev/null +++ b/attic/WindowsEthernetTapFactory.cpp @@ -0,0 +1,162 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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 . + * + * -- + * + * 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 "WindowsEthernetTapFactory.hpp" +#include "WindowsEthernetTap.hpp" + +namespace ZeroTier { + +WindowsEthernetTapFactory::Env::Env() +{ +#ifdef _WIN64 + is64Bit = TRUE; + devcon = "\\devcon_x64.exe"; + tapDriver = "\\tap-windows\\x64\\zttap200.inf"; +#else + is64Bit = FALSE; + IsWow64Process(GetCurrentProcess(),&is64Bit); + devcon = ((is64Bit == TRUE) ? "\\devcon_x64.exe" : "\\devcon_x86.exe"); + tapDriver = ((is64Bit == TRUE) ? "\\tap-windows\\x64\\zttap200.inf" : "\\tap-windows\\x86\\zttap200.inf"); +#endif +} +const WindowsEthernetTapFactory::Env WindowsEthernetTapFactory::WINENV; + +WindowsEthernetTapFactory::WindowsEthernetTapFactory(const char *pathToHelpers) : + _pathToHelpers(pathToHelpers) +{ +} + +WindowsEthernetTapFactory::~WindowsEthernetTapFactory() +{ + Mutex::Lock _l(_devices_m); + for(std::vector::iterator d(_devices.begin());d!=_devices.end();++d) + delete *d; +} + +EthernetTap *WindowsEthernetTapFactory::open( + const MAC &mac, + unsigned int mtu, + unsigned int metric, + uint64_t nwid, + const char *desiredDevice, + const char *friendlyName, + void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), + void *arg) +{ + Mutex::Lock _l(_devices_m); + EthernetTap *t = new WindowsEthernetTap(_pathToHelpers.c_str(),mac,mtu,metric,nwid,desiredDevice,friendlyName,handler,arg); + _devices.push_back(t); + return t; +} + +void WindowsEthernetTapFactory::close(EthernetTap *tap,bool destroyPersistentDevices) +{ + if (!tap) + return; + + std::string instanceId(((WindowsEthernetTap *)tap)->instanceId()); + Mutex::Lock _l(_devices_m); + + for(std::vector::iterator d(_devices.begin());d!=_devices.end();++d) { + if (*d == tap) { + _devices.erase(d); + break; + } + } + + delete tap; + + if (destroyPersistentDevices) + _deletePersistentTapDevice(_pathToHelpers.c_str(),instanceId.c_str()); +} + +void WindowsEthernetTapFactory::destroyAllPersistentTapDevices(const char *pathToHelpers) +{ + char subkeyName[4096]; + char subkeyClass[4096]; + char data[4096]; + + std::set instanceIdPathsToRemove; + { + HKEY nwAdapters; + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",0,KEY_READ|KEY_WRITE,&nwAdapters) != ERROR_SUCCESS) + return; + + for(DWORD subkeyIndex=0;;++subkeyIndex) { + DWORD type; + DWORD dataLen; + DWORD subkeyNameLen = sizeof(subkeyName); + DWORD subkeyClassLen = sizeof(subkeyClass); + FILETIME lastWriteTime; + if (RegEnumKeyExA(nwAdapters,subkeyIndex,subkeyName,&subkeyNameLen,(DWORD *)0,subkeyClass,&subkeyClassLen,&lastWriteTime) == ERROR_SUCCESS) { + type = 0; + dataLen = sizeof(data); + if (RegGetValueA(nwAdapters,subkeyName,"ComponentId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) { + data[dataLen] = '\0'; + if (!strnicmp(data,"zttap",5)) { + std::string instanceIdPath; + type = 0; + dataLen = sizeof(data); + if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) + instanceIdPath.assign(data,dataLen); + if (instanceIdPath.length() != 0) + instanceIdPathsToRemove.insert(instanceIdPath); + } + } + } else break; // end of list or failure + } + + RegCloseKey(nwAdapters); + } + + for(std::set::iterator iidp(instanceIdPathsToRemove.begin());iidp!=instanceIdPathsToRemove.end();++iidp) + _deletePersistentTapDevice(pathToHelpers,iidp->c_str()); +} + +void WindowsEthernetTapFactory::_deletePersistentTapDevice(const char *pathToHelpers,const char *instanceId) +{ + HANDLE devconLog = CreateFileA((std::string(pathToHelpers) + "\\devcon.log").c_str(),GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); + STARTUPINFOA startupInfo; + startupInfo.cb = sizeof(startupInfo); + if (devconLog != INVALID_HANDLE_VALUE) { + SetFilePointer(devconLog,0,0,FILE_END); + startupInfo.hStdOutput = devconLog; + startupInfo.hStdError = devconLog; + } + PROCESS_INFORMATION processInfo; + memset(&startupInfo,0,sizeof(STARTUPINFOA)); + memset(&processInfo,0,sizeof(PROCESS_INFORMATION)); + if (CreateProcessA(NULL,(LPSTR)(std::string("\"") + pathToHelpers + WINENV.devcon + "\" remove @" + instanceId).c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) { + WaitForSingleObject(processInfo.hProcess,INFINITE); + CloseHandle(processInfo.hProcess); + CloseHandle(processInfo.hThread); + } + if (devconLog != INVALID_HANDLE_VALUE) + CloseHandle(devconLog); +} + +} // namespace ZeroTier diff --git a/attic/WindowsEthernetTapFactory.hpp b/attic/WindowsEthernetTapFactory.hpp new file mode 100644 index 00000000..47e146e3 --- /dev/null +++ b/attic/WindowsEthernetTapFactory.hpp @@ -0,0 +1,90 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2015 ZeroTier, Inc. + * + * 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 . + * + * -- + * + * 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_WINDOWSETHERNETTAPFACTORY_HPP +#define ZT_WINDOWSETHERNETTAPFACTORY_HPP + +#include +#include + +#include "../node/EthernetTapFactory.hpp" +#include "../node/Mutex.hpp" + +namespace ZeroTier { + +class WindowsEthernetTapFactory : public EthernetTapFactory +{ +public: + class Env + { + public: + Env(); + BOOL is64Bit; // true if WIN64 or WoW64 (32-bit binary on 64-bit architecture) + const char *devcon; // name of devcon binary in pathToHelpers to use + const char *tapDriver; // relative path to driver under pathToHelpers to use + }; + + /** + * Constants related to Windows environment, computed on program start + */ + static const Env WINENV; + + /** + * @param pathToHelpers Path to devcon32.exe, devcon64.exe, and other required helper binaries (ZeroTier running directory) + */ + WindowsEthernetTapFactory(const char *pathToHelpers); + virtual ~WindowsEthernetTapFactory(); + + virtual EthernetTap *open( + const MAC &mac, + unsigned int mtu, + unsigned int metric, + uint64_t nwid, + const char *desiredDevice, + const char *friendlyName, + void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), + void *arg); + virtual void close(EthernetTap *tap,bool destroyPersistentDevices); + + /** + * Uninstalls all persistent tap devices in the system belonging to ZeroTier + * + * This is for uninstallation. Do not call this while tap devices are active. + */ + static void destroyAllPersistentTapDevices(const char *pathToHelpers); + +private: + static void _deletePersistentTapDevice(const char *pathToHelpers,const char *instanceId); + + std::string _pathToHelpers; + std::vector _devices; + Mutex _devices_m; +}; + +} // namespace ZeroTier + +#endif diff --git a/make-freebsd.mk b/make-freebsd.mk index 0830ad36..a69dab34 100644 --- a/make-freebsd.mk +++ b/make-freebsd.mk @@ -6,8 +6,8 @@ DEFS= LIBS= include objects.mk -OBJS+=osdep/BSDEthernetTapFactory.o osdep/BSDEthernetTap.o -TESTNET_OBJS=testnet/SimNet.o testnet/SimNetSocketManager.o testnet/TestEthernetTap.o testnet/TestEthernetTapFactory.o +OBJS+=osdep/BSDEthernetTap.o +TESTNET_OBJS=testnet/SimNet.o testnet/SimNetSocketManager.o testnet/TestEthernetTap.o # Enable SSE-optimized Salsa20 on x86 and x86_64 machines MACHINE=$(shell uname -m) diff --git a/make-linux.mk b/make-linux.mk index e8ce1156..b3b0fefd 100644 --- a/make-linux.mk +++ b/make-linux.mk @@ -7,8 +7,8 @@ DEFS= LIBS= include objects.mk -OBJS+=osdep/LinuxEthernetTap.o osdep/LinuxEthernetTapFactory.o -TESTNET_OBJS=testnet/SimNet.o testnet/SimNetSocketManager.o testnet/TestEthernetTap.o testnet/TestEthernetTapFactory.o +OBJS+=osdep/LinuxEthernetTap.o +TESTNET_OBJS=testnet/SimNet.o testnet/SimNetSocketManager.o testnet/TestEthernetTap.o # Enable SSE-optimized Salsa20 on x86 and x86_64 machines MACHINE=$(shell uname -m) diff --git a/make-mac.mk b/make-mac.mk index 29ea4863..1a159c65 100644 --- a/make-mac.mk +++ b/make-mac.mk @@ -7,8 +7,8 @@ LIBS= ARCH_FLAGS=-arch i386 -arch x86_64 include objects.mk -OBJS+=osdep/OSXEthernetTap.o osdep/OSXEthernetTapFactory.o -TESTNET_OBJS=testnet/SimNet.o testnet/SimNetSocketManager.o testnet/TestEthernetTap.o testnet/TestEthernetTapFactory.o +OBJS+=osdep/OSXEthernetTap.o +TESTNET_OBJS=testnet/SimNet.o testnet/SimNetSocketManager.o testnet/TestEthernetTap.o # Disable codesign since open source users will not have ZeroTier's certs CODESIGN=echo diff --git a/osdep/BSDEthernetTapFactory.cpp b/osdep/BSDEthernetTapFactory.cpp deleted file mode 100644 index 79ae73f7..00000000 --- a/osdep/BSDEthernetTapFactory.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. - * - * 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 . - * - * -- - * - * 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 -#include -#include - -#include "BSDEthernetTapFactory.hpp" -#include "BSDEthernetTap.hpp" - -namespace ZeroTier { - -BSDEthernetTapFactory::BSDEthernetTapFactory() -{ -} - -BSDEthernetTapFactory::~BSDEthernetTapFactory() -{ - Mutex::Lock _l(_devices_m); - for(std::vector::iterator d(_devices.begin());d!=_devices.end();++d) - delete *d; -} - -EthernetTap *BSDEthernetTapFactory::open( - const MAC &mac, - unsigned int mtu, - unsigned int metric, - uint64_t nwid, - const char *desiredDevice, - const char *friendlyName, - void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), - void *arg) -{ - Mutex::Lock _l(_devices_m); - EthernetTap *t = new BSDEthernetTap(mac,mtu,metric,nwid,desiredDevice,friendlyName,handler,arg); - _devices.push_back(t); - return t; -} - -void BSDEthernetTapFactory::close(EthernetTap *tap,bool destroyPersistentDevices) -{ - { - Mutex::Lock _l(_devices_m); - for(std::vector::iterator d(_devices.begin());d!=_devices.end();++d) { - if (*d == tap) { - _devices.erase(d); - break; - } - } - } - delete tap; -} - -} // namespace ZeroTier diff --git a/osdep/BSDEthernetTapFactory.hpp b/osdep/BSDEthernetTapFactory.hpp deleted file mode 100644 index 5c681fb4..00000000 --- a/osdep/BSDEthernetTapFactory.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. - * - * 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 . - * - * -- - * - * 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_BSDETHERNETTAPFACTORY_HPP -#define ZT_BSDETHERNETTAPFACTORY_HPP - -#include -#include - -#include "EthernetTapFactory.hpp" -#include "../node/Mutex.hpp" - -namespace ZeroTier { - -class BSDEthernetTapFactory : public EthernetTapFactory -{ -public: - BSDEthernetTapFactory(); - virtual ~BSDEthernetTapFactory(); - - virtual EthernetTap *open( - const MAC &mac, - unsigned int mtu, - unsigned int metric, - uint64_t nwid, - const char *desiredDevice, - const char *friendlyName, - void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), - void *arg); - virtual void close(EthernetTap *tap,bool destroyPersistentDevices); - -private: - std::vector _devices; - Mutex _devices_m; -}; - -} // namespace ZeroTier - -#endif diff --git a/osdep/LinuxEthernetTapFactory.cpp b/osdep/LinuxEthernetTapFactory.cpp deleted file mode 100644 index 014c6514..00000000 --- a/osdep/LinuxEthernetTapFactory.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. - * - * 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 . - * - * -- - * - * 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 "LinuxEthernetTapFactory.hpp" -#include "LinuxEthernetTap.hpp" - -namespace ZeroTier { - -LinuxEthernetTapFactory::LinuxEthernetTapFactory() -{ -} - -LinuxEthernetTapFactory::~LinuxEthernetTapFactory() -{ - Mutex::Lock _l(_devices_m); - for(std::vector::iterator d(_devices.begin());d!=_devices.end();++d) - delete *d; -} - -EthernetTap *LinuxEthernetTapFactory::open( - const MAC &mac, - unsigned int mtu, - unsigned int metric, - uint64_t nwid, - const char *desiredDevice, - const char *friendlyName, - void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), - void *arg) -{ - Mutex::Lock _l(_devices_m); - EthernetTap *t = new LinuxEthernetTap(mac,mtu,metric,nwid,desiredDevice,friendlyName,handler,arg); - _devices.push_back(t); - return t; -} - -void LinuxEthernetTapFactory::close(EthernetTap *tap,bool destroyPersistentDevices) -{ - { - Mutex::Lock _l(_devices_m); - for(std::vector::iterator d(_devices.begin());d!=_devices.end();++d) { - if (*d == tap) { - _devices.erase(d); - break; - } - } - } - delete tap; -} - -} // namespace ZeroTier diff --git a/osdep/LinuxEthernetTapFactory.hpp b/osdep/LinuxEthernetTapFactory.hpp deleted file mode 100644 index e61863ed..00000000 --- a/osdep/LinuxEthernetTapFactory.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. - * - * 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 . - * - * -- - * - * 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_LINUXETHERNETTAPFACTORY_HPP -#define ZT_LINUXETHERNETTAPFACTORY_HPP - -#include -#include - -#include "../node/EthernetTapFactory.hpp" -#include "../node/Mutex.hpp" - -namespace ZeroTier { - -class LinuxEthernetTapFactory : public EthernetTapFactory -{ -public: - LinuxEthernetTapFactory(); - virtual ~LinuxEthernetTapFactory(); - - virtual EthernetTap *open( - const MAC &mac, - unsigned int mtu, - unsigned int metric, - uint64_t nwid, - const char *desiredDevice, - const char *friendlyName, - void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), - void *arg); - virtual void close(EthernetTap *tap,bool destroyPersistentDevices); - -private: - std::vector _devices; - Mutex _devices_m; -}; - -} // namespace ZeroTier - -#endif diff --git a/osdep/OSXEthernetTapFactory.cpp b/osdep/OSXEthernetTapFactory.cpp deleted file mode 100644 index 4cad8daa..00000000 --- a/osdep/OSXEthernetTapFactory.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. - * - * 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 . - * - * -- - * - * 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 -#include -#include -#include -#include - -#include "OSXEthernetTapFactory.hpp" -#include "OSXEthernetTap.hpp" - -#include "../node/Utils.hpp" - -namespace ZeroTier { - -OSXEthernetTapFactory::OSXEthernetTapFactory(const char *pathToTapKext,const char *tapKextName) : - _pathToTapKext((pathToTapKext) ? pathToTapKext : ""), - _tapKextName((tapKextName) ? tapKextName : "") -{ - struct stat stattmp; - - if ((_pathToTapKext.length())&&(_tapKextName.length())) { - if (stat("/dev/zt0",&stattmp)) { - long kextpid = (long)vfork(); - if (kextpid == 0) { - ::chdir(_pathToTapKext.c_str()); - Utils::redirectUnixOutputs("/dev/null",(const char *)0); - ::execl("/sbin/kextload","/sbin/kextload","-q","-repository",_pathToTapKext.c_str(),_tapKextName.c_str(),(const char *)0); - ::_exit(-1); - } else if (kextpid > 0) { - int exitcode = -1; - ::waitpid(kextpid,&exitcode,0); - } else throw std::runtime_error("unable to create subprocess with fork()"); - } - } - - if (stat("/dev/zt0",&stattmp)) { - ::usleep(500); // give tap device driver time to start up and try again - if (stat("/dev/zt0",&stattmp)) - throw std::runtime_error("/dev/zt# tap devices do not exist and unable to load kernel extension"); - } -} - -OSXEthernetTapFactory::~OSXEthernetTapFactory() -{ - Mutex::Lock _l(_devices_m); - for(std::vector::iterator d(_devices.begin());d!=_devices.end();++d) - delete *d; - - if ((_pathToTapKext.length())&&(_tapKextName.length())) { - // Attempt to unload kext. If anything else is using a /dev/zt# node, this - // fails and the kext stays in the kernel. - char tmp[16384]; - sprintf(tmp,"%s/%s",_pathToTapKext.c_str(),_tapKextName.c_str()); - long kextpid = (long)vfork(); - if (kextpid == 0) { - Utils::redirectUnixOutputs("/dev/null",(const char *)0); - ::execl("/sbin/kextunload","/sbin/kextunload",tmp,(const char *)0); - ::_exit(-1); - } else if (kextpid > 0) { - int exitcode = -1; - ::waitpid(kextpid,&exitcode,0); - } - } -} - -EthernetTap *OSXEthernetTapFactory::open( - const MAC &mac, - unsigned int mtu, - unsigned int metric, - uint64_t nwid, - const char *desiredDevice, - const char *friendlyName, - void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), - void *arg) -{ - Mutex::Lock _l(_devices_m); - EthernetTap *t = new OSXEthernetTap(mac,mtu,metric,nwid,desiredDevice,friendlyName,handler,arg); - _devices.push_back(t); - return t; -} - -void OSXEthernetTapFactory::close(EthernetTap *tap,bool destroyPersistentDevices) -{ - { - Mutex::Lock _l(_devices_m); - for(std::vector::iterator d(_devices.begin());d!=_devices.end();++d) { - if (*d == tap) { - _devices.erase(d); - break; - } - } - } - delete tap; -} - -} // namespace ZeroTier diff --git a/osdep/OSXEthernetTapFactory.hpp b/osdep/OSXEthernetTapFactory.hpp deleted file mode 100644 index 2f2ee527..00000000 --- a/osdep/OSXEthernetTapFactory.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. - * - * 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 . - * - * -- - * - * 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_OSXETHERNETTAPFACTORY_HPP -#define ZT_OSXETHERNETTAPFACTORY_HPP - -#include -#include - -#include "../node/EthernetTapFactory.hpp" -#include "../node/Mutex.hpp" - -namespace ZeroTier { - -class OSXEthernetTapFactory : public EthernetTapFactory -{ -public: - /** - * Create OSX ethernet tap factory - * - * If kext paths are specified, an attempt will be made to load the kext - * on launch if not present and unload it on shutdown. - * - * @param pathToTapKext Full path to the location of the tap kext - * @param tapKextName Name of tap kext as found within tap kext path (usually "tap.kext") - * @throws std::runtime_error Tap not available and unable to load kext - */ - OSXEthernetTapFactory(const char *pathToTapKext,const char *tapKextName); - - virtual ~OSXEthernetTapFactory(); - - virtual EthernetTap *open( - const MAC &mac, - unsigned int mtu, - unsigned int metric, - uint64_t nwid, - const char *desiredDevice, - const char *friendlyName, - void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), - void *arg); - virtual void close(EthernetTap *tap,bool destroyPersistentDevices); - -private: - std::vector _devices; - Mutex _devices_m; - std::string _pathToTapKext; - std::string _tapKextName; -}; - -} // namespace ZeroTier - -#endif diff --git a/osdep/WindowsEthernetTapFactory.cpp b/osdep/WindowsEthernetTapFactory.cpp deleted file mode 100644 index 996460a1..00000000 --- a/osdep/WindowsEthernetTapFactory.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. - * - * 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 . - * - * -- - * - * 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 "WindowsEthernetTapFactory.hpp" -#include "WindowsEthernetTap.hpp" - -namespace ZeroTier { - -WindowsEthernetTapFactory::Env::Env() -{ -#ifdef _WIN64 - is64Bit = TRUE; - devcon = "\\devcon_x64.exe"; - tapDriver = "\\tap-windows\\x64\\zttap200.inf"; -#else - is64Bit = FALSE; - IsWow64Process(GetCurrentProcess(),&is64Bit); - devcon = ((is64Bit == TRUE) ? "\\devcon_x64.exe" : "\\devcon_x86.exe"); - tapDriver = ((is64Bit == TRUE) ? "\\tap-windows\\x64\\zttap200.inf" : "\\tap-windows\\x86\\zttap200.inf"); -#endif -} -const WindowsEthernetTapFactory::Env WindowsEthernetTapFactory::WINENV; - -WindowsEthernetTapFactory::WindowsEthernetTapFactory(const char *pathToHelpers) : - _pathToHelpers(pathToHelpers) -{ -} - -WindowsEthernetTapFactory::~WindowsEthernetTapFactory() -{ - Mutex::Lock _l(_devices_m); - for(std::vector::iterator d(_devices.begin());d!=_devices.end();++d) - delete *d; -} - -EthernetTap *WindowsEthernetTapFactory::open( - const MAC &mac, - unsigned int mtu, - unsigned int metric, - uint64_t nwid, - const char *desiredDevice, - const char *friendlyName, - void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), - void *arg) -{ - Mutex::Lock _l(_devices_m); - EthernetTap *t = new WindowsEthernetTap(_pathToHelpers.c_str(),mac,mtu,metric,nwid,desiredDevice,friendlyName,handler,arg); - _devices.push_back(t); - return t; -} - -void WindowsEthernetTapFactory::close(EthernetTap *tap,bool destroyPersistentDevices) -{ - if (!tap) - return; - - std::string instanceId(((WindowsEthernetTap *)tap)->instanceId()); - Mutex::Lock _l(_devices_m); - - for(std::vector::iterator d(_devices.begin());d!=_devices.end();++d) { - if (*d == tap) { - _devices.erase(d); - break; - } - } - - delete tap; - - if (destroyPersistentDevices) - _deletePersistentTapDevice(_pathToHelpers.c_str(),instanceId.c_str()); -} - -void WindowsEthernetTapFactory::destroyAllPersistentTapDevices(const char *pathToHelpers) -{ - char subkeyName[4096]; - char subkeyClass[4096]; - char data[4096]; - - std::set instanceIdPathsToRemove; - { - HKEY nwAdapters; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",0,KEY_READ|KEY_WRITE,&nwAdapters) != ERROR_SUCCESS) - return; - - for(DWORD subkeyIndex=0;;++subkeyIndex) { - DWORD type; - DWORD dataLen; - DWORD subkeyNameLen = sizeof(subkeyName); - DWORD subkeyClassLen = sizeof(subkeyClass); - FILETIME lastWriteTime; - if (RegEnumKeyExA(nwAdapters,subkeyIndex,subkeyName,&subkeyNameLen,(DWORD *)0,subkeyClass,&subkeyClassLen,&lastWriteTime) == ERROR_SUCCESS) { - type = 0; - dataLen = sizeof(data); - if (RegGetValueA(nwAdapters,subkeyName,"ComponentId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) { - data[dataLen] = '\0'; - if (!strnicmp(data,"zttap",5)) { - std::string instanceIdPath; - type = 0; - dataLen = sizeof(data); - if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) - instanceIdPath.assign(data,dataLen); - if (instanceIdPath.length() != 0) - instanceIdPathsToRemove.insert(instanceIdPath); - } - } - } else break; // end of list or failure - } - - RegCloseKey(nwAdapters); - } - - for(std::set::iterator iidp(instanceIdPathsToRemove.begin());iidp!=instanceIdPathsToRemove.end();++iidp) - _deletePersistentTapDevice(pathToHelpers,iidp->c_str()); -} - -void WindowsEthernetTapFactory::_deletePersistentTapDevice(const char *pathToHelpers,const char *instanceId) -{ - HANDLE devconLog = CreateFileA((std::string(pathToHelpers) + "\\devcon.log").c_str(),GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); - STARTUPINFOA startupInfo; - startupInfo.cb = sizeof(startupInfo); - if (devconLog != INVALID_HANDLE_VALUE) { - SetFilePointer(devconLog,0,0,FILE_END); - startupInfo.hStdOutput = devconLog; - startupInfo.hStdError = devconLog; - } - PROCESS_INFORMATION processInfo; - memset(&startupInfo,0,sizeof(STARTUPINFOA)); - memset(&processInfo,0,sizeof(PROCESS_INFORMATION)); - if (CreateProcessA(NULL,(LPSTR)(std::string("\"") + pathToHelpers + WINENV.devcon + "\" remove @" + instanceId).c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) { - WaitForSingleObject(processInfo.hProcess,INFINITE); - CloseHandle(processInfo.hProcess); - CloseHandle(processInfo.hThread); - } - if (devconLog != INVALID_HANDLE_VALUE) - CloseHandle(devconLog); -} - -} // namespace ZeroTier diff --git a/osdep/WindowsEthernetTapFactory.hpp b/osdep/WindowsEthernetTapFactory.hpp deleted file mode 100644 index 47e146e3..00000000 --- a/osdep/WindowsEthernetTapFactory.hpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2015 ZeroTier, Inc. - * - * 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 . - * - * -- - * - * 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_WINDOWSETHERNETTAPFACTORY_HPP -#define ZT_WINDOWSETHERNETTAPFACTORY_HPP - -#include -#include - -#include "../node/EthernetTapFactory.hpp" -#include "../node/Mutex.hpp" - -namespace ZeroTier { - -class WindowsEthernetTapFactory : public EthernetTapFactory -{ -public: - class Env - { - public: - Env(); - BOOL is64Bit; // true if WIN64 or WoW64 (32-bit binary on 64-bit architecture) - const char *devcon; // name of devcon binary in pathToHelpers to use - const char *tapDriver; // relative path to driver under pathToHelpers to use - }; - - /** - * Constants related to Windows environment, computed on program start - */ - static const Env WINENV; - - /** - * @param pathToHelpers Path to devcon32.exe, devcon64.exe, and other required helper binaries (ZeroTier running directory) - */ - WindowsEthernetTapFactory(const char *pathToHelpers); - virtual ~WindowsEthernetTapFactory(); - - virtual EthernetTap *open( - const MAC &mac, - unsigned int mtu, - unsigned int metric, - uint64_t nwid, - const char *desiredDevice, - const char *friendlyName, - void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &), - void *arg); - virtual void close(EthernetTap *tap,bool destroyPersistentDevices); - - /** - * Uninstalls all persistent tap devices in the system belonging to ZeroTier - * - * This is for uninstallation. Do not call this while tap devices are active. - */ - static void destroyAllPersistentTapDevices(const char *pathToHelpers); - -private: - static void _deletePersistentTapDevice(const char *pathToHelpers,const char *instanceId); - - std::string _pathToHelpers; - std::vector _devices; - Mutex _devices_m; -}; - -} // namespace ZeroTier - -#endif -- cgit v1.2.3