EthernetTap.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * Copyright (c)2019 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2025-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. #include "EthernetTap.hpp"
  14. #include "OSUtils.hpp"
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #ifdef ZT_SDK
  18. #include "../controller/EmbeddedNetworkController.hpp"
  19. #include "../node/Node.hpp"
  20. #include "../include/VirtualTap.hpp"
  21. #else
  22. #ifdef __APPLE__
  23. #include <sys/sysctl.h>
  24. #include "MacEthernetTap.hpp"
  25. #include "MacKextEthernetTap.hpp"
  26. #endif // __APPLE__
  27. #ifdef __LINUX__
  28. #include "LinuxEthernetTap.hpp"
  29. #endif // __LINUX__
  30. #ifdef __WINDOWS__
  31. #include "WindowsEthernetTap.hpp"
  32. #endif // __WINDOWS__
  33. #ifdef __FreeBSD__
  34. #include "BSDEthernetTap.hpp"
  35. #endif // __FreeBSD__
  36. #ifdef __NetBSD__
  37. #include "NetBSDEthernetTap.hpp"
  38. #endif // __NetBSD__
  39. #ifdef __OpenBSD__
  40. #include "BSDEthernetTap.hpp"
  41. #endif // __OpenBSD__
  42. #endif
  43. namespace ZeroTier {
  44. std::shared_ptr<EthernetTap> EthernetTap::newInstance(
  45. const char *tapDeviceType, // OS-specific, NULL for default
  46. const char *homePath,
  47. const MAC &mac,
  48. unsigned int mtu,
  49. unsigned int metric,
  50. uint64_t nwid,
  51. const char *friendlyName,
  52. void (*handler)(void *,void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
  53. void *arg)
  54. {
  55. #ifdef ZT_SDK
  56. return std::shared_ptr<EthernetTap>(new VirtualTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg));
  57. #else // not ZT_SDK
  58. #ifdef __APPLE__
  59. char osrelease[256];
  60. size_t size = sizeof(osrelease);
  61. if (sysctlbyname("kern.osrelease",osrelease,&size,nullptr,0) == 0) {
  62. char *dotAt = strchr(osrelease,'.');
  63. if (dotAt) {
  64. *dotAt = (char)0;
  65. // The "feth" virtual Ethernet device type appeared in Darwin 17.x.x. Older versions
  66. // (Sierra and earlier) must use the a kernel extension.
  67. if (strtol(osrelease,(char **)0,10) < 17) {
  68. return std::shared_ptr<EthernetTap>(new MacKextEthernetTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg));
  69. } else {
  70. return std::shared_ptr<EthernetTap>(new MacEthernetTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg));
  71. }
  72. }
  73. }
  74. #endif // __APPLE__
  75. #ifdef __LINUX__
  76. return std::shared_ptr<EthernetTap>(new LinuxEthernetTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg));
  77. #endif // __LINUX__
  78. #ifdef __WINDOWS__
  79. HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED);
  80. if (FAILED(hres)) {
  81. throw std::runtime_error("WinEthernetTap: COM initialization failed");
  82. }
  83. static bool _comInit = false;
  84. static Mutex _comInit_m;
  85. {
  86. Mutex::Lock l(_comInit_m);
  87. if (!_comInit) {
  88. hres = CoInitializeSecurity(
  89. NULL,
  90. -1,
  91. NULL,
  92. NULL,
  93. RPC_C_AUTHN_LEVEL_PKT,
  94. RPC_C_IMP_LEVEL_IMPERSONATE,
  95. NULL,
  96. EOAC_NONE,
  97. NULL
  98. );
  99. if (FAILED(hres)) {
  100. CoUninitialize();
  101. fprintf(stderr, "WinEthernetTap: Failed to initialize security");
  102. throw std::runtime_error("WinEthernetTap: Failed to initialize security");
  103. }
  104. _comInit = true;
  105. }
  106. }
  107. return std::shared_ptr<EthernetTap>(new WindowsEthernetTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg));
  108. #endif // __WINDOWS__
  109. #ifdef __FreeBSD__
  110. return std::shared_ptr<EthernetTap>(new BSDEthernetTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg));
  111. #endif // __FreeBSD__
  112. #ifdef __NetBSD__
  113. return std::shared_ptr<EthernetTap>(new NetBSDEthernetTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg));
  114. #endif // __NetBSD__
  115. #ifdef __OpenBSD__
  116. return std::shared_ptr<EthernetTap>(new BSDEthernetTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg));
  117. #endif // __OpenBSD__
  118. #endif // ZT_SDK?
  119. return std::shared_ptr<EthernetTap>();
  120. }
  121. EthernetTap::EthernetTap() {}
  122. EthernetTap::~EthernetTap() {}
  123. bool EthernetTap::addIps(std::vector<InetAddress> ips)
  124. {
  125. for(std::vector<InetAddress>::const_iterator i(ips.begin());i!=ips.end();++i) {
  126. if (!addIp(*i))
  127. return false;
  128. }
  129. return true;
  130. }
  131. std::string EthernetTap::friendlyName() const
  132. {
  133. // Most platforms do not have this.
  134. return std::string();
  135. }
  136. } // namespace ZeroTier