netvu-Netview/netvu/src/netvu.cpp
2021-01-31 13:53:41 +01:00

232 lines
6.3 KiB
C++

#include <algorithm>
#include <csignal>
#include <cstdint>
#include <cstdlib>
#include <exception>
#include <filesystem>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
#include <boost/program_options.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/value_semantic.hpp>
#include <boost/program_options/variables_map.hpp>
#include "netvuconfig.h"
#ifdef USE_SCANNER
# include "Scanner.h"
#endif
#ifdef USE_ANALYZER
# include "Analyzer.h"
#endif
#ifdef USE_SERVER
# include "Server.h"
#endif
std::string launchMode;
void signalHandler(int signal);
int main(int argc, char **argv) {
namespace po = boost::program_options;
namespace fs = std::filesystem;
po::options_description desc("Allowed options");
desc.add_options()
(
"help,h",
"print usage information and exit"
)
(
"config,c",
po::value<std::string>()->default_value("netvu.conf")->required(),
"alternative config file"
);
po::options_description config("Configuration");
config.add_options()
(
"mode,m",
po::value<std::string>(),
"runtime mode - scanner/analyzer/server"
);
po::options_description scannerConfig("Scanner");
scannerConfig.add_options()
(
"scanner.interface,i",
po::value<std::string>(),
"wireless interface"
)
(
"scanner.channels,C",
po::value< std::vector<std::string> >()->composing()->multitoken(),
"space separated 802.11 channels numbers"
)
(
"scanner.max_packets,M",
po::value< std::string >()->default_value("0"),
"packet capture limit"
)
(
"scanner.log_dir,l",
po::value<std::string>()->default_value("log")->required(),
"where to save captured packets"
)
(
"scanner.channel_hop_interval,I",
po::value<std::string>()->default_value("300")->required(),
"channel hop interval in milliseconds"
);
config.add(scannerConfig);
po::options_description analyzerConfig("Analyzer");
analyzerConfig.add_options()
(
"analyzer.log_dir,L",
po::value<std::string>()->default_value("log"),
"where captured packets are stored"
)
(
"analyzer.database_dir,D",
po::value<std::string>()->default_value("db"),
"where to save analisys result"
);
config.add(analyzerConfig);
po::options_description serverConfig("Server");
serverConfig.add_options()
(
"server.address,a",
po::value<std::string>()->default_value("0.0.0.0"),
"listening address"
)
(
"server.port,p",
po::value<std::string>()->default_value("9000"),
"listening port"
)
(
"server.database_dir,d",
po::value<std::string>()->default_value("db"),
"where analisys result is stored"
)
(
"server.cors,o",
po::value<std::string>()->default_value("*"),
"access control allow origin"
);
config.add(serverConfig);
desc.add(config);
try {
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
if (fs::exists(vm["config"].as<std::string>())) {
po::store(
po::parse_config_file(vm["config"].as<std::string>().data(), config),
vm
);
}
po::notify(vm);
if (vm.count("help")) {
std::cout << desc << "\n";
return EXIT_SUCCESS;
}
std::signal(SIGINT, signalHandler);
if (!vm.count("mode")) {
std::cout << desc << "\n";
return EXIT_SUCCESS;
}
auto mode = vm["mode"].as<std::string>();
if (mode == "scanner") {
#ifdef USE_SCANNER
std::cout << "Starting scanner\n";
launchMode = "scanner";
std::string interface;
if (vm.count("scanner.interface")) {
interface = vm["scanner.interface"].as<std::string>();
}
std::vector<std::string> channels;
if (vm.count("scanner.channels")) {
channels = vm["scanner.channels"].as<std::vector<std::string>>();
}
auto maxPackets = vm["scanner.max_packets"].as<std::string>();
auto logDir = vm["scanner.log_dir"].as<std::string>();
auto channelHopInterval = vm["scanner.channel_hop_interval"].as<std::string>();
auto wifiScanner = Scanner::WifiScanner(
interface,
channels,
maxPackets,
logDir,
channelHopInterval
);
wifiScanner.start();
#else
throw std::runtime_error("Netvu was compiled without Scanner support");
#endif
} else if (mode == "analyzer") {
#ifdef USE_ANALYZER
std::cout << "Starting analyzer\n";
launchMode = "analyzer";
auto logDir = vm["analyzer.log_dir"].as<std::string>();
auto databaseDir = vm["analyzer.database_dir"].as<std::string>();
auto pcapAnalyzer = Analyzer::PCAPAnalyzer(logDir, databaseDir);
pcapAnalyzer.start();
#else
throw std::runtime_error("Netvu was compiled without Analyzer support");
#endif
} else if (mode == "server") {
#ifdef USE_SERVER
std::cout << "Starting server\n";
launchMode = "server";
auto address = vm["server.address"].as<std::string>();
auto port = vm["server.port"].as<std::string>();
auto databaseDir = vm["server.database_dir"].as<std::string>();
auto cors = vm["server.cors"].as<std::string>();
auto httpServer = Server::HttpServer(databaseDir, address, port, cors);
httpServer.start();
#else
throw std::runtime_error("Netvu was compiled without Server support");
#endif
} else {
std::cerr << "Invalid runtime mode specified\n";
return EXIT_FAILURE;
}
} catch (const std::exception& ex) {
std::cerr << ex.what() << std::endl;
return EXIT_FAILURE;
}
}
void signalHandler(int signal) {
std::cout << "Stopping " + launchMode << '\n';
std::exit(2);
}