New logging implementation

-  Switch from the old 'log' class (ERR/DBG/etc) to a better
   'logger' class. Also use LOG_* as defined in syslog.h.

-  Make it possible to read debug messages even for release.

-  Add a new argument (-v|--verbose) to 'ndppd' to change
   verbosity level.
This commit is contained in:
Daniel Adolfsson 2012-01-31 20:17:19 +01:00
parent bc70f587ef
commit c8cc80925a
19 changed files with 402 additions and 272 deletions

View File

@ -1,3 +1,5 @@
DEBUG=1
ifdef DEBUG
CXXFLAGS ?= -g -std=c++0x -DDEBUG
else
@ -12,7 +14,7 @@ SBINDIR ?= ${DESTDIR}${PREFIX}/sbin
LIBS = -lconfuse
OBJS = src/log.o src/ndppd.o src/iface.o src/proxy.o src/address.o \
OBJS = src/logger.o src/ndppd.o src/iface.o src/proxy.o src/address.o \
src/rule.o src/session.o src/conf.o
all: ndppd ndppd.1.gz ndppd.conf.5.gz

View File

@ -28,7 +28,7 @@
#include "ndppd.h"
#include "address.h"
__NDPPD_NS_BEGIN
NDPPD_NS_BEGIN
address::address()
{
@ -273,4 +273,4 @@ bool address::is_unicast() const
return _addr.s6_addr[0] != 0xff;
}
__NDPPD_NS_END
NDPPD_NS_END

View File

@ -13,16 +13,14 @@
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef __NDPPD_ADDR_H
#define __NDPPD_ADDR_H
#pragma once
#include <string>
#include <netinet/ip6.h>
#include "ndppd.h"
__NDPPD_NS_BEGIN
NDPPD_NS_BEGIN
class iface;
@ -69,8 +67,4 @@ public:
};
__NDPPD_NS_END
#endif // __NDPPD_PROXY_H
NDPPD_NS_END

View File

@ -20,7 +20,7 @@
#include "ndppd.h"
__NDPPD_NS_BEGIN
NDPPD_NS_BEGIN
void conf::error_printf(cfg_t *cfg, const char *fmt, va_list ap)
{
@ -29,7 +29,7 @@ void conf::error_printf(cfg_t *cfg, const char *fmt, va_list ap)
if (vsnprintf(buf, sizeof(buf), fmt, ap) <= 0)
return;
ERR("[Config] %s", buf);
logger::error() << "[Config] " << buf;
}
int conf::validate_rule(cfg_t *cfg, cfg_opt_t *opt)
@ -79,8 +79,9 @@ bool conf::setup(cfg_t *cfg)
std::string ifname(cfg_getstr(rule_cfg, "iface"));
if (ifname.empty()) {
if (addr.prefix() <= 120)
NCE("Static rule prefix /%d <= 120 - is this what you want?", addr.prefix());
if (addr.prefix() <= 120) {
logger::warning() << "Static rule prefix /" << addr.prefix() << " <= 120 - is this what you want?";
}
pr->add_rule(addr);
}
@ -135,7 +136,7 @@ bool conf::load(const std::string& path)
break;
default:
ERR("Failed to load configuration file '%s'", path.c_str());
logger::error() << "Failed to load configuration file '" << path << "'";
return false;
}
@ -146,4 +147,4 @@ bool conf::load(const std::string& path)
return true;
}
__NDPPD_NS_END
NDPPD_NS_END

View File

@ -13,11 +13,9 @@
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef __NDPPD_CONF_H
#define __NDPPD_CONF_H
#pragma once
#include <string>
#include <cstdarg>
#include "ndppd.h"
@ -25,7 +23,7 @@
struct cfg_t;
struct cfg_opt_t;
__NDPPD_NS_BEGIN
NDPPD_NS_BEGIN
class conf
{
@ -37,8 +35,4 @@ public:
static bool load(const std::string& path);
};
__NDPPD_NS_END
#endif // __NDPPD_CONF_H
NDPPD_NS_END

View File

@ -40,7 +40,7 @@
#include "ndppd.h"
__NDPPD_NS_BEGIN
NDPPD_NS_BEGIN
std::map<std::string, std::shared_ptr<iface> > iface::_map;
@ -53,7 +53,7 @@ iface::iface() :
iface::~iface()
{
DBG("iface::~iface()");
logger::debug() << "iface::~iface()";
if (_ifd >= 0)
close(_ifd);
@ -84,11 +84,11 @@ std::shared_ptr<iface> iface::open_pfd(const std::string& name)
if (!ifa)
return std::shared_ptr<iface>();
// Create a socket.
if ((fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IPV6))) < 0) {
ERR("Unable to create socket");
logger::error() << "Unable to create socket";
return std::shared_ptr<iface>();
}
@ -102,13 +102,13 @@ std::shared_ptr<iface> iface::open_pfd(const std::string& name)
if (!(lladdr.sll_ifindex = if_nametoindex(name.c_str()))) {
close(fd);
ERR("Failed to bind to interface '%s'", name.c_str());
logger::error() << "Failed to bind to interface '" << name << "'";
return std::shared_ptr<iface>();
}
if (bind(fd, (struct sockaddr *)&lladdr, sizeof(struct sockaddr_ll)) < 0) {
close(fd);
ERR("Failed to bind to interface '%s'", name.c_str());
logger::error() << "Failed to bind to interface '" << name << "'";
return std::shared_ptr<iface>();
}
@ -118,7 +118,7 @@ std::shared_ptr<iface> iface::open_pfd(const std::string& name)
if (ioctl(fd, FIONBIO, (char *)&on) < 0) {
close(fd);
ERR("Failed to switch to non-blocking on interface '%s'", name.c_str());
logger::error() << "Failed to switch to non-blocking on interface '" << name << "'";
return std::shared_ptr<iface>();
}
@ -153,7 +153,7 @@ std::shared_ptr<iface> iface::open_pfd(const std::string& name)
fprog.len = 8;
if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)) < 0) {
ERR("Failed to set filter");
logger::error() << "Failed to set filter";
return std::shared_ptr<iface>();
}
@ -178,7 +178,7 @@ std::shared_ptr<iface> iface::open_ifd(const std::string& name)
// Create a socket.
if ((fd = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
ERR("Unable to create socket");
logger::error() << "Unable to create socket";
return std::shared_ptr<iface>();
}
@ -192,7 +192,7 @@ std::shared_ptr<iface> iface::open_ifd(const std::string& name)
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) {
close(fd);
ERR("Failed to bind to interface '%s'", name.c_str());
logger::error() << "Failed to bind to interface '" << name << "'";
return std::shared_ptr<iface>();
}
@ -204,11 +204,11 @@ std::shared_ptr<iface> iface::open_ifd(const std::string& name)
if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
close(fd);
ERR("Failed to detect link-layer address for interface '%s'", name.c_str());
logger::error() << "Failed to detect link-layer address for interface '" << name << "'";
return std::shared_ptr<iface>();
}
DBG("fd=%d, hwaddr=%s", fd, ether_ntoa((const struct ether_addr *)&ifr.ifr_hwaddr.sa_data));
logger::debug() << "fd=" << fd << ", hwaddr=" << ether_ntoa((const struct ether_addr *)&ifr.ifr_hwaddr.sa_data);;
// Set max hops.
@ -216,13 +216,13 @@ std::shared_ptr<iface> iface::open_ifd(const std::string& name)
if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, sizeof(hops)) < 0) {
close(fd);
ERR("iface::open_ifd() failed IPV6_MULTICAST_HOPS");
logger::error() << "iface::open_ifd() failed IPV6_MULTICAST_HOPS";
return std::shared_ptr<iface>();
}
if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, sizeof(hops)) < 0) {
close(fd);
ERR("iface::open_ifd() failed IPV6_UNICAST_HOPS");
logger::error() << "iface::open_ifd() failed IPV6_UNICAST_HOPS";
return std::shared_ptr<iface>();
}
@ -232,7 +232,7 @@ std::shared_ptr<iface> iface::open_ifd(const std::string& name)
if (ioctl(fd, FIONBIO, (char *)&on) < 0) {
close(fd);
ERR("Failed to switch to non-blocking on interface '%s'", name.c_str());
logger::error() << "Failed to switch to non-blocking on interface '" << name << "'";
return std::shared_ptr<iface>();
}
@ -243,7 +243,7 @@ std::shared_ptr<iface> iface::open_ifd(const std::string& name)
ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter);
if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(filter)) < 0) {
ERR("Failed to set filter");
logger::error() << "Failed to set filter";
return std::shared_ptr<iface>();
}
@ -295,7 +295,7 @@ ssize_t iface::read(int fd, struct sockaddr *saddr, uint8_t *msg, size_t size)
if (len < sizeof(struct icmp6_hdr))
return -1;
DBG("iface::read() len=%d", len);
logger::debug() << "iface::read() len=" << len;
return len;
}
@ -320,7 +320,7 @@ ssize_t iface::write(int fd, const address& daddr, const uint8_t *msg, size_t si
mhdr.msg_iov = &iov;
mhdr.msg_iovlen = 1;
DBG("iface::write() daddr=%s, len=%d", daddr.to_string().c_str(), size);
logger::debug() << "iface::write() daddr=" << daddr.to_string() << ", len=" << size;
int len;
@ -352,9 +352,7 @@ ssize_t iface::read_solicit(address& saddr, address& daddr, address& taddr)
daddr = ip6h->ip6_dst;
saddr = ip6h->ip6_src;
DBG("iface::read_solicit() saddr=%s, daddr=%s, taddr=%s, len=%d",
saddr.to_string().c_str(), daddr.to_string().c_str(),
taddr.to_string().c_str(), len);
logger::debug() << "iface::read_solicit() saddr=" << saddr.to_string() << ", daddr=" << daddr.to_string() << ", len=" << len;
return len;
}
@ -391,8 +389,7 @@ ssize_t iface::write_solicit(const address& taddr)
daddr.addr().s6_addr[14] = taddr.const_addr().s6_addr[14];
daddr.addr().s6_addr[15] = taddr.const_addr().s6_addr[15];
DBG("iface::write_solicit() taddr=%s, daddr=%s",
taddr.to_string().c_str(), daddr.to_string().c_str());
logger::debug() << "iface::write_solicit() taddr=" << taddr.to_string() << ", daddr=" << daddr.to_string();
return write(_ifd, daddr, (uint8_t *)buf, sizeof(struct nd_neighbor_solicit) + sizeof(struct nd_opt_hdr) + 6);
}
@ -419,8 +416,7 @@ ssize_t iface::write_advert(const address& daddr, const address& taddr, bool rou
memcpy(buf + sizeof(struct nd_neighbor_advert) + sizeof(struct nd_opt_hdr), &hwaddr, 6);
DBG("iface::write_advert() daddr=%s, taddr=%s",
daddr.to_string().c_str(), taddr.to_string().c_str());
logger::debug() << "iface::write_advert() daddr=" << daddr.to_string() << ", taddr=" << taddr.to_string();
return write(_ifd, daddr, (uint8_t *)buf, sizeof(struct nd_neighbor_advert) +
sizeof(struct nd_opt_hdr) + 6);
@ -442,8 +438,7 @@ ssize_t iface::read_advert(address& saddr, address& taddr)
taddr = ((struct nd_neighbor_solicit *)msg)->nd_ns_target;
DBG("iface::read_advert() saddr=%s, taddr=%s, len=%d",
saddr.to_string().c_str(), taddr.to_string().c_str(), len);
logger::debug() << "iface::read_advert() saddr=" << saddr.to_string() << ", taddr=" << taddr.to_string() << ", len=" << len;
return len;
}
@ -454,7 +449,7 @@ void iface::fixup_pollfds()
int i = 0;
DBG("iface::fixup_pollfds() _map.size()=%d", _map.size());
logger::debug() << "iface::fixup_pollfds() _map.size()=" << _map.size();
for (std::map<std::string, std::shared_ptr<iface> >::iterator it = _map.begin();
it != _map.end(); it++) {
@ -477,7 +472,7 @@ void iface::remove_session(const std::shared_ptr<session>& se)
if (it->lock() == se) {
_sessions.erase(it);
break;
}
}
}
}
@ -525,7 +520,7 @@ int iface::poll_all()
if (is_pfd) {
if (ifa->read_solicit(saddr, daddr, taddr) < 0) {
ERR("Failed to read from interface '%s'", ifa->_name.c_str());
logger::error() << "Failed to read from interface '%s'", ifa->_name.c_str();
continue;
}
@ -535,7 +530,7 @@ int iface::poll_all()
ifa->_pr->handle_solicit(saddr, daddr, taddr);
} else {
if (ifa->read_advert(saddr, taddr) < 0) {
ERR("Failed to read from interface '%s'", ifa->_name.c_str());
logger::error() << "Failed to read from interface '%s'", ifa->_name.c_str();
continue;
}
@ -557,8 +552,7 @@ int iface::allmulti(int state)
{
struct ifreq ifr;
DBG("iface::allmulti() state=%d, _name=\"%s\"",
state, _name.c_str());
logger::debug() << "iface::allmulti() state=" << state << ", _name=\"" << _name << "\"";
state = !!state;
@ -598,4 +592,4 @@ const std::shared_ptr<proxy>& iface::pr() const
return _pr;
}
__NDPPD_NS_END
NDPPD_NS_END

View File

@ -13,8 +13,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef __NDPPD_IFACE_H
#define __NDPPD_IFACE_H
#pragma once
#include <string>
#include <list>
@ -26,7 +25,7 @@
#include "ndppd.h"
__NDPPD_NS_BEGIN
NDPPD_NS_BEGIN
class session;
class proxy;
@ -115,6 +114,4 @@ public:
const std::shared_ptr<proxy>& pr() const;
};
__NDPPD_NS_END
#endif // __NDPPD_IFACE_H
NDPPD_NS_END

View File

@ -1,90 +0,0 @@
// ndppd - NDP Proxy Daemon
// Copyright (C) 2011 Daniel Adolfsson <daniel@priv.nu>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <cstdio>
#include <cstdarg>
#include <syslog.h>
#include "ndppd.h"
using namespace ndppd;
__NDPPD_NS_BEGIN
const char *log::_level_str[] =
{
"fatal",
"alert",
"critical",
"error",
"warning",
"notice",
"info",
"debug"
};
bool log::_syslog = false;
void log::puts(int level, const char *str)
{
const char *ls;
if ((level < 0) || (level > LOG_DEBUG))
ls = "unknown";
else
ls = _level_str[level];
if (_syslog)
::syslog(level, "(%s) %s", ls, str);
else
fprintf(stderr, "(% 8s) %s\n", ls, str);
}
void log::printf(int level, const char *fmt, ...)
{
char buf[256];
va_list args;
int ret;
va_start(args, fmt);
if (vsnprintf(buf, sizeof(buf), fmt, args) > 0) {
puts(level, buf);
}
va_end(args);
}
void log::syslog(bool sl)
{
if (sl == _syslog)
return;
if (_syslog = sl) {
#ifdef DEBUG
setlogmask(LOG_UPTO(LOG_DEBUG));
openlog("ndppd", LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
#else
setlogmask(LOG_UPTO(LOG_INFO));
openlog("ndppd", LOG_CONS, LOG_USER);
#endif
}
else
{
closelog();
}
}
__NDPPD_NS_END

View File

@ -1,52 +0,0 @@
// ndppd - NDP Proxy Daemon
// Copyright (C) 2011 Daniel Adolfsson <daniel@priv.nu>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef __NDPPD_LOG_H
#define __NDPPD_LOG_H
#include <syslog.h>
#ifdef DEBUG
#define DBG(...) log::printf(LOG_DEBUG, __VA_ARGS__)
#else
#define DBG(...)
#endif
#define ERR(...) log::printf(LOG_ERR, __VA_ARGS__)
#define WRN(...) log::printf(LOG_WARNING, __VA_ARGS__)
#define CRT(...) log::printf(LOG_CRIT, __VA_ARGS__)
#define NFO(...) log::printf(LOG_INFO, __VA_ARGS__)
#define NCE(...) log::printf(LOG_NOTICE, __VA_ARGS__)
__NDPPD_NS_BEGIN
class log
{
private:
static const char *_level_str[];
static bool _syslog;
public:
static void puts(int level, const char *str);
static void printf(int level, const char *fmt, ...);
static void syslog(bool enable);
};
__NDPPD_NS_END
#endif // __NDPPD_LOG_H

200
src/logger.cc Normal file
View File

@ -0,0 +1,200 @@
// ndppd - NDP Proxy Daemon
// Copyright (C) 2011 Daniel Adolfsson <daniel@priv.nu>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <cstdio>
#include <cstdarg>
#include <cctype>
#include <cstring>
#include <iostream>
#include <sstream>
#include "ndppd.h"
#include "logger.h"
NDPPD_NS_BEGIN
/*const char *log::_level_str[] =
{
"fatal",
"alert",
"critical",
"error",
"warning",
"notice",
"info",
"debug"
};*/
int logger::_max_pri = LOG_WARNING;
bool logger::_syslog = false;
const logger::pri_name logger::_pri_names[] = {
{ "emergency", LOG_EMERG },
{ "alert", LOG_ALERT },
{ "critical", LOG_CRIT },
{ "error", LOG_ERR },
{ "warning", LOG_WARNING },
{ "notice", LOG_NOTICE },
{ "info", LOG_INFO },
{ "debug", LOG_DEBUG },
{ NULL, 0 }
};
logger::logger(int pri) :
_pri(pri)
{
}
logger::logger(const logger &l) :
_pri(l._pri) //, _ss(l._ss.str())
{
_ss << l._ss.rdbuf();
}
logger::~logger()
{
flush();
}
std::string logger::format(const std::string& fmt, ...)
{
char buf[2048];
va_list va;
va_start(va, fmt);
vsnprintf(buf, sizeof(buf), fmt.c_str(), va);
va_end(va);
return buf;
}
logger logger::error()
{
return logger(LOG_ERR);
}
logger logger::info()
{
return logger(LOG_INFO);
}
logger logger::warning()
{
return logger(LOG_WARNING);
}
logger logger::debug()
{
return logger(LOG_DEBUG);
}
logger &logger::operator<<(const std::string &str)
{
_ss << str;
return *this;
}
logger &logger::operator<<(int n)
{
_ss << n;
return *this;
}
logger &logger::operator<<(logger &(*pf)(logger &))
{
pf(*this);
return *this;
}
logger &logger::endl(logger &__l)
{
__l.flush();
return __l;
}
logger &logger::force_log(bool b)
{
_force_log = b;
return *this;
}
void logger::flush()
{
if (!_ss.rdbuf()->in_avail())
return;
if (!_force_log && (_pri > _max_pri))
return;
#ifndef DISABLE_SYSLOG
if (_syslog) {
::syslog(_pri, "%s", _ss.str().c_str());
return;
}
#endif
std::cout << _ss.str() << std::endl;
_ss.str("");
}
#ifndef DISABLE_SYSLOG
void logger::syslog(bool sl)
{
if (sl == _syslog)
return;
if (_syslog = sl) {
setlogmask(LOG_UPTO(LOG_DEBUG));
openlog("ndppd", LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
} else {
closelog();
}
}
bool logger::syslog()
{
return _syslog;
}
#endif
void logger::max_pri(int pri)
{
_max_pri = pri;
}
bool logger::verbosity(const std::string &name)
{
const char *c_name = name.c_str();
if (!*c_name) {
return false;
}
if (isdigit(*c_name)) {
_max_pri = atoi(c_name);
return true;
}
for (int i = 0; _pri_names[i].name; i++) {
if (!strncmp(c_name, _pri_names[i].name, strlen(_pri_names[i].name))) {
_max_pri = _pri_names[i].pri;
return true;
}
}
return false;
}
NDPPD_NS_END

99
src/logger.h Normal file
View File

@ -0,0 +1,99 @@
// ndppd - NDP Proxy Daemon
// Copyright (C) 2011 Daniel Adolfsson <daniel@priv.nu>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#pragma once
#include <sstream>
#ifndef DISABLE_SYSLOG
# include <syslog.h>
#else
# define LOG_EMERG 0 /* system is unusable */
# define LOG_ALERT 1 /* action must be taken immediately */
# define LOG_CRIT 2 /* critical conditions */
# define LOG_ERR 3 /* error conditions */
# define LOG_WARNING 4 /* warning conditions */
# define LOG_NOTICE 5 /* normal but significant condition */
# define LOG_INFO 6 /* informational */
# define LOG_DEBUG 7 /* debug-level messages */
#endif
/*#define DBG(...) logger(logger::DEBUG) << logger::F(__VA_ARGS__) << logger::endl;
#define ERR(...) logger(logger::ERROR) << logger::F(__VA_ARGS__) << logger::endl;
#define WRN(...) logger(logger::WARNING) << logger::F(__VA_ARGS__) << logger::endl;
#define NFO(...) logger(logger::INFO) << logger::F(__VA_ARGS__) << logger::endl;*/
/* LOG_ERR; LOG_WARNING; LOG_CRIT; LOG_INFO; LOG_NOTICE */
NDPPD_NS_BEGIN
class logger
{
public:
logger(int pri = LOG_INFO);
logger(const logger &l);
~logger();
static std::string format(const std::string &fmt, ...);
static void syslog(bool enable);
static bool syslog();
static void max_pri(int pri);
void flush();
static bool verbosity(const std::string &name);
logger& operator<<(const std::string &str);
logger& operator<<(logger &(*pf)(logger &));
logger& operator<<(int n);
logger& force_log(bool b = true);
static logger& endl(logger &__l);
// Shortcuts.
static logger error();
static logger info();
static logger warning();
static logger debug();
private:
int _pri;
std::stringstream _ss;
bool _force_log;
struct pri_name {
const char *name;
int pri;
};
static const pri_name _pri_names[];
static bool _syslog;
static int _max_pri;
};
NDPPD_NS_END

View File

@ -53,6 +53,7 @@ int main(int argc, char *argv[], char *env[])
{
std::string config_path("/etc/ndppd.conf");
std::string pidfile;
std::string verbosity;
bool daemon = false;
while (1) {
@ -60,12 +61,13 @@ int main(int argc, char *argv[], char *env[])
static struct option long_options[] =
{
{ "config", 1, 0, 'c' },
{ "daemon", 0, 0, 'd' },
{ "config", 1, 0, 'c' },
{ "daemon", 0, 0, 'd' },
{ "verbose", 1, 0, 'v' },
{ 0, 0, 0, 0}
};
c = getopt_long(argc, argv, "c:dp:", long_options, &opt);
c = getopt_long(argc, argv, "c:dp:v::", long_options, &opt);
if (c == -1)
break;
@ -82,14 +84,23 @@ int main(int argc, char *argv[], char *env[])
case 'p':
pidfile = optarg;
break;
case 'v':
if (optarg) {
if (!logger::verbosity(optarg))
logger::error() << "Unknown verbosity level '" << optarg << "'";
} else {
logger::max_pri(LOG_INFO);
}
break;
}
}
if (daemon) {
log::syslog(true);
logger::syslog(true);
if (daemonize() < 0) {
ERR("Failed to daemonize process");
logger::error() << "Failed to daemonize process";
return 1;
}
}
@ -101,9 +112,9 @@ int main(int argc, char *argv[], char *env[])
pf.close();
}
NFO("ndppd (NDP Proxy Daemon) version " NDPPD_VERSION);
NFO("Using configuration file '%s'", config_path.c_str());
logger::info().force_log()
<< "ndppd (NDP Proxy Daemon) version " NDPPD_VERSION << logger::endl
<< "Using configuration file '" << config_path << "'";
if (!conf::load(config_path))
return -1;
@ -126,7 +137,7 @@ int main(int argc, char *argv[], char *env[])
session::update_all(elapsed_time);
}
ERR("iface::poll_all() failed");
logger::error() << "iface::poll_all() failed";
return 0;
}

View File

@ -13,20 +13,19 @@
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef __NDPPD_H
#define __NDPPD_H
#pragma once
#include <netinet/ip6.h>
#include <memory>
#define __NDPPD_NS_BEGIN namespace ndppd {
#define __NDPPD_NS_END }
#define NDPPD_NS_BEGIN namespace ndppd {
#define NDPPD_NS_END }
#define NDPPD_VERSION "0.2.1"
#define NDPPD_VERSION "0.2.2"
#include <assert.h>
#include "log.h"
#include "logger.h"
#include "conf.h"
#include "address.h"
@ -34,5 +33,3 @@
#include "proxy.h"
#include "session.h"
#include "rule.h"
#endif // __NDPPD_H

View File

@ -24,7 +24,7 @@
#include "rule.h"
#include "session.h"
__NDPPD_NS_BEGIN
NDPPD_NS_BEGIN
proxy::proxy() :
_router(true), _ttl(30000), _timeout(500)
@ -39,7 +39,7 @@ std::shared_ptr<proxy> proxy::create(const std::shared_ptr<iface>& ifa)
ifa->pr(pr);
DBG("proxy::create() if=%x", ifa->name().c_str());
logger::debug() << "proxy::create() if=" << ifa->name();
return pr;
}
@ -57,15 +57,15 @@ std::shared_ptr<proxy> proxy::open(const std::string& ifname)
void proxy::handle_solicit(const address& saddr, const address& daddr,
const address& taddr)
{
DBG("proxy::handle_solicit() saddr=%s, taddr=%s",
saddr.to_string().c_str(), taddr.to_string().c_str());
logger::debug() << "proxy::handle_solicit() saddr=" << saddr.to_string()
<< ", taddr=" << taddr.to_string();
// Let's check this proxy's list of sessions to see if we can
// find one with the same target address.
for (std::list<std::shared_ptr<session> >::iterator sit = _sessions.begin();
sit != _sessions.end(); sit++) {
if ((*sit)->taddr() == taddr) {
switch ((*sit)->status()) {
case session::WAITING:
@ -89,8 +89,7 @@ void proxy::handle_solicit(const address& saddr, const address& daddr,
it != _rules.end(); it++) {
std::shared_ptr<rule> ru = *it;
DBG("comparing %s against %s",
ru->addr().to_string().c_str(), taddr.to_string().c_str());
logger::debug() << "checking " << ru->addr().to_string() << " against " << taddr;
if (ru->addr() == taddr) {
if (!se)
@ -168,5 +167,5 @@ void proxy::timeout(int val)
_timeout = (val >= 0) ? val : 500;
}
__NDPPD_NS_END
NDPPD_NS_END

View File

@ -13,8 +13,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef __NDPPD_PROXY_H
#define __NDPPD_PROXY_H
#pragma once
#include <string>
#include <vector>
@ -24,7 +23,7 @@
#include "ndppd.h"
__NDPPD_NS_BEGIN
NDPPD_NS_BEGIN
class iface;
class rule;
@ -75,6 +74,4 @@ public:
void ttl(int val);
};
__NDPPD_NS_END
#endif // __NDPPD_PROXY_H
NDPPD_NS_END

View File

@ -22,7 +22,7 @@
#include "proxy.h"
#include "iface.h"
__NDPPD_NS_BEGIN
NDPPD_NS_BEGIN
rule::rule()
{
@ -36,8 +36,7 @@ std::shared_ptr<rule> rule::create(const std::shared_ptr<proxy>& pr, const addre
ru->_ifa = ifa;
ru->_addr = addr;
DBG("rule::create() if=%s, addr=%s",
pr->ifa()->name().c_str(), addr.to_string().c_str());
logger::debug() << "rule::create() if=" << pr->ifa()->name() << ", addr=" << addr;
return ru;
}
@ -49,8 +48,7 @@ std::shared_ptr<rule> rule::create(const std::shared_ptr<proxy>& pr, const addre
ru->_pr = pr;
ru->_addr = addr;
DBG("rule::create() if=%s, addr=%s",
pr->ifa()->name().c_str(), addr.to_string().c_str());
logger::debug() << "rule::create() if=" << pr->ifa()->name().c_str() << ", addr=" << addr;
return ru;
}
@ -75,4 +73,4 @@ bool rule::check(const address& addr) const
return _addr == addr;
}
__NDPPD_NS_END
NDPPD_NS_END

View File

@ -13,8 +13,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef __NDPPD_RULE_H
#define __NDPPD_RULE_H
#pragma once
#include <string>
#include <vector>
@ -24,7 +23,7 @@
#include "ndppd.h"
__NDPPD_NS_BEGIN
NDPPD_NS_BEGIN
class iface;
class proxy;
@ -57,8 +56,4 @@ public:
};
__NDPPD_NS_END
#endif // __NDPPD_PROXY_H
NDPPD_NS_END

View File

@ -20,7 +20,7 @@
#include "iface.h"
#include "session.h"
__NDPPD_NS_BEGIN
NDPPD_NS_BEGIN
std::list<std::weak_ptr<session> > session::_sessions;
@ -35,7 +35,7 @@ void session::update_all(int elapsed_time)
switch (se->_status) {
case session::WAITING:
DBG("session is now invalid");
logger::debug() << "session is now invalid";
se->_status = session::INVALID;
se->_ttl = se->_pr->ttl();
break;
@ -48,14 +48,14 @@ void session::update_all(int elapsed_time)
session::~session()
{
DBG("session::~session() this=%x", this);
logger::debug() << "session::~session() this=" << logger::format("%x", this);
for (std::list<std::weak_ptr<session> >::iterator it = _sessions.begin();
it != _sessions.end(); it++) {
if (it->lock() == _ptr.lock()) {
_sessions.erase(it);
break;
}
}
}
for (std::list<std::shared_ptr<iface> >::iterator it = _ifaces.begin();
@ -78,9 +78,8 @@ std::shared_ptr<session> session::create(const std::shared_ptr<proxy>& pr, const
_sessions.push_back(se);
DBG("session::create() pr=%x, saddr=%s, daddr=%s, taddr=%s, =%x",
(proxy *)pr, saddr.to_string().c_str(), daddr.to_string().c_str(),
taddr.to_string().c_str(), (session *)se);
logger::debug() << "session::create() pr=" << logger::format("%x", pr.get()) << ", saddr=" << saddr
<< ", daddr=" << daddr << ", taddr=" << taddr << " =" << logger::format("%x", se.get());
return se;
}
@ -96,11 +95,11 @@ void session::add_iface(const std::shared_ptr<iface>& ifa)
void session::send_solicit()
{
DBG("session::send_solicit() (%d)", _ifaces.size());
logger::debug() << "session::send_solicit() (" << _ifaces.size() << ")";
for (std::list<std::shared_ptr<iface> >::iterator it = _ifaces.begin();
it != _ifaces.end(); it++) {
DBG(" - %s", (*it)->name().c_str());
logger::debug() << " - %s" << (*it)->name();
(*it)->write_solicit(_taddr);
}
}
@ -143,4 +142,4 @@ void session::status(int val)
_status = val;
}
__NDPPD_NS_END
NDPPD_NS_END

View File

@ -13,14 +13,13 @@
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef __NDPPD_SESSION_H
#define __NDPPD_SESSION_H
#pragma once
#include <vector>
#include "ndppd.h"
__NDPPD_NS_BEGIN
NDPPD_NS_BEGIN
class proxy;
class iface;
@ -85,8 +84,4 @@ public:
};
__NDPPD_NS_END
#endif // __NDPPD_PROXY_H
NDPPD_NS_END