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:
parent
bc70f587ef
commit
c8cc80925a
4
Makefile
4
Makefile
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
13
src/conf.cc
13
src/conf.cc
@ -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
|
||||
|
12
src/conf.h
12
src/conf.h
@ -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
|
||||
|
58
src/iface.cc
58
src/iface.cc
@ -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);
|
||||
@ -88,7 +88,7 @@ std::shared_ptr<iface> iface::open_pfd(const std::string& name)
|
||||
// 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++) {
|
||||
@ -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
|
||||
|
@ -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
|
||||
|
90
src/log.cc
90
src/log.cc
@ -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
|
52
src/log.h
52
src/log.h
@ -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
200
src/logger.cc
Normal 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
99
src/logger.h
Normal 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
|
29
src/ndppd.cc
29
src/ndppd.cc
@ -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;
|
||||
}
|
||||
|
13
src/ndppd.h
13
src/ndppd.h
@ -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
|
||||
|
13
src/proxy.cc
13
src/proxy.cc
@ -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,8 +57,8 @@ 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.
|
||||
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
10
src/rule.cc
10
src/rule.cc
@ -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
|
||||
|
11
src/rule.h
11
src/rule.h
@ -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
|
||||
|
@ -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,7 +48,7 @@ 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++) {
|
||||
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user