EthernetTap.cpp 4.5 KB

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