EthernetTap.cpp 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469
  1. /*
  2. * ZeroTier One - Global Peer to Peer Ethernet
  3. * Copyright (C) 2012-2013 ZeroTier Networks LLC
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. * --
  19. *
  20. * ZeroTier may be used and distributed under the terms of the GPLv3, which
  21. * are available at: http://www.gnu.org/licenses/gpl-3.0.html
  22. *
  23. * If you would like to embed ZeroTier into a commercial application or
  24. * redistribute it in a modified binary form, please contact ZeroTier Networks
  25. * LLC. Start here: http://www.zerotier.com/
  26. */
  27. #include <string>
  28. #include <map>
  29. #include <set>
  30. #include <algorithm>
  31. #include "Constants.hpp"
  32. #include "EthernetTap.hpp"
  33. #include "Logger.hpp"
  34. #include "RuntimeEnvironment.hpp"
  35. #include "Utils.hpp"
  36. #include "Mutex.hpp"
  37. #include "Utils.hpp"
  38. // ff:ff:ff:ff:ff:ff with no ADI
  39. static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff),0);
  40. //
  41. // TAP implementation for *nix OSes, with some specialization for different flavors
  42. //
  43. #ifdef __UNIX_LIKE__ /////////////////////////////////////////////////////////
  44. #include <stdint.h>
  45. #include <stdio.h>
  46. #include <stdlib.h>
  47. #include <string.h>
  48. #include <unistd.h>
  49. #include <signal.h>
  50. #include <fcntl.h>
  51. #include <errno.h>
  52. #include <sys/types.h>
  53. #include <sys/stat.h>
  54. #include <sys/ioctl.h>
  55. #include <sys/wait.h>
  56. #include <sys/select.h>
  57. #include <netinet/in.h>
  58. #include <net/if_arp.h>
  59. #include <arpa/inet.h>
  60. // Command identifiers used with command finder static (on various *nixes)
  61. #define ZT_UNIX_IP_COMMAND 1
  62. #define ZT_UNIX_IFCONFIG_COMMAND 2
  63. #define ZT_MAC_KEXTLOAD_COMMAND 3
  64. #define ZT_MAC_IPCONFIG_COMMAND 4
  65. #define ZT_MAC_KEXTUNLOAD_COMMAND 5
  66. // Finds external commands on startup
  67. class _CommandFinder
  68. {
  69. public:
  70. _CommandFinder()
  71. {
  72. _findCmd(ZT_UNIX_IFCONFIG_COMMAND,"ifconfig");
  73. #ifdef __LINUX__
  74. _findCmd(ZT_UNIX_IP_COMMAND,"ip");
  75. #endif
  76. #ifdef __APPLE__
  77. _findCmd(ZT_MAC_KEXTLOAD_COMMAND,"kextload");
  78. _findCmd(ZT_MAC_IPCONFIG_COMMAND,"ipconfig");
  79. _findCmd(ZT_MAC_KEXTUNLOAD_COMMAND,"kextunload");
  80. #endif
  81. }
  82. // returns NULL if command was not found
  83. inline const char *operator[](int id) const
  84. throw()
  85. {
  86. std::map<int,std::string>::const_iterator c(_paths.find(id));
  87. if (c == _paths.end())
  88. return (const char *)0;
  89. return c->second.c_str();
  90. }
  91. private:
  92. inline void _findCmd(int id,const char *name)
  93. {
  94. char tmp[4096];
  95. ZeroTier::Utils::snprintf(tmp,sizeof(tmp),"/sbin/%s",name);
  96. if (ZeroTier::Utils::fileExists(tmp)) {
  97. _paths[id] = tmp;
  98. return;
  99. }
  100. ZeroTier::Utils::snprintf(tmp,sizeof(tmp),"/usr/sbin/%s",name);
  101. if (ZeroTier::Utils::fileExists(tmp)) {
  102. _paths[id] = tmp;
  103. return;
  104. }
  105. ZeroTier::Utils::snprintf(tmp,sizeof(tmp),"/bin/%s",name);
  106. if (ZeroTier::Utils::fileExists(tmp)) {
  107. _paths[id] = tmp;
  108. return;
  109. }
  110. ZeroTier::Utils::snprintf(tmp,sizeof(tmp),"/usr/bin/%s",name);
  111. if (ZeroTier::Utils::fileExists(tmp)) {
  112. _paths[id] = tmp;
  113. return;
  114. }
  115. }
  116. std::map<int,std::string> _paths;
  117. };
  118. static const _CommandFinder UNIX_COMMANDS;
  119. #ifdef __LINUX__
  120. #include <linux/if.h>
  121. #include <linux/if_tun.h>
  122. #include <linux/if_addr.h>
  123. #include <linux/if_ether.h>
  124. #endif // __LINUX__
  125. #ifdef __APPLE__
  126. #include <sys/cdefs.h>
  127. #include <sys/uio.h>
  128. #include <sys/param.h>
  129. #include <sys/sysctl.h>
  130. #include <net/route.h>
  131. #include <net/if.h>
  132. #include <net/if_dl.h>
  133. #include <ifaddrs.h>
  134. static volatile int EthernetTap_instances = 0;
  135. static ZeroTier::Mutex EthernetTap_instances_m;
  136. #endif // __APPLE__
  137. namespace ZeroTier {
  138. // Only permit one tap to be opened concurrently across the entire process
  139. static Mutex __tapCreateLock;
  140. #ifdef __LINUX__
  141. EthernetTap::EthernetTap(
  142. const RuntimeEnvironment *renv,
  143. const char *tag,
  144. const MAC &mac,
  145. unsigned int mtu,
  146. void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &),
  147. void *arg)
  148. throw(std::runtime_error) :
  149. _mac(mac),
  150. _mtu(mtu),
  151. _r(renv),
  152. _handler(handler),
  153. _arg(arg),
  154. _fd(0)
  155. {
  156. char procpath[128];
  157. Mutex::Lock _l(__tapCreateLock); // create only one tap at a time, globally
  158. if (mtu > 4096)
  159. throw std::runtime_error("max tap MTU is 4096");
  160. _fd = ::open("/dev/net/tun",O_RDWR);
  161. if (_fd <= 0)
  162. throw std::runtime_error(std::string("could not open TUN/TAP device: ") + strerror(errno));
  163. struct ifreq ifr;
  164. memset(&ifr,0,sizeof(ifr));
  165. { // pick an unused device name
  166. int devno = 0;
  167. struct stat sbuf;
  168. do {
  169. Utils::snprintf(ifr.ifr_name,sizeof(ifr.ifr_name),"zt%d",devno++);
  170. Utils::snprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name);
  171. } while (stat(procpath,&sbuf) == 0);
  172. }
  173. ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
  174. if (ioctl(_fd,TUNSETIFF,(void *)&ifr) < 0) {
  175. ::close(_fd);
  176. throw std::runtime_error("unable to configure TUN/TAP device for TAP operation");
  177. }
  178. strcpy(_dev,ifr.ifr_name);
  179. ioctl(_fd,TUNSETPERSIST,0); // valgrind may generate a false alarm here
  180. // Open an arbitrary socket to talk to netlink
  181. int sock = socket(AF_INET,SOCK_DGRAM,0);
  182. if (sock <= 0) {
  183. ::close(_fd);
  184. throw std::runtime_error("unable to open netlink socket");
  185. }
  186. // Set MAC address
  187. ifr.ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_ETHER;
  188. memcpy(ifr.ifr_ifru.ifru_hwaddr.sa_data,mac.data,6);
  189. if (ioctl(sock,SIOCSIFHWADDR,(void *)&ifr) < 0) {
  190. ::close(_fd);
  191. ::close(sock);
  192. throw std::runtime_error("unable to configure TAP hardware (MAC) address");
  193. return;
  194. }
  195. // Set MTU
  196. ifr.ifr_ifru.ifru_mtu = (int)mtu;
  197. if (ioctl(sock,SIOCSIFMTU,(void *)&ifr) < 0) {
  198. ::close(_fd);
  199. ::close(sock);
  200. throw std::runtime_error("unable to configure TAP MTU");
  201. }
  202. if (fcntl(_fd,F_SETFL,fcntl(_fd,F_GETFL) & ~O_NONBLOCK) == -1) {
  203. ::close(_fd);
  204. throw std::runtime_error("unable to set flags on file descriptor for TAP device");
  205. }
  206. /* Bring interface up */
  207. if (ioctl(sock,SIOCGIFFLAGS,(void *)&ifr) < 0) {
  208. ::close(_fd);
  209. ::close(sock);
  210. throw std::runtime_error("unable to get TAP interface flags");
  211. }
  212. ifr.ifr_flags |= IFF_UP;
  213. if (ioctl(sock,SIOCSIFFLAGS,(void *)&ifr) < 0) {
  214. ::close(_fd);
  215. ::close(sock);
  216. throw std::runtime_error("unable to set TAP interface flags");
  217. }
  218. ::close(sock);
  219. ::pipe(_shutdownSignalPipe);
  220. TRACE("tap %s created",_dev);
  221. _thread = Thread::start(this);
  222. }
  223. #endif // __LINUX__
  224. #ifdef __APPLE__
  225. EthernetTap::EthernetTap(
  226. const RuntimeEnvironment *renv,
  227. const char *tag,
  228. const MAC &mac,
  229. unsigned int mtu,
  230. void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &),
  231. void *arg)
  232. throw(std::runtime_error) :
  233. _mac(mac),
  234. _mtu(mtu),
  235. _r(renv),
  236. _handler(handler),
  237. _arg(arg),
  238. _fd(0)
  239. {
  240. char devpath[64],ethaddr[64],mtustr[16],tmp[4096];
  241. struct stat stattmp;
  242. Mutex::Lock _l(__tapCreateLock); // create only one tap at a time, globally
  243. if (mtu > 4096)
  244. throw std::runtime_error("max tap MTU is 4096");
  245. // Check for existence of ZT tap devices, try to load module if not there
  246. const char *kextload = UNIX_COMMANDS[ZT_MAC_KEXTLOAD_COMMAND];
  247. if ((stat("/dev/zt0",&stattmp))&&(kextload)) {
  248. strcpy(tmp,_r->homePath.c_str());
  249. long kextpid = (long)vfork();
  250. if (kextpid == 0) {
  251. chdir(tmp);
  252. execl(kextload,kextload,"-q","-repository",tmp,"tap.kext",(const char *)0);
  253. _exit(-1);
  254. } else if (kextpid > 0) {
  255. int exitcode = -1;
  256. waitpid(kextpid,&exitcode,0);
  257. usleep(500);
  258. } else throw std::runtime_error("unable to create subprocess with fork()");
  259. }
  260. if (stat("/dev/zt0",&stattmp))
  261. throw std::runtime_error("/dev/zt# tap devices do not exist and unable to load kernel extension");
  262. // Open the first available device (ones in use will fail with resource busy)
  263. for(int i=0;i<256;++i) {
  264. Utils::snprintf(devpath,sizeof(devpath),"/dev/zt%d",i);
  265. if (stat(devpath,&stattmp))
  266. throw std::runtime_error("no more TAP devices available");
  267. _fd = ::open(devpath,O_RDWR);
  268. if (_fd > 0) {
  269. Utils::snprintf(_dev,sizeof(_dev),"zt%d",i);
  270. break;
  271. }
  272. }
  273. if (_fd <= 0)
  274. throw std::runtime_error("unable to open TAP device or no more devices available");
  275. if (fcntl(_fd,F_SETFL,fcntl(_fd,F_GETFL) & ~O_NONBLOCK) == -1) {
  276. ::close(_fd);
  277. throw std::runtime_error("unable to set flags on file descriptor for TAP device");
  278. }
  279. const char *ifconfig = UNIX_COMMANDS[ZT_UNIX_IFCONFIG_COMMAND];
  280. if (!ifconfig) {
  281. ::close(_fd);
  282. throw std::runtime_error("unable to find 'ifconfig' command on system");
  283. }
  284. // Configure MAC address and MTU, bring interface up
  285. Utils::snprintf(ethaddr,sizeof(ethaddr),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(int)mac[0],(int)mac[1],(int)mac[2],(int)mac[3],(int)mac[4],(int)mac[5]);
  286. Utils::snprintf(mtustr,sizeof(mtustr),"%u",mtu);
  287. long cpid;
  288. if ((cpid = (long)vfork()) == 0) {
  289. execl(ifconfig,ifconfig,_dev,"lladdr",ethaddr,"mtu",mtustr,"up",(const char *)0);
  290. _exit(-1);
  291. } else {
  292. int exitcode = -1;
  293. waitpid(cpid,&exitcode,0);
  294. if (exitcode) {
  295. ::close(_fd);
  296. throw std::runtime_error("ifconfig failure setting link-layer address and activating tap interface");
  297. }
  298. }
  299. whack(); // turns on IPv6 on OSX
  300. ::pipe(_shutdownSignalPipe);
  301. _thread = Thread::start(this);
  302. EthernetTap_instances_m.lock();
  303. ++EthernetTap_instances;
  304. EthernetTap_instances_m.unlock();
  305. }
  306. #endif // __APPLE__
  307. EthernetTap::~EthernetTap()
  308. {
  309. ::write(_shutdownSignalPipe[1],"\0",1); // causes thread to exit
  310. Thread::join(_thread);
  311. ::close(_fd);
  312. #ifdef __APPLE__
  313. EthernetTap_instances_m.lock();
  314. int instances = --EthernetTap_instances;
  315. EthernetTap_instances_m.unlock();
  316. if (instances <= 0) {
  317. // Unload OSX kernel extension on the deletion of the last EthernetTap
  318. // instance.
  319. const char *kextunload = UNIX_COMMANDS[ZT_MAC_KEXTUNLOAD_COMMAND];
  320. if (kextunload) {
  321. char tmp[4096];
  322. sprintf(tmp,"%s/tap.kext",_r->homePath.c_str());
  323. long kextpid = (long)vfork();
  324. if (kextpid == 0) {
  325. execl(kextunload,kextunload,tmp,(const char *)0);
  326. _exit(-1);
  327. } else if (kextpid > 0) {
  328. int exitcode = -1;
  329. waitpid(kextpid,&exitcode,0);
  330. }
  331. }
  332. }
  333. #endif // __APPLE__
  334. }
  335. #ifdef __APPLE__
  336. void EthernetTap::whack()
  337. {
  338. const char *ipconfig = UNIX_COMMANDS[ZT_MAC_IPCONFIG_COMMAND];
  339. if (ipconfig) {
  340. long cpid = (long)vfork();
  341. if (cpid == 0) {
  342. execl(ipconfig,ipconfig,"set",_dev,"AUTOMATIC-V6",(const char *)0);
  343. _exit(-1);
  344. } else if (cpid > 0) {
  345. int exitcode = -1;
  346. waitpid(cpid,&exitcode,0);
  347. }
  348. }
  349. }
  350. #else
  351. void EthernetTap::whack() {}
  352. #endif // __APPLE__ / !__APPLE__
  353. void EthernetTap::setDisplayName(const char *dn)
  354. {
  355. }
  356. #ifdef __LINUX__
  357. static bool ___removeIp(const char *_dev,const InetAddress &ip)
  358. {
  359. const char *ipcmd = UNIX_COMMANDS[ZT_UNIX_IP_COMMAND];
  360. if (!ipcmd)
  361. return false;
  362. long cpid = (long)vfork();
  363. if (cpid == 0) {
  364. execl(ipcmd,ipcmd,"addr","del",ip.toString().c_str(),"dev",_dev,(const char *)0);
  365. _exit(-1);
  366. } else {
  367. int exitcode = -1;
  368. waitpid(cpid,&exitcode,0);
  369. return (exitcode == 0);
  370. }
  371. }
  372. bool EthernetTap::addIP(const InetAddress &ip)
  373. {
  374. const char *ipcmd = UNIX_COMMANDS[ZT_UNIX_IP_COMMAND];
  375. if (!ipcmd) {
  376. LOG("ERROR: could not configure IP address for %s: unable to find 'ip' command on system (checked /sbin, /bin, /usr/sbin, /usr/bin)",_dev);
  377. return false;
  378. }
  379. Mutex::Lock _l(_ips_m);
  380. if (!ip)
  381. return false;
  382. if (_ips.count(ip) > 0)
  383. return true;
  384. // Remove and reconfigure if address is the same but netmask is different
  385. for(std::set<InetAddress>::iterator i(_ips.begin());i!=_ips.end();++i) {
  386. if (i->ipsEqual(ip)) {
  387. if (___removeIp(_dev,*i)) {
  388. _ips.erase(i);
  389. break;
  390. } else {
  391. LOG("WARNING: failed to remove old IP/netmask %s to replace with %s",i->toString().c_str(),ip.toString().c_str());
  392. }
  393. }
  394. }
  395. long cpid;
  396. if ((cpid = (long)vfork()) == 0) {
  397. execl(ipcmd,ipcmd,"addr","add",ip.toString().c_str(),"dev",_dev,(const char *)0);
  398. _exit(-1);
  399. } else {
  400. int exitcode = -1;
  401. waitpid(cpid,&exitcode,0);
  402. if (exitcode == 0) {
  403. _ips.insert(ip);
  404. return true;
  405. } else return false;
  406. }
  407. return false;
  408. }
  409. #endif // __LINUX__
  410. #ifdef __APPLE__
  411. static bool ___removeIp(const char *_dev,const InetAddress &ip)
  412. {
  413. const char *ifconfig = UNIX_COMMANDS[ZT_UNIX_IFCONFIG_COMMAND];
  414. if (!ifconfig)
  415. return false;
  416. long cpid;
  417. if ((cpid = (long)vfork()) == 0) {
  418. execl(ifconfig,ifconfig,_dev,"inet",ip.toIpString().c_str(),"-alias",(const char *)0);
  419. _exit(-1);
  420. } else {
  421. int exitcode = -1;
  422. waitpid(cpid,&exitcode,0);
  423. return (exitcode == 0);
  424. }
  425. return false; // never reached, make compiler shut up about return value
  426. }
  427. bool EthernetTap::addIP(const InetAddress &ip)
  428. {
  429. const char *ifconfig = UNIX_COMMANDS[ZT_UNIX_IFCONFIG_COMMAND];
  430. if (!ifconfig) {
  431. LOG("ERROR: could not configure IP address for %s: unable to find 'ifconfig' command on system (checked /sbin, /bin, /usr/sbin, /usr/bin)",_dev);
  432. return false;
  433. }
  434. Mutex::Lock _l(_ips_m);
  435. if (!ip)
  436. return false;
  437. if (_ips.count(ip) > 0)
  438. return true; // IP/netmask already assigned
  439. // Remove and reconfigure if address is the same but netmask is different
  440. for(std::set<InetAddress>::iterator i(_ips.begin());i!=_ips.end();++i) {
  441. if ((i->ipsEqual(ip))&&(i->netmaskBits() != ip.netmaskBits())) {
  442. if (___removeIp(_dev,*i)) {
  443. _ips.erase(i);
  444. break;
  445. } else {
  446. LOG("WARNING: failed to remove old IP/netmask %s to replace with %s",i->toString().c_str(),ip.toString().c_str());
  447. }
  448. }
  449. }
  450. long cpid;
  451. if ((cpid = (long)vfork()) == 0) {
  452. execl(ifconfig,ifconfig,_dev,ip.isV4() ? "inet" : "inet6",ip.toString().c_str(),"alias",(const char *)0);
  453. _exit(-1);
  454. } else {
  455. int exitcode = -1;
  456. waitpid(cpid,&exitcode,0);
  457. if (exitcode == 0) {
  458. _ips.insert(ip);
  459. return true;
  460. }
  461. }
  462. return false;
  463. }
  464. #endif // __APPLE__
  465. bool EthernetTap::removeIP(const InetAddress &ip)
  466. {
  467. Mutex::Lock _l(_ips_m);
  468. if (_ips.count(ip) > 0) {
  469. if (___removeIp(_dev,ip)) {
  470. _ips.erase(ip);
  471. return true;
  472. }
  473. }
  474. return false;
  475. }
  476. std::set<InetAddress> EthernetTap::allIps() const
  477. {
  478. // TODO
  479. return ips();
  480. }
  481. void EthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
  482. {
  483. char putBuf[4096 + 14];
  484. if ((_fd > 0)&&(len <= _mtu)) {
  485. for(int i=0;i<6;++i)
  486. putBuf[i] = to.data[i];
  487. for(int i=0;i<6;++i)
  488. putBuf[i+6] = from.data[i];
  489. *((uint16_t *)(putBuf + 12)) = htons((uint16_t)etherType);
  490. memcpy(putBuf + 14,data,len);
  491. len += 14;
  492. int n = ::write(_fd,putBuf,len);
  493. if (n <= 0) {
  494. LOG("error writing packet to Ethernet tap device: %s",strerror(errno));
  495. } else if (n != (int)len) {
  496. // Saw this gremlin once, so log it if we see it again... OSX tap
  497. // or something seems to have goofy issues with certain MTUs.
  498. LOG("ERROR: write underrun: %s tap write() wrote %d of %u bytes of frame",_dev,n,len);
  499. }
  500. }
  501. }
  502. std::string EthernetTap::deviceName() const
  503. {
  504. return std::string(_dev);
  505. }
  506. #ifdef __LINUX__
  507. bool EthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
  508. {
  509. char *ptr,*ptr2;
  510. unsigned char mac[6];
  511. std::set<MulticastGroup> newGroups;
  512. int fd = ::open("/proc/net/dev_mcast",O_RDONLY);
  513. if (fd > 0) {
  514. char buf[131072];
  515. int n = (int)::read(fd,buf,sizeof(buf));
  516. if ((n > 0)&&(n < (int)sizeof(buf))) {
  517. buf[n] = (char)0;
  518. for(char *l=strtok_r(buf,"\r\n",&ptr);(l);l=strtok_r((char *)0,"\r\n",&ptr)) {
  519. int fno = 0;
  520. char *devname = (char *)0;
  521. char *mcastmac = (char *)0;
  522. for(char *f=strtok_r(l," \t",&ptr2);(f);f=strtok_r((char *)0," \t",&ptr2)) {
  523. if (fno == 1)
  524. devname = f;
  525. else if (fno == 4)
  526. mcastmac = f;
  527. ++fno;
  528. }
  529. if ((devname)&&(!strcmp(devname,_dev))&&(mcastmac)&&(Utils::unhex(mcastmac,mac,6) == 6))
  530. newGroups.insert(MulticastGroup(MAC(mac),0));
  531. }
  532. }
  533. ::close(fd);
  534. }
  535. {
  536. Mutex::Lock _l(_ips_m);
  537. for(std::set<InetAddress>::const_iterator i(_ips.begin());i!=_ips.end();++i)
  538. newGroups.insert(MulticastGroup::deriveMulticastGroupForAddressResolution(*i));
  539. }
  540. bool changed = false;
  541. newGroups.insert(_blindWildcardMulticastGroup); // always join this
  542. for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
  543. if (!groups.count(*mg)) {
  544. groups.insert(*mg);
  545. changed = true;
  546. }
  547. }
  548. for(std::set<MulticastGroup>::iterator mg(groups.begin());mg!=groups.end();) {
  549. if (!newGroups.count(*mg)) {
  550. groups.erase(mg++);
  551. changed = true;
  552. } else ++mg;
  553. }
  554. return changed;
  555. }
  556. #endif // __LINUX__
  557. #ifdef __APPLE__
  558. // --------------------------------------------------------------------------
  559. // This source is from:
  560. // http://www.opensource.apple.com/source/Libinfo/Libinfo-406.17/gen.subproj/getifmaddrs.c?txt
  561. // It's here because OSX 10.6 does not have this convenience function.
  562. #define SALIGN (sizeof(uint32_t) - 1)
  563. #define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : \
  564. (SALIGN + 1))
  565. #define MAX_SYSCTL_TRY 5
  566. #define RTA_MASKS (RTA_GATEWAY | RTA_IFP | RTA_IFA)
  567. /* FreeBSD uses NET_RT_IFMALIST and RTM_NEWMADDR from <sys/socket.h> */
  568. /* We can use NET_RT_IFLIST2 and RTM_NEWMADDR2 on Darwin */
  569. //#define DARWIN_COMPAT
  570. //#ifdef DARWIN_COMPAT
  571. #define GIM_SYSCTL_MIB NET_RT_IFLIST2
  572. #define GIM_RTM_ADDR RTM_NEWMADDR2
  573. //#else
  574. //#define GIM_SYSCTL_MIB NET_RT_IFMALIST
  575. //#define GIM_RTM_ADDR RTM_NEWMADDR
  576. //#endif
  577. static inline int _intl_getifmaddrs(struct ifmaddrs **pif)
  578. {
  579. int icnt = 1;
  580. int dcnt = 0;
  581. int ntry = 0;
  582. size_t len;
  583. size_t needed;
  584. int mib[6];
  585. int i;
  586. char *buf;
  587. char *data;
  588. char *next;
  589. char *p;
  590. struct ifma_msghdr2 *ifmam;
  591. struct ifmaddrs *ifa, *ift;
  592. struct rt_msghdr *rtm;
  593. struct sockaddr *sa;
  594. mib[0] = CTL_NET;
  595. mib[1] = PF_ROUTE;
  596. mib[2] = 0; /* protocol */
  597. mib[3] = 0; /* wildcard address family */
  598. mib[4] = GIM_SYSCTL_MIB;
  599. mib[5] = 0; /* no flags */
  600. do {
  601. if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
  602. return (-1);
  603. if ((buf = (char *)malloc(needed)) == NULL)
  604. return (-1);
  605. if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
  606. if (errno != ENOMEM || ++ntry >= MAX_SYSCTL_TRY) {
  607. free(buf);
  608. return (-1);
  609. }
  610. free(buf);
  611. buf = NULL;
  612. }
  613. } while (buf == NULL);
  614. for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
  615. rtm = (struct rt_msghdr *)(void *)next;
  616. if (rtm->rtm_version != RTM_VERSION)
  617. continue;
  618. switch (rtm->rtm_type) {
  619. case GIM_RTM_ADDR:
  620. ifmam = (struct ifma_msghdr2 *)(void *)rtm;
  621. if ((ifmam->ifmam_addrs & RTA_IFA) == 0)
  622. break;
  623. icnt++;
  624. p = (char *)(ifmam + 1);
  625. for (i = 0; i < RTAX_MAX; i++) {
  626. if ((RTA_MASKS & ifmam->ifmam_addrs &
  627. (1 << i)) == 0)
  628. continue;
  629. sa = (struct sockaddr *)(void *)p;
  630. len = SA_RLEN(sa);
  631. dcnt += len;
  632. p += len;
  633. }
  634. break;
  635. }
  636. }
  637. data = (char *)malloc(sizeof(struct ifmaddrs) * icnt + dcnt);
  638. if (data == NULL) {
  639. free(buf);
  640. return (-1);
  641. }
  642. ifa = (struct ifmaddrs *)(void *)data;
  643. data += sizeof(struct ifmaddrs) * icnt;
  644. memset(ifa, 0, sizeof(struct ifmaddrs) * icnt);
  645. ift = ifa;
  646. for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
  647. rtm = (struct rt_msghdr *)(void *)next;
  648. if (rtm->rtm_version != RTM_VERSION)
  649. continue;
  650. switch (rtm->rtm_type) {
  651. case GIM_RTM_ADDR:
  652. ifmam = (struct ifma_msghdr2 *)(void *)rtm;
  653. if ((ifmam->ifmam_addrs & RTA_IFA) == 0)
  654. break;
  655. p = (char *)(ifmam + 1);
  656. for (i = 0; i < RTAX_MAX; i++) {
  657. if ((RTA_MASKS & ifmam->ifmam_addrs &
  658. (1 << i)) == 0)
  659. continue;
  660. sa = (struct sockaddr *)(void *)p;
  661. len = SA_RLEN(sa);
  662. switch (i) {
  663. case RTAX_GATEWAY:
  664. ift->ifma_lladdr =
  665. (struct sockaddr *)(void *)data;
  666. memcpy(data, p, len);
  667. data += len;
  668. break;
  669. case RTAX_IFP:
  670. ift->ifma_name =
  671. (struct sockaddr *)(void *)data;
  672. memcpy(data, p, len);
  673. data += len;
  674. break;
  675. case RTAX_IFA:
  676. ift->ifma_addr =
  677. (struct sockaddr *)(void *)data;
  678. memcpy(data, p, len);
  679. data += len;
  680. break;
  681. default:
  682. data += len;
  683. break;
  684. }
  685. p += len;
  686. }
  687. ift->ifma_next = ift + 1;
  688. ift = ift->ifma_next;
  689. break;
  690. }
  691. }
  692. free(buf);
  693. if (ift > ifa) {
  694. ift--;
  695. ift->ifma_next = NULL;
  696. *pif = ifa;
  697. } else {
  698. *pif = NULL;
  699. free(ifa);
  700. }
  701. return (0);
  702. }
  703. static inline void _intl_freeifmaddrs(struct ifmaddrs *ifmp)
  704. {
  705. free(ifmp);
  706. }
  707. // --------------------------------------------------------------------------
  708. bool EthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
  709. {
  710. std::set<MulticastGroup> newGroups;
  711. struct ifmaddrs *ifmap = (struct ifmaddrs *)0;
  712. if (!_intl_getifmaddrs(&ifmap)) {
  713. struct ifmaddrs *p = ifmap;
  714. while (p) {
  715. if (p->ifma_addr->sa_family == AF_LINK) {
  716. struct sockaddr_dl *in = (struct sockaddr_dl *)p->ifma_name;
  717. struct sockaddr_dl *la = (struct sockaddr_dl *)p->ifma_addr;
  718. if ((la->sdl_alen == 6)&&(in->sdl_nlen <= sizeof(_dev))&&(!memcmp(_dev,in->sdl_data,in->sdl_nlen)))
  719. newGroups.insert(MulticastGroup(MAC(la->sdl_data + la->sdl_nlen),0));
  720. }
  721. p = p->ifma_next;
  722. }
  723. _intl_freeifmaddrs(ifmap);
  724. }
  725. {
  726. Mutex::Lock _l(_ips_m);
  727. for(std::set<InetAddress>::const_iterator i(_ips.begin());i!=_ips.end();++i)
  728. newGroups.insert(MulticastGroup::deriveMulticastGroupForAddressResolution(*i));
  729. }
  730. bool changed = false;
  731. newGroups.insert(_blindWildcardMulticastGroup); // always join this
  732. for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
  733. if (!groups.count(*mg)) {
  734. groups.insert(*mg);
  735. changed = true;
  736. }
  737. }
  738. for(std::set<MulticastGroup>::iterator mg(groups.begin());mg!=groups.end();) {
  739. if (!newGroups.count(*mg)) {
  740. groups.erase(mg++);
  741. changed = true;
  742. } else ++mg;
  743. }
  744. return changed;
  745. }
  746. #endif // __APPLE__
  747. void EthernetTap::threadMain()
  748. throw()
  749. {
  750. fd_set readfds,nullfds;
  751. MAC to,from;
  752. int n,nfds,r;
  753. char getBuf[8194];
  754. Buffer<4096> data;
  755. // Wait for a moment after startup -- wait for Network to finish
  756. // constructing itself.
  757. Thread::sleep(500);
  758. FD_ZERO(&readfds);
  759. FD_ZERO(&nullfds);
  760. nfds = (int)std::max(_shutdownSignalPipe[0],_fd) + 1;
  761. r = 0;
  762. for(;;) {
  763. FD_SET(_shutdownSignalPipe[0],&readfds);
  764. FD_SET(_fd,&readfds);
  765. select(nfds,&readfds,&nullfds,&nullfds,(struct timeval *)0);
  766. if (FD_ISSET(_shutdownSignalPipe[0],&readfds)) // writes to shutdown pipe terminate thread
  767. break;
  768. if (FD_ISSET(_fd,&readfds)) {
  769. n = (int)::read(_fd,getBuf + r,sizeof(getBuf) - r);
  770. if (n < 0) {
  771. if ((errno != EINTR)&&(errno != ETIMEDOUT)) {
  772. TRACE("unexpected error reading from tap: %s",strerror(errno));
  773. break;
  774. }
  775. } else {
  776. // Some tap drivers like to send the ethernet frame and the
  777. // payload in two chunks, so handle that by accumulating
  778. // data until we have at least a frame.
  779. r += n;
  780. if (r > 14) {
  781. if (r > ((int)_mtu + 14)) // sanity check for weird TAP behavior on some platforms
  782. r = _mtu + 14;
  783. for(int i=0;i<6;++i)
  784. to.data[i] = (unsigned char)getBuf[i];
  785. for(int i=0;i<6;++i)
  786. from.data[i] = (unsigned char)getBuf[i + 6];
  787. unsigned int etherType = ntohs(((const uint16_t *)getBuf)[6]);
  788. if (etherType != 0x8100) { // VLAN tagged frames are not supported!
  789. data.copyFrom(getBuf + 14,(unsigned int)r - 14);
  790. _handler(_arg,from,to,etherType,data);
  791. }
  792. r = 0;
  793. }
  794. }
  795. }
  796. }
  797. }
  798. } // namespace ZeroTier
  799. #endif // __UNIX_LIKE__ //////////////////////////////////////////////////////
  800. //////////////////////////////////////////////////////////////////////////////
  801. #ifdef __WINDOWS__ ///////////////////////////////////////////////////////////
  802. #include <stdio.h>
  803. #include <stdlib.h>
  804. #include <stdint.h>
  805. #include <string.h>
  806. #include <WinSock2.h>
  807. #include <Windows.h>
  808. #include <iphlpapi.h>
  809. #include <ws2ipdef.h>
  810. #include <WS2tcpip.h>
  811. #include <tchar.h>
  812. #include <winreg.h>
  813. #include <wchar.h>
  814. #include <nldef.h>
  815. #include <netioapi.h>
  816. #include "..\windows\TapDriver\tap-windows.h"
  817. namespace ZeroTier {
  818. // Helper function to get an adapter's LUID and index from its GUID. The LUID is
  819. // constant but the index can change, so go ahead and just look them both up by
  820. // the GUID which is constant. (The GUID is the instance ID in the registry.)
  821. static inline std::pair<NET_LUID,NET_IFINDEX> _findAdapterByGuid(const GUID &guid)
  822. throw(std::runtime_error)
  823. {
  824. MIB_IF_TABLE2 *ift = (MIB_IF_TABLE2 *)0;
  825. if (GetIfTable2Ex(MibIfTableRaw,&ift) != NO_ERROR)
  826. throw std::runtime_error("GetIfTable2Ex() failed");
  827. for(ULONG i=0;i<ift->NumEntries;++i) {
  828. if (ift->Table[i].InterfaceGuid == guid) {
  829. std::pair<NET_LUID,NET_IFINDEX> tmp(ift->Table[i].InterfaceLuid,ift->Table[i].InterfaceIndex);
  830. FreeMibTable(ift);
  831. return tmp;
  832. }
  833. }
  834. FreeMibTable(&ift);
  835. throw std::runtime_error("interface not found");
  836. }
  837. static Mutex _systemTapInitLock;
  838. EthernetTap::EthernetTap(
  839. const RuntimeEnvironment *renv,
  840. const char *tag,
  841. const MAC &mac,
  842. unsigned int mtu,
  843. void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &),
  844. void *arg)
  845. throw(std::runtime_error) :
  846. _mac(mac),
  847. _mtu(mtu),
  848. _r(renv),
  849. _handler(handler),
  850. _arg(arg),
  851. _tap(INVALID_HANDLE_VALUE),
  852. _injectSemaphore(INVALID_HANDLE_VALUE),
  853. _run(true)
  854. {
  855. char subkeyName[4096];
  856. char subkeyClass[4096];
  857. char data[4096];
  858. if (mtu > ZT_IF_MTU)
  859. throw std::runtime_error("MTU too large for Windows tap");
  860. #ifdef _WIN64
  861. BOOL is64Bit = TRUE;
  862. const char *devcon = "\\devcon_x64.exe";
  863. const char *tapDriver = "\\tap-windows\\x64\\ztTap100.inf";
  864. #else
  865. BOOL is64Bit = FALSE;
  866. IsWow64Process(GetCurrentProcess(),&is64Bit);
  867. const char *devcon = ((is64Bit == TRUE) ? "\\devcon_x64.exe" : "\\devcon_x86.exe");
  868. const char *tapDriver = ((is64Bit == TRUE) ? "\\tap-windows\\x64\\ztTap100.inf" : "\\tap-windows\\x86\\ztTap100.inf");
  869. #endif
  870. Mutex::Lock _l(_systemTapInitLock); // only init one tap at a time, process-wide
  871. HKEY nwAdapters;
  872. if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",0,KEY_READ|KEY_WRITE,&nwAdapters) != ERROR_SUCCESS)
  873. throw std::runtime_error("unable to open registry key for network adapter enumeration");
  874. std::set<std::string> existingDeviceInstances;
  875. std::string mySubkeyName;
  876. // Enumerate tap instances and look for one tagged with this tag
  877. for(DWORD subkeyIndex=0;subkeyIndex!=-1;) {
  878. DWORD type;
  879. DWORD dataLen;
  880. DWORD subkeyNameLen = sizeof(subkeyName);
  881. DWORD subkeyClassLen = sizeof(subkeyClass);
  882. FILETIME lastWriteTime;
  883. switch (RegEnumKeyExA(nwAdapters,subkeyIndex++,subkeyName,&subkeyNameLen,(DWORD *)0,subkeyClass,&subkeyClassLen,&lastWriteTime)) {
  884. case ERROR_NO_MORE_ITEMS: subkeyIndex = -1; break;
  885. case ERROR_SUCCESS:
  886. type = 0;
  887. dataLen = sizeof(data);
  888. if (RegGetValueA(nwAdapters,subkeyName,"ComponentId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
  889. data[dataLen] = '\0';
  890. if (!strnicmp(data,"zttap",5)) {
  891. std::string instanceId;
  892. type = 0;
  893. dataLen = sizeof(data);
  894. if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
  895. instanceId.assign(data,dataLen);
  896. existingDeviceInstances.insert(instanceId);
  897. }
  898. std::string instanceIdPath;
  899. type = 0;
  900. dataLen = sizeof(data);
  901. if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS)
  902. instanceIdPath.assign(data,dataLen);
  903. if ((_myDeviceInstanceId.length() == 0)&&(instanceId.length() != 0)&&(instanceIdPath.length() != 0)) {
  904. type = 0;
  905. dataLen = sizeof(data);
  906. if (RegGetValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
  907. data[dataLen] = '\0';
  908. if (!strcmp(data,tag)) {
  909. _myDeviceInstanceId = instanceId;
  910. _myDeviceInstanceIdPath = instanceIdPath;
  911. mySubkeyName = subkeyName;
  912. subkeyIndex = -1; // break outer loop
  913. }
  914. }
  915. }
  916. }
  917. }
  918. break;
  919. }
  920. }
  921. // If there is no device, try to create one
  922. if (_myDeviceInstanceId.length() == 0) {
  923. // Execute devcon to install an instance of the Microsoft Loopback Adapter
  924. STARTUPINFOA startupInfo;
  925. startupInfo.cb = sizeof(startupInfo);
  926. PROCESS_INFORMATION processInfo;
  927. memset(&startupInfo,0,sizeof(STARTUPINFOA));
  928. memset(&processInfo,0,sizeof(PROCESS_INFORMATION));
  929. if (!CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" install \"" + _r->homePath + tapDriver + "\" ztTap100").c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) {
  930. RegCloseKey(nwAdapters);
  931. throw std::runtime_error(std::string("unable to find or execute devcon at ")+devcon);
  932. }
  933. WaitForSingleObject(processInfo.hProcess,INFINITE);
  934. CloseHandle(processInfo.hProcess);
  935. CloseHandle(processInfo.hThread);
  936. // Scan for the new instance by simply looking for taps that weren't
  937. // there originally.
  938. for(DWORD subkeyIndex=0;subkeyIndex!=-1;) {
  939. DWORD type;
  940. DWORD dataLen;
  941. DWORD subkeyNameLen = sizeof(subkeyName);
  942. DWORD subkeyClassLen = sizeof(subkeyClass);
  943. FILETIME lastWriteTime;
  944. switch (RegEnumKeyExA(nwAdapters,subkeyIndex++,subkeyName,&subkeyNameLen,(DWORD *)0,subkeyClass,&subkeyClassLen,&lastWriteTime)) {
  945. case ERROR_NO_MORE_ITEMS: subkeyIndex = -1; break;
  946. case ERROR_SUCCESS:
  947. type = 0;
  948. dataLen = sizeof(data);
  949. if (RegGetValueA(nwAdapters,subkeyName,"ComponentId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
  950. data[dataLen] = '\0';
  951. if (!strnicmp(data,"zttap",5)) {
  952. type = 0;
  953. dataLen = sizeof(data);
  954. if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
  955. if (existingDeviceInstances.count(std::string(data,dataLen)) == 0) {
  956. RegSetKeyValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",REG_SZ,tag,(DWORD)(strlen(tag)+1));
  957. _myDeviceInstanceId.assign(data,dataLen);
  958. type = 0;
  959. dataLen = sizeof(data);
  960. if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS)
  961. _myDeviceInstanceIdPath.assign(data,dataLen);
  962. mySubkeyName = subkeyName;
  963. subkeyIndex = -1; // break outer loop
  964. }
  965. }
  966. }
  967. }
  968. break;
  969. }
  970. }
  971. }
  972. // If we have a device, configure it
  973. if (_myDeviceInstanceId.length() > 0) {
  974. char tmps[4096];
  975. unsigned int tmpsl = Utils::snprintf(tmps,sizeof(tmps),"%.2X-%.2X-%.2X-%.2X-%.2X-%.2X",(unsigned int)mac.data[0],(unsigned int)mac.data[1],(unsigned int)mac.data[2],(unsigned int)mac.data[3],(unsigned int)mac.data[4],(unsigned int)mac.data[5]) + 1;
  976. RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"NetworkAddress",REG_SZ,tmps,tmpsl);
  977. RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"MAC",REG_SZ,tmps,tmpsl);
  978. DWORD tmp = mtu;
  979. RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"MTU",REG_DWORD,(LPCVOID)&tmp,sizeof(tmp));
  980. tmp = 0;
  981. RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"EnableDHCP",REG_DWORD,(LPCVOID)&tmp,sizeof(tmp));
  982. }
  983. // Done with registry
  984. RegCloseKey(nwAdapters);
  985. // If we didn't get a device, we can't start
  986. if (_myDeviceInstanceId.length() == 0)
  987. throw std::runtime_error("unable to create new tap adapter");
  988. // Convert device GUID junk... blech
  989. {
  990. char nobraces[128];
  991. const char *nbtmp1 = _myDeviceInstanceId.c_str();
  992. char *nbtmp2 = nobraces;
  993. while (*nbtmp1) {
  994. if ((*nbtmp1 != '{')&&(*nbtmp1 != '}'))
  995. *nbtmp2++ = *nbtmp1;
  996. ++nbtmp1;
  997. }
  998. *nbtmp2 = (char)0;
  999. if (UuidFromStringA((RPC_CSTR)nobraces,&_deviceGuid) != RPC_S_OK)
  1000. throw std::runtime_error("unable to convert instance ID GUID to native GUID (invalid NetCfgInstanceId in registry?)");
  1001. }
  1002. // Disable and enable interface to ensure registry settings take effect
  1003. {
  1004. STARTUPINFOA startupInfo;
  1005. startupInfo.cb = sizeof(startupInfo);
  1006. PROCESS_INFORMATION processInfo;
  1007. memset(&startupInfo,0,sizeof(STARTUPINFOA));
  1008. memset(&processInfo,0,sizeof(PROCESS_INFORMATION));
  1009. if (!CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" disable @" + _myDeviceInstanceIdPath).c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) {
  1010. RegCloseKey(nwAdapters);
  1011. throw std::runtime_error(std::string("unable to find or execute devcon at ")+devcon);
  1012. }
  1013. WaitForSingleObject(processInfo.hProcess,INFINITE);
  1014. CloseHandle(processInfo.hProcess);
  1015. CloseHandle(processInfo.hThread);
  1016. }
  1017. {
  1018. STARTUPINFOA startupInfo;
  1019. startupInfo.cb = sizeof(startupInfo);
  1020. PROCESS_INFORMATION processInfo;
  1021. memset(&startupInfo,0,sizeof(STARTUPINFOA));
  1022. memset(&processInfo,0,sizeof(PROCESS_INFORMATION));
  1023. if (!CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" enable @" + _myDeviceInstanceIdPath).c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) {
  1024. RegCloseKey(nwAdapters);
  1025. throw std::runtime_error(std::string("unable to find or execute devcon at ")+devcon);
  1026. }
  1027. WaitForSingleObject(processInfo.hProcess,INFINITE);
  1028. CloseHandle(processInfo.hProcess);
  1029. CloseHandle(processInfo.hThread);
  1030. }
  1031. // Open the tap, which is in this weird Windows analog of /dev
  1032. char tapPath[4096];
  1033. Utils::snprintf(tapPath,sizeof(tapPath),"\\\\.\\Global\\%s.tap",_myDeviceInstanceId.c_str());
  1034. _tap = CreateFileA(tapPath,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM|FILE_FLAG_OVERLAPPED,NULL);
  1035. if (_tap == INVALID_HANDLE_VALUE)
  1036. throw std::runtime_error(std::string("unable to open tap device ")+tapPath);
  1037. // Set media status to enabled
  1038. uint32_t tmpi = 1;
  1039. DWORD bytesReturned = 0;
  1040. DeviceIoControl(_tap,TAP_WIN_IOCTL_SET_MEDIA_STATUS,&tmpi,sizeof(tmpi),&tmpi,sizeof(tmpi),&bytesReturned,NULL);
  1041. // Initialized overlapped I/O structures and related events
  1042. memset(&_tapOvlRead,0,sizeof(_tapOvlRead));
  1043. _tapOvlRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
  1044. memset(&_tapOvlWrite,0,sizeof(_tapOvlWrite));
  1045. _tapOvlWrite.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
  1046. // Start background thread that actually performs I/O
  1047. _injectSemaphore = CreateSemaphore(NULL,0,1,NULL);
  1048. _thread = Thread::start(this);
  1049. }
  1050. EthernetTap::~EthernetTap()
  1051. {
  1052. _run = false;
  1053. ReleaseSemaphore(_injectSemaphore,1,NULL);
  1054. Thread::join(_thread);
  1055. CloseHandle(_tap);
  1056. CloseHandle(_tapOvlRead.hEvent);
  1057. CloseHandle(_tapOvlWrite.hEvent);
  1058. CloseHandle(_injectSemaphore);
  1059. #ifdef _WIN64
  1060. BOOL is64Bit = TRUE;
  1061. const char *devcon = "\\devcon_x64.exe";
  1062. #else
  1063. BOOL is64Bit = FALSE;
  1064. IsWow64Process(GetCurrentProcess(),&is64Bit);
  1065. const char *devcon = ((is64Bit == TRUE) ? "\\devcon_x64.exe" : "\\devcon_x86.exe");
  1066. #endif
  1067. // Disable network device on shutdown
  1068. STARTUPINFOA startupInfo;
  1069. startupInfo.cb = sizeof(startupInfo);
  1070. PROCESS_INFORMATION processInfo;
  1071. memset(&startupInfo,0,sizeof(STARTUPINFOA));
  1072. memset(&processInfo,0,sizeof(PROCESS_INFORMATION));
  1073. if (CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" disable @" + _myDeviceInstanceIdPath).c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) {
  1074. WaitForSingleObject(processInfo.hProcess,INFINITE);
  1075. CloseHandle(processInfo.hProcess);
  1076. CloseHandle(processInfo.hThread);
  1077. }
  1078. }
  1079. void EthernetTap::whack()
  1080. {
  1081. }
  1082. void EthernetTap::setDisplayName(const char *dn)
  1083. {
  1084. HKEY ifp;
  1085. if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,(std::string("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\") + _myDeviceInstanceId).c_str(),0,KEY_READ|KEY_WRITE,&ifp) == ERROR_SUCCESS) {
  1086. RegSetKeyValueA(ifp,"Connection","Name",REG_SZ,(LPCVOID)dn,(DWORD)(strlen(dn)+1));
  1087. RegCloseKey(ifp);
  1088. }
  1089. }
  1090. bool EthernetTap::addIP(const InetAddress &ip)
  1091. {
  1092. Mutex::Lock _l(_ips_m);
  1093. if (_ips.count(ip))
  1094. return true;
  1095. if (!ip.port())
  1096. return false;
  1097. try {
  1098. std::pair<NET_LUID,NET_IFINDEX> ifidx = _findAdapterByGuid(_deviceGuid);
  1099. MIB_UNICASTIPADDRESS_ROW ipr;
  1100. InitializeUnicastIpAddressEntry(&ipr);
  1101. if (ip.isV4()) {
  1102. ipr.Address.Ipv4.sin_family = AF_INET;
  1103. ipr.Address.Ipv4.sin_addr.S_un.S_addr = *((const uint32_t *)ip.rawIpData());
  1104. ipr.OnLinkPrefixLength = ip.port();
  1105. } else if (ip.isV6()) {
  1106. } else return false;
  1107. ipr.PrefixOrigin = IpPrefixOriginManual;
  1108. ipr.SuffixOrigin = IpSuffixOriginManual;
  1109. ipr.ValidLifetime = 0xffffffff;
  1110. ipr.PreferredLifetime = 0xffffffff;
  1111. ipr.InterfaceLuid = ifidx.first;
  1112. ipr.InterfaceIndex = ifidx.second;
  1113. if (CreateUnicastIpAddressEntry(&ipr) == NO_ERROR) {
  1114. _ips.insert(ip);
  1115. return true;
  1116. }
  1117. } catch ( ... ) {}
  1118. return false;
  1119. }
  1120. bool EthernetTap::removeIP(const InetAddress &ip)
  1121. {
  1122. try {
  1123. MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0;
  1124. std::pair<NET_LUID,NET_IFINDEX> ifidx = _findAdapterByGuid(_deviceGuid);
  1125. if (GetUnicastIpAddressTable(AF_UNSPEC,&ipt) == NO_ERROR) {
  1126. for(DWORD i=0;i<ipt->NumEntries;++i) {
  1127. if ((ipt->Table[i].InterfaceLuid.Value == ifidx.first.Value)&&(ipt->Table[i].InterfaceIndex == ifidx.second)) {
  1128. InetAddress addr;
  1129. switch(ipt->Table[i].Address.si_family) {
  1130. case AF_INET:
  1131. addr.set(&(ipt->Table[i].Address.Ipv4.sin_addr.S_un.S_addr),4,ipt->Table[i].OnLinkPrefixLength);
  1132. break;
  1133. case AF_INET6:
  1134. addr.set(ipt->Table[i].Address.Ipv6.sin6_addr.u.Byte,16,ipt->Table[i].OnLinkPrefixLength);
  1135. break;
  1136. }
  1137. if (addr == ip) {
  1138. DeleteUnicastIpAddressEntry(&(ipt->Table[i]));
  1139. FreeMibTable(ipt);
  1140. Mutex::Lock _l(_ips_m);
  1141. _ips.erase(ip);
  1142. return true;
  1143. }
  1144. }
  1145. }
  1146. FreeMibTable(&ipt);
  1147. }
  1148. } catch ( ... ) {}
  1149. return false;
  1150. }
  1151. std::set<InetAddress> EthernetTap::allIps() const
  1152. {
  1153. static const InetAddress ifLoopback("fe80::1",64);
  1154. std::set<InetAddress> addrs;
  1155. try {
  1156. MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0;
  1157. std::pair<NET_LUID,NET_IFINDEX> ifidx = _findAdapterByGuid(_deviceGuid);
  1158. if (GetUnicastIpAddressTable(AF_UNSPEC,&ipt) == NO_ERROR) {
  1159. for(DWORD i=0;i<ipt->NumEntries;++i) {
  1160. if ((ipt->Table[i].InterfaceLuid.Value == ifidx.first.Value)&&(ipt->Table[i].InterfaceIndex == ifidx.second)) {
  1161. switch(ipt->Table[i].Address.si_family) {
  1162. case AF_INET:
  1163. addrs.insert(InetAddress(&(ipt->Table[i].Address.Ipv4.sin_addr.S_un.S_addr),4,ipt->Table[i].OnLinkPrefixLength));
  1164. break;
  1165. case AF_INET6: {
  1166. InetAddress ip(ipt->Table[i].Address.Ipv6.sin6_addr.u.Byte,16,ipt->Table[i].OnLinkPrefixLength);
  1167. if (ip != ifLoopback) // don't include fe80::1
  1168. addrs.insert(ip);
  1169. } break;
  1170. }
  1171. }
  1172. }
  1173. FreeMibTable(ipt);
  1174. }
  1175. } catch ( ... ) {}
  1176. return addrs;
  1177. }
  1178. void EthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
  1179. {
  1180. if (len > (ZT_IF_MTU))
  1181. return;
  1182. {
  1183. Mutex::Lock _l(_injectPending_m);
  1184. _injectPending.push( std::pair<Array<char,ZT_IF_MTU + 32>,unsigned int>(Array<char,ZT_IF_MTU + 32>(),len + 14) );
  1185. char *d = _injectPending.back().first.data;
  1186. memcpy(d,to.data,6);
  1187. memcpy(d + 6,from.data,6);
  1188. *((uint16_t *)(d + 12)) = Utils::hton(etherType);
  1189. memcpy(d + 14,data,len);
  1190. }
  1191. ReleaseSemaphore(_injectSemaphore,1,NULL);
  1192. }
  1193. std::string EthernetTap::deviceName() const
  1194. {
  1195. return _myDeviceInstanceId;
  1196. }
  1197. bool EthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
  1198. {
  1199. std::set<MulticastGroup> newGroups;
  1200. // Ensure that groups are added for each IP... this handles the MAC:ADI
  1201. // groups that are created from IPv4 addresses. Some of these may end
  1202. // up being duplicates of what the IOCTL returns but that's okay since
  1203. // the set will filter these.
  1204. std::set<InetAddress> ipaddrs(allIps());
  1205. for(std::set<InetAddress>::const_iterator i(ipaddrs.begin());i!=ipaddrs.end();++i)
  1206. newGroups.insert(MulticastGroup::deriveMulticastGroupForAddressResolution(*i));
  1207. // The ZT1 tap driver supports an IOCTL to get multicast memberships at the L2
  1208. // level... something Windows does not seem to expose ordinarily. This lets
  1209. // pretty much anything work... IPv4, IPv6, IPX, oldskool Netbios, who knows...
  1210. unsigned char mcastbuf[TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS_OUTPUT_BUF_SIZE];
  1211. DWORD bytesReturned = 0;
  1212. if (DeviceIoControl(_tap,TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS,(LPVOID)0,0,(LPVOID)mcastbuf,sizeof(mcastbuf),&bytesReturned,NULL)) {
  1213. printf("TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS: got %d bytes\n",(int)bytesReturned);
  1214. MAC mac;
  1215. DWORD i = 0;
  1216. while ((i + 6) <= bytesReturned) {
  1217. mac.data[0] = mcastbuf[i++];
  1218. mac.data[1] = mcastbuf[i++];
  1219. mac.data[2] = mcastbuf[i++];
  1220. mac.data[3] = mcastbuf[i++];
  1221. mac.data[4] = mcastbuf[i++];
  1222. mac.data[5] = mcastbuf[i++];
  1223. if (mac.isMulticast()) { // exclude the nulls that may be returned or any other junk Windows puts in there
  1224. newGroups.insert(MulticastGroup(mac,0));
  1225. printf("TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS: %s\n",mac.toString().c_str());
  1226. }
  1227. }
  1228. } else {
  1229. printf("TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS: failed\n");
  1230. }
  1231. newGroups.insert(_blindWildcardMulticastGroup); // always join this
  1232. bool changed = false;
  1233. for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
  1234. if (!groups.count(*mg)) {
  1235. groups.insert(*mg);
  1236. changed = true;
  1237. }
  1238. }
  1239. for(std::set<MulticastGroup>::iterator mg(groups.begin());mg!=groups.end();) {
  1240. if (!newGroups.count(*mg)) {
  1241. groups.erase(mg++);
  1242. changed = true;
  1243. } else ++mg;
  1244. }
  1245. return changed;
  1246. }
  1247. void EthernetTap::threadMain()
  1248. throw()
  1249. {
  1250. HANDLE wait4[3];
  1251. wait4[0] = _injectSemaphore;
  1252. wait4[1] = _tapOvlRead.hEvent;
  1253. wait4[2] = _tapOvlWrite.hEvent;
  1254. ReadFile(_tap,_tapReadBuf,sizeof(_tapReadBuf),NULL,&_tapOvlRead);
  1255. bool writeInProgress = false;
  1256. for(;;) {
  1257. if (!_run) break;
  1258. WaitForMultipleObjectsEx(3,wait4,FALSE,INFINITE,TRUE);
  1259. if (!_run) break;
  1260. if (HasOverlappedIoCompleted(&_tapOvlRead)) {
  1261. DWORD bytesRead = 0;
  1262. if (GetOverlappedResult(_tap,&_tapOvlRead,&bytesRead,FALSE)) {
  1263. if (bytesRead > 14) {
  1264. MAC to(_tapReadBuf);
  1265. MAC from(_tapReadBuf + 6);
  1266. unsigned int etherType = Utils::ntoh(*((const uint16_t *)(_tapReadBuf + 12)));
  1267. Buffer<4096> tmp(_tapReadBuf + 14,bytesRead - 14);
  1268. //printf("GOT FRAME: %u bytes: %s\r\n",(unsigned int)bytesRead,Utils::hex(_tapReadBuf,bytesRead).c_str());
  1269. _handler(_arg,from,to,etherType,tmp);
  1270. }
  1271. }
  1272. ReadFile(_tap,_tapReadBuf,sizeof(_tapReadBuf),NULL,&_tapOvlRead);
  1273. }
  1274. if (writeInProgress) {
  1275. if (HasOverlappedIoCompleted(&_tapOvlWrite)) {
  1276. writeInProgress = false;
  1277. _injectPending_m.lock();
  1278. _injectPending.pop();
  1279. } else continue; // still writing, so skip code below and wait
  1280. } else _injectPending_m.lock();
  1281. if (!_injectPending.empty()) {
  1282. WriteFile(_tap,_injectPending.front().first.data,_injectPending.front().second,NULL,&_tapOvlWrite);
  1283. writeInProgress = true;
  1284. }
  1285. _injectPending_m.unlock();
  1286. }
  1287. CancelIo(_tap);
  1288. }
  1289. } // namespace ZeroTier
  1290. #endif // __WINDOWS__ ////////////////////////////////////////////////////////