2
0

EthernetTap.cpp 4.4 KB

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