summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anytun.org>2009-02-22 02:35:13 +0000
committerChristian Pointner <equinox@anytun.org>2009-02-22 02:35:13 +0000
commitc9bc8e82a25fd160872fac488bfe920f95f5fe5f (patch)
treed9751f4c9984ff848b130a31ffe9dc7081d414af
parentadded file logging target (diff)
added extended logging capability
-rw-r--r--src/Makefile9
-rw-r--r--src/anytun-config.cpp5
-rw-r--r--src/anytun-controld.cpp2
-rw-r--r--src/anytun.cpp17
-rwxr-xr-xsrc/configure2
-rw-r--r--src/log.cpp96
-rw-r--r--src/log.h85
-rw-r--r--src/logTargets.cpp433
-rw-r--r--src/logTargets.h200
9 files changed, 677 insertions, 172 deletions
diff --git a/src/Makefile b/src/Makefile
index 87c3f47..fa4c519 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -50,6 +50,7 @@ OBJS := tunDevice.o \
routingTable.o \
signalController.o \
log.o \
+ logTargets.o \
options.o \
seqWindow.o \
routingTreeNode.o \
@@ -66,10 +67,12 @@ ANYCTROBJS := signalController.o \
anyCtrOptions.o \
buffer.o \
log.o \
+ logTargets.o \
syncTcpConnection.o \
syncServer.o
ANYCONFOBJS := log.o \
+ logTargets.o \
buffer.o \
keyDerivation.o \
keyDerivationFactory.o \
@@ -141,13 +144,13 @@ anytun-controld: $(ANYCTROBJS) anytun-controld.o
options.o: options.cpp
- $(CXX) -DANYTUN_OPTIONS $(CXXFLAGS) $< -c -o $@
+ $(CXX) $(CXXFLAGS) -DANYTUN_OPTIONS $< -c -o $@
anyCtrOptions.o: options.cpp
- $(CXX) -DANYCTR_OPTIONS $(CXXFLAGS) $< -c -o $@
+ $(CXX) $(CXXFLAGS) -DANYCTR_OPTIONS $< -c -o $@
anyConfOptions.o: options.cpp
- $(CXX) -DANYCONF_OPTIONS $(CXXFLAGS) $< -c -o $@
+ $(CXX) $(CXXFLAGS) -DANYCONF_OPTIONS $< -c -o $@
%.o: %.cpp
$(CXX) $(CXXFLAGS) $< -c
diff --git a/src/anytun-config.cpp b/src/anytun-config.cpp
index 650c75b..07344c1 100644
--- a/src/anytun-config.cpp
+++ b/src/anytun-config.cpp
@@ -55,7 +55,7 @@ void createConnection(const PacketSourceEndpoint & remote_end, ConnectionList &
seq_nr_t seq_nr_ = 0;
KeyDerivation * kd = KeyDerivationFactory::create( gOpt.getKdPrf() , gOpt.getAnytun02Compat() );
kd->init( gOpt.getKey(), gOpt.getSalt() );
-// cLog.msg(Log::PRIO_NOTICE) << "added connection remote host " << remote_end;
+ cLog.msg(Log::PRIO_NOTICE) << "added connection remote host " << remote_end;
ConnectionParam connparam ( (*kd), (*seq), seq_nr_, remote_end );
cl.addConnection( connparam, mux );
@@ -89,6 +89,7 @@ int main(int argc, char* argv[])
int ret=0;
try
{
+ cLog.addTarget("stderr:4");
bool result = gOpt.parse(argc, argv);
if(!result) {
gOpt.printUsage();
@@ -98,7 +99,7 @@ int main(int argc, char* argv[])
catch(syntax_error& e)
{
std::cerr << e << std::endl;
-// cLog.msg(Log::PRIO_NOTICE) << "exitting after syntax error";
+ cLog.msg(Log::PRIO_ERR) << "exitting after syntax error";
gOpt.printUsage();
exit(-1);
}
diff --git a/src/anytun-controld.cpp b/src/anytun-controld.cpp
index cff0932..680d143 100644
--- a/src/anytun-controld.cpp
+++ b/src/anytun-controld.cpp
@@ -97,7 +97,7 @@ int main(int argc, char* argv[])
bool daemonized=false;
try
{
- cLog.setLogName("anytun-controld");
+ cLog.addTarget("syslog:7,anytun-controld,daemon");
cLog.msg(Log::PRIO_NOTICE) << "anytun-controld started...";
try
diff --git a/src/anytun.cpp b/src/anytun.cpp
index 292d924..d954eae 100644
--- a/src/anytun.cpp
+++ b/src/anytun.cpp
@@ -360,11 +360,12 @@ int main(int argc, char* argv[])
#endif
try
{
- cLog.msg(Log::PRIO_NOTICE) << "anytun started...";
-/// std::cout << "anytun - secure anycast tunneling protocol" << std::endl;
-
try
{
+ cLog.addTarget("syslog:7,anytun,daemon");
+ cLog.msg(Log::PRIO_DEBUG) << "anytun started...";
+/// std::cout << "anytun - secure anycast tunneling protocol" << std::endl;
+
bool result = gOpt.parse(argc, argv);
if(!result) {
cLog.msg(Log::PRIO_NOTICE) << "printing help text and exitting";
@@ -375,7 +376,7 @@ int main(int argc, char* argv[])
catch(syntax_error& e)
{
std::cerr << e << std::endl;
- cLog.msg(Log::PRIO_NOTICE) << "exitting after syntax error";
+ cLog.msg(Log::PRIO_ERR) << "exitting after syntax error";
gOpt.printUsage();
exit(-1);
}
@@ -532,18 +533,14 @@ int main(int argc, char* argv[])
catch(std::runtime_error& e)
{
cLog.msg(Log::PRIO_ERR) << "uncaught runtime error, exiting: " << e.what();
-#ifndef LOG_STDOUT
- if(!daemonized)
+ if(!daemonized)
std::cout << "uncaught runtime error, exiting: " << e.what() << std::endl;
-#endif
}
catch(std::exception& e)
{
cLog.msg(Log::PRIO_ERR) << "uncaught exception, exiting: " << e.what();
-#ifndef LOG_STDOUT
- if(!daemonized)
+ if(!daemonized)
std::cout << "uncaught exception, exiting: " << e.what() << std::endl;
-#endif
}
#if defined(WIN_SERVICE)
gWinService.stop();
diff --git a/src/configure b/src/configure
index 764f83e..b664850 100755
--- a/src/configure
+++ b/src/configure
@@ -32,7 +32,7 @@
TARGET=`uname -s`
-CXXFLAGS='-g -Wall -O2 -DLOG_SYSLOG'
+CXXFLAGS='-g -Wall -O2 -DLOG_SYSLOG -DLOG_FILE -DLOG_STDOUT'
LDFLAGS='-g -Wall -O2 -lboost_thread -lboost_serialization -lboost_system'
CRYPTO_LIB='gcrypt'
diff --git a/src/log.cpp b/src/log.cpp
index 026a851..f99ee78 100644
--- a/src/log.cpp
+++ b/src/log.cpp
@@ -36,11 +36,6 @@
#include "threadUtils.hpp"
-#ifdef LOG_WINEVENTLOG
-#include <windows.h>
-#include <strsafe.h>
-#endif
-
Log* Log::inst = NULL;
Mutex Log::instMutex;
Log& cLog = Log::instance();
@@ -59,7 +54,6 @@ std::ostream& operator<<(std::ostream& stream, LogGpgError const& value)
std::ostream& operator<<(std::ostream& stream, LogErrno const& value)
{
boost::system::system_error err(boost::system::error_code(value.err_,boost::system::get_system_category()));
-// boost::system::system_error err(boost::system::error_code(value.err_,boost::system::get_posix_category()));
return stream << err.what();
}
@@ -88,65 +82,28 @@ Log& Log::instance()
return *inst;
}
-Log::Log()
-{
- facility = FAC_DAEMON;
- logName = "anytun";
- open();
-}
-
-Log::~Log()
+void Log::addTarget(std::string conf)
{
-#ifdef LOG_SYSLOG
- closelog();
-#endif
-#ifdef LOG_FILE
- if(log_file.is_open())
- log_file.close();
-#endif
-#ifdef LOG_WINEVENTLOG
- if(h_event_source_)
- DeregisterEventSource(h_event_source_);
-#endif
+ Lock lock(mutex);
+ LogTarget* target = targets.add(conf);
+ target->open();
+ target->enable();
}
-void Log::open()
+void Log::addTarget(LogTargetList::target_type_t type, int prio, std::string conf)
{
-#ifdef LOG_SYSLOG
- openlog(logName.c_str(), LOG_PID, facility);
-#endif
-#ifdef LOG_FILE
- log_file.open("anytun.log", std::fstream::out | std::fstream::app);
-#endif
-#ifdef LOG_WINEVENTLOG
- h_event_source_ = RegisterEventSourceA(NULL, logName.c_str());
-#endif
+ Lock lock(mutex);
+ LogTarget* target = targets.add(type, prio, conf);
+ target->open();
+ target->enable();
}
void Log::log(std::string msg, int prio)
{
Lock lock(mutex);
-#ifdef LOG_SYSLOG
- syslog(prio | facility, "%s", msg.c_str());
-#endif
-#ifdef LOG_STDOUT
- std::cout << "LOG-" << Log::prioToString(prio) << ": " << msg << std::endl;
-#endif
-#ifdef LOG_FILE
- if(log_file.is_open())
- log_file << Log::prioToString(prio) << ": " << msg << std::endl;
-#endif
-#ifdef LOG_WINEVENTLOG
- LPCTSTR lpszStrings[1];
- CHAR buffer[STERROR_TEXT_MAX];
- StringCchPrintfA(buffer, STERROR_TEXT_MAX, "%s", msg.c_str());
- lpszStrings[0] = buffer;
- if(log.h_event_source_)
- ReportEventA(log.h_event_source_, Log::prioToEventLogType(prio), 0, prio, NULL, 1, 0, lpszStrings, NULL);
-#endif
+ targets.log(msg, prio);
}
-#if defined(LOG_STDOUT) || defined(LOG_FILE)
std::string Log::prioToString(int prio)
{
switch(prio) {
@@ -161,34 +118,3 @@ std::string Log::prioToString(int prio)
default: return "UNKNOWN";
}
}
-#endif
-#ifdef LOG_WINEVENTLOG
-WORD Log::prioToEventLogType(int prio)
-{
- switch(prio) {
- case PRIO_EMERG: return EVENTLOG_ERROR_TYPE;
- case PRIO_ALERT: return EVENTLOG_ERROR_TYPE;
- case PRIO_CRIT: return EVENTLOG_ERROR_TYPE;
- case PRIO_ERR: return EVENTLOG_ERROR_TYPE;
- case PRIO_WARNING: return EVENTLOG_WARNING_TYPE;
- case PRIO_NOTICE: return EVENTLOG_INFORMATION_TYPE;
- case PRIO_INFO: return EVENTLOG_SUCCESS;
- case PRIO_DEBUG: return EVENTLOG_INFORMATION_TYPE;
- default: return EVENTLOG_ERROR_TYPE;
- }
-}
-#endif
-
-Log& Log::setLogName(std::string newLogName)
-{
- logName = newLogName;
- open();
- return *this;
-}
-
-Log& Log::setFacility(int newFacility)
-{
- facility = newFacility;
- open();
- return *this;
-}
diff --git a/src/log.h b/src/log.h
index 861ad2c..6550b10 100644
--- a/src/log.h
+++ b/src/log.h
@@ -34,7 +34,8 @@
#include <string>
#include <sstream>
-#include <fstream>
+
+#include "logTargets.h"
#ifdef LOG_SYSLOG
#include <syslog.h>
@@ -88,26 +89,6 @@ class Log : public std::ostringstream
{
public:
#ifdef LOG_SYSLOG
- static const int FAC_USER = LOG_USER;
- static const int FAC_MAIL = LOG_MAIL;
- static const int FAC_DAEMON = LOG_DAEMON;
- static const int FAC_AUTH = LOG_AUTH;
- static const int FAC_SYSLOG = LOG_SYSLOG;
- static const int FAC_LPR = LOG_LPR;
- static const int FAC_NEWS = LOG_NEWS;
- static const int FAC_UUCP = LOG_UUCP;
- static const int FAC_CRON = LOG_CRON;
- static const int FAC_AUTHPRIV = LOG_AUTHPRIV;
- static const int FAC_FTP = LOG_FTP;
- static const int FAC_LOCAL0 = LOG_LOCAL0;
- static const int FAC_LOCAL1 = LOG_LOCAL1;
- static const int FAC_LOCAL2 = LOG_LOCAL2;
- static const int FAC_LOCAL3 = LOG_LOCAL3;
- static const int FAC_LOCAL4 = LOG_LOCAL4;
- static const int FAC_LOCAL5 = LOG_LOCAL5;
- static const int FAC_LOCAL6 = LOG_LOCAL6;
- static const int FAC_LOCAL7 = LOG_LOCAL7;
-
static const int PRIO_EMERG = LOG_EMERG;
static const int PRIO_ALERT = LOG_ALERT;
static const int PRIO_CRIT = LOG_CRIT;
@@ -117,54 +98,26 @@ public:
static const int PRIO_INFO = LOG_INFO;
static const int PRIO_DEBUG = LOG_DEBUG;
#else
- static const int FAC_USER = 0;
- static const int FAC_MAIL = 0;
- static const int FAC_DAEMON = 0;
- static const int FAC_AUTH = 0;
- static const int FAC_SYSLOG = 0;
- static const int FAC_LPR = 0;
- static const int FAC_NEWS = 0;
- static const int FAC_UUCP = 0;
- static const int FAC_CRON = 0;
- static const int FAC_AUTHPRIV = 0;
- static const int FAC_FTP = 0;
- static const int FAC_LOCAL0 = 0;
- static const int FAC_LOCAL1 = 0;
- static const int FAC_LOCAL2 = 0;
- static const int FAC_LOCAL3 = 0;
- static const int FAC_LOCAL4 = 0;
- static const int FAC_LOCAL5 = 0;
- static const int FAC_LOCAL6 = 0;
- static const int FAC_LOCAL7 = 0;
-
- static const int PRIO_EMERG = 1;
- static const int PRIO_ALERT = 2;
- static const int PRIO_CRIT = 3;
- static const int PRIO_ERR = 4;
- static const int PRIO_WARNING = 5;
- static const int PRIO_NOTICE = 6;
- static const int PRIO_INFO = 7;
- static const int PRIO_DEBUG = 8;
+ static const int PRIO_EMERG = 0;
+ static const int PRIO_ALERT = 1;
+ static const int PRIO_CRIT = 2;
+ static const int PRIO_ERR = 3;
+ static const int PRIO_WARNING = 4;
+ static const int PRIO_NOTICE = 5;
+ static const int PRIO_INFO = 6;
+ static const int PRIO_DEBUG = 7;
#endif
-#if defined(LOG_STDOUT) || defined(LOG_FILE)
static std::string prioToString(int prio);
-#endif
-#ifdef LOG_WINEVENTLOG
- static WORD prioToEventLogType(int prio);
-#endif
static Log& instance();
- Log& setLogName(std::string newLogName);
- std::string getLogName() const { return logName; }
- Log& setFacility(int newFacility);
- int getFacility() const { return facility; }
-
+ void addTarget(std::string conf);
+ void addTarget(LogTargetList::target_type_t type, int prio, std::string conf);
LogStringBuilder msg(int prio=PRIO_INFO) { return LogStringBuilder(*this, prio); }
private:
- Log();
- ~Log();
+ Log() {};
+ ~Log() {};
Log(const Log &l);
void operator=(const Log &l);
@@ -178,20 +131,12 @@ private:
};
friend class instanceCleaner;
- void open();
void log(std::string msg, int prio);
Mutex mutex;
friend class LogStringBuilder;
- std::string logName;
- int facility;
-#ifdef LOG_FILE
- std::ofstream log_file;
-#endif
-#ifdef LOG_WINEVENTLOG
- HANDLE h_event_source_;
-#endif
+ LogTargetList targets;
};
extern Log& cLog;
diff --git a/src/logTargets.cpp b/src/logTargets.cpp
new file mode 100644
index 0000000..82bb6fd
--- /dev/null
+++ b/src/logTargets.cpp
@@ -0,0 +1,433 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl,
+ * Christian Pointner <satp@wirdorange.org>
+ *
+ * This file is part of Anytun.
+ *
+ * Anytun is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Anytun 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 anytun. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sstream>
+
+#include "datatypes.h"
+
+#include "logTargets.h"
+#include "log.h"
+
+#include "options.h"
+
+#ifdef LOG_WINEVENTLOG
+#include <windows.h>
+#include <strsafe.h>
+#endif
+
+LogTarget::LogTarget() : opened(false), enabled(false), max_prio(Log::PRIO_NOTICE)
+{
+}
+
+LogTarget::LogTarget(int prio) : opened(false), enabled(false), max_prio(prio)
+{
+}
+
+LogTargetList::~LogTargetList()
+{
+ clear();
+}
+
+LogTargetList::target_type_t LogTargetList::targetTypeFromString(std::string type)
+{
+ if(type == "syslog") return TARGET_SYSLOG;
+ if(type == "file") return TARGET_FILE;
+ if(type == "stdout") return TARGET_STDOUT;
+ if(type == "stderr") return TARGET_STDERR;
+ if(type == "eventlog") return TARGET_WINEVENTLOG;
+ return TARGET_UNKNOWN;
+}
+
+std::string LogTargetList::targetTypeToString(target_type_t type)
+{
+ switch(type) {
+ case TARGET_SYSLOG: return "syslog";
+ case TARGET_FILE: return "file";
+ case TARGET_STDOUT: return "stdout";
+ case TARGET_STDERR: return "stderr";
+ case TARGET_WINEVENTLOG: return "eventlog";
+ default: return "unknown";
+ }
+}
+
+LogTarget* LogTargetList::add(std::string conf)
+{
+ std::stringstream s(conf);
+ std::string type;
+ getline(s, type, ':');
+ if(!s.good())
+ throw syntax_error(conf, 0);
+
+ int prio = 0;
+ s >> prio;
+ if(s.fail())
+ throw syntax_error(conf, conf.find_first_of(':')+1);
+
+ char buff[100];
+ if(s.good()) {
+ s.ignore(1);
+ s.get(buff, 100);
+ }
+ else
+ buff[0] = 0;
+
+ return add(targetTypeFromString(type), prio, buff);
+}
+
+LogTarget* LogTargetList::add(target_type_t type, int prio, std::string conf)
+{
+ switch(type) {
+ case TARGET_SYSLOG: {
+ #ifdef LOG_SYSLOG
+ if(!LogTargetSyslog::duplicateAllowed() && targets.count(TARGET_SYSLOG))
+ throw std::runtime_error(targetTypeToString(TARGET_SYSLOG) + " logtarget is supported only once");
+
+ return targets.insert(TargetsMap::value_type(TARGET_SYSLOG, new LogTargetSyslog(prio, conf)))->second;
+ #else
+ throw std::runtime_error(targetTypeToString(TARGET_SYSLOG) + " logtarget is not supported");
+ #endif
+ }
+ case TARGET_FILE: {
+ #ifdef LOG_FILE
+ if(!LogTargetFile::duplicateAllowed() && targets.count(TARGET_FILE))
+ throw std::runtime_error(targetTypeToString(TARGET_FILE) + " logtarget is supported only once");
+
+ return targets.insert(TargetsMap::value_type(TARGET_FILE, new LogTargetFile(prio, conf)))->second;
+ #else
+ throw std::runtime_error(targetTypeToString(TARGET_FILE) + " logtarget is not supported");
+ #endif
+ }
+ case TARGET_STDOUT:
+ case TARGET_STDERR: {
+ #ifdef LOG_STDOUT
+ if(!LogTargetStdout::duplicateAllowed() && targets.count(type))
+ throw std::runtime_error(targetTypeToString(type) + " logtarget is supported only once");
+
+ if(type == TARGET_STDERR)
+ return targets.insert(TargetsMap::value_type(type, new LogTargetStdout(prio, std::cerr)))->second;
+ else
+ return targets.insert(TargetsMap::value_type(type, new LogTargetStdout(prio, std::cout)))->second;
+ #else
+ throw std::runtime_error(targetTypeToString(type) + " logtarget is not supported");
+ #endif
+ }
+ case TARGET_WINEVENTLOG: {
+ #ifdef LOG_WINEVENTLOG
+ if(!LogTargetSyslog::duplicateAllowed() && targets.count(TARGET_WINEVENTLOG))
+ throw std::runtime_error(targetTypeToString(TARGET_WINEVENTLOG) + " logtarget is supported only once");
+
+ return targets.insert(TargetsMap::value_type(TARGET_WINEVENTLOG, new LogTargetWinEventlog(prio, conf)))->second;
+ #else
+ throw std::runtime_error(targetTypeToString(TARGET_WINEVENTLOG) + " logtarget is not supported");
+ #endif
+ }
+ default:
+ throw std::runtime_error("unknown log target");
+ }
+}
+
+void LogTargetList::clear()
+{
+ TargetsMap::iterator it;
+ for(it = targets.begin(); it != targets.end(); ++it)
+ delete it->second;
+ targets.clear();
+}
+
+void LogTargetList::log(std::string msg, int prio)
+{
+ TargetsMap::const_iterator it;
+ for(it = targets.begin(); it != targets.end(); ++it) {
+ if(it->second->isEnabled() && it->second->getMaxPrio() >= prio)
+ it->second->log(msg, prio);
+ }
+}
+
+
+#ifdef LOG_SYSLOG
+int LogTargetSyslog::facilityFromString(std::string fac)
+{
+ if(fac == "user") return FAC_USER;
+ if(fac == "mail") return FAC_MAIL;
+ if(fac == "daemon") return FAC_DAEMON;
+ if(fac == "auth") return FAC_AUTH;
+ if(fac == "syslog") return FAC_SYSLOG;
+ if(fac == "lpr") return FAC_LPR;
+ if(fac == "news") return FAC_NEWS;
+ if(fac == "uucp") return FAC_UUCP;
+ if(fac == "cron") return FAC_CRON;
+ if(fac == "authpriv") return FAC_AUTHPRIV;
+ if(fac == "ftp") return FAC_FTP;
+ if(fac == "local0") return FAC_LOCAL0;
+ if(fac == "local1") return FAC_LOCAL1;
+ if(fac == "local2") return FAC_LOCAL2;
+ if(fac == "local3") return FAC_LOCAL3;
+ if(fac == "local4") return FAC_LOCAL4;
+ if(fac == "local5") return FAC_LOCAL5;
+ if(fac == "local6") return FAC_LOCAL6;
+ if(fac == "local7") return FAC_LOCAL7;
+
+ throw std::runtime_error("unknown syslog facility");
+}
+
+std::string LogTargetSyslog::facilityToString(int fac)
+{
+ switch(fac) {
+ case FAC_USER: return "user";
+ case FAC_MAIL: return "mail";
+ case FAC_DAEMON: return "daemon";
+ case FAC_AUTH: return "auth";
+ case FAC_SYSLOG: return "syslog";
+ case FAC_LPR: return "lpr";
+ case FAC_NEWS: return "news";
+ case FAC_UUCP: return "uucp";
+ case FAC_CRON: return "cron";
+ case FAC_AUTHPRIV: return "authpriv";
+ case FAC_FTP: return "ftp";
+ case FAC_LOCAL0: return "local0";
+ case FAC_LOCAL1: return "local1";
+ case FAC_LOCAL2: return "local2";
+ case FAC_LOCAL3: return "local3";
+ case FAC_LOCAL4: return "local4";
+ case FAC_LOCAL5: return "local5";
+ case FAC_LOCAL6: return "local6";
+ case FAC_LOCAL7: return "local7";
+ default: throw std::runtime_error("unknown syslog facility");
+ }
+}
+
+LogTargetSyslog::LogTargetSyslog(int prio, std::string conf) : LogTarget(prio)
+{
+ std::stringstream s(conf);
+ facility = FAC_DAEMON;
+ getline(s, logname, ',');
+ if(s.fail()) {
+ logname = "anytun";
+ return;
+ }
+ std::string fac;
+ getline(s, fac, ',');
+ if(s.fail())
+ return;
+
+ facility = LogTargetSyslog::facilityFromString(fac);
+}
+
+LogTargetSyslog::~LogTargetSyslog()
+{
+ if(opened)
+ close();
+}
+
+void LogTargetSyslog::open()
+{
+ openlog(logname.c_str(), LOG_PID, facility);
+ opened = true;
+}
+
+void LogTargetSyslog::close()
+{
+ closelog();
+ opened = false;
+}
+
+void LogTargetSyslog::log(std::string msg, int prio)
+{
+ if(!opened)
+ return;
+
+ syslog(prio | facility, "%s", msg.c_str());
+}
+
+LogTargetSyslog& LogTargetSyslog::setLogName(std::string l)
+{
+ logname = l;
+ if(opened)
+ close();
+ open();
+ return *this;
+}
+
+LogTargetSyslog& LogTargetSyslog::setFacility(int f)
+{
+ facility = f;
+ if(opened)
+ close();
+ open();
+ return *this;
+}
+#endif
+
+
+#ifdef LOG_FILE
+LogTargetFile::LogTargetFile(int prio, std::string conf) : LogTarget(prio)
+{
+ std::stringstream s(conf);
+ getline(s, logfilename, ',');
+ if(s.fail())
+ logfilename = "anytun.log";
+}
+
+LogTargetFile::~LogTargetFile()
+{
+ if(opened)
+ close();
+}
+
+void LogTargetFile::open()
+{
+ logfile.open(logfilename.c_str(), std::fstream::out | std::fstream::app);
+ opened = logfile.is_open();
+}
+
+void LogTargetFile::close()
+{
+ if(logfile.is_open())
+ logfile.close();
+ opened = false;
+}
+
+void LogTargetFile::log(std::string msg, int prio)
+{
+ if(!opened)
+ return;
+
+ logfile << Log::prioToString(prio) << ": " << msg << std::endl;
+}
+
+LogTargetFile& LogTargetFile::setLogFilename(std::string l)
+{
+ logfilename = l;
+ if(opened)
+ close();
+ open();
+ return *this;
+}
+#endif
+
+
+#ifdef LOG_STDOUT
+LogTargetStdout::LogTargetStdout(int prio, std::ostream& s) : LogTarget(prio), stream(s)
+{
+}
+
+LogTargetStdout::~LogTargetStdout()
+{
+ if(opened)
+ close();
+}
+
+void LogTargetStdout::open()
+{
+ opened = true;
+}
+
+void LogTargetStdout::close()
+{
+ opened = false;
+}
+
+void LogTargetStdout::log(std::string msg, int prio)
+{
+ if(!opened)
+ return;
+
+ stream << "LOG-" << Log::prioToString(prio) << ": " << msg << std::endl;
+}
+#endif
+
+
+#ifdef LOG_WINEVENTLOG
+LogTargetWinEventlog::LogTargetWinEventlog(int prio, std::string conf) : LogTarget(prio)
+{
+ std::stringstream s(conf);
+ getline(s, logname, ',');
+ if(s.fail())
+ logname = "anytun";
+}
+
+LogTargetWinEventlog::~LogTargetWinEventlog()
+{
+ if(opened)
+ close();
+}
+
+void LogTargetWinEventlog::open()
+{
+ h_event_source = RegisterEventSourceA(NULL, logname.c_str());
+ if(h_event_source)
+ opened = true;
+}
+
+void LogTargetWinEventlog::close()
+{
+ if(h_event_source)
+ DeregisterEventSource(h_event_source);
+ opened = false;
+}
+
+void LogTargetWinEventlog::log(std::string msg, int prio)
+{
+ if(!opened)
+ return;
+
+ LPCTSTR lpszStrings[1];
+ CHAR buffer[STERROR_TEXT_MAX];
+ StringCchPrintfA(buffer, STERROR_TEXT_MAX, "%s", msg.c_str());
+ lpszStrings[0] = buffer;
+ if(log.h_event_source)
+ ReportEventA(log.h_event_source_, Log::prioToEventLogType(prio), 0, prio, NULL, 1, 0, lpszStrings, NULL);
+}
+
+LogTargetEventlog& LogTargetWinEventlog::setLogName(std::string l)
+{
+ logname = l;
+ if(opened)
+ close();
+ open();
+ return *this;
+}
+
+WORD LogTargetWinEventlog::prioToEventLogType(int prio)
+{
+ switch(prio) {
+ case PRIO_EMERG: return EVENTLOG_ERROR_TYPE;
+ case PRIO_ALERT: return EVENTLOG_ERROR_TYPE;
+ case PRIO_CRIT: return EVENTLOG_ERROR_TYPE;
+ case PRIO_ERR: return EVENTLOG_ERROR_TYPE;
+ case PRIO_WARNING: return EVENTLOG_WARNING_TYPE;
+ case PRIO_NOTICE: return EVENTLOG_INFORMATION_TYPE;
+ case PRIO_INFO: return EVENTLOG_SUCCESS;
+ case PRIO_DEBUG: return EVENTLOG_INFORMATION_TYPE;
+ default: return EVENTLOG_ERROR_TYPE;
+ }
+}
+#endif
diff --git a/src/logTargets.h b/src/logTargets.h
new file mode 100644
index 0000000..4f249d4
--- /dev/null
+++ b/src/logTargets.h
@@ -0,0 +1,200 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl,
+ * Christian Pointner <satp@wirdorange.org>
+ *
+ * This file is part of Anytun.
+ *
+ * Anytun is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Anytun 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 anytun. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _LOG_TARGETS_H_
+#define _LOG_TARGETS_H_
+
+#include <string>
+#include <map>
+
+#ifdef LOG_SYSLOG
+#include <syslog.h>
+#endif
+
+#ifdef LOG_FILE
+#include <fstream>
+#endif
+
+class LogTarget
+{
+public:
+ LogTarget();;
+ LogTarget(int prio);
+
+ virtual void open() = 0;
+ virtual void close() = 0;
+ bool isOpen() { return opened; };
+
+ void enable() { enabled = true; };
+ void disable() { enabled = false; };
+ bool isEnabled() { return enabled; };
+
+ int getMaxPrio() { return max_prio; };
+ void setMaxPrio(int p) { max_prio = p; };
+
+ virtual void log(std::string msg, int prio) = 0;
+
+protected:
+ bool opened;
+ bool enabled;
+ int max_prio;
+};
+
+class LogTargetList
+{
+public:
+ typedef enum { TARGET_UNKNOWN, TARGET_SYSLOG, TARGET_FILE,
+ TARGET_STDOUT, TARGET_STDERR, TARGET_WINEVENTLOG } target_type_t;
+
+ static target_type_t targetTypeFromString(std::string type);
+ static std::string targetTypeToString(target_type_t type);
+
+ ~LogTargetList();
+ LogTarget* add(std::string conf);
+ LogTarget* add(target_type_t type, int prio, std::string conf);
+ void clear();
+
+ void log(std::string msg, int prio);
+
+private:
+ typedef std::multimap<target_type_t, LogTarget*> TargetsMap;
+ TargetsMap targets;
+};
+
+
+#ifdef LOG_SYSLOG
+class LogTargetSyslog : public LogTarget
+{
+public:
+ static const int FAC_USER = LOG_USER;
+ static const int FAC_MAIL = LOG_MAIL;
+ static const int FAC_DAEMON = LOG_DAEMON;
+ static const int FAC_AUTH = LOG_AUTH;
+ static const int FAC_SYSLOG = LOG_SYSLOG;
+ static const int FAC_LPR = LOG_LPR;
+ static const int FAC_NEWS = LOG_NEWS;
+ static const int FAC_UUCP = LOG_UUCP;
+ static const int FAC_CRON = LOG_CRON;
+ static const int FAC_AUTHPRIV = LOG_AUTHPRIV;
+ static const int FAC_FTP = LOG_FTP;
+ static const int FAC_LOCAL0 = LOG_LOCAL0;
+ static const int FAC_LOCAL1 = LOG_LOCAL1;
+ static const int FAC_LOCAL2 = LOG_LOCAL2;
+ static const int FAC_LOCAL3 = LOG_LOCAL3;
+ static const int FAC_LOCAL4 = LOG_LOCAL4;
+ static const int FAC_LOCAL5 = LOG_LOCAL5;
+ static const int FAC_LOCAL6 = LOG_LOCAL6;
+ static const int FAC_LOCAL7 = LOG_LOCAL7;
+
+ static int facilityFromString(std::string fac);
+ static std::string facilityToString(int fac);
+
+ LogTargetSyslog(int prio, std::string conf);
+ ~LogTargetSyslog();
+
+ void open();
+ void close();
+ void log(std::string msg, int prio);
+ static bool duplicateAllowed() { return false; };
+
+ LogTargetSyslog& setLogName(std::string l);
+ std::string getLogName() const { return logname; }
+ LogTargetSyslog& setFacility(int f);
+ int getFacility() const { return facility; }
+
+private:
+ std::string logname;
+ int facility;
+};
+#endif
+
+#ifdef LOG_FILE
+class LogTargetFile : public LogTarget
+{
+public:
+ LogTargetFile(int prio, std::string conf);
+ ~LogTargetFile();
+
+ void open();
+ void close();
+ void log(std::string msg, int prio);
+ static bool duplicateAllowed() { return true; };
+
+ LogTargetFile& setLogFilename(std::string l);
+ std::string getLogFilename() const { return logfilename; }
+
+private:
+ std::string logfilename;
+ std::ofstream logfile;
+};
+#endif
+
+#ifdef LOG_STDOUT
+class LogTargetStdout : public LogTarget
+{
+public:
+ LogTargetStdout(int prio, std::ostream& s);
+ ~LogTargetStdout();
+
+ void open();
+ void close();
+ void log(std::string msg, int prio);
+ static bool duplicateAllowed() { return false; };
+
+private:
+ std::ostream& stream;
+};
+#endif
+
+#ifdef LOG_WINEVENTLOG
+class LogTargetWinEventlog : public LogTarget
+{
+public:
+ LogTargetWinEventlog(int prio, std::string conf);
+ ~LogTargetWinEventlog();
+
+ void open();
+ void close();
+ void log(std::string msg, int prio);
+ static bool duplicateAllowed() { return false; };
+
+ LogTargetWinEventlog& setLogName(std::string l);
+ std::string getLogName() const { return logname; }
+
+private:
+ static WORD prioToEventLogType(int prio);
+
+ std::string logname;
+ HANDLE h_event_source;
+};
+#endif
+
+#endif