EthernetTap.cpp 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301
  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/uio.h>
  127. #include <sys/param.h>
  128. #include <sys/sysctl.h>
  129. #include <net/route.h>
  130. #include <net/if_dl.h>
  131. #include <ifaddrs.h>
  132. static volatile int EthernetTap_instances = 0;
  133. static ZeroTier::Mutex EthernetTap_instances_m;
  134. #endif // __APPLE__
  135. namespace ZeroTier {
  136. // Only permit one tap to be opened concurrently across the entire process
  137. static Mutex __tapCreateLock;
  138. #ifdef __LINUX__
  139. EthernetTap::EthernetTap(
  140. const RuntimeEnvironment *renv,
  141. const char *tag,
  142. const MAC &mac,
  143. unsigned int mtu,
  144. void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &),
  145. void *arg)
  146. throw(std::runtime_error) :
  147. _mac(mac),
  148. _mtu(mtu),
  149. _r(renv),
  150. _handler(handler),
  151. _arg(arg),
  152. _fd(0)
  153. {
  154. char procpath[128];
  155. Mutex::Lock _l(__tapCreateLock); // create only one tap at a time, globally
  156. if (mtu > 4096)
  157. throw std::runtime_error("max tap MTU is 4096");
  158. _fd = ::open("/dev/net/tun",O_RDWR);
  159. if (_fd <= 0)
  160. throw std::runtime_error(std::string("could not open TUN/TAP device: ") + strerror(errno));
  161. struct ifreq ifr;
  162. memset(&ifr,0,sizeof(ifr));
  163. { // pick an unused device name
  164. int devno = 0;
  165. struct stat sbuf;
  166. do {
  167. Utils::snprintf(ifr.ifr_name,sizeof(ifr.ifr_name),"zt%d",devno++);
  168. Utils::snprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name);
  169. } while (stat(procpath,&sbuf) == 0);
  170. }
  171. ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
  172. if (ioctl(_fd,TUNSETIFF,(void *)&ifr) < 0) {
  173. ::close(_fd);
  174. throw std::runtime_error("unable to configure TUN/TAP device for TAP operation");
  175. }
  176. strcpy(_dev,ifr.ifr_name);
  177. ioctl(_fd,TUNSETPERSIST,0); // valgrind may generate a false alarm here
  178. // Open an arbitrary socket to talk to netlink
  179. int sock = socket(AF_INET,SOCK_DGRAM,0);
  180. if (sock <= 0) {
  181. ::close(_fd);
  182. throw std::runtime_error("unable to open netlink socket");
  183. }
  184. // Set MAC address
  185. ifr.ifr_ifru.ifru_hwaddr.sa_family = ARPHRD_ETHER;
  186. memcpy(ifr.ifr_ifru.ifru_hwaddr.sa_data,mac.data,6);
  187. if (ioctl(sock,SIOCSIFHWADDR,(void *)&ifr) < 0) {
  188. ::close(_fd);
  189. ::close(sock);
  190. throw std::runtime_error("unable to configure TAP hardware (MAC) address");
  191. return;
  192. }
  193. // Set MTU
  194. ifr.ifr_ifru.ifru_mtu = (int)mtu;
  195. if (ioctl(sock,SIOCSIFMTU,(void *)&ifr) < 0) {
  196. ::close(_fd);
  197. ::close(sock);
  198. throw std::runtime_error("unable to configure TAP MTU");
  199. }
  200. if (fcntl(_fd,F_SETFL,fcntl(_fd,F_GETFL) & ~O_NONBLOCK) == -1) {
  201. ::close(_fd);
  202. throw std::runtime_error("unable to set flags on file descriptor for TAP device");
  203. }
  204. /* Bring interface up */
  205. if (ioctl(sock,SIOCGIFFLAGS,(void *)&ifr) < 0) {
  206. ::close(_fd);
  207. ::close(sock);
  208. throw std::runtime_error("unable to get TAP interface flags");
  209. }
  210. ifr.ifr_flags |= IFF_UP;
  211. if (ioctl(sock,SIOCSIFFLAGS,(void *)&ifr) < 0) {
  212. ::close(_fd);
  213. ::close(sock);
  214. throw std::runtime_error("unable to set TAP interface flags");
  215. }
  216. ::close(sock);
  217. ::pipe(_shutdownSignalPipe);
  218. TRACE("tap %s created",_dev);
  219. _thread = Thread::start(this);
  220. }
  221. #endif // __LINUX__
  222. #ifdef __APPLE__
  223. EthernetTap::EthernetTap(
  224. const RuntimeEnvironment *renv,
  225. const char *tag,
  226. const MAC &mac,
  227. unsigned int mtu,
  228. void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &),
  229. void *arg)
  230. throw(std::runtime_error) :
  231. _mac(mac),
  232. _mtu(mtu),
  233. _r(renv),
  234. _handler(handler),
  235. _arg(arg),
  236. _dhcp(false),
  237. _dhcp6(false),
  238. _fd(0)
  239. {
  240. char devpath[64],ethaddr[64],mtustr[16];
  241. struct stat tmp;
  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",&tmp))&&(kextload)) {
  248. long kextpid;
  249. char tmp[4096];
  250. strcpy(tmp,_r->homePath.c_str());
  251. if ((kextpid = (long)vfork()) == 0) {
  252. chdir(tmp);
  253. execl(kextload,kextload,"-q","-repository",tmp,"tap.kext",(const char *)0);
  254. _exit(-1);
  255. } else {
  256. int exitcode = -1;
  257. waitpid(kextpid,&exitcode,0);
  258. usleep(500);
  259. }
  260. }
  261. if (stat("/dev/zt0",&tmp))
  262. throw std::runtime_error("/dev/zt# tap devices do not exist and unable to load kernel extension");
  263. // Open the first available device (ones in use will fail with resource busy)
  264. for(int i=0;i<256;++i) {
  265. Utils::snprintf(devpath,sizeof(devpath),"/dev/zt%d",i);
  266. if (stat(devpath,&tmp))
  267. throw std::runtime_error("no more TAP devices available");
  268. _fd = ::open(devpath,O_RDWR);
  269. if (_fd > 0) {
  270. Utils::snprintf(_dev,sizeof(_dev),"zt%d",i);
  271. break;
  272. }
  273. }
  274. if (_fd <= 0)
  275. throw std::runtime_error("unable to open TAP device or no more devices available");
  276. if (fcntl(_fd,F_SETFL,fcntl(_fd,F_GETFL) & ~O_NONBLOCK) == -1) {
  277. ::close(_fd);
  278. throw std::runtime_error("unable to set flags on file descriptor for TAP device");
  279. }
  280. const char *ifconfig = UNIX_COMMANDS[ZT_UNIX_IFCONFIG_COMMAND];
  281. if (!ifconfig) {
  282. ::close(_fd);
  283. throw std::runtime_error("unable to find 'ifconfig' command on system");
  284. }
  285. // Configure MAC address and MTU, bring interface up
  286. 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]);
  287. Utils::snprintf(mtustr,sizeof(mtustr),"%u",mtu);
  288. long cpid;
  289. if ((cpid = (long)vfork()) == 0) {
  290. execl(ifconfig,ifconfig,_dev,"lladdr",ethaddr,"mtu",mtustr,"up",(const char *)0);
  291. _exit(-1);
  292. } else {
  293. int exitcode = -1;
  294. waitpid(cpid,&exitcode,0);
  295. if (exitcode) {
  296. ::close(_fd);
  297. throw std::runtime_error("ifconfig failure setting link-layer address and activating tap interface");
  298. }
  299. }
  300. whack(); // turns on IPv6 on OSX
  301. ::pipe(_shutdownSignalPipe);
  302. _thread = Thread::start(this);
  303. EthernetTap_instances_m.lock();
  304. ++EthernetTap_instances;
  305. EthernetTap_instances_m.unlock();
  306. }
  307. #endif // __APPLE__
  308. EthernetTap::~EthernetTap()
  309. {
  310. ::write(_shutdownSignalPipe[1],"\0",1); // causes thread to exit
  311. Thread::join(_thread);
  312. ::close(_fd);
  313. #ifdef __APPLE__
  314. EthernetTap_instances_m.lock();
  315. int instances = --EthernetTap_instances;
  316. EthernetTap_instances_m.unlock();
  317. if (instances <= 0) {
  318. // Unload OSX kernel extension on the deletion of the last EthernetTap
  319. // instance.
  320. const char *kextunload = UNIX_COMMANDS[ZT_MAC_KEXTUNLOAD_COMMAND];
  321. if (kextunload) {
  322. long kextpid;
  323. char tmp[4096];
  324. sprintf(tmp,"%s/tap.kext",_r->homePath.c_str());
  325. if ((kextpid = (long)vfork()) == 0) {
  326. execl(kextunload,kextunload,tmp,(const char *)0);
  327. _exit(-1);
  328. } else if (kextpid > 0) {
  329. int exitcode = -1;
  330. waitpid(kextpid,&exitcode,0);
  331. }
  332. }
  333. }
  334. #endif // __APPLE__
  335. }
  336. #ifdef __APPLE__
  337. void EthernetTap::whack()
  338. {
  339. const char *ipconfig = UNIX_COMMANDS[ZT_MAC_IPCONFIG_COMMAND];
  340. if (ipconfig) {
  341. long cpid = (long)vfork();
  342. if (cpid == 0) {
  343. execl(ipconfig,ipconfig,"set",_dev,"AUTOMATIC-V6",(const char *)0);
  344. _exit(-1);
  345. } else {
  346. int exitcode = -1;
  347. waitpid(cpid,&exitcode,0);
  348. }
  349. }
  350. }
  351. #else
  352. void EthernetTap::whack() {}
  353. #endif // __APPLE__ / !__APPLE__
  354. bool EthernetTap::setDhcpEnabled(bool dhcp)
  355. {
  356. // TODO
  357. return _dhcp;
  358. }
  359. bool EthernetTap::setDhcp6Enabled(bool dhcp)
  360. {
  361. return _dhcp6;
  362. }
  363. void EthernetTap::setDisplayName(const char *dn)
  364. {
  365. }
  366. #ifdef __LINUX__
  367. static bool ___removeIp(const char *_dev,const InetAddress &ip)
  368. {
  369. const char *ipcmd = UNIX_COMMANDS[ZT_UNIX_IP_COMMAND];
  370. if (!ipcmd)
  371. return false;
  372. long cpid = (long)vfork();
  373. if (cpid == 0) {
  374. execl(ipcmd,ipcmd,"addr","del",ip.toString().c_str(),"dev",_dev,(const char *)0);
  375. _exit(-1);
  376. } else {
  377. int exitcode = -1;
  378. waitpid(cpid,&exitcode,0);
  379. return (exitcode == 0);
  380. }
  381. }
  382. bool EthernetTap::addIP(const InetAddress &ip)
  383. {
  384. const char *ipcmd = UNIX_COMMANDS[ZT_UNIX_IP_COMMAND];
  385. if (!ipcmd) {
  386. LOG("ERROR: could not configure IP address for %s: unable to find 'ip' command on system (checked /sbin, /bin, /usr/sbin, /usr/bin)",_dev);
  387. return false;
  388. }
  389. Mutex::Lock _l(_ips_m);
  390. if (!ip)
  391. return false;
  392. if (_ips.count(ip) > 0)
  393. return true;
  394. // Remove and reconfigure if address is the same but netmask is different
  395. for(std::set<InetAddress>::iterator i(_ips.begin());i!=_ips.end();++i) {
  396. if (i->ipsEqual(ip)) {
  397. if (___removeIp(_dev,*i)) {
  398. _ips.erase(i);
  399. break;
  400. } else {
  401. LOG("WARNING: failed to remove old IP/netmask %s to replace with %s",i->toString().c_str(),ip.toString().c_str());
  402. }
  403. }
  404. }
  405. long cpid;
  406. if ((cpid = (long)vfork()) == 0) {
  407. execl(ipcmd,ipcmd,"addr","add",ip.toString().c_str(),"dev",_dev,(const char *)0);
  408. _exit(-1);
  409. } else {
  410. int exitcode = -1;
  411. waitpid(cpid,&exitcode,0);
  412. if (exitcode == 0) {
  413. _ips.insert(ip);
  414. return true;
  415. } else return false;
  416. }
  417. return false;
  418. }
  419. #endif // __LINUX__
  420. #ifdef __APPLE__
  421. static bool ___removeIp(const char *_dev,const InetAddress &ip)
  422. {
  423. const char *ifconfig = UNIX_COMMANDS[ZT_UNIX_IFCONFIG_COMMAND];
  424. if (!ifconfig)
  425. return false;
  426. long cpid;
  427. if ((cpid = (long)vfork()) == 0) {
  428. execl(ifconfig,ifconfig,_dev,"inet",ip.toIpString().c_str(),"-alias",(const char *)0);
  429. _exit(-1);
  430. } else {
  431. int exitcode = -1;
  432. waitpid(cpid,&exitcode,0);
  433. return (exitcode == 0);
  434. }
  435. return false; // never reached, make compiler shut up about return value
  436. }
  437. bool EthernetTap::addIP(const InetAddress &ip)
  438. {
  439. const char *ifconfig = UNIX_COMMANDS[ZT_UNIX_IFCONFIG_COMMAND];
  440. if (!ifconfig) {
  441. LOG("ERROR: could not configure IP address for %s: unable to find 'ifconfig' command on system (checked /sbin, /bin, /usr/sbin, /usr/bin)",_dev);
  442. return false;
  443. }
  444. Mutex::Lock _l(_ips_m);
  445. if (!ip)
  446. return false;
  447. if (_ips.count(ip) > 0)
  448. return true; // IP/netmask already assigned
  449. // Remove and reconfigure if address is the same but netmask is different
  450. for(std::set<InetAddress>::iterator i(_ips.begin());i!=_ips.end();++i) {
  451. if ((i->ipsEqual(ip))&&(i->netmaskBits() != ip.netmaskBits())) {
  452. if (___removeIp(_dev,*i)) {
  453. _ips.erase(i);
  454. break;
  455. } else {
  456. LOG("WARNING: failed to remove old IP/netmask %s to replace with %s",i->toString().c_str(),ip.toString().c_str());
  457. }
  458. }
  459. }
  460. long cpid;
  461. if ((cpid = (long)vfork()) == 0) {
  462. execl(ifconfig,ifconfig,_dev,ip.isV4() ? "inet" : "inet6",ip.toString().c_str(),"alias",(const char *)0);
  463. _exit(-1);
  464. } else {
  465. int exitcode = -1;
  466. waitpid(cpid,&exitcode,0);
  467. if (exitcode == 0) {
  468. _ips.insert(ip);
  469. return true;
  470. }
  471. }
  472. return false;
  473. }
  474. #endif // __APPLE__
  475. bool EthernetTap::removeIP(const InetAddress &ip)
  476. {
  477. Mutex::Lock _l(_ips_m);
  478. if (_ips.count(ip) > 0) {
  479. if (___removeIp(_dev,ip)) {
  480. _ips.erase(ip);
  481. return true;
  482. }
  483. }
  484. return false;
  485. }
  486. std::set<InetAddress> EthernetTap::allIps() const
  487. {
  488. // TODO
  489. return ips();
  490. }
  491. void EthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
  492. {
  493. char putBuf[4096 + 14];
  494. if ((_fd > 0)&&(len <= _mtu)) {
  495. for(int i=0;i<6;++i)
  496. putBuf[i] = to.data[i];
  497. for(int i=0;i<6;++i)
  498. putBuf[i+6] = from.data[i];
  499. *((uint16_t *)(putBuf + 12)) = htons((uint16_t)etherType);
  500. memcpy(putBuf + 14,data,len);
  501. len += 14;
  502. int n = ::write(_fd,putBuf,len);
  503. if (n <= 0) {
  504. LOG("error writing packet to Ethernet tap device: %s",strerror(errno));
  505. } else if (n != (int)len) {
  506. // Saw this gremlin once, so log it if we see it again... OSX tap
  507. // or something seems to have goofy issues with certain MTUs.
  508. LOG("ERROR: write underrun: %s tap write() wrote %d of %u bytes of frame",_dev,n,len);
  509. }
  510. }
  511. }
  512. std::string EthernetTap::deviceName() const
  513. {
  514. return std::string(_dev);
  515. }
  516. #ifdef __LINUX__
  517. bool EthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
  518. {
  519. char *ptr,*ptr2;
  520. unsigned char mac[6];
  521. std::set<MulticastGroup> newGroups;
  522. int fd = ::open("/proc/net/dev_mcast",O_RDONLY);
  523. if (fd > 0) {
  524. char buf[131072];
  525. int n = (int)::read(fd,buf,sizeof(buf));
  526. if ((n > 0)&&(n < (int)sizeof(buf))) {
  527. buf[n] = (char)0;
  528. for(char *l=strtok_r(buf,"\r\n",&ptr);(l);l=strtok_r((char *)0,"\r\n",&ptr)) {
  529. int fno = 0;
  530. char *devname = (char *)0;
  531. char *mcastmac = (char *)0;
  532. for(char *f=strtok_r(l," \t",&ptr2);(f);f=strtok_r((char *)0," \t",&ptr2)) {
  533. if (fno == 1)
  534. devname = f;
  535. else if (fno == 4)
  536. mcastmac = f;
  537. ++fno;
  538. }
  539. if ((devname)&&(!strcmp(devname,_dev))&&(mcastmac)&&(Utils::unhex(mcastmac,mac,6) == 6))
  540. newGroups.insert(MulticastGroup(MAC(mac),0));
  541. }
  542. }
  543. ::close(fd);
  544. }
  545. {
  546. Mutex::Lock _l(_ips_m);
  547. for(std::set<InetAddress>::const_iterator i(_ips.begin());i!=_ips.end();++i)
  548. newGroups.insert(MulticastGroup::deriveMulticastGroupForAddressResolution(*i));
  549. }
  550. bool changed = false;
  551. newGroups.insert(_blindWildcardMulticastGroup); // always join this
  552. for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
  553. if (!groups.count(*mg)) {
  554. groups.insert(*mg);
  555. changed = true;
  556. }
  557. }
  558. for(std::set<MulticastGroup>::iterator mg(groups.begin());mg!=groups.end();) {
  559. if (!newGroups.count(*mg)) {
  560. groups.erase(mg++);
  561. changed = true;
  562. } else ++mg;
  563. }
  564. return changed;
  565. }
  566. #endif // __LINUX__
  567. #ifdef __APPLE__
  568. bool EthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
  569. {
  570. std::set<MulticastGroup> newGroups;
  571. struct ifmaddrs *ifmap = (struct ifmaddrs *)0;
  572. if (!getifmaddrs(&ifmap)) {
  573. struct ifmaddrs *p = ifmap;
  574. while (p) {
  575. if (p->ifma_addr->sa_family == AF_LINK) {
  576. struct sockaddr_dl *in = (struct sockaddr_dl *)p->ifma_name;
  577. struct sockaddr_dl *la = (struct sockaddr_dl *)p->ifma_addr;
  578. if ((la->sdl_alen == 6)&&(in->sdl_nlen <= sizeof(_dev))&&(!memcmp(_dev,in->sdl_data,in->sdl_nlen)))
  579. newGroups.insert(MulticastGroup(MAC(la->sdl_data + la->sdl_nlen),0));
  580. }
  581. p = p->ifma_next;
  582. }
  583. freeifmaddrs(ifmap);
  584. }
  585. {
  586. Mutex::Lock _l(_ips_m);
  587. for(std::set<InetAddress>::const_iterator i(_ips.begin());i!=_ips.end();++i)
  588. newGroups.insert(MulticastGroup::deriveMulticastGroupForAddressResolution(*i));
  589. }
  590. bool changed = false;
  591. newGroups.insert(_blindWildcardMulticastGroup); // always join this
  592. for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
  593. if (!groups.count(*mg)) {
  594. groups.insert(*mg);
  595. changed = true;
  596. }
  597. }
  598. for(std::set<MulticastGroup>::iterator mg(groups.begin());mg!=groups.end();) {
  599. if (!newGroups.count(*mg)) {
  600. groups.erase(mg++);
  601. changed = true;
  602. } else ++mg;
  603. }
  604. return changed;
  605. }
  606. #endif // __APPLE__
  607. void EthernetTap::threadMain()
  608. throw()
  609. {
  610. fd_set readfds,nullfds;
  611. MAC to,from;
  612. int n,nfds,r;
  613. char getBuf[8194];
  614. Buffer<4096> data;
  615. // Wait for a moment after startup -- wait for Network to finish
  616. // constructing itself.
  617. Thread::sleep(500);
  618. FD_ZERO(&readfds);
  619. FD_ZERO(&nullfds);
  620. nfds = (int)std::max(_shutdownSignalPipe[0],_fd) + 1;
  621. r = 0;
  622. for(;;) {
  623. FD_SET(_shutdownSignalPipe[0],&readfds);
  624. FD_SET(_fd,&readfds);
  625. select(nfds,&readfds,&nullfds,&nullfds,(struct timeval *)0);
  626. if (FD_ISSET(_shutdownSignalPipe[0],&readfds)) // writes to shutdown pipe terminate thread
  627. break;
  628. if (FD_ISSET(_fd,&readfds)) {
  629. n = (int)::read(_fd,getBuf + r,sizeof(getBuf) - r);
  630. if (n < 0) {
  631. if ((errno != EINTR)&&(errno != ETIMEDOUT)) {
  632. TRACE("unexpected error reading from tap: %s",strerror(errno));
  633. break;
  634. }
  635. } else {
  636. // Some tap drivers like to send the ethernet frame and the
  637. // payload in two chunks, so handle that by accumulating
  638. // data until we have at least a frame.
  639. r += n;
  640. if (r > 14) {
  641. if (r > ((int)_mtu + 14)) // sanity check for weird TAP behavior on some platforms
  642. r = _mtu + 14;
  643. for(int i=0;i<6;++i)
  644. to.data[i] = (unsigned char)getBuf[i];
  645. for(int i=0;i<6;++i)
  646. from.data[i] = (unsigned char)getBuf[i + 6];
  647. unsigned int etherType = ntohs(((const uint16_t *)getBuf)[6]);
  648. if (etherType != 0x8100) { // VLAN tagged frames are not supported!
  649. data.copyFrom(getBuf + 14,(unsigned int)r - 14);
  650. _handler(_arg,from,to,etherType,data);
  651. }
  652. r = 0;
  653. }
  654. }
  655. }
  656. }
  657. }
  658. } // namespace ZeroTier
  659. #endif // __UNIX_LIKE__ //////////////////////////////////////////////////////
  660. //////////////////////////////////////////////////////////////////////////////
  661. #ifdef __WINDOWS__ ///////////////////////////////////////////////////////////
  662. #include <stdio.h>
  663. #include <stdlib.h>
  664. #include <stdint.h>
  665. #include <string.h>
  666. #include <WinSock2.h>
  667. #include <Windows.h>
  668. #include <iphlpapi.h>
  669. #include <ws2ipdef.h>
  670. #include <WS2tcpip.h>
  671. #include <tchar.h>
  672. #include <winreg.h>
  673. #include <wchar.h>
  674. #include <nldef.h>
  675. #include <netioapi.h>
  676. #include "..\vsprojects\TapDriver\tap-windows.h"
  677. namespace ZeroTier {
  678. // Helper function to get an adapter's LUID and index from its GUID. The LUID is
  679. // constant but the index can change, so go ahead and just look them both up by
  680. // the GUID which is constant. (The GUID is the instance ID in the registry.)
  681. static inline std::pair<NET_LUID,NET_IFINDEX> _findAdapterByGuid(const GUID &guid)
  682. throw(std::runtime_error)
  683. {
  684. MIB_IF_TABLE2 *ift = (MIB_IF_TABLE2 *)0;
  685. if (GetIfTable2Ex(MibIfTableRaw,&ift) != NO_ERROR)
  686. throw std::runtime_error("GetIfTable2Ex() failed");
  687. for(ULONG i=0;i<ift->NumEntries;++i) {
  688. if (ift->Table[i].InterfaceGuid == guid) {
  689. std::pair<NET_LUID,NET_IFINDEX> tmp(ift->Table[i].InterfaceLuid,ift->Table[i].InterfaceIndex);
  690. FreeMibTable(ift);
  691. return tmp;
  692. }
  693. }
  694. FreeMibTable(&ift);
  695. throw std::runtime_error("interface not found");
  696. }
  697. static Mutex _systemTapInitLock;
  698. EthernetTap::EthernetTap(
  699. const RuntimeEnvironment *renv,
  700. const char *tag,
  701. const MAC &mac,
  702. unsigned int mtu,
  703. void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &),
  704. void *arg)
  705. throw(std::runtime_error) :
  706. _mac(mac),
  707. _mtu(mtu),
  708. _r(renv),
  709. _handler(handler),
  710. _arg(arg),
  711. _dhcp(false),
  712. _dhcp6(false),
  713. _tap(INVALID_HANDLE_VALUE),
  714. _injectSemaphore(INVALID_HANDLE_VALUE),
  715. _run(true)
  716. {
  717. char subkeyName[4096];
  718. char subkeyClass[4096];
  719. char data[4096];
  720. if (mtu > ZT_IF_MTU)
  721. throw std::runtime_error("MTU too large for Windows tap");
  722. #ifdef _WIN64
  723. const char *devcon = "\\devcon64.exe";
  724. #else
  725. BOOL f64 = FALSE;
  726. const char *devcon = ((IsWow64Process(GetCurrentProcess(),&f64) == TRUE) ? "\\devcon64.exe" : "\\devcon32.exe");
  727. #endif
  728. Mutex::Lock _l(_systemTapInitLock); // only init one tap at a time, process-wide
  729. HKEY nwAdapters;
  730. if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",0,KEY_READ|KEY_WRITE,&nwAdapters) != ERROR_SUCCESS)
  731. throw std::runtime_error("unable to open registry key for network adapter enumeration");
  732. std::set<std::string> existingDeviceInstances;
  733. std::string mySubkeyName;
  734. // Enumerate tap instances and look for one tagged with this tag
  735. for(DWORD subkeyIndex=0;subkeyIndex!=-1;) {
  736. DWORD type;
  737. DWORD dataLen;
  738. DWORD subkeyNameLen = sizeof(subkeyName);
  739. DWORD subkeyClassLen = sizeof(subkeyClass);
  740. FILETIME lastWriteTime;
  741. switch (RegEnumKeyExA(nwAdapters,subkeyIndex++,subkeyName,&subkeyNameLen,(DWORD *)0,subkeyClass,&subkeyClassLen,&lastWriteTime)) {
  742. case ERROR_NO_MORE_ITEMS: subkeyIndex = -1; break;
  743. case ERROR_SUCCESS:
  744. type = 0;
  745. dataLen = sizeof(data);
  746. if (RegGetValueA(nwAdapters,subkeyName,"ComponentId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
  747. data[dataLen] = '\0';
  748. if (!strnicmp(data,"zttap",5)) {
  749. std::string instanceId;
  750. type = 0;
  751. dataLen = sizeof(data);
  752. if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
  753. instanceId.assign(data,dataLen);
  754. existingDeviceInstances.insert(instanceId);
  755. }
  756. std::string instanceIdPath;
  757. type = 0;
  758. dataLen = sizeof(data);
  759. if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS)
  760. instanceIdPath.assign(data,dataLen);
  761. if ((_myDeviceInstanceId.length() == 0)&&(instanceId.length() != 0)&&(instanceIdPath.length() != 0)) {
  762. type = 0;
  763. dataLen = sizeof(data);
  764. if (RegGetValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
  765. data[dataLen] = '\0';
  766. if (!strcmp(data,tag)) {
  767. _myDeviceInstanceId = instanceId;
  768. _myDeviceInstanceIdPath = instanceIdPath;
  769. mySubkeyName = subkeyName;
  770. subkeyIndex = -1; // break outer loop
  771. }
  772. }
  773. }
  774. }
  775. }
  776. break;
  777. }
  778. }
  779. // If there is no device, try to create one
  780. if (_myDeviceInstanceId.length() == 0) {
  781. // Execute devcon to install an instance of the Microsoft Loopback Adapter
  782. STARTUPINFOA startupInfo;
  783. startupInfo.cb = sizeof(startupInfo);
  784. PROCESS_INFORMATION processInfo;
  785. memset(&startupInfo,0,sizeof(STARTUPINFOA));
  786. memset(&processInfo,0,sizeof(PROCESS_INFORMATION));
  787. if (!CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" install \"" + _r->homePath + "\\ztTap100.inf\" ztTap100").c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) {
  788. RegCloseKey(nwAdapters);
  789. throw std::runtime_error(std::string("unable to find or execute devcon at ")+devcon);
  790. }
  791. WaitForSingleObject(processInfo.hProcess,INFINITE);
  792. CloseHandle(processInfo.hProcess);
  793. CloseHandle(processInfo.hThread);
  794. // Scan for the new instance by simply looking for taps that weren't
  795. // there originally.
  796. for(DWORD subkeyIndex=0;subkeyIndex!=-1;) {
  797. DWORD type;
  798. DWORD dataLen;
  799. DWORD subkeyNameLen = sizeof(subkeyName);
  800. DWORD subkeyClassLen = sizeof(subkeyClass);
  801. FILETIME lastWriteTime;
  802. switch (RegEnumKeyExA(nwAdapters,subkeyIndex++,subkeyName,&subkeyNameLen,(DWORD *)0,subkeyClass,&subkeyClassLen,&lastWriteTime)) {
  803. case ERROR_NO_MORE_ITEMS: subkeyIndex = -1; break;
  804. case ERROR_SUCCESS:
  805. type = 0;
  806. dataLen = sizeof(data);
  807. if (RegGetValueA(nwAdapters,subkeyName,"ComponentId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
  808. data[dataLen] = '\0';
  809. if (!strnicmp(data,"zttap",5)) {
  810. type = 0;
  811. dataLen = sizeof(data);
  812. if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) {
  813. if (existingDeviceInstances.count(std::string(data,dataLen)) == 0) {
  814. RegSetKeyValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",REG_SZ,tag,(DWORD)(strlen(tag)+1));
  815. _myDeviceInstanceId.assign(data,dataLen);
  816. type = 0;
  817. dataLen = sizeof(data);
  818. if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS)
  819. _myDeviceInstanceIdPath.assign(data,dataLen);
  820. mySubkeyName = subkeyName;
  821. subkeyIndex = -1; // break outer loop
  822. }
  823. }
  824. }
  825. }
  826. break;
  827. }
  828. }
  829. }
  830. // If we have a device, configure it
  831. if (_myDeviceInstanceId.length() > 0) {
  832. char tmps[4096];
  833. 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;
  834. RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"NetworkAddress",REG_SZ,tmps,tmpsl);
  835. RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"MAC",REG_SZ,tmps,tmpsl);
  836. DWORD tmp = mtu;
  837. RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"MTU",REG_DWORD,(LPCVOID)&tmp,sizeof(tmp));
  838. tmp = 0;
  839. RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"EnableDHCP",REG_DWORD,(LPCVOID)&tmp,sizeof(tmp));
  840. }
  841. // Done with registry
  842. RegCloseKey(nwAdapters);
  843. // If we didn't get a device, we can't start
  844. if (_myDeviceInstanceId.length() == 0)
  845. throw std::runtime_error("unable to create new tap adapter");
  846. // Convert device GUID junk... blech
  847. {
  848. char nobraces[128];
  849. const char *nbtmp1 = _myDeviceInstanceId.c_str();
  850. char *nbtmp2 = nobraces;
  851. while (*nbtmp1) {
  852. if ((*nbtmp1 != '{')&&(*nbtmp1 != '}'))
  853. *nbtmp2++ = *nbtmp1;
  854. ++nbtmp1;
  855. }
  856. *nbtmp2 = (char)0;
  857. if (UuidFromStringA((RPC_CSTR)nobraces,&_deviceGuid) != RPC_S_OK)
  858. throw std::runtime_error("unable to convert instance ID GUID to native GUID (invalid NetCfgInstanceId in registry?)");
  859. }
  860. setDhcpEnabled(false);
  861. setDhcp6Enabled(false);
  862. // Disable and enable interface to ensure registry settings take effect
  863. {
  864. STARTUPINFOA startupInfo;
  865. startupInfo.cb = sizeof(startupInfo);
  866. PROCESS_INFORMATION processInfo;
  867. memset(&startupInfo,0,sizeof(STARTUPINFOA));
  868. memset(&processInfo,0,sizeof(PROCESS_INFORMATION));
  869. if (!CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" disable @" + _myDeviceInstanceIdPath).c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) {
  870. RegCloseKey(nwAdapters);
  871. throw std::runtime_error(std::string("unable to find or execute devcon at ")+devcon);
  872. }
  873. WaitForSingleObject(processInfo.hProcess,INFINITE);
  874. CloseHandle(processInfo.hProcess);
  875. CloseHandle(processInfo.hThread);
  876. }
  877. {
  878. STARTUPINFOA startupInfo;
  879. startupInfo.cb = sizeof(startupInfo);
  880. PROCESS_INFORMATION processInfo;
  881. memset(&startupInfo,0,sizeof(STARTUPINFOA));
  882. memset(&processInfo,0,sizeof(PROCESS_INFORMATION));
  883. if (!CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" enable @" + _myDeviceInstanceIdPath).c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) {
  884. RegCloseKey(nwAdapters);
  885. throw std::runtime_error(std::string("unable to find or execute devcon at ")+devcon);
  886. }
  887. WaitForSingleObject(processInfo.hProcess,INFINITE);
  888. CloseHandle(processInfo.hProcess);
  889. CloseHandle(processInfo.hThread);
  890. }
  891. // Open the tap, which is in this weird Windows analog of /dev
  892. char tapPath[4096];
  893. Utils::snprintf(tapPath,sizeof(tapPath),"\\\\.\\Global\\%s.tap",_myDeviceInstanceId.c_str());
  894. _tap = CreateFileA(tapPath,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM|FILE_FLAG_OVERLAPPED,NULL);
  895. if (_tap == INVALID_HANDLE_VALUE)
  896. throw std::runtime_error("unable to open tap in \\\\.\\Global\\ namespace");
  897. // Set media status to enabled
  898. uint32_t tmpi = 1;
  899. DWORD bytesReturned = 0;
  900. DeviceIoControl(_tap,TAP_WIN_IOCTL_SET_MEDIA_STATUS,&tmpi,sizeof(tmpi),&tmpi,sizeof(tmpi),&bytesReturned,NULL);
  901. // Initialized overlapped I/O structures and related events
  902. memset(&_tapOvlRead,0,sizeof(_tapOvlRead));
  903. _tapOvlRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
  904. memset(&_tapOvlWrite,0,sizeof(_tapOvlWrite));
  905. _tapOvlWrite.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
  906. // Start background thread that actually performs I/O
  907. _injectSemaphore = CreateSemaphore(NULL,0,1,NULL);
  908. _thread = Thread::start(this);
  909. }
  910. EthernetTap::~EthernetTap()
  911. {
  912. _run = false;
  913. ReleaseSemaphore(_injectSemaphore,1,NULL);
  914. Thread::join(_thread);
  915. CloseHandle(_tap);
  916. CloseHandle(_tapOvlRead.hEvent);
  917. CloseHandle(_tapOvlWrite.hEvent);
  918. CloseHandle(_injectSemaphore);
  919. // Disable network device on shutdown
  920. #ifdef _WIN64
  921. const char *devcon = "\\devcon64.exe";
  922. #else
  923. BOOL f64 = FALSE;
  924. const char *devcon = ((IsWow64Process(GetCurrentProcess(),&f64) == TRUE) ? "\\devcon64.exe" : "\\devcon32.exe");
  925. #endif
  926. {
  927. STARTUPINFOA startupInfo;
  928. startupInfo.cb = sizeof(startupInfo);
  929. PROCESS_INFORMATION processInfo;
  930. memset(&startupInfo,0,sizeof(STARTUPINFOA));
  931. memset(&processInfo,0,sizeof(PROCESS_INFORMATION));
  932. if (CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" disable @" + _myDeviceInstanceIdPath).c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) {
  933. WaitForSingleObject(processInfo.hProcess,INFINITE);
  934. CloseHandle(processInfo.hProcess);
  935. CloseHandle(processInfo.hThread);
  936. }
  937. }
  938. }
  939. void EthernetTap::whack()
  940. {
  941. }
  942. bool EthernetTap::setDhcpEnabled(bool dhcp)
  943. {
  944. HKEY tcpIpInterfaces;
  945. if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces",0,KEY_READ|KEY_WRITE,&tcpIpInterfaces) == ERROR_SUCCESS) {
  946. _dhcp = dhcp;
  947. DWORD enable = (dhcp ? 1 : 0);
  948. RegSetKeyValueA(tcpIpInterfaces,_myDeviceInstanceId.c_str(),"EnableDHCP",REG_DWORD,&enable,sizeof(enable));
  949. RegCloseKey(tcpIpInterfaces);
  950. } else _dhcp = false;
  951. return _dhcp;
  952. }
  953. bool EthernetTap::setDhcp6Enabled(bool dhcp)
  954. {
  955. // TODO
  956. return _dhcp6;
  957. }
  958. void EthernetTap::setDisplayName(const char *dn)
  959. {
  960. HKEY ifp;
  961. 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) {
  962. RegSetKeyValueA(ifp,"Connection","Name",REG_SZ,(LPCVOID)dn,(DWORD)(strlen(dn)+1));
  963. RegCloseKey(ifp);
  964. }
  965. }
  966. bool EthernetTap::addIP(const InetAddress &ip)
  967. {
  968. Mutex::Lock _l(_ips_m);
  969. if (_ips.count(ip))
  970. return true;
  971. if (!ip.port())
  972. return false;
  973. try {
  974. std::pair<NET_LUID,NET_IFINDEX> ifidx = _findAdapterByGuid(_deviceGuid);
  975. MIB_UNICASTIPADDRESS_ROW ipr;
  976. InitializeUnicastIpAddressEntry(&ipr);
  977. if (ip.isV4()) {
  978. ipr.Address.Ipv4.sin_family = AF_INET;
  979. ipr.Address.Ipv4.sin_addr.S_un.S_addr = *((const uint32_t *)ip.rawIpData());
  980. ipr.OnLinkPrefixLength = ip.port();
  981. } else if (ip.isV6()) {
  982. } else return false;
  983. ipr.PrefixOrigin = IpPrefixOriginManual;
  984. ipr.SuffixOrigin = IpSuffixOriginManual;
  985. ipr.ValidLifetime = 0xffffffff;
  986. ipr.PreferredLifetime = 0xffffffff;
  987. ipr.InterfaceLuid = ifidx.first;
  988. ipr.InterfaceIndex = ifidx.second;
  989. if (CreateUnicastIpAddressEntry(&ipr) == NO_ERROR) {
  990. _ips.insert(ip);
  991. return true;
  992. }
  993. } catch ( ... ) {}
  994. return false;
  995. }
  996. bool EthernetTap::removeIP(const InetAddress &ip)
  997. {
  998. try {
  999. MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0;
  1000. std::pair<NET_LUID,NET_IFINDEX> ifidx = _findAdapterByGuid(_deviceGuid);
  1001. if (GetUnicastIpAddressTable(AF_UNSPEC,&ipt) == NO_ERROR) {
  1002. for(DWORD i=0;i<ipt->NumEntries;++i) {
  1003. if ((ipt->Table[i].InterfaceLuid.Value == ifidx.first.Value)&&(ipt->Table[i].InterfaceIndex == ifidx.second)) {
  1004. InetAddress addr;
  1005. switch(ipt->Table[i].Address.si_family) {
  1006. case AF_INET:
  1007. addr.set(&(ipt->Table[i].Address.Ipv4.sin_addr.S_un.S_addr),4,ipt->Table[i].OnLinkPrefixLength);
  1008. break;
  1009. case AF_INET6:
  1010. addr.set(ipt->Table[i].Address.Ipv6.sin6_addr.u.Byte,16,ipt->Table[i].OnLinkPrefixLength);
  1011. break;
  1012. }
  1013. if (addr == ip) {
  1014. DeleteUnicastIpAddressEntry(&(ipt->Table[i]));
  1015. FreeMibTable(ipt);
  1016. Mutex::Lock _l(_ips_m);
  1017. _ips.erase(ip);
  1018. return true;
  1019. }
  1020. }
  1021. }
  1022. FreeMibTable(&ipt);
  1023. }
  1024. } catch ( ... ) {}
  1025. return false;
  1026. }
  1027. std::set<InetAddress> EthernetTap::allIps() const
  1028. {
  1029. static const InetAddress ifLoopback("fe80::1",64);
  1030. std::set<InetAddress> addrs;
  1031. try {
  1032. MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0;
  1033. std::pair<NET_LUID,NET_IFINDEX> ifidx = _findAdapterByGuid(_deviceGuid);
  1034. if (GetUnicastIpAddressTable(AF_UNSPEC,&ipt) == NO_ERROR) {
  1035. for(DWORD i=0;i<ipt->NumEntries;++i) {
  1036. if ((ipt->Table[i].InterfaceLuid.Value == ifidx.first.Value)&&(ipt->Table[i].InterfaceIndex == ifidx.second)) {
  1037. switch(ipt->Table[i].Address.si_family) {
  1038. case AF_INET:
  1039. addrs.insert(InetAddress(&(ipt->Table[i].Address.Ipv4.sin_addr.S_un.S_addr),4,ipt->Table[i].OnLinkPrefixLength));
  1040. break;
  1041. case AF_INET6: {
  1042. InetAddress ip(ipt->Table[i].Address.Ipv6.sin6_addr.u.Byte,16,ipt->Table[i].OnLinkPrefixLength);
  1043. if (ip != ifLoopback) // don't include fe80::1
  1044. addrs.insert(ip);
  1045. } break;
  1046. }
  1047. }
  1048. }
  1049. FreeMibTable(ipt);
  1050. }
  1051. } catch ( ... ) {}
  1052. return addrs;
  1053. }
  1054. void EthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len)
  1055. {
  1056. if (len > (ZT_IF_MTU))
  1057. return;
  1058. {
  1059. Mutex::Lock _l(_injectPending_m);
  1060. _injectPending.push( std::pair<Array<char,ZT_IF_MTU + 32>,unsigned int>(Array<char,ZT_IF_MTU + 32>(),len + 14) );
  1061. char *d = _injectPending.back().first.data;
  1062. memcpy(d,to.data,6);
  1063. memcpy(d + 6,from.data,6);
  1064. *((uint16_t *)(d + 12)) = Utils::hton(etherType);
  1065. memcpy(d + 14,data,len);
  1066. }
  1067. ReleaseSemaphore(_injectSemaphore,1,NULL);
  1068. }
  1069. std::string EthernetTap::deviceName() const
  1070. {
  1071. return _myDeviceInstanceId;
  1072. }
  1073. bool EthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
  1074. {
  1075. std::set<MulticastGroup> newGroups;
  1076. std::set<InetAddress> ipaddrs(allIps());
  1077. for(std::set<InetAddress>::const_iterator i(ipaddrs.begin());i!=ipaddrs.end();++i)
  1078. newGroups.insert(MulticastGroup::deriveMulticastGroupForAddressResolution(*i));
  1079. bool changed = false;
  1080. newGroups.insert(_blindWildcardMulticastGroup); // always join this
  1081. for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) {
  1082. if (!groups.count(*mg)) {
  1083. groups.insert(*mg);
  1084. changed = true;
  1085. }
  1086. }
  1087. for(std::set<MulticastGroup>::iterator mg(groups.begin());mg!=groups.end();) {
  1088. if (!newGroups.count(*mg)) {
  1089. groups.erase(mg++);
  1090. changed = true;
  1091. } else ++mg;
  1092. }
  1093. return changed;
  1094. }
  1095. void EthernetTap::threadMain()
  1096. throw()
  1097. {
  1098. HANDLE wait4[3];
  1099. wait4[0] = _injectSemaphore;
  1100. wait4[1] = _tapOvlRead.hEvent;
  1101. wait4[2] = _tapOvlWrite.hEvent;
  1102. ReadFile(_tap,_tapReadBuf,sizeof(_tapReadBuf),NULL,&_tapOvlRead);
  1103. bool writeInProgress = false;
  1104. for(;;) {
  1105. if (!_run) break;
  1106. WaitForMultipleObjectsEx(3,wait4,FALSE,INFINITE,TRUE);
  1107. if (!_run) break;
  1108. if (HasOverlappedIoCompleted(&_tapOvlRead)) {
  1109. DWORD bytesRead = 0;
  1110. if (GetOverlappedResult(_tap,&_tapOvlRead,&bytesRead,FALSE)) {
  1111. if (bytesRead > 14) {
  1112. MAC to(_tapReadBuf);
  1113. MAC from(_tapReadBuf + 6);
  1114. unsigned int etherType = Utils::ntoh(*((const uint16_t *)(_tapReadBuf + 12)));
  1115. Buffer<4096> tmp(_tapReadBuf + 14,bytesRead - 14);
  1116. //printf("GOT FRAME: %u bytes: %s\r\n",(unsigned int)bytesRead,Utils::hex(_tapReadBuf,bytesRead).c_str());
  1117. _handler(_arg,from,to,etherType,tmp);
  1118. }
  1119. }
  1120. ReadFile(_tap,_tapReadBuf,sizeof(_tapReadBuf),NULL,&_tapOvlRead);
  1121. }
  1122. if (writeInProgress) {
  1123. if (HasOverlappedIoCompleted(&_tapOvlWrite)) {
  1124. writeInProgress = false;
  1125. _injectPending_m.lock();
  1126. _injectPending.pop();
  1127. } else continue; // still writing, so skip code below and wait
  1128. } else _injectPending_m.lock();
  1129. if (!_injectPending.empty()) {
  1130. WriteFile(_tap,_injectPending.front().first.data,_injectPending.front().second,NULL,&_tapOvlWrite);
  1131. writeInProgress = true;
  1132. }
  1133. _injectPending_m.unlock();
  1134. }
  1135. CancelIo(_tap);
  1136. }
  1137. } // namespace ZeroTier
  1138. #endif // __WINDOWS__ ////////////////////////////////////////////////////////