26#ifndef MYSQL_HARNESS_NET_TS_IMPL_NETIF_H_
27#define MYSQL_HARNESS_NET_TS_IMPL_NETIF_H_
30#include <forward_list>
35#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
48#include <netinet/in.h>
54#pragma comment(lib, "iphlpapi.lib")
73 using value_type =
decltype(IP_ADAPTER_ADDRESSES::Flags);
89template <
class NetworkT>
114 template <
class... Args>
116 return nets_.emplace_back(std::forward<Args>(args)...);
136 std::string
id()
const {
return id_; }
205 template <
class BytesClass>
206 static constexpr int get_prefix_len(
const BytesClass &
mask) {
211 for (
size_t ndx{}; ndx <
mask.size(); ++ndx) {
212 uint8_t mask_byte =
mask[ndx];
214 for (uint8_t b = mask_byte; b & 0x80; b <<= 1, ++prefix_len)
218 if (mask_byte != 0xff)
break;
226 struct scoped_ifaddrs {
227 constexpr scoped_ifaddrs(ifaddrs *captured_ifaddrs)
228 : ifaddrs_{captured_ifaddrs} {}
230 if (ifaddrs_) ::freeifaddrs(ifaddrs_);
235 auto tail =
results_.before_begin();
249 for (
auto cur = ifs; cur !=
nullptr; cur = cur->ifa_next) {
252 [&cur](
const auto &v) {
253 return v.id() == cur->ifa_name;
256 tail =
results_.emplace_after(tail, cur->ifa_name, cur->ifa_name,
263 [&cur](
const auto &v) { return v.id() == cur->ifa_name; });
267 switch (cur->ifa_addr->sa_family) {
269 auto *sa =
reinterpret_cast<const sockaddr_in *
>(cur->ifa_addr);
272 if (bytes.size() <
sizeof(sa->sin_addr.s_addr)) std::terminate();
273 std::memcpy(bytes.data(), &(sa->sin_addr),
sizeof(sa->sin_addr));
277 sa =
reinterpret_cast<const sockaddr_in *
>(cur->ifa_netmask);
278 if (bytes.size() <
sizeof(sa->sin_addr.s_addr)) std::terminate();
279 std::memcpy(bytes.data(), &(sa->sin_addr.s_addr),
280 sizeof(sa->sin_addr.s_addr));
283 auto prefix_len = get_prefix_len(netmask.to_bytes());
284 cur_res_it->v4_networks().emplace_back(addr, prefix_len);
288 0x80, 0x00, 0x00, 0x00)) == 1,
291 0xff, 0x00, 0x00, 0x00)) == 8,
294 0xff, 0x80, 0x00, 0x00)) == 9,
299 0x00, 0x80, 0x00, 0x00)) == 0,
305 auto *sa =
reinterpret_cast<const sockaddr_in6 *
>(cur->ifa_addr);
308 if (bytes.size() <
sizeof(sa->sin6_addr.s6_addr)) std::terminate();
310 std::memcpy(bytes.data(), &(sa->sin6_addr.s6_addr),
311 sizeof(sa->sin6_addr.s6_addr));
314 sa =
reinterpret_cast<const sockaddr_in6 *
>(cur->ifa_netmask);
315 if (bytes.size() <
sizeof(sa->sin6_addr.s6_addr)) std::terminate();
316 std::memcpy(bytes.data(), &(sa->sin6_addr.s6_addr),
317 sizeof(sa->sin6_addr.s6_addr));
320 auto prefix_len = get_prefix_len(netmask.to_bytes());
321 cur_res_it->v6_networks().emplace_back(addr, prefix_len);
335 const std::wstring_view &ws) {
339 auto out_len = WideCharToMultiByte(CP_UTF8, 0, ws.data(), ws.size(),
340 nullptr, 0,
nullptr,
nullptr);
344 std::error_code(GetLastError(), std::system_category()));
350 WideCharToMultiByte(CP_UTF8, 0, ws.data(), ws.size(), &out.front(),
351 out.capacity(),
nullptr,
nullptr);
354 std::error_code(GetLastError(), std::system_category()));
364 auto tail =
results_.before_begin();
366 for (
auto cur = ifs.get(); cur; cur = cur->Next) {
367 tail =
results_.emplace_after(tail, std::string{cur->AdapterName},
368 convert_wstring_to_utf8(cur->Description)
369 .value_or(
"<invalid-wstring>"),
375 [&cur](
const auto &v) { return v.id() == cur->AdapterName; });
377 for (
auto cur_unicast_addr = cur->FirstUnicastAddress; cur_unicast_addr;
378 cur_unicast_addr = cur_unicast_addr->Next) {
379 if (cur_unicast_addr->Address.lpSockaddr->sa_family == AF_INET) {
380 auto *sa =
reinterpret_cast<const sockaddr_in *
>(
381 cur_unicast_addr->Address.lpSockaddr);
383 std::memcpy(bytes.data(), &(sa->sin_addr.s_addr),
384 sizeof(sa->sin_addr.s_addr));
387 cur_res_it->v4_networks().emplace_back(
388 addr, cur_unicast_addr->OnLinkPrefixLength);
390 auto *sa =
reinterpret_cast<const sockaddr_in6 *
>(
391 cur_unicast_addr->Address.lpSockaddr);
393 std::memcpy(bytes.data(), &(sa->sin6_addr.s6_addr),
394 sizeof(sa->sin6_addr.s6_addr));
396 cur_res_it->v6_networks().emplace_back(
397 addr, cur_unicast_addr->OnLinkPrefixLength);
412 unsigned long ifs_size{0};
414 ::GetAdaptersAddresses(AF_UNSPEC, 0,
nullptr,
nullptr, &ifs_size);
416 if (res != ERROR_BUFFER_OVERFLOW) {
418 std::error_code{
static_cast<int>(res), std::system_category()});
422 reinterpret_cast<IP_ADAPTER_ADDRESSES *
>(
malloc(ifs_size)), &
free);
424 res = ::GetAdaptersAddresses(AF_UNSPEC, 0,
nullptr, ifs.get(), &ifs_size);
425 if (ERROR_SUCCESS != res) {
427 std::error_code{
static_cast<int>(res), std::system_category()});
432 ifaddrs *ifs =
nullptr;
434 if (-1 == ::getifaddrs(&ifs)) {
flags of the network interface.
Definition: netif.h:66
constexpr value_type value() const
Definition: netif.h:80
constexpr InterfaceFlag(value_type v) noexcept
Definition: netif.h:78
const value_type v_
Definition: netif.h:83
decltype(ifaddrs::ifa_flags) value_type
Definition: netif.h:75
an entry in the network interface result.
Definition: netif.h:126
NetworkInterfaceNetworks< net::ip::network_v6 > & v6_networks()
Definition: netif.h:148
const NetworkInterfaceNetworks< net::ip::network_v4 > & v4_networks() const
Definition: netif.h:144
NetworkInterfaceNetworks< net::ip::network_v6 > net_v6_s_
Definition: netif.h:161
std::string id_
Definition: netif.h:157
flags_type flags() const
Definition: netif.h:138
const NetworkInterfaceNetworks< net::ip::network_v6 > & v6_networks() const
Definition: netif.h:152
std::string display_name_
Definition: netif.h:158
NetworkInterfaceEntry(std::string id, std::string display_name, flags_type::value_type flags)
Definition: netif.h:130
NetworkInterfaceNetworks< net::ip::network_v4 > net_v4_s_
Definition: netif.h:160
flags_type flags_
Definition: netif.h:159
std::string display_name() const
Definition: netif.h:137
NetworkInterfaceNetworks< net::ip::network_v4 > & v4_networks()
Definition: netif.h:140
std::string id() const
Definition: netif.h:136
networks of a network interface.
Definition: netif.h:90
auto emplace_back(Args &&... args)
emplace an object in the container.
Definition: netif.h:115
std::list< value_type > container_type
Definition: netif.h:93
const_iterator end() const
Definition: netif.h:105
typename container_type::const_iterator const_iterator
Definition: netif.h:96
ptrdiff_t difference_type
Definition: netif.h:98
void push_back(const value_type &v)
Definition: netif.h:107
container_type nets_
Definition: netif.h:120
const value_type & const_reference
Definition: netif.h:94
value_type & reference
Definition: netif.h:95
const_iterator iterator
Definition: netif.h:97
NetworkT value_type
Definition: netif.h:92
size_t size_type
Definition: netif.h:99
bool empty() const noexcept
Definition: netif.h:102
const_iterator begin() const
Definition: netif.h:104
size_type max_size() const noexcept
Definition: netif.h:101
stdx::expected< NetworkInterfaceResults, std::error_code > query()
Definition: netif.h:410
results of a NetworkInterfaceResolver::query().
Definition: netif.h:167
typename std::forward_list< value_type >::const_iterator const_iterator
Definition: netif.h:172
const_iterator cend() const
Definition: netif.h:186
const_iterator cbegin() const
Definition: netif.h:185
size_type size() const noexcept
Definition: netif.h:179
bool empty() const noexcept
Definition: netif.h:181
const_iterator begin() const
Definition: netif.h:183
const_iterator iterator
Definition: netif.h:173
ptrdiff_t difference_type
Definition: netif.h:174
size_type max_size() const noexcept
Definition: netif.h:180
const_iterator end() const
Definition: netif.h:184
size_t size_type
Definition: netif.h:175
std::forward_list< value_type > results_
Definition: netif.h:404
NetworkInterfaceResults()=default
size_t size_
Definition: netif.h:405
Definition: internet.h:93
IPv6 address with scope_id.
Definition: internet.h:182
Definition: expected.h:284
#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:2438
Definition: internet.h:96
Definition: internet.h:184