26#ifndef MYSQL_HARNESS_NET_TS_IMPL_NETIF_H_
27#define MYSQL_HARNESS_NET_TS_IMPL_NETIF_H_
31#include <forward_list>
36#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
49#include <netinet/in.h>
55#pragma comment(lib, "iphlpapi.lib")
74 using value_type =
decltype(IP_ADAPTER_ADDRESSES::Flags);
90template <
class NetworkT>
115 template <
class... Args>
117 return nets_.emplace_back(std::forward<Args>(args)...);
137 std::string
id()
const {
return id_; }
206 template <
class BytesClass>
207 static constexpr int get_prefix_len(
const BytesClass &
mask) {
212 for (
size_t ndx{}; ndx <
mask.size(); ++ndx) {
213 uint8_t mask_byte =
mask[ndx];
215 for (uint8_t b = mask_byte; b & 0x80; b <<= 1, ++prefix_len)
219 if (mask_byte != 0xff)
break;
227 struct scoped_ifaddrs {
228 constexpr scoped_ifaddrs(ifaddrs *captured_ifaddrs)
229 : ifaddrs_{captured_ifaddrs} {}
231 if (ifaddrs_) ::freeifaddrs(ifaddrs_);
236 auto tail =
results_.before_begin();
250 for (
auto cur = ifs; cur !=
nullptr; cur = cur->ifa_next) {
253 [&cur](
const auto &v) {
254 return v.id() == cur->ifa_name;
257 tail =
results_.emplace_after(tail, cur->ifa_name, cur->ifa_name,
264 [&cur](
const auto &v) { return v.id() == cur->ifa_name; });
268 switch (cur->ifa_addr->sa_family) {
270 auto *sa =
reinterpret_cast<const sockaddr_in *
>(cur->ifa_addr);
273 if (bytes.size() <
sizeof(sa->sin_addr.s_addr)) std::terminate();
274 std::memcpy(bytes.data(), &(sa->sin_addr),
sizeof(sa->sin_addr));
278 sa =
reinterpret_cast<const sockaddr_in *
>(cur->ifa_netmask);
279 if (bytes.size() <
sizeof(sa->sin_addr.s_addr)) std::terminate();
280 std::memcpy(bytes.data(), &(sa->sin_addr.s_addr),
281 sizeof(sa->sin_addr.s_addr));
284 auto prefix_len = get_prefix_len(netmask.to_bytes());
285 cur_res_it->v4_networks().emplace_back(addr, prefix_len);
289 0x80, 0x00, 0x00, 0x00)) == 1,
292 0xff, 0x00, 0x00, 0x00)) == 8,
295 0xff, 0x80, 0x00, 0x00)) == 9,
300 0x00, 0x80, 0x00, 0x00)) == 0,
306 auto *sa =
reinterpret_cast<const sockaddr_in6 *
>(cur->ifa_addr);
309 if (bytes.size() <
sizeof(sa->sin6_addr.s6_addr)) std::terminate();
311 std::memcpy(bytes.data(), &(sa->sin6_addr.s6_addr),
312 sizeof(sa->sin6_addr.s6_addr));
315 sa =
reinterpret_cast<const sockaddr_in6 *
>(cur->ifa_netmask);
316 if (bytes.size() <
sizeof(sa->sin6_addr.s6_addr)) std::terminate();
317 std::memcpy(bytes.data(), &(sa->sin6_addr.s6_addr),
318 sizeof(sa->sin6_addr.s6_addr));
321 auto prefix_len = get_prefix_len(netmask.to_bytes());
322 cur_res_it->v6_networks().emplace_back(addr, prefix_len);
336 const std::wstring_view &ws) {
340 auto out_len = WideCharToMultiByte(CP_UTF8, 0, ws.data(), ws.size(),
341 nullptr, 0,
nullptr,
nullptr);
345 std::error_code(GetLastError(), std::system_category()));
351 WideCharToMultiByte(CP_UTF8, 0, ws.data(), ws.size(), &out.front(),
352 out.capacity(),
nullptr,
nullptr);
355 std::error_code(GetLastError(), std::system_category()));
365 auto tail =
results_.before_begin();
367 for (
auto cur = ifs.get(); cur; cur = cur->Next) {
368 tail =
results_.emplace_after(tail, std::string{cur->AdapterName},
369 convert_wstring_to_utf8(cur->Description)
370 .value_or(
"<invalid-wstring>"),
376 [&cur](
const auto &v) { return v.id() == cur->AdapterName; });
378 for (
auto cur_unicast_addr = cur->FirstUnicastAddress; cur_unicast_addr;
379 cur_unicast_addr = cur_unicast_addr->Next) {
380 if (cur_unicast_addr->Address.lpSockaddr->sa_family == AF_INET) {
381 auto *sa =
reinterpret_cast<const sockaddr_in *
>(
382 cur_unicast_addr->Address.lpSockaddr);
384 std::memcpy(bytes.data(), &(sa->sin_addr.s_addr),
385 sizeof(sa->sin_addr.s_addr));
388 cur_res_it->v4_networks().emplace_back(
389 addr, cur_unicast_addr->OnLinkPrefixLength);
391 auto *sa =
reinterpret_cast<const sockaddr_in6 *
>(
392 cur_unicast_addr->Address.lpSockaddr);
394 std::memcpy(bytes.data(), &(sa->sin6_addr.s6_addr),
395 sizeof(sa->sin6_addr.s6_addr));
397 cur_res_it->v6_networks().emplace_back(
398 addr, cur_unicast_addr->OnLinkPrefixLength);
413 unsigned long ifs_size{0};
415 ::GetAdaptersAddresses(AF_UNSPEC, 0,
nullptr,
nullptr, &ifs_size);
417 if (res != ERROR_BUFFER_OVERFLOW) {
419 std::error_code{
static_cast<int>(res), std::system_category()});
423 reinterpret_cast<IP_ADAPTER_ADDRESSES *
>(
malloc(ifs_size)), &
free);
425 res = ::GetAdaptersAddresses(AF_UNSPEC, 0,
nullptr, ifs.get(), &ifs_size);
426 if (ERROR_SUCCESS != res) {
428 std::error_code{
static_cast<int>(res), std::system_category()});
433 ifaddrs *ifs =
nullptr;
435 if (-1 == ::getifaddrs(&ifs)) {
flags of the network interface.
Definition: netif.h:67
constexpr value_type value() const
Definition: netif.h:81
constexpr InterfaceFlag(value_type v) noexcept
Definition: netif.h:79
const value_type v_
Definition: netif.h:84
decltype(ifaddrs::ifa_flags) value_type
Definition: netif.h:76
an entry in the network interface result.
Definition: netif.h:127
NetworkInterfaceNetworks< net::ip::network_v6 > & v6_networks()
Definition: netif.h:149
const NetworkInterfaceNetworks< net::ip::network_v4 > & v4_networks() const
Definition: netif.h:145
NetworkInterfaceNetworks< net::ip::network_v6 > net_v6_s_
Definition: netif.h:162
std::string id_
Definition: netif.h:158
flags_type flags() const
Definition: netif.h:139
const NetworkInterfaceNetworks< net::ip::network_v6 > & v6_networks() const
Definition: netif.h:153
std::string display_name_
Definition: netif.h:159
NetworkInterfaceEntry(std::string id, std::string display_name, flags_type::value_type flags)
Definition: netif.h:131
NetworkInterfaceNetworks< net::ip::network_v4 > net_v4_s_
Definition: netif.h:161
flags_type flags_
Definition: netif.h:160
std::string display_name() const
Definition: netif.h:138
NetworkInterfaceNetworks< net::ip::network_v4 > & v4_networks()
Definition: netif.h:141
std::string id() const
Definition: netif.h:137
networks of a network interface.
Definition: netif.h:91
std::list< value_type > container_type
Definition: netif.h:94
const_iterator end() const
Definition: netif.h:106
typename container_type::const_iterator const_iterator
Definition: netif.h:97
ptrdiff_t difference_type
Definition: netif.h:99
void push_back(const value_type &v)
Definition: netif.h:108
container_type nets_
Definition: netif.h:121
const value_type & const_reference
Definition: netif.h:95
value_type & reference
Definition: netif.h:96
const_iterator iterator
Definition: netif.h:98
NetworkT value_type
Definition: netif.h:93
size_t size_type
Definition: netif.h:100
bool empty() const noexcept
Definition: netif.h:103
const_iterator begin() const
Definition: netif.h:105
size_type max_size() const noexcept
Definition: netif.h:102
auto emplace_back(Args &&...args)
emplace an object in the container.
Definition: netif.h:116
stdx::expected< NetworkInterfaceResults, std::error_code > query()
Definition: netif.h:411
results of a NetworkInterfaceResolver::query().
Definition: netif.h:168
typename std::forward_list< value_type >::const_iterator const_iterator
Definition: netif.h:173
const_iterator cend() const
Definition: netif.h:187
const_iterator cbegin() const
Definition: netif.h:186
size_type size() const noexcept
Definition: netif.h:180
bool empty() const noexcept
Definition: netif.h:182
const_iterator begin() const
Definition: netif.h:184
const_iterator iterator
Definition: netif.h:174
ptrdiff_t difference_type
Definition: netif.h:175
size_type max_size() const noexcept
Definition: netif.h:181
const_iterator end() const
Definition: netif.h:185
size_t size_type
Definition: netif.h:176
std::forward_list< value_type > results_
Definition: netif.h:405
NetworkInterfaceResults()=default
size_t size_
Definition: netif.h:406
Definition: internet.h:93
IPv6 address with scope_id.
Definition: internet.h:182
Definition: expected.h:286
#define malloc(A)
Definition: lexyy.cc:914
#define free(A)
Definition: lexyy.cc:915
static mi_bit_type mask[]
Definition: mi_packrec.cc:141
Container::const_iterator find_if(const Container &c, Find_if &&find_if)
Definition: generic.h:54
std::error_code last_error_code()
get last std::error_code for socket-errors.
Definition: socket_error.h:107
Definition: gcs_xcom_synode.h:64
unexpected(E) -> unexpected< E >
std::conditional_t< !std::is_array< T >::value, std::unique_ptr< T, detail::Deleter< T > >, std::conditional_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, detail::Array_deleter< std::remove_extent_t< T > > >, void > > unique_ptr
The following is a common type that is returned by all the ut::make_unique (non-aligned) specializati...
Definition: ut0new.h:2440
Definition: internet.h:96
Definition: internet.h:184