File: main.cpp

package info (click to toggle)
libksysguard 4%3A6.5.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,596 kB
  • sloc: cpp: 13,691; xml: 297; sh: 23; makefile: 11
file content (92 lines) | stat: -rw-r--r-- 2,600 bytes parent folder | download
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;
}