LinuxNetLink.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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. #ifndef ZT_LINUX_NETLINK_HPP
  14. #define ZT_LINUX_NETLINK_HPP
  15. #include "../node/Constants.hpp"
  16. #ifdef __LINUX__
  17. #include <vector>
  18. #include <map>
  19. #include <set>
  20. #include <sys/socket.h>
  21. #include <asm/types.h>
  22. #include <linux/rtnetlink.h>
  23. #include <sys/socket.h>
  24. //#include <linux/if.h>
  25. #include "../node/InetAddress.hpp"
  26. #include "../node/MAC.hpp"
  27. #include "Thread.hpp"
  28. #include "../node/Hashtable.hpp"
  29. #include "../node/Mutex.hpp"
  30. namespace ZeroTier {
  31. /**
  32. * Interface with Linux's RTNETLINK
  33. */
  34. class LinuxNetLink
  35. {
  36. private:
  37. LinuxNetLink();
  38. ~LinuxNetLink();
  39. public:
  40. struct Route {
  41. InetAddress target;
  42. InetAddress via;
  43. InetAddress src;
  44. int ifidx;
  45. inline bool operator==(const Route &r) const
  46. { return ((target == r.target)&&(via == r.via)&&(src == r.src)&&(ifidx == r.ifidx)); }
  47. inline bool operator!=(const Route &r) const
  48. { return (!(*this == r)); }
  49. inline bool operator<(const Route &r) const
  50. {
  51. if (target < r.target) {
  52. return true;
  53. } else if (target == r.target) {
  54. if (via < r.via) {
  55. return true;
  56. } else if (via == r.via) {
  57. if (src < r.src) {
  58. return true;
  59. } else if (src == r.src) {
  60. return (ifidx < r.ifidx);
  61. }
  62. }
  63. }
  64. return false;
  65. }
  66. inline bool operator>(const Route &r) const
  67. { return (r < *this); }
  68. inline bool operator<=(const Route &r) const
  69. { return !(r < *this); }
  70. inline bool operator>=(const Route &r) const
  71. { return !(*this < r); }
  72. };
  73. static LinuxNetLink& getInstance()
  74. {
  75. static LinuxNetLink instance;
  76. return instance;
  77. }
  78. LinuxNetLink(LinuxNetLink const&) = delete;
  79. void operator=(LinuxNetLink const&) = delete;
  80. void addRoute(const InetAddress &target, const InetAddress &via, const InetAddress &src, const char *ifaceName);
  81. void delRoute(const InetAddress &target, const InetAddress &via, const InetAddress &src, const char *ifaceName);
  82. void addAddress(const InetAddress &addr, const char *iface);
  83. void removeAddress(const InetAddress &addr, const char *iface);
  84. bool routeIsSet(const InetAddress &target, const InetAddress &via, const InetAddress &src, const char *ifname);
  85. void threadMain() throw();
  86. private:
  87. int _doRecv(int fd);
  88. void _processMessage(struct nlmsghdr *nlp, int nll);
  89. void _routeAdded(struct nlmsghdr *nlp);
  90. void _routeDeleted(struct nlmsghdr *nlp);
  91. void _linkAdded(struct nlmsghdr *nlp);
  92. void _linkDeleted(struct nlmsghdr *nlp);
  93. void _ipAddressAdded(struct nlmsghdr *nlp);
  94. void _ipAddressDeleted(struct nlmsghdr *nlp);
  95. void _requestInterfaceList();
  96. void _requestIPv4Routes();
  97. void _requestIPv6Routes();
  98. int _indexForInterface(const char *iface);
  99. void _setSocketTimeout(int fd, int seconds = 1);
  100. Thread _t;
  101. bool _running;
  102. uint32_t _seq;
  103. std::map< InetAddress,std::set<LinuxNetLink::Route> > _routes;
  104. Mutex _routes_m;
  105. struct iface_entry {
  106. iface_entry()
  107. { memset(this,0,sizeof(iface_entry)); }
  108. int index;
  109. char ifacename[16]; // IFNAMSIZ on Linux == 16
  110. char mac[18];
  111. char mac_bin[6];
  112. unsigned int mtu;
  113. };
  114. Hashtable<int, iface_entry> _interfaces;
  115. Mutex _if_m;
  116. // socket communication vars;
  117. int _fd;
  118. struct sockaddr_nl _la;
  119. };
  120. }
  121. #endif
  122. #endif // ZT_LINUX_NETLINK_HPPS