0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-10-01 05:08:59 +02:00

ircd::net: Add conditional interface to getifaddrs() w/ console cmd.

This commit is contained in:
Jason Volk 2019-03-25 13:29:46 -07:00
parent 4d3fd753e1
commit 8c27cb847a
4 changed files with 113 additions and 0 deletions

26
include/ircd/net/addrs.h Normal file
View file

@ -0,0 +1,26 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2019 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#pragma once
#define HAVE_IRCD_NET_ADDRS_H
extern "C"
{
struct ifaddrs;
}
namespace ircd::net::addrs
{
using closure = std::function<bool (const string_view &, const ipport &, const uint &)>;
using raw_closure = std::function<bool (const struct ::ifaddrs &)>;
bool for_each(const raw_closure &);
bool for_each(const closure &);
}

View file

@ -40,6 +40,7 @@ namespace ircd::net
#include "listener.h"
#include "listener_udp.h"
#include "sock_opts.h"
#include "addrs.h"
#include "open.h"
#include "close.h"
#include "wait.h"

View file

@ -9,6 +9,7 @@
// full license for this software is available in the LICENSE file.
#include <ircd/asio.h>
#include <RB_INC_IFADDRS_H
namespace ircd::net
{
@ -684,6 +685,74 @@ ircd::net::open(socket &socket,
connector({}, opts.hostport, opts.ipport);
}
///////////////////////////////////////////////////////////////////////////////
//
// net/addrs.h
//
bool
ircd::net::addrs::for_each(const closure &closure)
{
return for_each([&closure]
(const struct ::ifaddrs &ifa)
{
const string_view &name(ifa.ifa_name);
const uint &flags(ifa.ifa_flags);
ipport ipport;
if(ifa.ifa_addr) switch(ifa.ifa_addr->sa_family)
{
case AF_INET6:
{
const auto &sin(reinterpret_cast<const struct sockaddr_in6 *>(ifa.ifa_addr));
ipport =
{
ntoh(*reinterpret_cast<const uint128_t *>(sin->sin6_addr.s6_addr)),
sin->sin6_port
};
break;
}
case AF_INET:
{
const auto &sin(reinterpret_cast<const struct sockaddr_in *>(ifa.ifa_addr));
ipport = { ntoh(sin->sin_addr.s_addr), sin->sin_port };
break;
}
default:
return true;
}
return closure(name, ipport, flags);
});
}
#ifdef HAVE_IFADDRS_H
bool
ircd::net::addrs::for_each(const raw_closure &closure)
{
struct ::ifaddrs *ifap_;
syscall(::getifaddrs, &ifap_);
const custom_ptr<struct ::ifaddrs> ifap
{
ifap_, ::freeifaddrs
};
for(auto ifa(ifap.get()); ifa; ifa = ifa->ifa_next)
if(!closure(*ifa))
return false;
return true;
}
#else
bool
ircd::net::addrs::for_each(const raw_closure &closure)
{
return true;
}
#endif
///////////////////////////////////////////////////////////////////////////////
//
// net/sopts.h

View file

@ -4179,6 +4179,23 @@ catch(const std::out_of_range &e)
// net
//
bool
console_cmd__net__addrs(opt &out, const string_view &line)
{
net::addrs::for_each([&out]
(const string_view &name, const ipport &addr, const uint &flags)
{
out << std::left << std::setw(16) << name << " "
<< std::setw(32) << addr << " "
<< "(0x" << std::hex << flags << ")" << std::dec
<< std::endl;
return true;
});
return true;
}
bool
console_cmd__net__host(opt &out, const string_view &line)
{