Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ScanIpIfAddrs.hpp 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /* Copyright 2016, Ableton AG, Berlin. All rights reserved.
  2. *
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. * If you would like to incorporate Link into a proprietary software application,
  17. * please contact <link-devs@ableton.com>.
  18. */
  19. #pragma once
  20. #include <ableton/platforms/asio/AsioWrapper.hpp>
  21. #include <ableton/platforms/asio/Util.hpp>
  22. #include <arpa/inet.h>
  23. #include <ifaddrs.h>
  24. #include <net/if.h>
  25. #include <vector>
  26. namespace ableton
  27. {
  28. namespace platforms
  29. {
  30. namespace posix
  31. {
  32. namespace detail
  33. {
  34. // RAII type to make [get,free]ifaddrs function pairs exception safe
  35. class GetIfAddrs
  36. {
  37. public:
  38. GetIfAddrs()
  39. {
  40. if (getifaddrs(&interfaces)) // returns 0 on success
  41. {
  42. interfaces = NULL;
  43. }
  44. }
  45. ~GetIfAddrs()
  46. {
  47. if (interfaces)
  48. freeifaddrs(interfaces);
  49. }
  50. // RAII must not copy
  51. GetIfAddrs(GetIfAddrs&) = delete;
  52. GetIfAddrs& operator=(GetIfAddrs&) = delete;
  53. template <typename Function>
  54. void withIfAddrs(Function f)
  55. {
  56. if (interfaces)
  57. f(*interfaces);
  58. }
  59. private:
  60. struct ifaddrs* interfaces = NULL;
  61. };
  62. } // namespace detail
  63. // Posix implementation of ip interface address scanner
  64. struct ScanIpIfAddrs
  65. {
  66. // Scan active network interfaces and return corresponding addresses
  67. // for all ip-based interfaces.
  68. std::vector<::asio::ip::address> operator()()
  69. {
  70. std::vector<::asio::ip::address> addrs;
  71. detail::GetIfAddrs getIfAddrs;
  72. getIfAddrs.withIfAddrs([&addrs](const struct ifaddrs& interfaces) {
  73. const struct ifaddrs* interface;
  74. for (interface = &interfaces; interface; interface = interface->ifa_next)
  75. {
  76. auto addr = reinterpret_cast<const struct sockaddr_in*>(interface->ifa_addr);
  77. if (addr && interface->ifa_flags & IFF_UP)
  78. {
  79. if (addr->sin_family == AF_INET)
  80. {
  81. auto bytes = reinterpret_cast<const char*>(&addr->sin_addr);
  82. addrs.emplace_back(asio::makeAddress<::asio::ip::address_v4>(bytes));
  83. }
  84. else if (addr->sin_family == AF_INET6)
  85. {
  86. auto addr6 = reinterpret_cast<const struct sockaddr_in6*>(addr);
  87. auto bytes = reinterpret_cast<const char*>(&addr6->sin6_addr);
  88. addrs.emplace_back(asio::makeAddress<::asio::ip::address_v6>(bytes));
  89. }
  90. }
  91. }
  92. });
  93. return addrs;
  94. }
  95. };
  96. } // namespace posix
  97. } // namespace platforms
  98. } // namespace ableton