#include "include/capture/pcapCapture.hpp" #include #include #include #include "include/cli/filter.hpp" #include #include #include #include "include/cli/argsParse.hpp" #include "include/TUI/view.hpp" #define SNAP_LEN 1518 int main(int argc, char **argv) { /* initialize capture */ PcapCapture capture; capture.initialize(); /* initialize stats */ Stats stats; /* initializing the command line parser */ argsParser parser(argc, argv); /* check helper flags */ if (parser.vm.contains("help")) { parser.print_help(); return 0; } if (parser.vm.contains("interfaces")) { capture.print_interfaces(); return 0; } /* take the arguments of the flags into variables */ std::string interface = parser.vm["interface"].as(); int count = parser.vm["count"].as(); int limit = parser.vm["limit"].as(); int time = parser.vm["time"].as(); std::string filterString = ""; /* get a filter, use vector for multiple */ std::vector filters; if (parser.vm.contains("filter")) { auto& f = parser.vm["filter"].as>(); for (auto& x : f) { filters.push_back(parse(x)); filterString += x + " "; } } /* converting the filter to a pcap readable string */ std::string expression = get_bpf_filter(filters); bool isOffline = parser.vm.contains("offline"); /* set the flags to capture engine */ capture.set_capabilities(interface, count, expression, limit, &stats); std::atomic capture_finished = false; /* if we capture packets offline, we read the file in full, then print the result */ if (isOffline) { capture.start_offline(parser.vm["offline"].as()); /* full recalculation of statistics after file processing */ stats.update_packets(); stats.update_application_stats(); stats.update_transport_stats(); stats.update_ip_stats(10); stats.update_pairs(); stats.update_bandwidth(); } /* otherwise start live capture */ else { capture.start(); } /* UI */ using namespace ftxui; auto screen = ScreenInteractive::Fullscreen(); /* our class for UI */ View view; /* timer */ std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); std::chrono::seconds timer{0}; auto renderer = Renderer([&] { auto snapshot = stats.snapshot; return view.render(snapshot, interface, filterString, capture_finished, timer); }); auto component = CatchEvent(renderer, [&](Event e) { if (e == Event::Character('q') || e == Event::Escape) { capture.stop(); screen.Exit(); } return true; }); std::thread updater; if (!isOffline) { updater = std::thread([&] { while (capture.isRunning()) { stats.update_packets(); stats.update_application_stats(); stats.update_transport_stats(); stats.update_ip_stats(10); stats.update_pairs(); stats.update_bandwidth(); screen.PostEvent(Event::Custom); std::this_thread::sleep_for(std::chrono::milliseconds(300)); auto current_time = std::chrono::steady_clock::now(); timer = std::chrono::duration_cast( current_time - begin); if (timer >= std::chrono::seconds(time)) break; } capture_finished = true; screen.PostEvent(Event::Custom); }); } screen.Loop(component); if (updater.joinable()) updater.join(); /* check export flags */ if (parser.vm.contains("csv")) { stats.export_csv(parser.vm["csv"].as()); } if (parser.vm.contains("json")) { stats.export_json(parser.vm["json"].as()); } return 0; }