WindowsEthernetTap.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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. #ifndef ZT_WINDOWSETHERNETTAP_HPP
  9. #define ZT_WINDOWSETHERNETTAP_HPP
  10. #include "../node/Constants.hpp"
  11. #include "../node/InetAddress.hpp"
  12. #include "../node/MulticastGroup.hpp"
  13. #include "../node/Mutex.hpp"
  14. #include "../osdep/Thread.hpp"
  15. #include "EthernetTap.hpp"
  16. #include <ifdef.h>
  17. #include <queue>
  18. #include <stdexcept>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string>
  22. namespace ZeroTier {
  23. class WindowsEthernetTap : public EthernetTap {
  24. public:
  25. /**
  26. * Installs a new instance of the ZT tap driver
  27. *
  28. * @param pathToInf Path to zttap driver .inf file
  29. * @param deviceInstanceId Buffer to fill with device instance ID on success (and if SetupDiGetDeviceInstanceIdA succeeds, which it should)
  30. * @return Empty string on success, otherwise an error message
  31. */
  32. static std::string addNewPersistentTapDevice(const char* pathToInf, std::string& deviceInstanceId);
  33. /**
  34. * Uninstalls all persistent tap devices that have legacy drivers
  35. *
  36. * @return Empty string on success, otherwise an error message
  37. */
  38. static std::string destroyAllLegacyPersistentTapDevices();
  39. /**
  40. * Uninstalls all persistent tap devices on the system
  41. *
  42. * @return Empty string on success, otherwise an error message
  43. */
  44. static std::string destroyAllPersistentTapDevices();
  45. /**
  46. * Uninstalls a specific persistent tap device by instance ID
  47. *
  48. * @param instanceId Device instance ID
  49. * @return Empty string on success, otherwise an error message
  50. */
  51. static std::string deletePersistentTapDevice(const char* instanceId);
  52. /**
  53. * Disable a persistent tap device by instance ID
  54. *
  55. * @param instanceId Device instance ID
  56. * @param enabled Enable device?
  57. * @return True if device was found and disabled
  58. */
  59. static bool setPersistentTapDeviceState(const char* instanceId, bool enabled);
  60. WindowsEthernetTap(
  61. const char* hp,
  62. const MAC& mac,
  63. unsigned int mtu,
  64. unsigned int metric,
  65. uint64_t nwid,
  66. const char* friendlyName,
  67. void (*handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int),
  68. void* arg);
  69. virtual ~WindowsEthernetTap();
  70. virtual void setEnabled(bool en);
  71. virtual bool enabled() const;
  72. virtual bool addIp(const InetAddress& ip);
  73. virtual bool removeIp(const InetAddress& ip);
  74. virtual std::vector<InetAddress> ips() const;
  75. virtual void put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len);
  76. virtual std::string deviceName() const;
  77. virtual void setFriendlyName(const char* friendlyName);
  78. virtual std::string friendlyName() const;
  79. virtual void scanMulticastGroups(std::vector<MulticastGroup>& added, std::vector<MulticastGroup>& removed);
  80. virtual void setMtu(unsigned int mtu);
  81. virtual void setDns(const char* domain, const std::vector<InetAddress>& servers);
  82. inline const NET_LUID& luid() const
  83. {
  84. return _deviceLuid;
  85. }
  86. inline const GUID& guid() const
  87. {
  88. return _deviceGuid;
  89. }
  90. inline const std::string& instanceId() const
  91. {
  92. return _deviceInstanceId;
  93. }
  94. NET_IFINDEX interfaceIndex() const;
  95. void threadMain() throw();
  96. bool isInitialized() const
  97. {
  98. return _initialized;
  99. };
  100. private:
  101. NET_IFINDEX _getDeviceIndex(); // throws on failure
  102. std::vector<std::string> _getRegistryIPv4Value(const char* regKey);
  103. void _setRegistryIPv4Value(const char* regKey, const std::vector<std::string>& value);
  104. void _syncIps();
  105. void (*_handler)(void*, void*, uint64_t, const MAC&, const MAC&, unsigned int, unsigned int, const void*, unsigned int);
  106. void* _arg;
  107. MAC _mac;
  108. uint64_t _nwid;
  109. volatile unsigned int _mtu;
  110. Thread _thread;
  111. volatile HANDLE _tap;
  112. HANDLE _injectSemaphore;
  113. GUID _deviceGuid;
  114. NET_LUID _deviceLuid;
  115. std::string _netCfgInstanceId;
  116. std::string _deviceInstanceId;
  117. std::string _mySubkeyName;
  118. std::string _friendlyName;
  119. Mutex _friendlyName_m;
  120. std::vector<InetAddress> _assignedIps; // IPs assigned with addIp
  121. Mutex _assignedIps_m;
  122. std::vector<MulticastGroup> _multicastGroups;
  123. struct _InjectPending {
  124. unsigned int len;
  125. char data[ZT_MAX_MTU + 32];
  126. };
  127. std::queue<_InjectPending> _injectPending;
  128. Mutex _injectPending_m;
  129. std::string _pathToHelpers;
  130. volatile bool _run;
  131. volatile bool _initialized;
  132. volatile bool _enabled;
  133. mutable std::vector<InetAddress> _ifaddrs;
  134. mutable uint64_t _lastIfAddrsUpdate;
  135. };
  136. } // namespace ZeroTier
  137. #endif