Added a global list of all the IP addresses that the interfaces of the local machine which will be used to cover some missing solicitation requests

This commit is contained in:
John Sharratt 2017-07-03 17:15:54 +02:00
parent 89130bf099
commit a690d128e7
8 changed files with 134 additions and 9 deletions

View File

@ -4,6 +4,12 @@
route-ttl 30000 route-ttl 30000
# address-ttl <integer> (NEW)
# This tells 'ndppd' how often to reload the IP address file /proc/net/if_inet6
# Default value is '30000' (30 seconds).
address-ttl 30000
# proxy <interface> # proxy <interface>
# This sets up a listener, that will listen for any Neighbor Solicitation # This sets up a listener, that will listen for any Neighbor Solicitation
# messages, and respond to them according to a set of rules (see below). # messages, and respond to them according to a set of rules (see below).

View File

@ -15,6 +15,8 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <string> #include <string>
#include <vector> #include <vector>
#include <fstream>
#include <list>
#include <map> #include <map>
#include <cstring> #include <cstring>
@ -27,9 +29,16 @@
#include "ndppd.h" #include "ndppd.h"
#include "address.h" #include "address.h"
#include "route.h"
NDPPD_NS_BEGIN NDPPD_NS_BEGIN
std::list<ptr<route> > address::_addresses;
int address::_ttl;
int address::_c_ttl;
address::address() address::address()
{ {
reset(); reset();
@ -302,4 +311,73 @@ bool address::is_unicast() const
return _addr.s6_addr[0] != 0xff; return _addr.s6_addr[0] != 0xff;
} }
void address::add(const address& addr, const std::string& ifname)
{
ptr<route> rt(new route(addr, ifname));
// logger::debug() << "address::create() addr=" << addr << ", ifname=" << ifname;
_addresses.push_back(rt);
}
std::list<ptr<route> > address::addresses()
{
return _addresses;
}
void address::load(const std::string& path)
{
// Hack to make sure the addresses are not freed prematurely.
std::list<ptr<route> > tmp_addresses(_addresses);
_addresses.clear();
logger::debug() << "reading IP addresses";
try {
std::ifstream ifs;
ifs.exceptions(std::ifstream::badbit | std::ifstream::failbit);
ifs.open(path.c_str(), std::ios::in);
ifs.exceptions(std::ifstream::badbit);
while (!ifs.eof()) {
char buf[1024];
ifs.getline(buf, sizeof(buf));
if (ifs.gcount() < 53) {
continue;
}
address addr;
if (route::hexdec(buf, (unsigned char* )&addr.addr(), 32) != 32) {
// TODO: Warn here?
continue;
}
addr.prefix(128);
address::add(addr, route::token(buf + 45));
}
} catch (std::ifstream::failure e) {
logger::warning() << "Failed to parse IPv6 address data from '" << path << "'";
logger::error() << e.what();
}
}
void address::update(int elapsed_time)
{
if ((_c_ttl -= elapsed_time) <= 0) {
load("/proc/net/if_inet6");
_c_ttl = _ttl;
}
}
int address::ttl()
{
return _ttl;
}
void address::ttl(int ttl)
{
_ttl = ttl;
}
NDPPD_NS_END NDPPD_NS_END

View File

@ -16,6 +16,7 @@
#pragma once #pragma once
#include <string> #include <string>
#include <list>
#include <netinet/ip6.h> #include <netinet/ip6.h>
#include "ndppd.h" #include "ndppd.h"
@ -24,6 +25,8 @@ NDPPD_NS_BEGIN
class iface; class iface;
class route;
class address { class address {
public: public:
address(); address();
@ -33,6 +36,12 @@ public:
address(const in6_addr& addr); address(const in6_addr& addr);
address(const in6_addr& addr, const in6_addr& mask); address(const in6_addr& addr, const in6_addr& mask);
address(const in6_addr& addr, int prefix); address(const in6_addr& addr, int prefix);
static void update(int elapsed_time);
static int ttl();
static void ttl(int ttl);
struct in6_addr& addr(); struct in6_addr& addr();
@ -60,8 +69,20 @@ public:
bool is_multicast() const; bool is_multicast() const;
operator std::string() const; operator std::string() const;
static std::list<ptr<route> > addresses();
static void add(const address& addr, const std::string& ifname);
static void load(const std::string& path);
private: private:
static int _ttl;
static int _c_ttl;
static std::list<ptr<route> > _addresses;
struct in6_addr _addr, _mask; struct in6_addr _addr, _mask;
}; };

View File

@ -141,6 +141,11 @@ static bool configure(ptr<conf>& cf)
route::ttl(30000); route::ttl(30000);
else else
route::ttl(*x_cf); route::ttl(*x_cf);
if (!(x_cf = cf->find("address-ttl")))
address::ttl(30000);
else
address::ttl(*x_cf);
std::vector<ptr<conf> >::const_iterator p_it; std::vector<ptr<conf> >::const_iterator p_it;
@ -334,6 +339,9 @@ int main(int argc, char* argv[], char* env[])
if (rule::any_auto()) if (rule::any_auto())
route::update(elapsed_time); route::update(elapsed_time);
if (rule::any_iface())
address::update(elapsed_time);
session::update_all(elapsed_time); session::update_all(elapsed_time);
} }

View File

@ -105,19 +105,19 @@ void route::load(const std::string& path)
unsigned char pfx; unsigned char pfx;
if (hexdec(buf, (unsigned char* )&addr.addr(), 16) != 16) { if (route::hexdec(buf, (unsigned char* )&addr.addr(), 16) != 16) {
// TODO: Warn here? // TODO: Warn here?
continue; continue;
} }
if (hexdec(buf + 33,& pfx, 1) != 1) { if (route::hexdec(buf + 33,& pfx, 1) != 1) {
// TODO: Warn here? // TODO: Warn here?
continue; continue;
} }
addr.prefix((int)pfx); addr.prefix((int)pfx);
route::create(addr, token(buf + 141)); route::create(addr, route::token(buf + 141));
} }
} catch (std::ifstream::failure e) { } catch (std::ifstream::failure e) {
logger::warning() << "Failed to parse IPv6 routing data from '" << path << "'"; logger::warning() << "Failed to parse IPv6 routing data from '" << path << "'";

View File

@ -44,6 +44,12 @@ public:
const address& addr() const; const address& addr() const;
ptr<iface> ifa(); ptr<iface> ifa();
route(const address& addr, const std::string& ifname);
static size_t hexdec(const char* str, unsigned char* buf, size_t size);
static std::string token(const char* str);
private: private:
static int _ttl; static int _ttl;
@ -56,14 +62,8 @@ private:
ptr<iface> _ifa; ptr<iface> _ifa;
static size_t hexdec(const char* str, unsigned char* buf, size_t size);
static std::string token(const char* str);
static std::list<ptr<route> > _routes; static std::list<ptr<route> > _routes;
route(const address& addr, const std::string& ifname);
}; };
NDPPD_NS_END NDPPD_NS_END

View File

@ -29,6 +29,8 @@ std::vector<interface> interfaces;
bool rule::_any_aut = false; bool rule::_any_aut = false;
bool rule::_any_iface = false;
rule::rule() rule::rule()
{ {
} }
@ -41,6 +43,7 @@ ptr<rule> rule::create(const ptr<proxy>& pr, const address& addr, const ptr<ifac
ru->_ifa = ifa; ru->_ifa = ifa;
ru->_addr = addr; ru->_addr = addr;
ru->_aut = false; ru->_aut = false;
_any_iface = true;
unsigned int ifindex; unsigned int ifindex;
ifindex = if_nametoindex(pr->ifa()->name().c_str()); ifindex = if_nametoindex(pr->ifa()->name().c_str());
@ -93,6 +96,11 @@ bool rule::any_auto()
return _any_aut; return _any_aut;
} }
bool rule::any_iface()
{
return _any_iface;
}
bool rule::check(const address& addr) const bool rule::check(const address& addr) const
{ {
return _addr == addr; return _addr == addr;

View File

@ -44,6 +44,8 @@ public:
bool check(const address& addr) const; bool check(const address& addr) const;
static bool any_auto(); static bool any_auto();
static bool any_iface();
private: private:
weak_ptr<rule> _ptr; weak_ptr<rule> _ptr;
@ -57,6 +59,8 @@ private:
bool _aut; bool _aut;
static bool _any_aut; static bool _any_aut;
static bool _any_iface;
rule(); rule();
}; };