1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
/*
SPDX-FileCopyrightText: 2019 Arjen Hiemstra <ahiemstra@heimr.nl>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include <atomic>
#include <csignal>
#include <iomanip>
#include <iostream>
#include <thread>
#include <getopt.h>
#include "Accumulator.h"
#include "Capture.h"
#include "ConnectionMapping.h"
#include "Packet.h"
#include "TimeStamps.h"
static std::atomic_bool g_running{false};
int main(int argc, char **argv)
{
static struct option long_options[] = {
{"help", 0, nullptr, 'h'},
{"stats", 0, nullptr, 's'},
{nullptr, 0, nullptr, 0},
};
auto statsRequested = false;
auto optionIndex = 0;
auto option = -1;
while ((option = getopt_long(argc, argv, "", long_options, &optionIndex)) != -1) {
switch (option) {
case 's':
statsRequested = true;
break;
default:
std::cerr << "Usage: " << argv[0] << " [options]\n";
std::cerr << "This is a helper application for tracking per-process network usage.\n";
std::cerr << "\n";
std::cerr << "Options:\n";
std::cerr << " --stats Print packet capture statistics.\n";
std::cerr << " --help Display this help.\n";
return 0;
}
}
auto mapping = std::make_shared<ConnectionMapping>();
auto capture = std::make_shared<Capture>();
if (!capture->start()) {
std::cerr << capture->lastError() << std::endl;
return 1;
}
auto accumulator = std::make_shared<Accumulator>(capture, mapping);
signal(SIGINT, [](int) {
g_running = false;
});
signal(SIGTERM, [](int) {
g_running = false;
});
g_running = true;
while (g_running) {
auto data = accumulator->data();
auto timeStamp = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
if (statsRequested != 0) {
capture->reportStatistics();
}
if (data.empty()) {
std::cout << std::put_time(std::localtime(&timeStamp), "%T") << std::endl;
} else {
for (auto itr = data.begin(); itr != data.end(); ++itr) {
std::cout << std::put_time(std::localtime(&timeStamp), "%T");
std::cout << "|PID|" << (*itr).first << "|IN|" << (*itr).second.first << "|OUT|" << (*itr).second.second;
std::cout << std::endl;
}
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
capture->stop();
return 0;
}
|