WindowsEthernetTap.cpp 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293
  1. /*
  2. * Copyright (c)2019 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2023-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <stdint.h>
  16. #include <string.h>
  17. #include <WinSock2.h>
  18. #include <Windows.h>
  19. #include <tchar.h>
  20. #include <malloc.h>
  21. #include <winreg.h>
  22. #include <wchar.h>
  23. #include <ws2ipdef.h>
  24. #include <WS2tcpip.h>
  25. #include <IPHlpApi.h>
  26. #include <nldef.h>
  27. #include <netioapi.h>
  28. #include <atlbase.h>
  29. #include <netlistmgr.h>
  30. #include <nldef.h>
  31. #include <SetupAPI.h>
  32. #include <newdev.h>
  33. #include <cfgmgr32.h>
  34. #include <iostream>
  35. #include <set>
  36. #include "../node/Constants.hpp"
  37. #include "../node/Utils.hpp"
  38. #include "../node/Mutex.hpp"
  39. #include "WindowsEthernetTap.hpp"
  40. #include "OSUtils.hpp"
  41. #include "..\windows\TapDriver6\tap-windows.h"
  42. #include <netcon.h>
  43. // Create a fake unused default route to force detection of network type on networks without gateways
  44. #define ZT_WINDOWS_CREATE_FAKE_DEFAULT_ROUTE
  45. // Function signatures of dynamically loaded functions, from newdev.h, setupapi.h, and cfgmgr32.h
  46. typedef BOOL (WINAPI *UpdateDriverForPlugAndPlayDevicesA_t)(_In_opt_ HWND hwndParent,_In_ LPCSTR HardwareId,_In_ LPCSTR FullInfPath,_In_ DWORD InstallFlags,_Out_opt_ PBOOL bRebootRequired);
  47. typedef BOOL (WINAPI *SetupDiGetINFClassA_t)(_In_ PCSTR InfName,_Out_ LPGUID ClassGuid,_Out_writes_(ClassNameSize) PSTR ClassName,_In_ DWORD ClassNameSize,_Out_opt_ PDWORD RequiredSize);
  48. typedef HDEVINFO (WINAPI *SetupDiCreateDeviceInfoList_t)(_In_opt_ CONST GUID *ClassGuid,_In_opt_ HWND hwndParent);
  49. typedef BOOL (WINAPI *SetupDiCreateDeviceInfoA_t)(_In_ HDEVINFO DeviceInfoSet,_In_ PCSTR DeviceName,_In_ CONST GUID *ClassGuid,_In_opt_ PCSTR DeviceDescription,_In_opt_ HWND hwndParent,_In_ DWORD CreationFlags,_Out_opt_ PSP_DEVINFO_DATA DeviceInfoData);
  50. typedef BOOL (WINAPI *SetupDiSetDeviceRegistryPropertyA_t)(_In_ HDEVINFO DeviceInfoSet,_Inout_ PSP_DEVINFO_DATA DeviceInfoData,_In_ DWORD Property,_In_reads_bytes_opt_(PropertyBufferSize) CONST BYTE *PropertyBuffer,_In_ DWORD PropertyBufferSize);
  51. typedef BOOL (WINAPI *SetupDiCallClassInstaller_t)(_In_ DI_FUNCTION InstallFunction,_In_ HDEVINFO DeviceInfoSet,_In_opt_ PSP_DEVINFO_DATA DeviceInfoData);
  52. typedef BOOL (WINAPI *SetupDiDestroyDeviceInfoList_t)(_In_ HDEVINFO DeviceInfoSet);
  53. typedef HDEVINFO (WINAPI *SetupDiGetClassDevsExA_t)(_In_opt_ CONST GUID *ClassGuid,_In_opt_ PCSTR Enumerator,_In_opt_ HWND hwndParent,_In_ DWORD Flags,_In_opt_ HDEVINFO DeviceInfoSet,_In_opt_ PCSTR MachineName,_Reserved_ PVOID Reserved);
  54. typedef BOOL (WINAPI *SetupDiOpenDeviceInfoA_t)(_In_ HDEVINFO DeviceInfoSet,_In_ PCSTR DeviceInstanceId,_In_opt_ HWND hwndParent,_In_ DWORD OpenFlags,_Out_opt_ PSP_DEVINFO_DATA DeviceInfoData);
  55. typedef BOOL (WINAPI *SetupDiEnumDeviceInfo_t)(_In_ HDEVINFO DeviceInfoSet,_In_ DWORD MemberIndex,_Out_ PSP_DEVINFO_DATA DeviceInfoData);
  56. typedef BOOL (WINAPI *SetupDiSetClassInstallParamsA_t)(_In_ HDEVINFO DeviceInfoSet,_In_opt_ PSP_DEVINFO_DATA DeviceInfoData,_In_reads_bytes_opt_(ClassInstallParamsSize) PSP_CLASSINSTALL_HEADER ClassInstallParams,_In_ DWORD ClassInstallParamsSize);
  57. typedef CONFIGRET (WINAPI *CM_Get_Device_ID_ExA_t)(_In_ DEVINST dnDevInst,_Out_writes_(BufferLen) PSTR Buffer,_In_ ULONG BufferLen,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine);
  58. typedef BOOL (WINAPI *SetupDiGetDeviceInstanceIdA_t)(_In_ HDEVINFO DeviceInfoSet,_In_ PSP_DEVINFO_DATA DeviceInfoData,_Out_writes_opt_(DeviceInstanceIdSize) PSTR DeviceInstanceId,_In_ DWORD DeviceInstanceIdSize,_Out_opt_ PDWORD RequiredSize);
  59. namespace ZeroTier {
  60. namespace {
  61. // Static/singleton class that when initialized loads a bunch of environment information and a few dynamically loaded DLLs
  62. class WindowsEthernetTapEnv
  63. {
  64. public:
  65. WindowsEthernetTapEnv()
  66. {
  67. #ifdef _WIN64
  68. is64Bit = TRUE;
  69. tapDriverPath = "\\tap-windows\\x64\\zttap300.inf";
  70. #else
  71. is64Bit = FALSE;
  72. IsWow64Process(GetCurrentProcess(),&is64Bit);
  73. if (is64Bit) {
  74. fprintf(stderr,"FATAL: you must use the 64-bit ZeroTier One service on 64-bit Windows systems\r\n");
  75. _exit(1);
  76. }
  77. tapDriverPath = "\\tap-windows\\x86\\zttap300.inf";
  78. #endif
  79. tapDriverName = "zttap300";
  80. setupApiMod = LoadLibraryA("setupapi.dll");
  81. if (!setupApiMod) {
  82. fprintf(stderr,"FATAL: unable to dynamically load setupapi.dll\r\n");
  83. _exit(1);
  84. }
  85. if (!(this->SetupDiGetINFClassA = (SetupDiGetINFClassA_t)GetProcAddress(setupApiMod,"SetupDiGetINFClassA"))) {
  86. fprintf(stderr,"FATAL: SetupDiGetINFClassA not found in setupapi.dll\r\n");
  87. _exit(1);
  88. }
  89. if (!(this->SetupDiCreateDeviceInfoList = (SetupDiCreateDeviceInfoList_t)GetProcAddress(setupApiMod,"SetupDiCreateDeviceInfoList"))) {
  90. fprintf(stderr,"FATAL: SetupDiCreateDeviceInfoList not found in setupapi.dll\r\n");
  91. _exit(1);
  92. }
  93. if (!(this->SetupDiCreateDeviceInfoA = (SetupDiCreateDeviceInfoA_t)GetProcAddress(setupApiMod,"SetupDiCreateDeviceInfoA"))) {
  94. fprintf(stderr,"FATAL: SetupDiCreateDeviceInfoA not found in setupapi.dll\r\n");
  95. _exit(1);
  96. }
  97. if (!(this->SetupDiSetDeviceRegistryPropertyA = (SetupDiSetDeviceRegistryPropertyA_t)GetProcAddress(setupApiMod,"SetupDiSetDeviceRegistryPropertyA"))) {
  98. fprintf(stderr,"FATAL: SetupDiSetDeviceRegistryPropertyA not found in setupapi.dll\r\n");
  99. _exit(1);
  100. }
  101. if (!(this->SetupDiCallClassInstaller = (SetupDiCallClassInstaller_t)GetProcAddress(setupApiMod,"SetupDiCallClassInstaller"))) {
  102. fprintf(stderr,"FATAL: SetupDiCallClassInstaller not found in setupapi.dll\r\n");
  103. _exit(1);
  104. }
  105. if (!(this->SetupDiDestroyDeviceInfoList = (SetupDiDestroyDeviceInfoList_t)GetProcAddress(setupApiMod,"SetupDiDestroyDeviceInfoList"))) {
  106. fprintf(stderr,"FATAL: SetupDiDestroyDeviceInfoList not found in setupapi.dll\r\n");
  107. _exit(1);
  108. }
  109. if (!(this->SetupDiGetClassDevsExA = (SetupDiGetClassDevsExA_t)GetProcAddress(setupApiMod,"SetupDiGetClassDevsExA"))) {
  110. fprintf(stderr,"FATAL: SetupDiGetClassDevsExA not found in setupapi.dll\r\n");
  111. _exit(1);
  112. }
  113. if (!(this->SetupDiOpenDeviceInfoA = (SetupDiOpenDeviceInfoA_t)GetProcAddress(setupApiMod,"SetupDiOpenDeviceInfoA"))) {
  114. fprintf(stderr,"FATAL: SetupDiOpenDeviceInfoA not found in setupapi.dll\r\n");
  115. _exit(1);
  116. }
  117. if (!(this->SetupDiEnumDeviceInfo = (SetupDiEnumDeviceInfo_t)GetProcAddress(setupApiMod,"SetupDiEnumDeviceInfo"))) {
  118. fprintf(stderr,"FATAL: SetupDiEnumDeviceInfo not found in setupapi.dll\r\n");
  119. _exit(1);
  120. }
  121. if (!(this->SetupDiSetClassInstallParamsA = (SetupDiSetClassInstallParamsA_t)GetProcAddress(setupApiMod,"SetupDiSetClassInstallParamsA"))) {
  122. fprintf(stderr,"FATAL: SetupDiSetClassInstallParamsA not found in setupapi.dll\r\n");
  123. _exit(1);
  124. }
  125. if (!(this->SetupDiGetDeviceInstanceIdA = (SetupDiGetDeviceInstanceIdA_t)GetProcAddress(setupApiMod,"SetupDiGetDeviceInstanceIdA"))) {
  126. fprintf(stderr,"FATAL: SetupDiGetDeviceInstanceIdA not found in setupapi.dll\r\n");
  127. _exit(1);
  128. }
  129. newDevMod = LoadLibraryA("newdev.dll");
  130. if (!newDevMod) {
  131. fprintf(stderr,"FATAL: unable to dynamically load newdev.dll\r\n");
  132. _exit(1);
  133. }
  134. if (!(this->UpdateDriverForPlugAndPlayDevicesA = (UpdateDriverForPlugAndPlayDevicesA_t)GetProcAddress(newDevMod,"UpdateDriverForPlugAndPlayDevicesA"))) {
  135. fprintf(stderr,"FATAL: UpdateDriverForPlugAndPlayDevicesA not found in newdev.dll\r\n");
  136. _exit(1);
  137. }
  138. cfgMgrMod = LoadLibraryA("cfgmgr32.dll");
  139. if (!cfgMgrMod) {
  140. fprintf(stderr,"FATAL: unable to dynamically load cfgmgr32.dll\r\n");
  141. _exit(1);
  142. }
  143. if (!(this->CM_Get_Device_ID_ExA = (CM_Get_Device_ID_ExA_t)GetProcAddress(cfgMgrMod,"CM_Get_Device_ID_ExA"))) {
  144. fprintf(stderr,"FATAL: CM_Get_Device_ID_ExA not found in cfgmgr32.dll\r\n");
  145. _exit(1);
  146. }
  147. }
  148. BOOL is64Bit; // is the system 64-bit, regardless of whether this binary is or not
  149. std::string tapDriverPath;
  150. std::string tapDriverName;
  151. UpdateDriverForPlugAndPlayDevicesA_t UpdateDriverForPlugAndPlayDevicesA;
  152. SetupDiGetINFClassA_t SetupDiGetINFClassA;
  153. SetupDiCreateDeviceInfoList_t SetupDiCreateDeviceInfoList;
  154. SetupDiCreateDeviceInfoA_t SetupDiCreateDeviceInfoA;
  155. SetupDiSetDeviceRegistryPropertyA_t SetupDiSetDeviceRegistryPropertyA;
  156. SetupDiCallClassInstaller_t SetupDiCallClassInstaller;
  157. SetupDiDestroyDeviceInfoList_t SetupDiDestroyDeviceInfoList;
  158. SetupDiGetClassDevsExA_t SetupDiGetClassDevsExA;
  159. SetupDiOpenDeviceInfoA_t SetupDiOpenDeviceInfoA;
  160. SetupDiEnumDeviceInfo_t SetupDiEnumDeviceInfo;
  161. SetupDiSetClassInstallParamsA_t SetupDiSetClassInstallParamsA;
  162. SetupDiGetDeviceInstanceIdA_t SetupDiGetDeviceInstanceIdA;
  163. CM_Get_Device_ID_ExA_t CM_Get_Device_ID_ExA;
  164. private:
  165. HMODULE setupApiMod;
  166. HMODULE newDevMod;
  167. HMODULE cfgMgrMod;
  168. };
  169. static const WindowsEthernetTapEnv WINENV;
  170. // Only create or delete devices one at a time
  171. static Mutex _systemTapInitLock;
  172. // Only perform installation or uninstallation options one at a time
  173. static Mutex _systemDeviceManagementLock;
  174. } // anonymous namespace
  175. std::string WindowsEthernetTap::addNewPersistentTapDevice(const char *pathToInf,std::string &deviceInstanceId)
  176. {
  177. Mutex::Lock _l(_systemDeviceManagementLock);
  178. GUID classGuid;
  179. char className[1024];
  180. if (!WINENV.SetupDiGetINFClassA(pathToInf,&classGuid,className,sizeof(className),(PDWORD)0)) {
  181. return std::string("SetupDiGetINFClassA() failed -- unable to read zttap driver INF file");
  182. }
  183. HDEVINFO deviceInfoSet = WINENV.SetupDiCreateDeviceInfoList(&classGuid,(HWND)0);
  184. if (deviceInfoSet == INVALID_HANDLE_VALUE) {
  185. return std::string("SetupDiCreateDeviceInfoList() failed");
  186. }
  187. SP_DEVINFO_DATA deviceInfoData;
  188. memset(&deviceInfoData,0,sizeof(deviceInfoData));
  189. deviceInfoData.cbSize = sizeof(deviceInfoData);
  190. if (!WINENV.SetupDiCreateDeviceInfoA(deviceInfoSet,className,&classGuid,(PCSTR)0,(HWND)0,DICD_GENERATE_ID,&deviceInfoData)) {
  191. WINENV.SetupDiDestroyDeviceInfoList(deviceInfoSet);
  192. return std::string("SetupDiCreateDeviceInfoA() failed");
  193. }
  194. if (!WINENV.SetupDiSetDeviceRegistryPropertyA(deviceInfoSet,&deviceInfoData,SPDRP_HARDWAREID,(const BYTE *)WINENV.tapDriverName.c_str(),(DWORD)(WINENV.tapDriverName.length() + 1))) {
  195. WINENV.SetupDiDestroyDeviceInfoList(deviceInfoSet);
  196. return std::string("SetupDiSetDeviceRegistryPropertyA() failed");
  197. }
  198. if (!WINENV.SetupDiCallClassInstaller(DIF_REGISTERDEVICE,deviceInfoSet,&deviceInfoData)) {
  199. WINENV.SetupDiDestroyDeviceInfoList(deviceInfoSet);
  200. return std::string("SetupDiCallClassInstaller(DIF_REGISTERDEVICE) failed");
  201. }
  202. // HACK: During upgrades, this can fail while the installer is still running. So make 60 attempts
  203. // with a 1s delay between each attempt.
  204. bool driverInstalled = false;
  205. for(int retryCounter=0;retryCounter<60;++retryCounter) {
  206. BOOL rebootRequired = FALSE;
  207. if (WINENV.UpdateDriverForPlugAndPlayDevicesA((HWND)0,WINENV.tapDriverName.c_str(),pathToInf,INSTALLFLAG_FORCE|INSTALLFLAG_NONINTERACTIVE,&rebootRequired)) {
  208. driverInstalled = true;
  209. break;
  210. } else Sleep(1000);
  211. }
  212. if (!driverInstalled) {
  213. WINENV.SetupDiDestroyDeviceInfoList(deviceInfoSet);
  214. return std::string("UpdateDriverForPlugAndPlayDevices() failed (made 60 attempts)");
  215. }
  216. char iidbuf[1024];
  217. DWORD iidReqSize = sizeof(iidbuf);
  218. if (WINENV.SetupDiGetDeviceInstanceIdA(deviceInfoSet,&deviceInfoData,iidbuf,sizeof(iidbuf),&iidReqSize)) {
  219. deviceInstanceId = iidbuf;
  220. } // failure here is not fatal since we only need this on Vista and 2008 -- other versions fill it into the registry automatically
  221. WINENV.SetupDiDestroyDeviceInfoList(deviceInfoSet);
  222. return std::string();
  223. }
  224. std::string WindowsEthernetTap::destroyAllLegacyPersistentTapDevices()
  225. {
  226. char subkeyName[1024];
  227. char subkeyClass[1024];
  228. char data[1024];
  229. std::set<std::string> instanceIdPathsToRemove;
  230. {
  231. HKEY nwAdapters;
  232. if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",0,KEY_READ|KEY_WRITE,&nwAdapters) != ERROR_SUCCESS)
  233. return std::string("Could not open registry key");
  234. for(DWORD subkeyIndex=0;;++subkeyIndex) {
  235. DWORD type;
  236. DWORD dataLen;
  237. DWORD subkeyNameLen = sizeof(subkeyName);
  238. DWORD subkeyClassLen = sizeof(subkeyClass);
  239. FILETIME lastWriteTime;
  240. if (RegEnumKeyExA(nwAdapters,subkeyIndex,subkeyName,&subkeyNameLen,(DWORD *)0,subkeyClass,&subkeyClassLen,&lastWriteTime) == ERROR_SUCCESS) {
  241. type = 0;
  242. dataLen = sizeof(data);
  243. if (RegGetValueA(nwAdapters,subkeyName,"ComponentId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
  244. data[dataLen] = '\0';
  245. if ((!strnicmp(data,"zttap",5))&&(WINENV.tapDriverName != data)) {
  246. std::string instanceIdPath;
  247. type = 0;
  248. dataLen = sizeof(data);
  249. if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS)
  250. instanceIdPath.assign(data,dataLen);
  251. if (instanceIdPath.length() != 0)
  252. instanceIdPathsToRemove.insert(instanceIdPath);
  253. }
  254. }
  255. } else break; // end of list or failure
  256. }
  257. RegCloseKey(nwAdapters);
  258. }
  259. std::string errlist;
  260. for(std::set<std::string>::iterator iidp(instanceIdPathsToRemove.begin());iidp!=instanceIdPathsToRemove.end();++iidp) {
  261. std::string err = deletePersistentTapDevice(iidp->c_str());
  262. if (err.length() > 0) {
  263. if (errlist.length() > 0)
  264. errlist.push_back(',');
  265. errlist.append(err);
  266. }
  267. }
  268. return errlist;
  269. }
  270. std::string WindowsEthernetTap::destroyAllPersistentTapDevices()
  271. {
  272. char subkeyName[1024];
  273. char subkeyClass[1024];
  274. char data[1024];
  275. std::set<std::string> instanceIdPathsToRemove;
  276. {
  277. HKEY nwAdapters;
  278. if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",0,KEY_READ|KEY_WRITE,&nwAdapters) != ERROR_SUCCESS)
  279. return std::string("Could not open registry key");
  280. for(DWORD subkeyIndex=0;;++subkeyIndex) {
  281. DWORD type;
  282. DWORD dataLen;
  283. DWORD subkeyNameLen = sizeof(subkeyName);
  284. DWORD subkeyClassLen = sizeof(subkeyClass);
  285. FILETIME lastWriteTime;
  286. if (RegEnumKeyExA(nwAdapters,subkeyIndex,subkeyName,&subkeyNameLen,(DWORD *)0,subkeyClass,&subkeyClassLen,&lastWriteTime) == ERROR_SUCCESS) {
  287. type = 0;
  288. dataLen = sizeof(data);
  289. if (RegGetValueA(nwAdapters,subkeyName,"ComponentId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
  290. data[dataLen] = '\0';
  291. if (!strnicmp(data,"zttap",5)) {
  292. std::string instanceIdPath;
  293. type = 0;
  294. dataLen = sizeof(data);
  295. if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS)
  296. instanceIdPath.assign(data,dataLen);
  297. if (instanceIdPath.length() != 0)
  298. instanceIdPathsToRemove.insert(instanceIdPath);
  299. }
  300. }
  301. } else break; // end of list or failure
  302. }
  303. RegCloseKey(nwAdapters);
  304. }
  305. std::string errlist;
  306. for(std::set<std::string>::iterator iidp(instanceIdPathsToRemove.begin());iidp!=instanceIdPathsToRemove.end();++iidp) {
  307. std::string err = deletePersistentTapDevice(iidp->c_str());
  308. if (err.length() > 0) {
  309. if (errlist.length() > 0)
  310. errlist.push_back(',');
  311. errlist.append(err);
  312. }
  313. }
  314. return errlist;
  315. }
  316. std::string WindowsEthernetTap::deletePersistentTapDevice(const char *instanceId)
  317. {
  318. char iid[256];
  319. SP_REMOVEDEVICE_PARAMS rmdParams;
  320. memset(&rmdParams,0,sizeof(rmdParams));
  321. rmdParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
  322. rmdParams.ClassInstallHeader.InstallFunction = DIF_REMOVE;
  323. rmdParams.Scope = DI_REMOVEDEVICE_GLOBAL;
  324. rmdParams.HwProfile = 0;
  325. Mutex::Lock _l(_systemDeviceManagementLock);
  326. HDEVINFO devInfo = WINENV.SetupDiGetClassDevsExA((const GUID *)0,(PCSTR)0,(HWND)0,DIGCF_ALLCLASSES,(HDEVINFO)0,(PCSTR)0,(PVOID)0);
  327. if (devInfo == INVALID_HANDLE_VALUE)
  328. return std::string("SetupDiGetClassDevsExA() failed");
  329. WINENV.SetupDiOpenDeviceInfoA(devInfo,instanceId,(HWND)0,0,(PSP_DEVINFO_DATA)0);
  330. SP_DEVINFO_DATA devInfoData;
  331. memset(&devInfoData,0,sizeof(devInfoData));
  332. devInfoData.cbSize = sizeof(devInfoData);
  333. for(DWORD devIndex=0;WINENV.SetupDiEnumDeviceInfo(devInfo,devIndex,&devInfoData);devIndex++) {
  334. if ((WINENV.CM_Get_Device_ID_ExA(devInfoData.DevInst,iid,sizeof(iid),0,(HMACHINE)0) == CR_SUCCESS)&&(!strcmp(iid,instanceId))) {
  335. if (!WINENV.SetupDiSetClassInstallParamsA(devInfo,&devInfoData,&rmdParams.ClassInstallHeader,sizeof(rmdParams))) {
  336. WINENV.SetupDiDestroyDeviceInfoList(devInfo);
  337. return std::string("SetupDiSetClassInstallParams() failed");
  338. }
  339. if (!WINENV.SetupDiCallClassInstaller(DIF_REMOVE,devInfo,&devInfoData)) {
  340. WINENV.SetupDiDestroyDeviceInfoList(devInfo);
  341. return std::string("SetupDiCallClassInstaller(DIF_REMOVE) failed");
  342. }
  343. WINENV.SetupDiDestroyDeviceInfoList(devInfo);
  344. return std::string();
  345. }
  346. }
  347. WINENV.SetupDiDestroyDeviceInfoList(devInfo);
  348. return std::string("instance ID not found");
  349. }
  350. bool WindowsEthernetTap::setPersistentTapDeviceState(const char *instanceId,bool enabled)
  351. {
  352. char iid[256];
  353. SP_PROPCHANGE_PARAMS params;
  354. Mutex::Lock _l(_systemDeviceManagementLock);
  355. HDEVINFO devInfo = WINENV.SetupDiGetClassDevsExA((const GUID *)0,(PCSTR)0,(HWND)0,DIGCF_ALLCLASSES,(HDEVINFO)0,(PCSTR)0,(PVOID)0);
  356. if (devInfo == INVALID_HANDLE_VALUE)
  357. return false;
  358. WINENV.SetupDiOpenDeviceInfoA(devInfo,instanceId,(HWND)0,0,(PSP_DEVINFO_DATA)0);
  359. SP_DEVINFO_DATA devInfoData;
  360. memset(&devInfoData,0,sizeof(devInfoData));
  361. devInfoData.cbSize = sizeof(devInfoData);
  362. for(DWORD devIndex=0;WINENV.SetupDiEnumDeviceInfo(devInfo,devIndex,&devInfoData);devIndex++) {
  363. if ((WINENV.CM_Get_Device_ID_ExA(devInfoData.DevInst,iid,sizeof(iid),0,(HMACHINE)0) == CR_SUCCESS)&&(!strcmp(iid,instanceId))) {
  364. memset(&params,0,sizeof(params));
  365. params.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
  366. params.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
  367. params.StateChange = enabled ? DICS_ENABLE : DICS_DISABLE;
  368. params.Scope = DICS_FLAG_GLOBAL;
  369. params.HwProfile = 0;
  370. WINENV.SetupDiSetClassInstallParamsA(devInfo,&devInfoData,&params.ClassInstallHeader,sizeof(params));
  371. WINENV.SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,devInfo,&devInfoData);
  372. memset(&params,0,sizeof(params));
  373. params.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
  374. params.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
  375. params.StateChange = enabled ? DICS_ENABLE : DICS_DISABLE;
  376. params.Scope = DICS_FLAG_CONFIGSPECIFIC;
  377. params.HwProfile = 0;
  378. WINENV.SetupDiSetClassInstallParamsA(devInfo,&devInfoData,&params.ClassInstallHeader,sizeof(params));
  379. WINENV.SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,devInfo,&devInfoData);
  380. WINENV.SetupDiDestroyDeviceInfoList(devInfo);
  381. return true;
  382. }
  383. }
  384. WINENV.SetupDiDestroyDeviceInfoList(devInfo);
  385. return false;
  386. }
  387. WindowsEthernetTap::WindowsEthernetTap(
  388. const char *hp,
  389. const MAC &mac,
  390. unsigned int mtu,
  391. unsigned int metric,
  392. uint64_t nwid,
  393. const char *friendlyName,
  394. void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
  395. void *arg) :
  396. _handler(handler),
  397. _arg(arg),
  398. _mac(mac),
  399. _nwid(nwid),
  400. _mtu(mtu),
  401. _tap(INVALID_HANDLE_VALUE),
  402. _friendlyName(friendlyName),
  403. _injectSemaphore(INVALID_HANDLE_VALUE),
  404. _pathToHelpers(hp),
  405. _run(true),
  406. _initialized(false),
  407. _enabled(true)
  408. {
  409. char subkeyName[1024];
  410. char subkeyClass[1024];
  411. char data[1024];
  412. char tag[24];
  413. // We "tag" registry entries with the network ID to identify persistent devices
  414. OSUtils::ztsnprintf(tag,sizeof(tag),"%.16llx",(unsigned long long)nwid);
  415. Mutex::Lock _l(_systemTapInitLock);
  416. HKEY nwAdapters;
  417. if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",0,KEY_READ|KEY_WRITE,&nwAdapters) != ERROR_SUCCESS)
  418. throw std::runtime_error("unable to open registry key for network adapter enumeration");
  419. // Look for the tap instance that corresponds with this network
  420. for(DWORD subkeyIndex=0;;++subkeyIndex) {
  421. DWORD type;
  422. DWORD dataLen;
  423. DWORD subkeyNameLen = sizeof(subkeyName);
  424. DWORD subkeyClassLen = sizeof(subkeyClass);
  425. FILETIME lastWriteTime;
  426. if (RegEnumKeyExA(nwAdapters,subkeyIndex,subkeyName,&subkeyNameLen,(DWORD *)0,subkeyClass,&subkeyClassLen,&lastWriteTime) == ERROR_SUCCESS) {
  427. type = 0;
  428. dataLen = sizeof(data);
  429. if (RegGetValueA(nwAdapters,subkeyName,"ComponentId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
  430. data[dataLen] = (char)0;
  431. if (WINENV.tapDriverName == data) {
  432. std::string instanceId;
  433. type = 0;
  434. dataLen = sizeof(data);
  435. if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS)
  436. instanceId.assign(data,dataLen);
  437. std::string instanceIdPath;
  438. type = 0;
  439. dataLen = sizeof(data);
  440. if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS)
  441. instanceIdPath.assign(data,dataLen);
  442. if ((_netCfgInstanceId.length() == 0)&&(instanceId.length() != 0)&&(instanceIdPath.length() != 0)) {
  443. type = 0;
  444. dataLen = sizeof(data);
  445. if (RegGetValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
  446. data[dataLen] = '\0';
  447. if (!strcmp(data,tag)) {
  448. _netCfgInstanceId = instanceId;
  449. _deviceInstanceId = instanceIdPath;
  450. _mySubkeyName = subkeyName;
  451. break; // found it!
  452. }
  453. }
  454. }
  455. }
  456. }
  457. } else break; // no more subkeys or error occurred enumerating them
  458. }
  459. // If there is no device, try to create one
  460. bool creatingNewDevice = (_netCfgInstanceId.length() == 0);
  461. std::string newDeviceInstanceId;
  462. if (creatingNewDevice) {
  463. for(int getNewAttemptCounter=0;getNewAttemptCounter<2;++getNewAttemptCounter) {
  464. for(DWORD subkeyIndex=0;;++subkeyIndex) {
  465. DWORD type;
  466. DWORD dataLen;
  467. DWORD subkeyNameLen = sizeof(subkeyName);
  468. DWORD subkeyClassLen = sizeof(subkeyClass);
  469. FILETIME lastWriteTime;
  470. if (RegEnumKeyExA(nwAdapters,subkeyIndex,subkeyName,&subkeyNameLen,(DWORD *)0,subkeyClass,&subkeyClassLen,&lastWriteTime) == ERROR_SUCCESS) {
  471. type = 0;
  472. dataLen = sizeof(data);
  473. if (RegGetValueA(nwAdapters,subkeyName,"ComponentId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
  474. data[dataLen] = '\0';
  475. if (WINENV.tapDriverName == data) {
  476. type = 0;
  477. dataLen = sizeof(data);
  478. if ((RegGetValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",RRF_RT_ANY,&type,(PVOID)data,&dataLen) != ERROR_SUCCESS)||(dataLen <= 0)) {
  479. type = 0;
  480. dataLen = sizeof(data);
  481. if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
  482. RegSetKeyValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",REG_SZ,tag,(DWORD)(strlen(tag)+1));
  483. _netCfgInstanceId.assign(data,dataLen);
  484. type = 0;
  485. dataLen = sizeof(data);
  486. if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS)
  487. _deviceInstanceId.assign(data,dataLen);
  488. _mySubkeyName = subkeyName;
  489. // Disable DHCP by default on new devices
  490. HKEY tcpIpInterfaces;
  491. if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces",0,KEY_READ|KEY_WRITE,&tcpIpInterfaces) == ERROR_SUCCESS) {
  492. DWORD enable = 0;
  493. RegSetKeyValueA(tcpIpInterfaces,_netCfgInstanceId.c_str(),"EnableDHCP",REG_DWORD,&enable,sizeof(enable));
  494. RegCloseKey(tcpIpInterfaces);
  495. }
  496. break; // found an unused zttap device
  497. }
  498. }
  499. }
  500. }
  501. } else break; // no more keys or error occurred
  502. }
  503. if (_netCfgInstanceId.length() > 0) {
  504. break; // found an unused zttap device
  505. } else {
  506. // no unused zttap devices, so create one
  507. std::string errm = addNewPersistentTapDevice((std::string(_pathToHelpers) + WINENV.tapDriverPath).c_str(),newDeviceInstanceId);
  508. if (errm.length() > 0)
  509. throw std::runtime_error(std::string("unable to create new device instance: ")+errm);
  510. }
  511. }
  512. }
  513. if (_netCfgInstanceId.length() > 0) {
  514. char tmps[64];
  515. unsigned int tmpsl = OSUtils::ztsnprintf(tmps,sizeof(tmps),"%.2X-%.2X-%.2X-%.2X-%.2X-%.2X",(unsigned int)mac[0],(unsigned int)mac[1],(unsigned int)mac[2],(unsigned int)mac[3],(unsigned int)mac[4],(unsigned int)mac[5]) + 1;
  516. RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"NetworkAddress",REG_SZ,tmps,tmpsl);
  517. RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"MAC",REG_SZ,tmps,tmpsl);
  518. tmpsl = OSUtils::ztsnprintf(tmps, sizeof(tmps), "%d", mtu);
  519. RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"MTU",REG_SZ,tmps,tmpsl);
  520. DWORD tmp = 0;
  521. RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"*NdisDeviceType",REG_DWORD,(LPCVOID)&tmp,sizeof(tmp));
  522. tmp = IF_TYPE_ETHERNET_CSMACD;
  523. RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"*IfType",REG_DWORD,(LPCVOID)&tmp,sizeof(tmp));
  524. if (creatingNewDevice) {
  525. // Vista/2008 does not set this
  526. if (newDeviceInstanceId.length() > 0)
  527. RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"DeviceInstanceID",REG_SZ,newDeviceInstanceId.c_str(),(DWORD)newDeviceInstanceId.length());
  528. // Set EnableDHCP to 0 by default on new devices
  529. tmp = 0;
  530. RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"EnableDHCP",REG_DWORD,(LPCVOID)&tmp,sizeof(tmp));
  531. }
  532. RegCloseKey(nwAdapters);
  533. } else {
  534. RegCloseKey(nwAdapters);
  535. throw std::runtime_error("unable to find or create tap adapter");
  536. }
  537. {
  538. char nobraces[128]; // strip braces from GUID before converting it, because Windows
  539. const char *nbtmp1 = _netCfgInstanceId.c_str();
  540. char *nbtmp2 = nobraces;
  541. while (*nbtmp1) {
  542. if ((*nbtmp1 != '{')&&(*nbtmp1 != '}'))
  543. *nbtmp2++ = *nbtmp1;
  544. ++nbtmp1;
  545. }
  546. *nbtmp2 = (char)0;
  547. if (UuidFromStringA((RPC_CSTR)nobraces,&_deviceGuid) != RPC_S_OK)
  548. throw std::runtime_error("unable to convert instance ID GUID to native GUID (invalid NetCfgInstanceId in registry?)");
  549. }
  550. // Get the LUID, which is one of like four fucking ways to refer to a network device in Windows
  551. if (ConvertInterfaceGuidToLuid(&_deviceGuid,&_deviceLuid) != NO_ERROR)
  552. throw std::runtime_error("unable to convert device interface GUID to LUID");
  553. //_initialized = true;
  554. if (friendlyName)
  555. setFriendlyName(friendlyName);
  556. _injectSemaphore = CreateSemaphore(NULL,0,1,NULL);
  557. _thread = Thread::start(this);
  558. }
  559. WindowsEthernetTap::~WindowsEthernetTap()
  560. {
  561. _run = false;
  562. ReleaseSemaphore(_injectSemaphore,1,NULL);
  563. Thread::join(_thread);
  564. CloseHandle(_injectSemaphore);
  565. setPersistentTapDeviceState(_deviceInstanceId.c_str(),false);
  566. }
  567. void WindowsEthernetTap::setEnabled(bool en)
  568. {
  569. _enabled = en;
  570. }
  571. bool WindowsEthernetTap::enabled() const
  572. {
  573. return _enabled;
  574. }
  575. bool WindowsEthernetTap::addIp(const InetAddress &ip)
  576. {
  577. if (!ip.netmaskBits()) // sanity check... netmask of 0.0.0.0 is WUT?
  578. return false;
  579. Mutex::Lock _l(_assignedIps_m);
  580. if (std::find(_assignedIps.begin(),_assignedIps.end(),ip) != _assignedIps.end())
  581. return true;
  582. _assignedIps.push_back(ip);
  583. _syncIps();
  584. return true;
  585. }
  586. bool WindowsEthernetTap::removeIp(const InetAddress &ip)
  587. {
  588. if (ip.isV6())
  589. return true;
  590. {
  591. Mutex::Lock _l(_assignedIps_m);
  592. std::vector<InetAddress>::iterator aip(std::find(_assignedIps.begin(),_assignedIps.end(),ip));
  593. if (aip != _assignedIps.end())
  594. _assignedIps.erase(aip);
  595. }
  596. if (!_initialized)
  597. return false;
  598. try {
  599. MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0;
  600. if (GetUnicastIpAddressTable(AF_UNSPEC,&ipt) == NO_ERROR) {
  601. if ((ipt)&&(ipt->NumEntries > 0)) {
  602. for(DWORD i=0;i<(DWORD)ipt->NumEntries;++i) {
  603. if (ipt->Table[i].InterfaceLuid.Value == _deviceLuid.Value) {
  604. InetAddress addr;
  605. switch(ipt->Table[i].Address.si_family) {
  606. case AF_INET:
  607. addr.set(&(ipt->Table[i].Address.Ipv4.sin_addr.S_un.S_addr),4,ipt->Table[i].OnLinkPrefixLength);
  608. break;
  609. case AF_INET6:
  610. addr.set(ipt->Table[i].Address.Ipv6.sin6_addr.u.Byte,16,ipt->Table[i].OnLinkPrefixLength);
  611. if (addr.ipScope() == InetAddress::IP_SCOPE_LINK_LOCAL)
  612. continue; // can't remove link-local IPv6 addresses
  613. break;
  614. }
  615. if (addr == ip) {
  616. DeleteUnicastIpAddressEntry(&(ipt->Table[i]));
  617. FreeMibTable(ipt);
  618. if (ip.isV4()) {
  619. std::vector<std::string> regIps(_getRegistryIPv4Value("IPAddress"));
  620. std::vector<std::string> regSubnetMasks(_getRegistryIPv4Value("SubnetMask"));
  621. char ipbuf[64];
  622. std::string ipstr(ip.toIpString(ipbuf));
  623. for (std::vector<std::string>::iterator rip(regIps.begin()), rm(regSubnetMasks.begin()); ((rip != regIps.end()) && (rm != regSubnetMasks.end())); ++rip, ++rm) {
  624. if (*rip == ipstr) {
  625. regIps.erase(rip);
  626. regSubnetMasks.erase(rm);
  627. _setRegistryIPv4Value("IPAddress", regIps);
  628. _setRegistryIPv4Value("SubnetMask", regSubnetMasks);
  629. break;
  630. }
  631. }
  632. }
  633. return true;
  634. }
  635. }
  636. }
  637. }
  638. FreeMibTable((PVOID)ipt);
  639. }
  640. } catch ( ... ) {}
  641. return false;
  642. }
  643. std::vector<InetAddress> WindowsEthernetTap::ips() const
  644. {
  645. static const InetAddress linkLocalLoopback("fe80::1/64"); // what is this and why does Windows assign it?
  646. std::vector<InetAddress> addrs;
  647. if (!_initialized)
  648. return addrs;
  649. try {
  650. MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0;
  651. if (GetUnicastIpAddressTable(AF_UNSPEC,&ipt) == NO_ERROR) {
  652. if ((ipt)&&(ipt->NumEntries > 0)) {
  653. for(DWORD i=0;i<(DWORD)ipt->NumEntries;++i) {
  654. if (ipt->Table[i].InterfaceLuid.Value == _deviceLuid.Value) {
  655. switch(ipt->Table[i].Address.si_family) {
  656. case AF_INET: {
  657. InetAddress ip(&(ipt->Table[i].Address.Ipv4.sin_addr.S_un.S_addr),4,ipt->Table[i].OnLinkPrefixLength);
  658. if (ip != InetAddress::LO4)
  659. addrs.push_back(ip);
  660. } break;
  661. case AF_INET6: {
  662. InetAddress ip(ipt->Table[i].Address.Ipv6.sin6_addr.u.Byte,16,ipt->Table[i].OnLinkPrefixLength);
  663. if ((ip != linkLocalLoopback)&&(ip != InetAddress::LO6))
  664. addrs.push_back(ip);
  665. } break;
  666. }
  667. }
  668. }
  669. }
  670. FreeMibTable(ipt);
  671. }
  672. } catch ( ... ) {} // sanity check, shouldn't happen unless out of memory
  673. std::sort(addrs.begin(),addrs.end());
  674. addrs.erase(std::unique(addrs.begin(),addrs.end()),addrs.end());
  675. return addrs;
  676. }
  677. void WindowsEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
  678. {
  679. if ((!_initialized)||(!_enabled)||(_tap == INVALID_HANDLE_VALUE)||(len > _mtu))
  680. return;
  681. Mutex::Lock _l(_injectPending_m);
  682. _injectPending.emplace();
  683. _injectPending.back().len = len + 14;
  684. char *const d = _injectPending.back().data;
  685. to.copyTo(d,6);
  686. from.copyTo(d + 6,6);
  687. d[12] = (char)((etherType >> 8) & 0xff);
  688. d[13] = (char)(etherType & 0xff);
  689. memcpy(d + 14,data,len);
  690. ReleaseSemaphore(_injectSemaphore,1,NULL);
  691. }
  692. std::string WindowsEthernetTap::deviceName() const
  693. {
  694. char tmp[1024];
  695. if (ConvertInterfaceLuidToNameA(&_deviceLuid,tmp,sizeof(tmp)) != NO_ERROR)
  696. return std::string("[ConvertInterfaceLuidToName() failed]");
  697. return std::string(tmp);
  698. }
  699. void WindowsEthernetTap::setFriendlyName(const char *dn)
  700. {
  701. if (!_initialized)
  702. return;
  703. HKEY ifp;
  704. if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,(std::string("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\") + _netCfgInstanceId).c_str(),0,KEY_READ|KEY_WRITE,&ifp) == ERROR_SUCCESS) {
  705. RegSetKeyValueA(ifp,"Connection","Name",REG_SZ,(LPCVOID)dn,(DWORD)(strlen(dn)+1));
  706. RegCloseKey(ifp);
  707. }
  708. HRESULT hr = CoInitialize(nullptr);
  709. if (hr != S_OK) return;
  710. CoInitializeSecurity(NULL, -1, NULL, NULL,
  711. RPC_C_AUTHN_LEVEL_PKT,
  712. RPC_C_IMP_LEVEL_IMPERSONATE,
  713. NULL, EOAC_NONE, NULL);
  714. if (hr != S_OK) return;
  715. INetSharingManager *nsm;
  716. hr = CoCreateInstance(__uuidof(NetSharingManager), NULL, CLSCTX_ALL, __uuidof(INetSharingManager), (void**)&nsm);
  717. if (hr != S_OK) return;
  718. bool found = false;
  719. INetSharingEveryConnectionCollection *nsecc = nullptr;
  720. hr = nsm->get_EnumEveryConnection(&nsecc);
  721. if (!nsecc) {
  722. fprintf(stderr, "Failed to get NSM connections");
  723. return;
  724. }
  725. IEnumVARIANT *ev = nullptr;
  726. IUnknown *unk = nullptr;
  727. hr = nsecc->get__NewEnum(&unk);
  728. if (unk) {
  729. hr = unk->QueryInterface(__uuidof(IEnumVARIANT), (void**)&ev);
  730. unk->Release();
  731. }
  732. if (ev) {
  733. VARIANT v;
  734. VariantInit(&v);
  735. while ((S_OK == ev->Next(1, &v, NULL)) && found == FALSE) {
  736. if (V_VT(&v) == VT_UNKNOWN) {
  737. INetConnection *nc = nullptr;
  738. V_UNKNOWN(&v)->QueryInterface(__uuidof(INetConnection), (void**)&nc);
  739. if (nc) {
  740. NETCON_PROPERTIES *ncp = nullptr;
  741. nc->GetProperties(&ncp);
  742. GUID curId = ncp->guidId;
  743. if (curId == _deviceGuid) {
  744. wchar_t wtext[255];
  745. mbstowcs(wtext, dn, strlen(dn)+1);
  746. nc->Rename(wtext);
  747. found = true;
  748. }
  749. nc->Release();
  750. }
  751. }
  752. VariantClear(&v);
  753. }
  754. ev->Release();
  755. }
  756. nsecc->Release();
  757. }
  758. void WindowsEthernetTap::scanMulticastGroups(std::vector<MulticastGroup> &added,std::vector<MulticastGroup> &removed)
  759. {
  760. if (!_initialized)
  761. return;
  762. HANDLE t = _tap;
  763. if (t == INVALID_HANDLE_VALUE)
  764. return;
  765. std::vector<MulticastGroup> newGroups;
  766. // The ZT1 tap driver supports an IOCTL to get multicast memberships at the L2
  767. // level... something Windows does not seem to expose ordinarily. This lets
  768. // pretty much anything work... IPv4, IPv6, IPX, oldskool Netbios, who knows...
  769. unsigned char mcastbuf[TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS_OUTPUT_BUF_SIZE];
  770. DWORD bytesReturned = 0;
  771. if (DeviceIoControl(t,TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS,(LPVOID)mcastbuf,sizeof(mcastbuf),(LPVOID)mcastbuf,sizeof(mcastbuf),&bytesReturned,NULL)) {
  772. if ((bytesReturned > 0)&&(bytesReturned <= TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS_OUTPUT_BUF_SIZE)) { // sanity check
  773. MAC mac;
  774. DWORD i = 0;
  775. while ((i + 6) <= bytesReturned) {
  776. mac.setTo(mcastbuf + i,6);
  777. i += 6;
  778. if ((mac.isMulticast())&&(!mac.isBroadcast())) {
  779. // exclude the nulls that may be returned or any other junk Windows puts in there
  780. newGroups.push_back(MulticastGroup(mac,0));
  781. }
  782. }
  783. }
  784. }
  785. std::vector<InetAddress> allIps(ips());
  786. for(std::vector<InetAddress>::iterator ip(allIps.begin());ip!=allIps.end();++ip)
  787. newGroups.push_back(MulticastGroup::deriveMulticastGroupForAddressResolution(*ip));
  788. std::sort(newGroups.begin(),newGroups.end());
  789. newGroups.erase(std::unique(newGroups.begin(),newGroups.end()),newGroups.end());
  790. for(std::vector<MulticastGroup>::iterator m(newGroups.begin());m!=newGroups.end();++m) {
  791. if (!std::binary_search(_multicastGroups.begin(),_multicastGroups.end(),*m))
  792. added.push_back(*m);
  793. }
  794. for(std::vector<MulticastGroup>::iterator m(_multicastGroups.begin());m!=_multicastGroups.end();++m) {
  795. if (!std::binary_search(newGroups.begin(),newGroups.end(),*m))
  796. removed.push_back(*m);
  797. }
  798. _multicastGroups.swap(newGroups);
  799. }
  800. void WindowsEthernetTap::setMtu(unsigned int mtu)
  801. {
  802. if (mtu != _mtu) {
  803. _mtu = mtu;
  804. HKEY nwAdapters;
  805. if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 0, KEY_READ | KEY_WRITE, &nwAdapters) == ERROR_SUCCESS) {
  806. char tmps[64];
  807. unsigned int tmpsl = OSUtils::ztsnprintf(tmps, sizeof(tmps), "%d", mtu);
  808. RegSetKeyValueA(nwAdapters, _mySubkeyName.c_str(), "MTU", REG_SZ, tmps, tmpsl);
  809. RegCloseKey(nwAdapters);
  810. }
  811. }
  812. }
  813. NET_IFINDEX WindowsEthernetTap::interfaceIndex() const
  814. {
  815. NET_IFINDEX idx = -1;
  816. if (ConvertInterfaceLuidToIndex(&_deviceLuid,&idx) == NO_ERROR)
  817. return idx;
  818. return -1;
  819. }
  820. void WindowsEthernetTap::threadMain()
  821. throw()
  822. {
  823. char tapReadBuf[ZT_MAX_MTU + 32];
  824. char tapPath[128];
  825. HANDLE wait4[3];
  826. OVERLAPPED tapOvlRead,tapOvlWrite;
  827. OSUtils::ztsnprintf(tapPath,sizeof(tapPath),"\\\\.\\Global\\%s.tap",_netCfgInstanceId.c_str());
  828. try {
  829. while (_run) {
  830. // Because Windows
  831. Sleep(250);
  832. setPersistentTapDeviceState(_deviceInstanceId.c_str(),false);
  833. Sleep(250);
  834. setPersistentTapDeviceState(_deviceInstanceId.c_str(),true);
  835. Sleep(250);
  836. setPersistentTapDeviceState(_deviceInstanceId.c_str(),false);
  837. Sleep(250);
  838. setPersistentTapDeviceState(_deviceInstanceId.c_str(),true);
  839. Sleep(250);
  840. _tap = CreateFileA(tapPath,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM|FILE_FLAG_OVERLAPPED,NULL);
  841. if (_tap == INVALID_HANDLE_VALUE) {
  842. Sleep(250);
  843. continue;
  844. }
  845. {
  846. uint32_t tmpi = 1;
  847. DWORD bytesReturned = 0;
  848. DeviceIoControl(_tap,TAP_WIN_IOCTL_SET_MEDIA_STATUS,&tmpi,sizeof(tmpi),&tmpi,sizeof(tmpi),&bytesReturned,NULL);
  849. }
  850. #ifdef ZT_WINDOWS_CREATE_FAKE_DEFAULT_ROUTE
  851. {
  852. /* This inserts a fake default route and a fake ARP entry, forcing
  853. * Windows to detect this as a "real" network and apply proper
  854. * firewall rules.
  855. *
  856. * This hack is completely stupid, but Windows made me do it
  857. * by being broken and insane.
  858. *
  859. * Background: Windows tries to detect its network location by
  860. * matching it to the ARP address of the default route. Networks
  861. * without default routes are "unidentified networks" and cannot
  862. * have their firewall classification changed by the user (easily).
  863. *
  864. * Yes, you read that right.
  865. *
  866. * The common workaround is to set *NdisDeviceType to 1, which
  867. * totally disables all Windows firewall functionality. This is
  868. * the answer you'll find on most forums for things like OpenVPN.
  869. *
  870. * Yes, you read that right.
  871. *
  872. * The default route workaround is also known, but for this to
  873. * work there must be a known default IP that resolves to a known
  874. * ARP address. This works for an OpenVPN tunnel, but not here
  875. * because this isn't a tunnel. It's a mesh. There is no "other
  876. * end," or any other known always on IP.
  877. *
  878. * So let's make a fake one and shove it in there along with its
  879. * fake static ARP entry. Also makes it instant-on and static.
  880. *
  881. * We'll have to see what DHCP does with this. In the future we
  882. * probably will not want to do this on DHCP-enabled networks, so
  883. * when we enable DHCP we will go in and yank this wacko hacko from
  884. * the routing table before doing so.
  885. *
  886. * Like Jesse Pinkman would say: "YEEEEAAH BITCH!" */
  887. const uint32_t fakeIp = htonl(0x19fffffe); // 25.255.255.254 -- unrouted IPv4 block
  888. for(int i=0;i<8;++i) {
  889. MIB_IPNET_ROW2 ipnr;
  890. memset(&ipnr,0,sizeof(ipnr));
  891. ipnr.Address.si_family = AF_INET;
  892. ipnr.Address.Ipv4.sin_addr.s_addr = fakeIp;
  893. ipnr.InterfaceLuid.Value = _deviceLuid.Value;
  894. ipnr.PhysicalAddress[0] = _mac[0] ^ 0x10; // just make something up that's consistent and not part of this net
  895. ipnr.PhysicalAddress[1] = 0x00;
  896. ipnr.PhysicalAddress[2] = (UCHAR)((_deviceGuid.Data1 >> 24) & 0xff);
  897. ipnr.PhysicalAddress[3] = (UCHAR)((_deviceGuid.Data1 >> 16) & 0xff);
  898. ipnr.PhysicalAddress[4] = (UCHAR)((_deviceGuid.Data1 >> 8) & 0xff);
  899. ipnr.PhysicalAddress[5] = (UCHAR)(_deviceGuid.Data1 & 0xff);
  900. ipnr.PhysicalAddressLength = 6;
  901. ipnr.State = NlnsPermanent;
  902. ipnr.IsRouter = 1;
  903. ipnr.IsUnreachable = 0;
  904. ipnr.ReachabilityTime.LastReachable = 0x0fffffff;
  905. ipnr.ReachabilityTime.LastUnreachable = 1;
  906. DWORD result = CreateIpNetEntry2(&ipnr);
  907. if (result != NO_ERROR)
  908. Sleep(250);
  909. else break;
  910. }
  911. for(int i=0;i<8;++i) {
  912. MIB_IPFORWARD_ROW2 nr;
  913. memset(&nr,0,sizeof(nr));
  914. InitializeIpForwardEntry(&nr);
  915. nr.InterfaceLuid.Value = _deviceLuid.Value;
  916. nr.DestinationPrefix.Prefix.si_family = AF_INET; // rest is left as 0.0.0.0/0
  917. nr.NextHop.si_family = AF_INET;
  918. nr.NextHop.Ipv4.sin_addr.s_addr = fakeIp;
  919. nr.Metric = 9999; // do not use as real default route
  920. nr.Protocol = MIB_IPPROTO_NETMGMT;
  921. DWORD result = CreateIpForwardEntry2(&nr);
  922. if (result != NO_ERROR)
  923. Sleep(250);
  924. else break;
  925. }
  926. }
  927. #endif
  928. // Assign or re-assign any should-be-assigned IPs in case we have restarted
  929. {
  930. Mutex::Lock _l(_assignedIps_m);
  931. _syncIps();
  932. }
  933. memset(&tapOvlRead,0,sizeof(tapOvlRead));
  934. tapOvlRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
  935. memset(&tapOvlWrite,0,sizeof(tapOvlWrite));
  936. tapOvlWrite.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
  937. wait4[0] = _injectSemaphore;
  938. wait4[1] = tapOvlRead.hEvent;
  939. wait4[2] = tapOvlWrite.hEvent; // only included if writeInProgress is true
  940. ReadFile(_tap,tapReadBuf,sizeof(tapReadBuf),NULL,&tapOvlRead);
  941. bool writeInProgress = false;
  942. ULONGLONG timeOfLastBorkCheck = GetTickCount64();
  943. _initialized = true;
  944. unsigned int oldmtu = _mtu;
  945. setFriendlyName(_friendlyName.c_str());
  946. while (_run) {
  947. DWORD waitResult = WaitForMultipleObjectsEx(writeInProgress ? 3 : 2,wait4,FALSE,2500,TRUE);
  948. if (!_run) break; // will also break outer while(_run) since _run is false
  949. // Check for changes in MTU and break to restart tap device to reconfigure in this case
  950. if (_mtu != oldmtu)
  951. break;
  952. // Check for issues with adapter and close/reopen if any are detected. This
  953. // check fixes a while boatload of Windows adapter 'coma' issues after
  954. // sleep/wake and when adapters are added/removed. Basically if the tap
  955. // device is borked, whack it.
  956. {
  957. ULONGLONG tc = GetTickCount64();
  958. if ((tc - timeOfLastBorkCheck) >= 2500) {
  959. timeOfLastBorkCheck = tc;
  960. char aabuf[16384];
  961. ULONG aalen = sizeof(aabuf);
  962. if (GetAdaptersAddresses(AF_UNSPEC,GAA_FLAG_SKIP_UNICAST|GAA_FLAG_SKIP_ANYCAST|GAA_FLAG_SKIP_MULTICAST|GAA_FLAG_SKIP_DNS_SERVER|GAA_FLAG_SKIP_FRIENDLY_NAME,(void *)0,reinterpret_cast<PIP_ADAPTER_ADDRESSES>(aabuf),&aalen) == NO_ERROR) {
  963. bool isBorked = false;
  964. PIP_ADAPTER_ADDRESSES aa = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(aabuf);
  965. while (aa) {
  966. if (_deviceLuid.Value == aa->Luid.Value) {
  967. isBorked = (aa->OperStatus != IfOperStatusUp);
  968. break;
  969. }
  970. aa = aa->Next;
  971. }
  972. if (isBorked) {
  973. // Close and reopen tap device if there's an issue (outer loop)
  974. break;
  975. }
  976. }
  977. }
  978. }
  979. if ((waitResult == WAIT_TIMEOUT)||(waitResult == WAIT_FAILED)) {
  980. Sleep(250); // guard against spinning under some conditions
  981. continue;
  982. }
  983. if (HasOverlappedIoCompleted(&tapOvlRead)) {
  984. DWORD bytesRead = 0;
  985. if (GetOverlappedResult(_tap,&tapOvlRead,&bytesRead,FALSE)) {
  986. if ((bytesRead > 14)&&(_enabled)) {
  987. MAC to(tapReadBuf,6);
  988. MAC from(tapReadBuf + 6,6);
  989. unsigned int etherType = ((((unsigned int)tapReadBuf[12]) & 0xff) << 8) | (((unsigned int)tapReadBuf[13]) & 0xff);
  990. try {
  991. _handler(_arg,(void *)0,_nwid,from,to,etherType,0,tapReadBuf + 14,bytesRead - 14);
  992. } catch ( ... ) {} // handlers should not throw
  993. }
  994. }
  995. ReadFile(_tap,tapReadBuf,ZT_MAX_MTU + 32,NULL,&tapOvlRead);
  996. }
  997. if (writeInProgress) {
  998. if (HasOverlappedIoCompleted(&tapOvlWrite)) {
  999. writeInProgress = false;
  1000. _injectPending_m.lock();
  1001. _injectPending.pop();
  1002. } else continue; // still writing, so skip code below and wait
  1003. } else _injectPending_m.lock();
  1004. if (!_injectPending.empty()) {
  1005. WriteFile(_tap,_injectPending.front().data,_injectPending.front().len,NULL,&tapOvlWrite);
  1006. writeInProgress = true;
  1007. }
  1008. _injectPending_m.unlock();
  1009. }
  1010. CancelIo(_tap);
  1011. CloseHandle(tapOvlRead.hEvent);
  1012. CloseHandle(tapOvlWrite.hEvent);
  1013. CloseHandle(_tap);
  1014. _tap = INVALID_HANDLE_VALUE;
  1015. // We will restart and re-open the tap unless _run == false
  1016. }
  1017. } catch ( ... ) {} // catch unexpected exceptions -- this should not happen but would prevent program crash or other weird issues since threads should not throw
  1018. }
  1019. NET_IFINDEX WindowsEthernetTap::_getDeviceIndex()
  1020. {
  1021. MIB_IF_TABLE2 *ift = (MIB_IF_TABLE2 *)0;
  1022. if (GetIfTable2Ex(MibIfTableRaw,&ift) != NO_ERROR)
  1023. throw std::runtime_error("GetIfTable2Ex() failed");
  1024. if (ift->NumEntries > 0) {
  1025. for(ULONG i=0;i<ift->NumEntries;++i) {
  1026. if (ift->Table[i].InterfaceLuid.Value == _deviceLuid.Value) {
  1027. NET_IFINDEX idx = ift->Table[i].InterfaceIndex;
  1028. FreeMibTable(ift);
  1029. return idx;
  1030. }
  1031. }
  1032. }
  1033. FreeMibTable(&ift);
  1034. throw std::runtime_error("interface not found");
  1035. }
  1036. std::vector<std::string> WindowsEthernetTap::_getRegistryIPv4Value(const char *regKey)
  1037. {
  1038. std::vector<std::string> value;
  1039. HKEY tcpIpInterfaces;
  1040. if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces",0,KEY_READ|KEY_WRITE,&tcpIpInterfaces) == ERROR_SUCCESS) {
  1041. char buf[16384];
  1042. DWORD len = sizeof(buf);
  1043. DWORD kt = REG_MULTI_SZ;
  1044. if (RegGetValueA(tcpIpInterfaces,_netCfgInstanceId.c_str(),regKey,0,&kt,&buf,&len) == ERROR_SUCCESS) {
  1045. switch(kt) {
  1046. case REG_SZ:
  1047. if (len > 0)
  1048. value.push_back(std::string(buf));
  1049. break;
  1050. case REG_MULTI_SZ: {
  1051. for(DWORD k=0,s=0;k<len;++k) {
  1052. if (!buf[k]) {
  1053. if (s < k) {
  1054. value.push_back(std::string(buf + s));
  1055. s = k + 1;
  1056. } else break;
  1057. }
  1058. }
  1059. } break;
  1060. }
  1061. }
  1062. RegCloseKey(tcpIpInterfaces);
  1063. }
  1064. return value;
  1065. }
  1066. void WindowsEthernetTap::_setRegistryIPv4Value(const char *regKey,const std::vector<std::string> &value)
  1067. {
  1068. std::string regMulti;
  1069. for(std::vector<std::string>::const_iterator s(value.begin());s!=value.end();++s) {
  1070. regMulti.append(*s);
  1071. regMulti.push_back((char)0);
  1072. }
  1073. HKEY tcpIpInterfaces;
  1074. if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces",0,KEY_READ|KEY_WRITE,&tcpIpInterfaces) == ERROR_SUCCESS) {
  1075. if (regMulti.length() > 0) {
  1076. regMulti.push_back((char)0);
  1077. RegSetKeyValueA(tcpIpInterfaces,_netCfgInstanceId.c_str(),regKey,REG_MULTI_SZ,regMulti.data(),(DWORD)regMulti.length());
  1078. } else {
  1079. RegDeleteKeyValueA(tcpIpInterfaces,_netCfgInstanceId.c_str(),regKey);
  1080. }
  1081. RegCloseKey(tcpIpInterfaces);
  1082. }
  1083. }
  1084. void WindowsEthernetTap::_syncIps()
  1085. {
  1086. // assumes _assignedIps_m is locked
  1087. if (!_initialized)
  1088. return;
  1089. std::vector<InetAddress> haveIps(ips());
  1090. for(std::vector<InetAddress>::const_iterator aip(_assignedIps.begin());aip!=_assignedIps.end();++aip) {
  1091. if (std::find(haveIps.begin(),haveIps.end(),*aip) == haveIps.end()) {
  1092. MIB_UNICASTIPADDRESS_ROW ipr;
  1093. InitializeUnicastIpAddressEntry(&ipr);
  1094. if (aip->isV4()) {
  1095. ipr.Address.Ipv4.sin_family = AF_INET;
  1096. ipr.Address.Ipv4.sin_addr.S_un.S_addr = *((const uint32_t *)aip->rawIpData());
  1097. ipr.OnLinkPrefixLength = aip->netmaskBits();
  1098. if (ipr.OnLinkPrefixLength >= 32)
  1099. continue;
  1100. } else if (aip->isV6()) {
  1101. ipr.Address.Ipv6.sin6_family = AF_INET6;
  1102. memcpy(ipr.Address.Ipv6.sin6_addr.u.Byte,aip->rawIpData(),16);
  1103. ipr.OnLinkPrefixLength = aip->netmaskBits();
  1104. if (ipr.OnLinkPrefixLength >= 128)
  1105. continue;
  1106. } else continue;
  1107. ipr.PrefixOrigin = IpPrefixOriginManual;
  1108. ipr.SuffixOrigin = IpSuffixOriginManual;
  1109. ipr.ValidLifetime = 0xffffffff;
  1110. ipr.PreferredLifetime = 0xffffffff;
  1111. ipr.InterfaceLuid = _deviceLuid;
  1112. ipr.InterfaceIndex = _getDeviceIndex();
  1113. CreateUnicastIpAddressEntry(&ipr);
  1114. }
  1115. if (aip->isV4()) {
  1116. char ipbuf[64];
  1117. std::string ipStr(aip->toIpString(ipbuf));
  1118. std::vector<std::string> regIps(_getRegistryIPv4Value("IPAddress"));
  1119. if (std::find(regIps.begin(), regIps.end(), ipStr) == regIps.end()) {
  1120. std::vector<std::string> regSubnetMasks(_getRegistryIPv4Value("SubnetMask"));
  1121. regIps.push_back(ipStr);
  1122. regSubnetMasks.push_back(aip->netmask().toIpString(ipbuf));
  1123. _setRegistryIPv4Value("IPAddress", regIps);
  1124. _setRegistryIPv4Value("SubnetMask", regSubnetMasks);
  1125. }
  1126. }
  1127. }
  1128. }
  1129. } // namespace ZeroTier