From e55789a3f665de4416dc4809e4a8934266110ffd Mon Sep 17 00:00:00 2001 From: fgo Date: Tue, 19 Sep 2023 15:15:31 +0200 Subject: [PATCH] Return IPv6 addresses when scanning --- .../ableton/platforms/posix/ScanIpIfAddrs.hpp | 41 +++++++++++++------ .../platforms/windows/ScanIpIfAddrs.hpp | 38 ++++++++++++++--- 2 files changed, 61 insertions(+), 18 deletions(-) diff --git a/include/ableton/platforms/posix/ScanIpIfAddrs.hpp b/include/ableton/platforms/posix/ScanIpIfAddrs.hpp index 4e59045e..ba07dc5f 100644 --- a/include/ableton/platforms/posix/ScanIpIfAddrs.hpp +++ b/include/ableton/platforms/posix/ScanIpIfAddrs.hpp @@ -22,7 +22,9 @@ #include #include #include +#include #include +#include #include namespace ableton @@ -77,31 +79,46 @@ struct ScanIpIfAddrs std::vector operator()() { std::vector addrs; + std::map IpInterfaceNames; detail::GetIfAddrs getIfAddrs; - getIfAddrs.withIfAddrs([&addrs](const struct ifaddrs& interfaces) { + getIfAddrs.withIfAddrs([&addrs, &IpInterfaceNames](const struct ifaddrs& interfaces) { const struct ifaddrs* interface; for (interface = &interfaces; interface; interface = interface->ifa_next) { auto addr = reinterpret_cast(interface->ifa_addr); - if (addr && interface->ifa_flags & IFF_UP) + if (addr && interface->ifa_flags & IFF_RUNNING && addr->sin_family == AF_INET) { - if (addr->sin_family == AF_INET) - { - auto bytes = reinterpret_cast(&addr->sin_addr); - addrs.emplace_back(discovery::makeAddress(bytes)); - } - else if (addr->sin_family == AF_INET6) + auto bytes = reinterpret_cast(&addr->sin_addr); + auto address = discovery::makeAddress(bytes); + addrs.emplace_back(std::move(address)); + IpInterfaceNames.insert(std::make_pair(interface->ifa_name, address)); + } + } + }); + + getIfAddrs.withIfAddrs([&addrs, &IpInterfaceNames](const struct ifaddrs& interfaces) { + const struct ifaddrs* interface; + for (interface = &interfaces; interface; interface = interface->ifa_next) + { + auto addr = reinterpret_cast(interface->ifa_addr); + if (addr && interface->ifa_flags & IFF_RUNNING && addr->sin_family == AF_INET6) + { + auto addr6 = reinterpret_cast(addr); + auto bytes = reinterpret_cast(&addr6->sin6_addr); + auto scopeId = addr6->sin6_scope_id; + auto address = discovery::makeAddress(bytes, scopeId); + if (IpInterfaceNames.find(interface->ifa_name) != IpInterfaceNames.end() + && !address.is_loopback() && address.is_link_local()) { - auto addr6 = reinterpret_cast(addr); - auto bytes = reinterpret_cast(&addr6->sin6_addr); - addrs.emplace_back(discovery::makeAddress(bytes)); + addrs.emplace_back(std::move(address)); } } } }); + return addrs; - } + }; }; } // namespace posix diff --git a/include/ableton/platforms/windows/ScanIpIfAddrs.hpp b/include/ableton/platforms/windows/ScanIpIfAddrs.hpp index 0d79f7e5..229486e9 100644 --- a/include/ableton/platforms/windows/ScanIpIfAddrs.hpp +++ b/include/ableton/platforms/windows/ScanIpIfAddrs.hpp @@ -21,7 +21,9 @@ #include #include +#include #include +#include #include #include #include @@ -101,9 +103,10 @@ struct ScanIpIfAddrs std::vector operator()() { std::vector addrs; + std::map IpInterfaceNames; detail::GetIfAddrs getIfAddrs; - getIfAddrs.withIfAddrs([&addrs](const IP_ADAPTER_ADDRESSES& interfaces) { + getIfAddrs.withIfAddrs([&](const IP_ADAPTER_ADDRESSES& interfaces) { const IP_ADAPTER_ADDRESSES* networkInterface; for (networkInterface = &interfaces; networkInterface; networkInterface = networkInterface->Next) @@ -118,18 +121,41 @@ struct ScanIpIfAddrs SOCKADDR_IN* addr4 = reinterpret_cast(address->Address.lpSockaddr); auto bytes = reinterpret_cast(&addr4->sin_addr); - addrs.emplace_back(discovery::makeAddress(bytes)); + auto ipv4address = discovery::makeAddress(bytes); + addrs.emplace_back(ipv4address); + IpInterfaceNames.insert( + std::make_pair(networkInterface->AdapterName, ipv4address)); } - else if (AF_INET6 == family) + } + } + }); + + getIfAddrs.withIfAddrs([&](const IP_ADAPTER_ADDRESSES& interfaces) { + const IP_ADAPTER_ADDRESSES* networkInterface; + for (networkInterface = &interfaces; networkInterface; + networkInterface = networkInterface->Next) + { + for (IP_ADAPTER_UNICAST_ADDRESS* address = networkInterface->FirstUnicastAddress; + NULL != address; address = address->Next) + { + auto family = address->Address.lpSockaddr->sa_family; + if (AF_INET6 == family + && IpInterfaceNames.find(networkInterface->AdapterName) + != IpInterfaceNames.end()) { - SOCKADDR_IN6* addr6 = + SOCKADDR_IN6* sockAddr = reinterpret_cast(address->Address.lpSockaddr); - auto bytes = reinterpret_cast(&addr6->sin6_addr); - addrs.emplace_back(discovery::makeAddress(bytes)); + auto bytes = reinterpret_cast(&sockAddr->sin6_addr); + auto addr6 = discovery::makeAddress(bytes); + if (!addr6.is_loopback() && addr6.is_link_local()) + { + addrs.emplace_back(addr6); + } } } } }); + return addrs; } };