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 methodes 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-2009 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/>.
35 #include "datatypes.h"
37 #include "logTargets.h"
39 #include "anytunError.h"
43 #ifdef LOG_WINEVENTLOG
48 #include <boost/date_time/posix_time/posix_time.hpp>
50 LogTarget::LogTarget() : opened(false), enabled(false), max_prio(Log::PRIO_NOTICE)
54 LogTarget::LogTarget(int prio) : opened(false), enabled(false), max_prio(prio)
58 LogTargetList::~LogTargetList()
63 LogTargetList::target_type_t LogTargetList::targetTypeFromString(std::string type)
65 if(type == "syslog") return TARGET_SYSLOG;
66 if(type == "file") return TARGET_FILE;
67 if(type == "stdout") return TARGET_STDOUT;
68 if(type == "stderr") return TARGET_STDERR;
69 if(type == "eventlog") return TARGET_WINEVENTLOG;
70 return TARGET_UNKNOWN;
73 std::string LogTargetList::targetTypeToString(target_type_t type)
76 case TARGET_SYSLOG: return "syslog";
77 case TARGET_FILE: return "file";
78 case TARGET_STDOUT: return "stdout";
79 case TARGET_STDERR: return "stderr";
80 case TARGET_WINEVENTLOG: return "eventlog";
81 default: return "unknown";
85 LogTarget* LogTargetList::add(std::string conf)
87 std::stringstream s(conf);
89 getline(s, type, ':');
91 throw syntax_error(conf, 0);
93 int prio = Log::PRIO_NOTICE;
96 throw syntax_error(conf, conf.find_first_of(':')+1);
102 throw syntax_error(conf, (s.tellg() > 0) ? static_cast<size_t>(s.tellg()) - 1 : 0);
108 return add(targetTypeFromString(type), prio, buff);
111 LogTarget* LogTargetList::add(target_type_t type, int prio, std::string conf)
114 case TARGET_SYSLOG: {
116 if(!LogTargetSyslog::duplicateAllowed() && targets.count(TARGET_SYSLOG))
117 AnytunError::throwErr() << targetTypeToString(TARGET_SYSLOG) << " logtarget is supported only once";
119 return targets.insert(TargetsMap::value_type(TARGET_SYSLOG, new LogTargetSyslog(prio, conf)))->second;
121 AnytunError::throwErr() << targetTypeToString(TARGET_SYSLOG) << " logtarget is not supported";
126 if(!LogTargetFile::duplicateAllowed() && targets.count(TARGET_FILE))
127 AnytunError::throwErr() << targetTypeToString(TARGET_FILE) << " logtarget is supported only once";
129 return targets.insert(TargetsMap::value_type(TARGET_FILE, new LogTargetFile(prio, conf)))->second;
131 AnytunError::throwErr() << targetTypeToString(TARGET_FILE) << " logtarget is not supported";
135 case TARGET_STDERR: {
137 if(!LogTargetStdout::duplicateAllowed() && targets.count(type))
138 AnytunError::throwErr() << targetTypeToString(type) << " logtarget is supported only once";
140 if(type == TARGET_STDERR)
141 return targets.insert(TargetsMap::value_type(type, new LogTargetStdout(prio, std::cerr)))->second;
143 return targets.insert(TargetsMap::value_type(type, new LogTargetStdout(prio, std::cout)))->second;
145 AnytunError::throwErr() << targetTypeToString(type) + " logtarget is not supported";
148 case TARGET_WINEVENTLOG: {
149 #ifdef LOG_WINEVENTLOG
150 if(!LogTargetWinEventlog::duplicateAllowed() && targets.count(TARGET_WINEVENTLOG))
151 AnytunError::throwErr() << targetTypeToString(TARGET_WINEVENTLOG) << " logtarget is supported only once";
153 return targets.insert(TargetsMap::value_type(TARGET_WINEVENTLOG, new LogTargetWinEventlog(prio, conf)))->second;
155 AnytunError::throwErr() << targetTypeToString(TARGET_WINEVENTLOG) << " logtarget is not supported";
159 AnytunError::throwErr() << "unknown log target";
164 void LogTargetList::clear()
166 TargetsMap::iterator it;
167 for(it = targets.begin(); it != targets.end(); ++it)
172 void LogTargetList::log(std::string msg, int prio)
174 TargetsMap::const_iterator it;
175 for(it = targets.begin(); it != targets.end(); ++it) {
176 if(it->second->isEnabled() && it->second->getMaxPrio() >= prio)
177 it->second->log(msg, prio);
183 int LogTargetSyslog::facilityFromString(std::string fac)
185 if(fac == "user") return FAC_USER;
186 if(fac == "mail") return FAC_MAIL;
187 if(fac == "daemon") return FAC_DAEMON;
188 if(fac == "auth") return FAC_AUTH;
189 if(fac == "syslog") return FAC_SYSLOG;
190 if(fac == "lpr") return FAC_LPR;
191 if(fac == "news") return FAC_NEWS;
192 if(fac == "uucp") return FAC_UUCP;
193 if(fac == "cron") return FAC_CRON;
194 if(fac == "authpriv") return FAC_AUTHPRIV;
195 if(fac == "ftp") return FAC_FTP;
196 if(fac == "local0") return FAC_LOCAL0;
197 if(fac == "local1") return FAC_LOCAL1;
198 if(fac == "local2") return FAC_LOCAL2;
199 if(fac == "local3") return FAC_LOCAL3;
200 if(fac == "local4") return FAC_LOCAL4;
201 if(fac == "local5") return FAC_LOCAL5;
202 if(fac == "local6") return FAC_LOCAL6;
203 if(fac == "local7") return FAC_LOCAL7;
205 AnytunError::throwErr() << "unknown syslog facility";
209 std::string LogTargetSyslog::facilityToString(int fac)
212 case FAC_USER: return "user";
213 case FAC_MAIL: return "mail";
214 case FAC_DAEMON: return "daemon";
215 case FAC_AUTH: return "auth";
216 case FAC_SYSLOG: return "syslog";
217 case FAC_LPR: return "lpr";
218 case FAC_NEWS: return "news";
219 case FAC_UUCP: return "uucp";
220 case FAC_CRON: return "cron";
221 case FAC_AUTHPRIV: return "authpriv";
222 case FAC_FTP: return "ftp";
223 case FAC_LOCAL0: return "local0";
224 case FAC_LOCAL1: return "local1";
225 case FAC_LOCAL2: return "local2";
226 case FAC_LOCAL3: return "local3";
227 case FAC_LOCAL4: return "local4";
228 case FAC_LOCAL5: return "local5";
229 case FAC_LOCAL6: return "local6";
230 case FAC_LOCAL7: return "local7";
231 default: AnytunError::throwErr() << "unknown syslog facility";
236 LogTargetSyslog::LogTargetSyslog(int prio, std::string conf) : LogTarget(prio)
238 std::stringstream s(conf);
239 facility = FAC_DAEMON;
240 getline(s, logname, ',');
246 getline(s, fac, ',');
250 facility = LogTargetSyslog::facilityFromString(fac);
253 LogTargetSyslog::~LogTargetSyslog()
259 void LogTargetSyslog::open()
261 openlog(logname.c_str(), LOG_PID, facility);
265 void LogTargetSyslog::close()
271 void LogTargetSyslog::log(std::string msg, int prio)
276 syslog((prio + 2) | facility, "%s", msg.c_str());
279 LogTargetSyslog& LogTargetSyslog::setLogName(std::string l)
288 LogTargetSyslog& LogTargetSyslog::setFacility(int f)
300 LogTargetFile::LogTargetFile(int prio, std::string conf) : LogTarget(prio)
302 std::stringstream s(conf);
303 getline(s, logfilename, ',');
305 logfilename = "anytun.log";
308 LogTargetFile::~LogTargetFile()
314 void LogTargetFile::open()
316 logfile.open(logfilename.c_str(), std::fstream::out | std::fstream::app);
317 opened = logfile.is_open();
320 void LogTargetFile::close()
322 if(logfile.is_open())
327 void LogTargetFile::log(std::string msg, int prio)
332 std::string timestamp = boost::posix_time::to_simple_string(boost::posix_time::second_clock::local_time());
333 logfile << timestamp << " " << Log::prioToString(prio) << ": " << msg << std::endl;
336 LogTargetFile& LogTargetFile::setLogFilename(std::string l)
348 LogTargetStdout::LogTargetStdout(int prio, std::ostream& s) : LogTarget(prio), stream(s)
352 LogTargetStdout::~LogTargetStdout()
358 void LogTargetStdout::open()
363 void LogTargetStdout::close()
368 void LogTargetStdout::log(std::string msg, int prio)
373 std::string timestamp = boost::posix_time::to_simple_string(boost::posix_time::second_clock::local_time());
374 stream << timestamp << " " << Log::prioToString(prio) << ": " << msg << std::endl;
379 #ifdef LOG_WINEVENTLOG
380 LogTargetWinEventlog::LogTargetWinEventlog(int prio, std::string conf) : LogTarget(prio)
382 std::stringstream s(conf);
383 getline(s, logname, ',');
388 LogTargetWinEventlog::~LogTargetWinEventlog()
394 void LogTargetWinEventlog::open()
396 h_event_source = RegisterEventSourceA(NULL, logname.c_str());
401 void LogTargetWinEventlog::close()
404 DeregisterEventSource(h_event_source);
408 void LogTargetWinEventlog::log(std::string msg, int prio)
413 LPCTSTR lpszStrings[1];
414 CHAR buffer[STERROR_TEXT_MAX];
415 StringCchPrintfA(buffer, STERROR_TEXT_MAX, "%s", msg.c_str());
416 lpszStrings[0] = buffer;
418 ReportEventA(h_event_source, prioToEventLogType(prio), 0, prio, NULL, 1, 0, lpszStrings, NULL);
421 LogTargetWinEventlog& LogTargetWinEventlog::setLogName(std::string l)
430 WORD LogTargetWinEventlog::prioToEventLogType(int prio)
433 case Log::PRIO_ERROR: return EVENTLOG_ERROR_TYPE;
434 case Log::PRIO_WARNING: return EVENTLOG_WARNING_TYPE;
435 case Log::PRIO_NOTICE: return EVENTLOG_INFORMATION_TYPE;
436 case Log::PRIO_INFO: return EVENTLOG_SUCCESS;
437 case Log::PRIO_DEBUG: return EVENTLOG_INFORMATION_TYPE;
438 default: return EVENTLOG_ERROR_TYPE;