4 * The secure anycast tunneling protocol (satp) defines a protocol used
5 * for communication between any combination of unicast and anycast
6 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
7 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
8 * ethernet, ip, arp ...). satp directly includes cryptography and
9 * message authentication based on the methods used by SRTP. It is
10 * intended to deliver a generic, scaleable and secure solution for
11 * tunneling and relaying of packets of any protocol.
14 * Copyright (C) 2007-2014 Markus Grüneis, Othmar Gsenger, Erwin Nindl,
15 * Christian Pointner <satp@wirdorange.org>
17 * This file is part of Anytun.
19 * Anytun is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation, either version 3 of the License, or
24 * Anytun is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with Anytun. If not, see <http://www.gnu.org/licenses/>.
32 * In addition, as a special exception, the copyright holders give
33 * permission to link the code of portions of this program with the
34 * OpenSSL library under certain conditions as described in each
35 * individual source file, and distribute linked combinations
37 * You must obey the GNU General Public License in all respects
38 * for all of the code used other than OpenSSL. If you modify
39 * file(s) with this exception, you may extend this exception to your
40 * version of the file(s), but you are not obligated to do so. If you
41 * do not wish to do so, delete this exception statement from your
42 * version. If you delete this exception statement from all source
43 * files in the program, then also delete it here.
48 #include "datatypes.h"
50 #include "logTargets.h"
52 #include "anytunError.h"
56 #ifdef LOG_WINEVENTLOG
61 #include <boost/date_time/posix_time/posix_time.hpp>
63 LogTarget::LogTarget() : opened(false), enabled(false), max_prio(Log::PRIO_NOTICE)
67 LogTarget::LogTarget(int prio) : opened(false), enabled(false), max_prio(prio)
71 LogTargetList::~LogTargetList()
76 LogTargetList::target_type_t LogTargetList::targetTypeFromString(std::string type)
78 if(type == "syslog") { return TARGET_SYSLOG; }
79 if(type == "file") { return TARGET_FILE; }
80 if(type == "stdout") { return TARGET_STDOUT; }
81 if(type == "stderr") { return TARGET_STDERR; }
82 if(type == "eventlog") { return TARGET_WINEVENTLOG; }
83 return TARGET_UNKNOWN;
86 std::string LogTargetList::targetTypeToString(target_type_t type)
97 case TARGET_WINEVENTLOG:
104 LogTarget* LogTargetList::add(std::string conf)
106 std::stringstream s(conf);
108 getline(s, type, ':');
110 throw syntax_error(conf, 0);
113 int prio = Log::PRIO_NOTICE;
116 throw syntax_error(conf, conf.find_first_of(':')+1);
123 throw syntax_error(conf, (s.tellg() > 0) ? static_cast<size_t>(s.tellg()) - 1 : 0);
130 return add(targetTypeFromString(type), prio, buff);
133 LogTarget* LogTargetList::add(target_type_t type, int prio, std::string conf)
136 case TARGET_SYSLOG: {
138 if(!LogTargetSyslog::duplicateAllowed() && targets.count(TARGET_SYSLOG)) {
139 AnytunError::throwErr() << targetTypeToString(TARGET_SYSLOG) << " logtarget is supported only once";
142 return targets.insert(TargetsMap::value_type(TARGET_SYSLOG, new LogTargetSyslog(prio, conf)))->second;
144 AnytunError::throwErr() << targetTypeToString(TARGET_SYSLOG) << " logtarget is not supported";
149 if(!LogTargetFile::duplicateAllowed() && targets.count(TARGET_FILE)) {
150 AnytunError::throwErr() << targetTypeToString(TARGET_FILE) << " logtarget is supported only once";
153 return targets.insert(TargetsMap::value_type(TARGET_FILE, new LogTargetFile(prio, conf)))->second;
155 AnytunError::throwErr() << targetTypeToString(TARGET_FILE) << " logtarget is not supported";
159 case TARGET_STDERR: {
161 if(!LogTargetStdout::duplicateAllowed() && targets.count(type)) {
162 AnytunError::throwErr() << targetTypeToString(type) << " logtarget is supported only once";
165 if(type == TARGET_STDERR) {
166 return targets.insert(TargetsMap::value_type(type, new LogTargetStdout(prio, std::cerr)))->second;
168 return targets.insert(TargetsMap::value_type(type, new LogTargetStdout(prio, std::cout)))->second;
171 AnytunError::throwErr() << targetTypeToString(type) + " logtarget is not supported";
174 case TARGET_WINEVENTLOG: {
175 #ifdef LOG_WINEVENTLOG
176 if(!LogTargetWinEventlog::duplicateAllowed() && targets.count(TARGET_WINEVENTLOG)) {
177 AnytunError::throwErr() << targetTypeToString(TARGET_WINEVENTLOG) << " logtarget is supported only once";
180 return targets.insert(TargetsMap::value_type(TARGET_WINEVENTLOG, new LogTargetWinEventlog(prio, conf)))->second;
182 AnytunError::throwErr() << targetTypeToString(TARGET_WINEVENTLOG) << " logtarget is not supported";
186 AnytunError::throwErr() << "unknown log target";
191 void LogTargetList::clear()
193 TargetsMap::iterator it;
194 for(it = targets.begin(); it != targets.end(); ++it) {
200 void LogTargetList::log(std::string msg, int prio)
202 TargetsMap::const_iterator it;
203 for(it = targets.begin(); it != targets.end(); ++it) {
204 if(it->second->isEnabled() && it->second->getMaxPrio() >= prio) {
205 it->second->log(msg, prio);
212 int LogTargetSyslog::facilityFromString(std::string fac)
214 if(fac == "user") { return FAC_USER; }
215 if(fac == "mail") { return FAC_MAIL; }
216 if(fac == "daemon") { return FAC_DAEMON; }
217 if(fac == "auth") { return FAC_AUTH; }
218 if(fac == "syslog") { return FAC_SYSLOG; }
219 if(fac == "lpr") { return FAC_LPR; }
220 if(fac == "news") { return FAC_NEWS; }
221 if(fac == "uucp") { return FAC_UUCP; }
222 if(fac == "cron") { return FAC_CRON; }
223 if(fac == "authpriv") { return FAC_AUTHPRIV; }
224 if(fac == "ftp") { return FAC_FTP; }
225 if(fac == "local0") { return FAC_LOCAL0; }
226 if(fac == "local1") { return FAC_LOCAL1; }
227 if(fac == "local2") { return FAC_LOCAL2; }
228 if(fac == "local3") { return FAC_LOCAL3; }
229 if(fac == "local4") { return FAC_LOCAL4; }
230 if(fac == "local5") { return FAC_LOCAL5; }
231 if(fac == "local6") { return FAC_LOCAL6; }
232 if(fac == "local7") { return FAC_LOCAL7; }
234 AnytunError::throwErr() << "unknown syslog facility";
238 std::string LogTargetSyslog::facilityToString(int fac)
280 AnytunError::throwErr() << "unknown syslog facility";
285 LogTargetSyslog::LogTargetSyslog(int prio, std::string conf) : LogTarget(prio)
287 std::stringstream s(conf);
288 facility = FAC_DAEMON;
289 getline(s, logname, ',');
295 getline(s, fac, ',');
300 facility = LogTargetSyslog::facilityFromString(fac);
303 LogTargetSyslog::~LogTargetSyslog()
310 void LogTargetSyslog::open()
312 openlog(logname.c_str(), LOG_PID, facility);
316 void LogTargetSyslog::close()
322 void LogTargetSyslog::log(std::string msg, int prio)
328 syslog((prio + 2) | facility, "%s", msg.c_str());
331 LogTargetSyslog& LogTargetSyslog::setLogName(std::string l)
341 LogTargetSyslog& LogTargetSyslog::setFacility(int f)
354 LogTargetFile::LogTargetFile(int prio, std::string conf) : LogTarget(prio)
356 std::stringstream s(conf);
357 getline(s, logfilename, ',');
359 logfilename = "anytun.log";
363 LogTargetFile::~LogTargetFile()
370 void LogTargetFile::open()
372 logfile.open(logfilename.c_str(), std::fstream::out | std::fstream::app);
373 opened = logfile.is_open();
376 void LogTargetFile::close()
378 if(logfile.is_open()) {
384 void LogTargetFile::log(std::string msg, int prio)
390 std::string timestamp = boost::posix_time::to_simple_string(boost::posix_time::second_clock::local_time());
391 logfile << timestamp << " " << Log::prioToString(prio) << ": " << msg << std::endl;
394 LogTargetFile& LogTargetFile::setLogFilename(std::string l)
407 LogTargetStdout::LogTargetStdout(int prio, std::ostream& s) : LogTarget(prio), stream(s)
411 LogTargetStdout::~LogTargetStdout()
418 void LogTargetStdout::open()
423 void LogTargetStdout::close()
428 void LogTargetStdout::log(std::string msg, int prio)
434 std::string timestamp = boost::posix_time::to_simple_string(boost::posix_time::second_clock::local_time());
435 stream << timestamp << " " << Log::prioToString(prio) << ": " << msg << std::endl;
440 #ifdef LOG_WINEVENTLOG
441 LogTargetWinEventlog::LogTargetWinEventlog(int prio, std::string conf) : LogTarget(prio)
443 std::stringstream s(conf);
444 getline(s, logname, ',');
450 LogTargetWinEventlog::~LogTargetWinEventlog()
457 void LogTargetWinEventlog::open()
459 h_event_source = RegisterEventSourceA(NULL, logname.c_str());
465 void LogTargetWinEventlog::close()
468 DeregisterEventSource(h_event_source);
473 void LogTargetWinEventlog::log(std::string msg, int prio)
479 LPCTSTR lpszStrings[1];
480 CHAR buffer[STERROR_TEXT_MAX];
481 StringCchPrintfA(buffer, STERROR_TEXT_MAX, "%s", msg.c_str());
482 lpszStrings[0] = buffer;
484 ReportEventA(h_event_source, prioToEventLogType(prio), 0, prio, NULL, 1, 0, lpszStrings, NULL);
488 LogTargetWinEventlog& LogTargetWinEventlog::setLogName(std::string l)
498 WORD LogTargetWinEventlog::prioToEventLogType(int prio)
501 case Log::PRIO_ERROR:
502 return EVENTLOG_ERROR_TYPE;
503 case Log::PRIO_WARNING:
504 return EVENTLOG_WARNING_TYPE;
505 case Log::PRIO_NOTICE:
506 return EVENTLOG_INFORMATION_TYPE;
508 return EVENTLOG_SUCCESS;
509 case Log::PRIO_DEBUG:
510 return EVENTLOG_INFORMATION_TYPE;
512 return EVENTLOG_ERROR_TYPE;