File indexing completed on 2024-06-23 05:27:54
0001 /* 0002 SPDX-FileCopyrightText: 2019 Arjen Hiemstra <ahiemstra@heimr.nl> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include <atomic> 0008 #include <csignal> 0009 #include <iomanip> 0010 #include <iostream> 0011 #include <thread> 0012 0013 #include <getopt.h> 0014 0015 #include "Accumulator.h" 0016 #include "Capture.h" 0017 #include "ConnectionMapping.h" 0018 #include "Packet.h" 0019 #include "TimeStamps.h" 0020 0021 static std::atomic_bool g_running{false}; 0022 0023 int main(int argc, char **argv) 0024 { 0025 static struct option long_options[] = { 0026 {"help", 0, nullptr, 'h'}, 0027 {"stats", 0, nullptr, 's'}, 0028 {nullptr, 0, nullptr, 0}, 0029 }; 0030 0031 auto statsRequested = false; 0032 auto optionIndex = 0; 0033 auto option = -1; 0034 while ((option = getopt_long(argc, argv, "", long_options, &optionIndex)) != -1) { 0035 switch (option) { 0036 case 's': 0037 statsRequested = true; 0038 break; 0039 default: 0040 std::cerr << "Usage: " << argv[0] << " [options]\n"; 0041 std::cerr << "This is a helper application for tracking per-process network usage.\n"; 0042 std::cerr << "\n"; 0043 std::cerr << "Options:\n"; 0044 std::cerr << " --stats Print packet capture statistics.\n"; 0045 std::cerr << " --help Display this help.\n"; 0046 return 0; 0047 } 0048 } 0049 0050 auto mapping = std::make_shared<ConnectionMapping>(); 0051 0052 auto capture = std::make_shared<Capture>(); 0053 if (!capture->start()) { 0054 std::cerr << capture->lastError() << std::endl; 0055 return 1; 0056 } 0057 0058 auto accumulator = std::make_shared<Accumulator>(capture, mapping); 0059 0060 signal(SIGINT, [](int) { 0061 g_running = false; 0062 }); 0063 signal(SIGTERM, [](int) { 0064 g_running = false; 0065 }); 0066 0067 g_running = true; 0068 while (g_running) { 0069 auto data = accumulator->data(); 0070 auto timeStamp = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); 0071 0072 if (statsRequested != 0) { 0073 capture->reportStatistics(); 0074 } 0075 0076 if (data.empty()) { 0077 std::cout << std::put_time(std::localtime(&timeStamp), "%T") << std::endl; 0078 } else { 0079 for (auto itr = data.begin(); itr != data.end(); ++itr) { 0080 std::cout << std::put_time(std::localtime(&timeStamp), "%T"); 0081 std::cout << "|PID|" << (*itr).first << "|IN|" << (*itr).second.first << "|OUT|" << (*itr).second.second; 0082 std::cout << std::endl; 0083 } 0084 } 0085 0086 std::this_thread::sleep_for(std::chrono::seconds(1)); 0087 } 0088 0089 return 0; 0090 }