Skip to content

Commit 70e7853

Browse files
Lukas HutakLukas955
authored andcommitted
fdsdump: printer: define flow printer components
1 parent a092af2 commit 70e7853

File tree

8 files changed

+1009
-0
lines changed

8 files changed

+1009
-0
lines changed

src/tools/fdsdump/src/jsonPrinter.cpp

Lines changed: 419 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
2+
#pragma once
3+
4+
#include <string>
5+
6+
#include "field.hpp"
7+
#include "printer.hpp"
8+
9+
class JsonPrinter : public Printer {
10+
public:
11+
JsonPrinter(const shared_iemgr &iemgr, const std::string &args);
12+
13+
virtual
14+
~JsonPrinter();
15+
16+
virtual void
17+
print_prologue() override;
18+
19+
virtual unsigned int
20+
print_record(Flow *flow) override;
21+
22+
virtual void
23+
print_epilogue() override;
24+
25+
private:
26+
void parse_fields(const std::string &str, const shared_iemgr &iemgr);
27+
void parse_opts(const std::string &str);
28+
29+
void print_record(struct fds_drec *rec, bool reverse);
30+
31+
void append_value(struct fds_drec *rec, Field &field, bool reverse);
32+
void append_value(const struct fds_drec_field &field);
33+
34+
void append_octet_array(const fds_drec_field &field);
35+
void append_uint(const fds_drec_field &field);
36+
void append_int(const fds_drec_field &field);
37+
void append_float(const fds_drec_field &field);
38+
void append_boolean(const fds_drec_field &field);
39+
void append_timestamp(const fds_drec_field &field);
40+
void append_string(const fds_drec_field &field);
41+
void append_mac(const fds_drec_field &field);
42+
void append_ip(const fds_drec_field &field);
43+
44+
void append_null();
45+
void append_invalid();
46+
void append_unsupported();
47+
48+
std::vector<Field> m_fields;
49+
std::string m_buffer;
50+
unsigned int m_rec_printed = 0;
51+
bool m_biflow_split = true;
52+
};
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
2+
#include <cstdlib>
3+
#include <iostream>
4+
#include <string>
5+
#include <stdexcept>
6+
#include <vector>
7+
8+
#include "common.hpp"
9+
#include "jsonRawPrinter.hpp"
10+
11+
JsonRawPrinter::JsonRawPrinter(const shared_iemgr &iemgr, const std::string &args)
12+
{
13+
const std::vector<std::string> args_vec = string_split(args, ",");
14+
15+
m_iemgr = iemgr;
16+
17+
if (args.empty()) {
18+
return;
19+
}
20+
21+
for (const std::string &arg_raw : args_vec) {
22+
const std::string arg = string_trim_copy(arg_raw);
23+
24+
if (strcasecmp(arg.c_str(), "biflow-split") == 0) {
25+
m_biflow_split = true;
26+
} else if (strcasecmp(arg.c_str(), "hide-reverse") == 0) {
27+
m_biflow_hide_reverse = true;
28+
} else {
29+
throw std::invalid_argument("JSON output: unknown option '" + arg + "'");
30+
}
31+
}
32+
33+
if (m_biflow_hide_reverse && !m_biflow_split) {
34+
throw std::invalid_argument(
35+
"JSON output: reverse field hidding requires enabled biflow splitting");
36+
}
37+
}
38+
39+
JsonRawPrinter::~JsonRawPrinter()
40+
{
41+
if (m_buffer) {
42+
free(m_buffer);
43+
}
44+
}
45+
46+
void
47+
JsonRawPrinter::print_record(struct fds_drec *rec, uint32_t flags)
48+
{
49+
const uint32_t base_flags =
50+
FDS_CD2J_ALLOW_REALLOC | FDS_CD2J_OCTETS_NOINT | FDS_CD2J_TS_FORMAT_MSEC;
51+
int ret;
52+
53+
flags |= base_flags;
54+
55+
ret = fds_drec2json(rec, flags, m_iemgr.get(), &m_buffer, &m_buffer_size);
56+
if (ret < 0) {
57+
throw std::runtime_error("JSON conversion failed: " + std::to_string(ret));
58+
}
59+
60+
std::cout << m_buffer << "\n";
61+
}
62+
63+
unsigned int
64+
JsonRawPrinter::print_record(Flow *flow)
65+
{
66+
uint32_t flags = 0;
67+
int printed = 0;
68+
int ret;
69+
70+
if (m_biflow_hide_reverse) {
71+
flags |= FDS_CD2J_REVERSE_SKIP;
72+
}
73+
74+
switch (flow->dir) {
75+
case DIRECTION_NONE:
76+
return 0;
77+
case DIRECTION_FWD:
78+
print_record(&flow->rec, flags);
79+
return 1;
80+
case DIRECTION_REV:
81+
print_record(&flow->rec, flags | FDS_CD2J_BIFLOW_REVERSE);
82+
return 1;
83+
case DIRECTION_BOTH:
84+
if (m_biflow_split) {
85+
print_record(&flow->rec, flags);
86+
print_record(&flow->rec, flags | FDS_CD2J_BIFLOW_REVERSE);
87+
return 2;
88+
} else {
89+
print_record(&flow->rec, flags);
90+
return 1;
91+
}
92+
}
93+
94+
return 0;
95+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
#pragma once
3+
4+
#include <string>
5+
6+
#include "printer.hpp"
7+
8+
class JsonRawPrinter : public Printer {
9+
public:
10+
JsonRawPrinter(const shared_iemgr &iemgr, const std::string &args);
11+
12+
virtual
13+
~JsonRawPrinter();
14+
15+
virtual void
16+
print_prologue() override {};
17+
18+
virtual unsigned int
19+
print_record(Flow *flow) override;
20+
21+
virtual void
22+
print_epilogue() override {};
23+
24+
private:
25+
void print_record(struct fds_drec *rec, uint32_t flags);
26+
27+
shared_iemgr m_iemgr {};
28+
char *m_buffer = nullptr;
29+
size_t m_buffer_size = 0;
30+
31+
bool m_biflow_split = false;
32+
bool m_biflow_hide_reverse = false;
33+
};

src/tools/fdsdump/src/printer.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
2+
#include <algorithm>
3+
#include <cassert>
4+
#include <functional>
5+
#include <stdexcept>
6+
#include <vector>
7+
8+
#include "common.hpp"
9+
#include "printer.hpp"
10+
#include "jsonPrinter.hpp"
11+
#include "jsonRawPrinter.hpp"
12+
#include "tablePrinter.hpp"
13+
14+
struct PrinterFactory {
15+
const char *name;
16+
std::function<Printer *(const shared_iemgr &iemgr, const std::string &)> create_fn;
17+
};
18+
19+
static const std::vector<struct PrinterFactory> g_printers {
20+
{"json", [](const shared_iemgr &iemgr, const std::string &args) {
21+
return new JsonPrinter(iemgr, args); }
22+
},
23+
{"json-raw", [](const shared_iemgr &iemgr, const std::string &args) {
24+
return new JsonRawPrinter(iemgr, args); }
25+
},
26+
{"table", [](const shared_iemgr &iemgr, const std::string &args){
27+
return new TablePrinter(iemgr, args); }
28+
},
29+
};
30+
31+
std::unique_ptr<Printer>
32+
printer_factory(const shared_iemgr &iemgr, const std::string &manual)
33+
{
34+
std::string type;
35+
std::string args;
36+
size_t delim_pos;
37+
38+
delim_pos = manual.find(':');
39+
type = manual.substr(0, delim_pos);
40+
args = (delim_pos != std::string::npos)
41+
? manual.substr(delim_pos + 1, std::string::npos)
42+
: "";
43+
44+
// Convert type to lower case
45+
std::for_each(type.begin(), type.end(), [](char &c) { c = std::tolower(c); });
46+
47+
for (const auto &it : g_printers) {
48+
if (type != it.name) {
49+
continue;
50+
}
51+
52+
return std::unique_ptr<Printer>(it.create_fn(iemgr, args));
53+
}
54+
55+
throw std::invalid_argument("Unsupported output type '" + type + "'");
56+
}

src/tools/fdsdump/src/printer.hpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
#pragma once
3+
4+
#include <functional>
5+
#include <memory>
6+
#include <string>
7+
8+
#include <libfds.h>
9+
10+
#include "common.hpp"
11+
#include "flow.hpp"
12+
13+
/**
14+
* @brief Interface of an output printer for flow records.
15+
*
16+
*/
17+
class Printer {
18+
public:
19+
virtual
20+
~Printer() {};
21+
22+
virtual void
23+
print_prologue() = 0;
24+
25+
virtual unsigned int
26+
print_record(Flow *flow) = 0;
27+
28+
virtual void
29+
print_epilogue() = 0;
30+
};
31+
32+
std::unique_ptr<Printer>
33+
printer_factory(const shared_iemgr &iemgr, const std::string &manual);

0 commit comments

Comments
 (0)