|
22 | 22 | #include <ableton/discovery/AsioTypes.hpp> |
23 | 23 | #include <arpa/inet.h> |
24 | 24 | #include <ifaddrs.h> |
| 25 | +#include <map> |
25 | 26 | #include <net/if.h> |
| 27 | +#include <string> |
26 | 28 | #include <vector> |
27 | 29 |
|
28 | 30 | namespace ableton |
@@ -77,31 +79,46 @@ struct ScanIpIfAddrs |
77 | 79 | std::vector<discovery::IpAddress> operator()() |
78 | 80 | { |
79 | 81 | std::vector<discovery::IpAddress> addrs; |
| 82 | + std::map<std::string, discovery::IpAddress> IpInterfaceNames; |
80 | 83 |
|
81 | 84 | detail::GetIfAddrs getIfAddrs; |
82 | | - getIfAddrs.withIfAddrs([&addrs](const struct ifaddrs& interfaces) { |
| 85 | + getIfAddrs.withIfAddrs([&addrs, &IpInterfaceNames](const struct ifaddrs& interfaces) { |
83 | 86 | const struct ifaddrs* interface; |
84 | 87 | for (interface = &interfaces; interface; interface = interface->ifa_next) |
85 | 88 | { |
86 | 89 | auto addr = reinterpret_cast<const struct sockaddr_in*>(interface->ifa_addr); |
87 | | - if (addr && interface->ifa_flags & IFF_UP) |
| 90 | + if (addr && interface->ifa_flags & IFF_RUNNING && addr->sin_family == AF_INET) |
88 | 91 | { |
89 | | - if (addr->sin_family == AF_INET) |
90 | | - { |
91 | | - auto bytes = reinterpret_cast<const char*>(&addr->sin_addr); |
92 | | - addrs.emplace_back(discovery::makeAddress<discovery::IpAddressV4>(bytes)); |
93 | | - } |
94 | | - else if (addr->sin_family == AF_INET6) |
| 92 | + auto bytes = reinterpret_cast<const char*>(&addr->sin_addr); |
| 93 | + auto address = discovery::makeAddress<discovery::IpAddressV4>(bytes); |
| 94 | + addrs.emplace_back(std::move(address)); |
| 95 | + IpInterfaceNames.insert(std::make_pair(interface->ifa_name, address)); |
| 96 | + } |
| 97 | + } |
| 98 | + }); |
| 99 | + |
| 100 | + getIfAddrs.withIfAddrs([&addrs, &IpInterfaceNames](const struct ifaddrs& interfaces) { |
| 101 | + const struct ifaddrs* interface; |
| 102 | + for (interface = &interfaces; interface; interface = interface->ifa_next) |
| 103 | + { |
| 104 | + auto addr = reinterpret_cast<const struct sockaddr_in*>(interface->ifa_addr); |
| 105 | + if (addr && interface->ifa_flags & IFF_RUNNING && addr->sin_family == AF_INET6) |
| 106 | + { |
| 107 | + auto addr6 = reinterpret_cast<const struct sockaddr_in6*>(addr); |
| 108 | + auto bytes = reinterpret_cast<const char*>(&addr6->sin6_addr); |
| 109 | + auto scopeId = addr6->sin6_scope_id; |
| 110 | + auto address = discovery::makeAddress<discovery::IpAddressV6>(bytes, scopeId); |
| 111 | + if (IpInterfaceNames.find(interface->ifa_name) != IpInterfaceNames.end() |
| 112 | + && !address.is_loopback() && address.is_link_local()) |
95 | 113 | { |
96 | | - auto addr6 = reinterpret_cast<const struct sockaddr_in6*>(addr); |
97 | | - auto bytes = reinterpret_cast<const char*>(&addr6->sin6_addr); |
98 | | - addrs.emplace_back(discovery::makeAddress<discovery::IpAddressV6>(bytes)); |
| 114 | + addrs.emplace_back(std::move(address)); |
99 | 115 | } |
100 | 116 | } |
101 | 117 | } |
102 | 118 | }); |
| 119 | + |
103 | 120 | return addrs; |
104 | | - } |
| 121 | + }; |
105 | 122 | }; |
106 | 123 |
|
107 | 124 | } // namespace posix |
|
0 commit comments