📄 meter.cc
字号:
/*! \file Meter.cc Copyright 2003-2004 Fraunhofer Institute for Open Communication Systems (FOKUS), Berlin, Germany This file is part of Network Measurement and Accounting System (NETMATE). NETMATE 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 2 of the License, or (at your option) any later version. NETMATE 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 software; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Description: the main class $Id: Meter.cc,v 1.9 2006/02/01 07:47:20 s_zander Exp $*/#include "Meter.h"#include "ParserFcts.h"// globals in Meter classint Meter::s_sigpipe[2];int Meter::onlineCap = 1;int Meter::enableCtrl = 0;// global timeout flagint g_timeout = 0;/* version string embedded into executable file can be found via 'strings <path>/netmate | grep version'*/const char *NETMATE_VERSION = "NetMate version " VERSION ", (c) 2003-2004 Fraunhofer Institute FOKUS, Germany";const char *NETMATE_OPTIONS = "compile options: ""multi-threading support = "#ifdef ENABLE_THREADS"[YES]"#else"[NO]"#endif", secure sockets (SSL) support = "#ifdef USE_SSL"[YES]"#else"[NO]"#endif" ";// remove newline from end of C stringstatic inline char *noNewline( char* s ){ char *p = strchr( s, '\n' ); if (p != NULL) { *p = '\0'; } return s;}/* ------------------------- Meter ------------------------- */Meter::Meter( int argc, char *argv[]) : pprocThread(0), classThread(0), expThread(0){ // record meter start time for later output startTime = ::time(NULL); try { if (pipe((int *)&s_sigpipe) < 0) { throw Error("failed to create signal pipe"); } fdList[make_fd(s_sigpipe[0], FD_RD)] = NULL; // the read fd must not block fcntl(s_sigpipe[0], F_SETFL, O_NONBLOCK); // install signal handlers signal(SIGINT, sigint_handler); signal(SIGTERM, sigint_handler); signal(SIGUSR1, sigusr1_handler); signal(SIGALRM, sigalarm_handler); // FIXME sighup for log file rotation auto_ptr<CommandLineArgs> _args(new CommandLineArgs()); args = _args; // basic args args->add('c', "ConfigFile", "<file>", "use alternative config file", "MAIN", "configfile"); args->add('l', "LogFile", "<file>", "use alternative log file", "MAIN", "logfile"); args->add('r', "RuleFile", "<file>", "use specified rule file", "MAIN", "rulefile"); args->addFlag('V', "RelVersion", "show version info and exit", "MAIN", "version"); args->add('D', "FilterDefFile", "<file>", "use alternative file for filter definitions", "MAIN", "fdeffile"); args->add('C', "FilterConstFile", "<file>", "use alternative file for filter constants", "MAIN", "fcontfile");#ifdef USE_SSL args->addFlag('x', "UseSSL", "use SSL for control communication", "CONTROL", "usessl");#endif args->add('P', "ControlPort", "<portnumber>", "use alternative control port", "CONTROL", "cport");#ifndef ENABLE_NF#ifndef HAVE_LIBIPULOG_LIBIPULOG_H args->add('i', "NetInterface", "<iface>[,<iface2>,...]", "select network interface(s)" " to capture from", "MAIN", "interface"); args->add('f', "CaptureFile", "<file>[,<file2>,...]", "use capture file(s) to read" " packets from", "MAIN", "tracefile"); args->add('s', "SnapSize", "<size>", "specify packet snap size", "CLASSIFIER", "snapsize"); args->addFlag('p', "NoPromiscInt", "don't put interface in " "promiscuous mode", "MAIN", "nopromisc");#endif#endif#ifdef HAVE_ERF args->addFlag('L', "ERFLegacy", "read legacy ERF format", "MAIN", "erflegacy");#endif // get command line arguments from components via static method ClassifierSimple::add_args(args.get()); // parse command line args if (args->parseArgs(argc, argv)) { // user wanted help exit(0); } if (args->getArgValue('V') == "yes") { cout << getHelloMsg(); exit(0); } // test before registering the exit function if (alreadyRunning()) { throw Error("already running on this machine - terminating" ); } // register exit function atexit(exit_fct); auto_ptr<Logger> _log(Logger::getInstance()); log = _log; ch = log->createChannel("Meter"); log->log(ch,"Initializing netmate system"); log->log(ch,"Program executable = %s", argv[0]); log->log(ch,"Started at %s", noNewline(ctime(&startTime))); // parse config file configFileName = args->getArgValue('c'); if (configFileName.empty()) { // is no config file is given then use the default // file located in a relative location to the binary configFileName = DEFAULT_CONFIG_FILE; } auto_ptr<ConfigManager> _conf(new ConfigManager(configFileName, argv[0])); conf = _conf; // merge into config conf->mergeArgs(args->getArgList(), args->getArgVals()); // dont need this anymore CommandLineArgs *a = args.release(); saveDelete(a); // use logfilename (in order of precedence): // from command line / from config file / hardcoded default // query command line for log file name logFileName = conf->getValue("LogFile", "MAIN"); if (logFileName.empty()) { logFileName = DEFAULT_LOG_FILE; } log->setDefaultLogfile(logFileName); cout << "netmate logfile is: " << logFileName << endl; // set logging vebosity level if configured string verbosity = conf->getValue("VerboseLevel", "MAIN"); if (!verbosity.empty()) { log->setLogLevel( ParserFcts::parseInt( verbosity, -1, 4 ) ); } log->log(ch,"configfilename used is: '%s'", configFileName.c_str());#ifdef DEBUG log->dlog(ch,"------- startup -------" );#endif // startup other core classes auto_ptr<PerfTimer> _perf(PerfTimer::getInstance()); perf = _perf; auto_ptr<RuleManager> _rulm(new RuleManager(conf->getValue("FilterDefFile", "MAIN"), conf->getValue("FilterConstFile", "MAIN"))); rulm = _rulm; auto_ptr<EventScheduler> _evnt(new EventScheduler()); evnt = _evnt; // startup meter components#ifdef ENABLE_THREADS auto_ptr<Exporter> _expt(new Exporter(conf.get(), conf->isTrue("Thread", "EXPORTER"))); expThread = conf->isTrue("Thread", "EXPORTER"); auto_ptr<PacketProcessor> _proc(new PacketProcessor(conf.get(), conf->isTrue("Thread", "PKTPROCESSOR"))); pprocThread = conf->isTrue("Thread", "PKTPROCESSOR");#else auto_ptr<Exporter> _expt(new Exporter(conf.get(), 0)); auto_ptr<PacketProcessor> _proc(new PacketProcessor(conf.get(), 0)); pprocThread = 0; if (conf->isTrue("Thread", "EXPORTER") || conf->isTrue("Thread", "PKTPROCESSOR") || conf->isTrue("Thread", "CLASSIFIER")) { log->wlog(ch, "Threads enabled in config file but executable is compiled without thread support"); }#endif expt = _expt; proc = _proc; expt->mergeFDs(&fdList); proc->mergeFDs(&fdList); // give packet processor handle to Exporter proc->setExporter(expt.get()); // initialize sampler string smpl = conf->getValue("Sampling", "CLASSIFIER"); if ((smpl == "All") || (smpl.empty())) { auto_ptr<Sampler> _samp(new SamplerAll()); samp = _samp; } else { throw Error("Unknown sampling algorithm '%s' specified", smpl.c_str()); }#ifdef ENABLE_NF#ifdef HAVE_LIBIPULOG_LIBIPULOG_H clss = auto_ptr<Classifier>(new ClassifierNetfilter(conf.get(), 0));#endif#else // capture file overules device setting string cp = conf->getValue("CaptureFile", "MAIN"); string ni = cp.empty() ? conf->getValue("NetInterface", "MAIN") : cp; string sz = conf->getValue("SnapSize", "CLASSIFIER"); onlineCap = cp.empty() ? 1 : 0; Timeval::setCapMode(onlineCap); int snapsize = sz.empty() ? DEF_SNAPSIZE : atoi(sz.c_str()); int bsize = conf->getValue("RcvBufSize", "CLASSIFIER").empty() ? 65535 : atoi(conf->getValue("RcvBufSize", "CLASSIFIER").c_str()); string cl = conf->getValue("Algorithm", "CLASSIFIER"); string tt = conf->getValue("TapType", "CLASSIFIER");#ifdef ENABLE_THREADS classThread = conf->isTrue("Thread", "CLASSIFIER");#endif if ((cl == "Simple") || (cl.empty())) { auto_ptr<Classifier> _clss(new ClassifierSimple(conf.get(), samp.get(), proc->getQueue(), classThread)); clss = _clss; } else if (cl == "RFC") { auto_ptr<Classifier> _clss(new ClassifierRFC(conf.get(), samp.get(), proc->getQueue(), classThread)); clss = _clss; } else { throw Error("Unknown classifier '%s' specified", cl.c_str()); }#endif int p1 = 0, p2 = 0, last = 1, first = 1; while(((p2 = ni.find(",",p1)) > 0) || last) { NetTap *nett; if (p2 <= 0) { p2 = ni.length(); last = 0; } // FIXME remove leading/trailing spaces string dev = ni.substr(p1,p2-p1); if (onlineCap || first) { if (tt == "erf") {#ifdef HAVE_ERF if (conf->isTrue("ERFLegacy", "MAIN")) { nett = new NetTapERF(dev, onlineCap, conf->isFalse("NoPromiscInt", "MAIN"), snapsize, 1, bsize, 1); } else { nett = new NetTapERF(dev, onlineCap, conf->isFalse("NoPromiscInt", "MAIN"), snapsize, 1, bsize); }#else throw Error("No support for ERF");#endif } else { /* pcap by default */#ifdef ENABLE_THREADS nett = new NetTapPcap(dev, onlineCap, conf->isFalse("NoPromiscInt", "MAIN"), snapsize, !conf->isTrue("Thread", "CLASSIFIER"), bsize); #else nett = new NetTapPcap(dev, onlineCap, conf->isFalse("NoPromiscInt", "MAIN"), snapsize, 1, bsize);#endif } clss->registerTap(nett); first = 0; } else { // store remaining capture file names capFiles.push_back(dev); } p1 = p2+1; } clss->mergeFDs(&fdList); // setup initial rules string rfn = conf->getValue("RuleFile", "MAIN"); if (!rfn.empty()) { if (!onlineCap) { /* handle loading of rules from rule file _immediately_ (synchronous call) when reading from packet capture files since else we are missing packets at the start because the net tap delivers packets before we have installed the rules */ AddRulesEvent e = AddRulesEvent(rfn); handleEvent(&e, NULL); } else { // for live packet capture just schedule rule addition evnt->addEvent(new AddRulesEvent(rfn)); } } // disable logger threading if not needed if (!classThread && !pprocThread && !expThread) { log->setThreaded(0); } enableCtrl = conf->isTrue("Enable", "CONTROL"); if (!onlineCap) { // always disable enableCtrl = 0; } if (enableCtrl) { // ctrlcomm can never be a separate thread auto_ptr<CtrlComm> _comm(new CtrlComm(conf.get(), 0)); comm = _comm; comm->mergeFDs(&fdList); } } catch (Error &e) { if (log.get()) { log->elog(ch, e); } throw e; }}/* ------------------------- ~Meter ------------------------- */Meter::~Meter(){ // objects are destroyed by their auto ptrs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -