diff --git a/Makefile b/Makefile index d8b0659..2c6a297 100644 --- a/Makefile +++ b/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 diff --git a/src/address.cc b/src/address.cc index 054e57c..5c678e6 100644 --- a/src/address.cc +++ b/src/address.cc @@ -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 diff --git a/src/address.h b/src/address.h index ccc9887..93e4fe0 100644 --- a/src/address.h +++ b/src/address.h @@ -13,16 +13,14 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#ifndef __NDPPD_ADDR_H -#define __NDPPD_ADDR_H +#pragma once #include - #include #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 diff --git a/src/conf.cc b/src/conf.cc index 0c209ff..13bd109 100644 --- a/src/conf.cc +++ b/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 diff --git a/src/conf.h b/src/conf.h index 4b0867a..bda8c8e 100644 --- a/src/conf.h +++ b/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 . -#ifndef __NDPPD_CONF_H -#define __NDPPD_CONF_H +#pragma once #include - #include #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 diff --git a/src/iface.cc b/src/iface.cc index 4b65855..c66c0c1 100644 --- a/src/iface.cc +++ b/src/iface.cc @@ -40,7 +40,7 @@ #include "ndppd.h" -__NDPPD_NS_BEGIN +NDPPD_NS_BEGIN std::map > 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::open_pfd(const std::string& name) if (!ifa) return std::shared_ptr(); - + // 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(); } @@ -102,13 +102,13 @@ std::shared_ptr 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(); } 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(); } @@ -118,7 +118,7 @@ std::shared_ptr 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(); } @@ -153,7 +153,7 @@ std::shared_ptr 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(); } @@ -178,7 +178,7 @@ std::shared_ptr 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(); } @@ -192,7 +192,7 @@ std::shared_ptr 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(); } @@ -204,11 +204,11 @@ std::shared_ptr 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(); } - 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::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(); } 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(); } @@ -232,7 +232,7 @@ std::shared_ptr 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(); } @@ -243,7 +243,7 @@ std::shared_ptr 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(); } @@ -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 >::iterator it = _map.begin(); it != _map.end(); it++) { @@ -477,7 +472,7 @@ void iface::remove_session(const std::shared_ptr& 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& iface::pr() const return _pr; } -__NDPPD_NS_END +NDPPD_NS_END diff --git a/src/iface.h b/src/iface.h index 08b5b12..0084496 100644 --- a/src/iface.h +++ b/src/iface.h @@ -13,8 +13,7 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#ifndef __NDPPD_IFACE_H -#define __NDPPD_IFACE_H +#pragma once #include #include @@ -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& pr() const; }; -__NDPPD_NS_END - -#endif // __NDPPD_IFACE_H +NDPPD_NS_END diff --git a/src/log.cc b/src/log.cc deleted file mode 100644 index 24c685e..0000000 --- a/src/log.cc +++ /dev/null @@ -1,90 +0,0 @@ -// ndppd - NDP Proxy Daemon -// Copyright (C) 2011 Daniel Adolfsson -// -// 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 . -#include -#include -#include - -#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 diff --git a/src/log.h b/src/log.h deleted file mode 100644 index 4569a35..0000000 --- a/src/log.h +++ /dev/null @@ -1,52 +0,0 @@ -// ndppd - NDP Proxy Daemon -// Copyright (C) 2011 Daniel Adolfsson -// -// 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 . -#ifndef __NDPPD_LOG_H -#define __NDPPD_LOG_H - -#include - -#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 diff --git a/src/logger.cc b/src/logger.cc new file mode 100644 index 0000000..c500226 --- /dev/null +++ b/src/logger.cc @@ -0,0 +1,200 @@ + // ndppd - NDP Proxy Daemon +// Copyright (C) 2011 Daniel Adolfsson +// +// 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 . +#include +#include +#include +#include +#include +#include + +#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 diff --git a/src/logger.h b/src/logger.h new file mode 100644 index 0000000..638aa2f --- /dev/null +++ b/src/logger.h @@ -0,0 +1,99 @@ +// ndppd - NDP Proxy Daemon +// Copyright (C) 2011 Daniel Adolfsson +// +// 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 . +#pragma once + +#include + +#ifndef DISABLE_SYSLOG +# include +#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 diff --git a/src/ndppd.cc b/src/ndppd.cc index 053b2e4..a3f21f6 100644 --- a/src/ndppd.cc +++ b/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; } diff --git a/src/ndppd.h b/src/ndppd.h index 2ed88f2..3126da9 100644 --- a/src/ndppd.h +++ b/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 . -#ifndef __NDPPD_H -#define __NDPPD_H +#pragma once #include #include -#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 -#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 diff --git a/src/proxy.cc b/src/proxy.cc index 973ba1b..2d5c0f2 100644 --- a/src/proxy.cc +++ b/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::create(const std::shared_ptr& 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::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 >::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 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 diff --git a/src/proxy.h b/src/proxy.h index d64ddae..7a28e13 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -13,8 +13,7 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#ifndef __NDPPD_PROXY_H -#define __NDPPD_PROXY_H +#pragma once #include #include @@ -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 diff --git a/src/rule.cc b/src/rule.cc index 4aa7cce..24adb12 100644 --- a/src/rule.cc +++ b/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::create(const std::shared_ptr& 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::create(const std::shared_ptr& 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 diff --git a/src/rule.h b/src/rule.h index a8a49ed..4ccefaf 100644 --- a/src/rule.h +++ b/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 . -#ifndef __NDPPD_RULE_H -#define __NDPPD_RULE_H +#pragma once #include #include @@ -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 diff --git a/src/session.cc b/src/session.cc index 266265f..7631ab7 100644 --- a/src/session.cc +++ b/src/session.cc @@ -20,7 +20,7 @@ #include "iface.h" #include "session.h" -__NDPPD_NS_BEGIN +NDPPD_NS_BEGIN std::list > 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 >::iterator it = _sessions.begin(); it != _sessions.end(); it++) { if (it->lock() == _ptr.lock()) { _sessions.erase(it); break; - } + } } for (std::list >::iterator it = _ifaces.begin(); @@ -78,9 +78,8 @@ std::shared_ptr session::create(const std::shared_ptr& 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& ifa) void session::send_solicit() { - DBG("session::send_solicit() (%d)", _ifaces.size()); + logger::debug() << "session::send_solicit() (" << _ifaces.size() << ")"; for (std::list >::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 diff --git a/src/session.h b/src/session.h index 78fb75a..f058bf6 100644 --- a/src/session.h +++ b/src/session.h @@ -13,14 +13,13 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#ifndef __NDPPD_SESSION_H -#define __NDPPD_SESSION_H +#pragma once #include #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