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:2444
Definition: internet.h:96
Definition: internet.h:184