LinuxNetLink.hpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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: 2023-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 <vector>
  16. #include <sys/socket.h>
  17. #include <asm/types.h>
  18. #include <linux/rtnetlink.h>
  19. #include <sys/socket.h>
  20. #include <linux/if.h>
  21. #include "../node/InetAddress.hpp"
  22. #include "../node/MAC.hpp"
  23. #include "Thread.hpp"
  24. #include "../node/Hashtable.hpp"
  25. #include "../node/Mutex.hpp"
  26. namespace ZeroTier {
  27. struct route_entry {
  28. InetAddress target;
  29. InetAddress via;
  30. int if_index;
  31. char iface[IFNAMSIZ];
  32. };
  33. typedef std::vector<route_entry> RouteList;
  34. /**
  35. * Interface with Linux's RTNETLINK
  36. */
  37. class LinuxNetLink
  38. {
  39. private:
  40. LinuxNetLink();
  41. ~LinuxNetLink();
  42. public:
  43. static LinuxNetLink& getInstance()
  44. {
  45. static LinuxNetLink instance;
  46. return instance;
  47. }
  48. LinuxNetLink(LinuxNetLink const&) = delete;
  49. void operator=(LinuxNetLink const&) = delete;
  50. void addRoute(const InetAddress &target, const InetAddress &via, const InetAddress &src, const char *ifaceName);
  51. void delRoute(const InetAddress &target, const InetAddress &via, const InetAddress &src, const char *ifaceName);
  52. RouteList getIPV4Routes() const;
  53. RouteList getIPV6Routes() const;
  54. void addAddress(const InetAddress &addr, const char *iface);
  55. void removeAddress(const InetAddress &addr, const char *iface);
  56. void threadMain() throw();
  57. private:
  58. int _doRecv(int fd);
  59. void _processMessage(struct nlmsghdr *nlp, int nll);
  60. void _routeAdded(struct nlmsghdr *nlp);
  61. void _routeDeleted(struct nlmsghdr *nlp);
  62. void _linkAdded(struct nlmsghdr *nlp);
  63. void _linkDeleted(struct nlmsghdr *nlp);
  64. void _ipAddressAdded(struct nlmsghdr *nlp);
  65. void _ipAddressDeleted(struct nlmsghdr *nlp);
  66. void _requestInterfaceList();
  67. void _requestIPv4Routes();
  68. void _requestIPv6Routes();
  69. int _indexForInterface(const char *iface);
  70. void _setSocketTimeout(int fd, int seconds = 1);
  71. Thread _t;
  72. bool _running;
  73. RouteList _routes_ipv4;
  74. Mutex _rv4_m;
  75. RouteList _routes_ipv6;
  76. Mutex _rv6_m;
  77. uint32_t _seq;
  78. struct iface_entry {
  79. int index;
  80. char ifacename[IFNAMSIZ];
  81. char mac[18];
  82. char mac_bin[6];
  83. unsigned int mtu;
  84. };
  85. Hashtable<int, iface_entry> _interfaces;
  86. Mutex _if_m;
  87. // socket communication vars;
  88. int _fd;
  89. struct sockaddr_nl _la;
  90. };
  91. }
  92. #endif // ZT_LINUX_NETLINK_HPPS