Skip to content

Commit 8b62bff

Browse files
committed
fdsdump: introduce file statistics
1 parent c1465cd commit 8b62bff

File tree

13 files changed

+461
-2
lines changed

13 files changed

+461
-2
lines changed

src/tools/fdsdump/src/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
44
add_subdirectory(common)
55
add_subdirectory(lister)
66
add_subdirectory(aggregator)
7+
add_subdirectory(statistics)
78

89
add_executable(fdsdump
910
main.cpp
1011
options.cpp
1112
$<TARGET_OBJECTS:common_obj>
1213
$<TARGET_OBJECTS:lister_obj>
1314
$<TARGET_OBJECTS:aggregator_obj>
15+
$<TARGET_OBJECTS:statistics_obj>
1416
)
1517

1618
target_include_directories(fdsdump

src/tools/fdsdump/src/main.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <common/filelist.hpp>
1111
#include <lister/lister.hpp>
1212
#include <aggregator/mode.hpp>
13+
#include <statistics/mode.hpp>
1314

1415
#include "options.hpp"
1516

@@ -55,6 +56,9 @@ main(int argc, char *argv[])
5556
case Options::Mode::aggregate:
5657
aggregator::mode_aggregate(iemgr, options);
5758
break;
59+
case Options::Mode::stats:
60+
statistics::mode_statistics(iemgr, options);
61+
break;
5862
default:
5963
throw std::runtime_error("Invalid mode");
6064
}

src/tools/fdsdump/src/options.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ void Options::parse(int argc, char *argv[])
5757
{"no-biflow-autoignore", no_argument, NULL, OPT_BIFLOW_AUTOIGNORE_OFF},
5858
{0, 0, 0, 0},
5959
};
60-
const char *short_opts = "r:c:o:O:F:A:S:";
60+
const char *short_opts = "r:c:o:O:F:A:S:I";
6161
int opt;
6262

6363
while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
@@ -80,6 +80,9 @@ void Options::parse(int argc, char *argv[])
8080
case 'A':
8181
m_aggregation_keys = optarg;
8282
break;
83+
case 'I':
84+
m_mode = Mode::stats;
85+
break;
8386
case 'S':
8487
m_aggregation_fields = optarg;
8588
break;
@@ -101,7 +104,13 @@ void Options::parse(int argc, char *argv[])
101104

102105
void Options::validate()
103106
{
104-
if (!m_aggregation_keys.empty()) {
107+
if (m_mode == Mode::stats) {
108+
// File statistics
109+
if (m_output_specifier.empty()) {
110+
m_output_specifier = "table";
111+
}
112+
113+
} else if (!m_aggregation_keys.empty()) {
105114
// Record aggregation
106115
m_mode = Mode::aggregate;
107116

src/tools/fdsdump/src/options.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class Options {
3131
undefined,
3232
list,
3333
aggregate,
34+
stats,
3435
};
3536

3637
/**
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Create a common "statistics" library
2+
set(STATISTICS_SRC
3+
mode.cpp
4+
printer.cpp
5+
jsonPrinter.cpp
6+
tablePrinter.cpp
7+
)
8+
9+
add_library(statistics_obj OBJECT ${STATISTICS_SRC})
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
2+
#include <iostream>
3+
#include <stdexcept>
4+
#include <string>
5+
6+
#include "jsonPrinter.hpp"
7+
8+
namespace fdsdump {
9+
namespace statistics {
10+
11+
JsonPrinter::JsonPrinter(const std::string &args)
12+
{
13+
if (!args.empty()) {
14+
throw std::invalid_argument("JSON output: options are not supported");
15+
}
16+
}
17+
18+
JsonPrinter::~JsonPrinter()
19+
{
20+
}
21+
22+
void
23+
JsonPrinter::print_prologue()
24+
{
25+
}
26+
27+
void
28+
JsonPrinter::print_stats(const fds_file_stats &stats)
29+
{
30+
const uint64_t flows_total = stats.recs_total - stats.recs_opts_total;
31+
32+
std::cout << "{";
33+
34+
std::cout << "\"recs_total\":" << stats.recs_total << ",";
35+
std::cout << "\"recs_flow_total\":" << flows_total << ",";
36+
std::cout << "\"recs_bf_total\":" << stats.recs_bf_total << ",";
37+
std::cout << "\"recs_opts_total\":" << stats.recs_opts_total << ",";
38+
std::cout << "\"recs_tcp\":" << stats.recs_tcp << ",";
39+
std::cout << "\"recs_udp\":" << stats.recs_udp << ",";
40+
std::cout << "\"recs_icmp\":" << stats.recs_icmp << ",";
41+
std::cout << "\"recs_other\":" << stats.recs_other << ",";
42+
std::cout << "\"recs_bf_tcp\":" << stats.recs_bf_tcp << ",";
43+
std::cout << "\"recs_bf_udp\":" << stats.recs_bf_udp << ",";
44+
std::cout << "\"recs_bf_icmp\":" << stats.recs_bf_icmp << ",";
45+
std::cout << "\"recs_bf_other\":" << stats.recs_bf_other << ",";
46+
std::cout << "\"pkts_total\":" << stats.pkts_total << ",";
47+
std::cout << "\"pkts_tcp\":" << stats.pkts_tcp << ",";
48+
std::cout << "\"pkts_udp\":" << stats.pkts_udp << ",";
49+
std::cout << "\"pkts_icmp\":" << stats.pkts_icmp << ",";
50+
std::cout << "\"pkts_other\":" << stats.pkts_other << ",";
51+
std::cout << "\"bytes_total\":" << stats.bytes_total << ",";
52+
std::cout << "\"bytes_tcp\":" << stats.bytes_tcp << ",";
53+
std::cout << "\"bytes_udp\":" << stats.bytes_udp << ",";
54+
std::cout << "\"bytes_icmp\":" << stats.bytes_icmp << ",";
55+
std::cout << "\"bytes_other\":" << stats.bytes_other;
56+
57+
std::cout << "}\n";
58+
}
59+
60+
void
61+
JsonPrinter::print_epilogue()
62+
{
63+
}
64+
65+
} // statistics
66+
} // fdsdump
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
#pragma once
3+
4+
#include <string>
5+
#include "printer.hpp"
6+
7+
namespace fdsdump {
8+
namespace statistics {
9+
10+
class JsonPrinter : public Printer {
11+
public:
12+
JsonPrinter(const std::string &args);
13+
14+
virtual
15+
~JsonPrinter();
16+
17+
virtual void
18+
print_prologue() override;
19+
20+
virtual void
21+
print_stats(const fds_file_stats &stats) override;
22+
23+
virtual void
24+
print_epilogue() override;
25+
};
26+
27+
} // statistics
28+
} // fdsdump
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
2+
#include <iostream>
3+
4+
#include "common/flowProvider.hpp"
5+
6+
#include "mode.hpp"
7+
#include "printer.hpp"
8+
9+
namespace fdsdump {
10+
namespace statistics {
11+
12+
static void stats_merge(
13+
fds_file_stats &dst,
14+
const fds_file_stats &src)
15+
{
16+
dst.recs_total += src.recs_total;
17+
dst.recs_bf_total += src.recs_bf_total;
18+
dst.recs_opts_total += src.recs_opts_total;
19+
dst.bytes_total += src.bytes_total;
20+
dst.pkts_total += src.pkts_total;
21+
dst.recs_tcp += src.recs_tcp;
22+
dst.recs_udp += src.recs_udp;
23+
dst.recs_icmp += src.recs_icmp;
24+
dst.recs_other += src.recs_other;
25+
dst.recs_bf_tcp += src.recs_bf_tcp;
26+
dst.recs_bf_udp += src.recs_bf_udp;
27+
dst.recs_bf_icmp += src.recs_bf_icmp;
28+
dst.recs_bf_other += src.recs_bf_other;
29+
dst.bytes_tcp += src.bytes_tcp;
30+
dst.bytes_udp += src.bytes_udp;
31+
dst.bytes_icmp += src.bytes_icmp;
32+
dst.bytes_other += src.bytes_other;
33+
dst.pkts_tcp += src.pkts_tcp;
34+
dst.pkts_udp += src.pkts_udp;
35+
dst.pkts_icmp += src.pkts_icmp;
36+
dst.pkts_other += src.pkts_other;
37+
}
38+
39+
void
40+
mode_statistics(const shared_iemgr &iemgr, const Options &opts)
41+
{
42+
auto printer = printer_factory(opts.get_output_specifier());
43+
const FileList &file_names = opts.get_input_files();
44+
unique_file file {nullptr, &fds_file_close};
45+
fds_file_stats stats {};
46+
47+
file.reset(fds_file_init());
48+
if (!file) {
49+
throw std::runtime_error("fds_file_init() has failed");
50+
}
51+
52+
for (const auto &file_name : file_names) {
53+
const uint32_t flags = FDS_FILE_READ | FDS_FILE_NOASYNC;
54+
const fds_file_stats *file_stats;
55+
int ret;
56+
57+
ret = fds_file_open(file.get(), file_name.c_str(), flags);
58+
if (ret != FDS_OK) {
59+
const std::string err_msg = fds_file_error(file.get());
60+
std::cerr << "fds_file_open('" << file_name << "') failed: " << err_msg << std::endl;
61+
continue;
62+
}
63+
64+
file_stats = fds_file_stats_get(file.get());
65+
if (!file_stats) {
66+
std::cerr << "fds_file_stats_get('" << file_name << "') failed" << std::endl;
67+
continue;
68+
}
69+
70+
stats_merge(stats, *file_stats);
71+
}
72+
73+
printer->print_prologue();
74+
printer->print_stats(stats);
75+
printer->print_epilogue();
76+
77+
(void) iemgr;
78+
return;
79+
}
80+
81+
} // statistics
82+
} // fdsdump
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#pragma once
2+
3+
#include "common/common.hpp"
4+
#include "options.hpp"
5+
6+
namespace fdsdump {
7+
namespace statistics {
8+
9+
void
10+
mode_statistics(const shared_iemgr &iemgr, const Options &opts);
11+
12+
} // statistics
13+
} // fdsdump
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include <algorithm>
2+
#include <cassert>
3+
#include <functional>
4+
#include <stdexcept>
5+
#include <vector>
6+
7+
#include "printer.hpp"
8+
#include "jsonPrinter.hpp"
9+
#include "tablePrinter.hpp"
10+
11+
namespace fdsdump {
12+
namespace statistics {
13+
14+
struct PrinterFactory {
15+
const char *name;
16+
std::function<Printer *(const std::string &)> create_fn;
17+
};
18+
19+
static const std::vector<struct PrinterFactory> g_printers {
20+
{"json", [](const std::string &args) {
21+
return new JsonPrinter(args); }
22+
},
23+
{"table", [](const std::string &args){
24+
return new TablePrinter(args); }
25+
},
26+
};
27+
28+
std::unique_ptr<Printer>
29+
printer_factory(const std::string &manual)
30+
{
31+
std::string type;
32+
std::string args;
33+
size_t delim_pos;
34+
35+
delim_pos = manual.find(':');
36+
type = manual.substr(0, delim_pos);
37+
args = (delim_pos != std::string::npos)
38+
? manual.substr(delim_pos + 1, std::string::npos)
39+
: "";
40+
41+
// Convert type to lower case
42+
std::for_each(type.begin(), type.end(), [](char &c) { c = std::tolower(c); });
43+
44+
for (const auto &it : g_printers) {
45+
if (type != it.name) {
46+
continue;
47+
}
48+
49+
return std::unique_ptr<Printer>(it.create_fn(args));
50+
}
51+
52+
throw std::invalid_argument("Unsupported output type '" + type + "'");
53+
}
54+
55+
} // statistics
56+
} // fdsdump

0 commit comments

Comments
 (0)