Skip to content

Commit 400d24e

Browse files
Lukas HutakLukas955
authored andcommitted
fdsdump: field: define component
1 parent 5a5adce commit 400d24e

File tree

2 files changed

+288
-0
lines changed

2 files changed

+288
-0
lines changed

src/tools/fdsdump/src/field.cpp

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
2+
#include <cassert>
3+
#include <stdexcept>
4+
5+
#include "field.hpp"
6+
7+
Field::Field(std::string name, const shared_iemgr &iemgr)
8+
: m_name(name), m_iemgr(iemgr)
9+
{
10+
string_trim(m_name);
11+
12+
m_alias = fds_iemgr_alias_find(m_iemgr.get(), m_name.c_str());
13+
if (m_alias) {
14+
// Success
15+
m_type = get_type_of_alias(m_alias);
16+
return;
17+
}
18+
19+
m_elem = fds_iemgr_elem_find_name(m_iemgr.get(), m_name.c_str());
20+
if (m_elem) {
21+
// Success
22+
m_type = get_type_of_element(m_elem);
23+
return;
24+
}
25+
26+
throw std::invalid_argument("unknown field '" + name + "'");
27+
}
28+
29+
FieldType
30+
Field::get_type_of_element(const struct fds_iemgr_elem *elem) const
31+
{
32+
switch (elem->data_type) {
33+
case FDS_ET_OCTET_ARRAY:
34+
return FieldType::bytes;
35+
36+
case FDS_ET_UNSIGNED_8:
37+
case FDS_ET_UNSIGNED_16:
38+
case FDS_ET_UNSIGNED_32:
39+
case FDS_ET_UNSIGNED_64:
40+
return FieldType::num_unsigned;
41+
42+
case FDS_ET_SIGNED_8:
43+
case FDS_ET_SIGNED_16:
44+
case FDS_ET_SIGNED_32:
45+
case FDS_ET_SIGNED_64:
46+
return FieldType::num_signed;
47+
48+
case FDS_ET_FLOAT_32:
49+
case FDS_ET_FLOAT_64:
50+
return FieldType::num_float;
51+
52+
case FDS_ET_BOOLEAN:
53+
return FieldType::boolean;
54+
55+
case FDS_ET_MAC_ADDRESS:
56+
return FieldType::macaddr;
57+
58+
case FDS_ET_STRING:
59+
return FieldType::string;
60+
61+
case FDS_ET_DATE_TIME_SECONDS:
62+
case FDS_ET_DATE_TIME_MILLISECONDS:
63+
case FDS_ET_DATE_TIME_MICROSECONDS:
64+
case FDS_ET_DATE_TIME_NANOSECONDS:
65+
return FieldType::datetime;
66+
67+
case FDS_ET_IPV4_ADDRESS:
68+
case FDS_ET_IPV6_ADDRESS:
69+
return FieldType::ipaddr;
70+
71+
case FDS_ET_BASIC_LIST:
72+
case FDS_ET_SUB_TEMPLATE_LIST:
73+
case FDS_ET_SUB_TEMPLATE_MULTILIST:
74+
return FieldType::list;
75+
76+
default:
77+
return FieldType::none;
78+
}
79+
}
80+
81+
FieldType
82+
Field::get_type_of_alias(const struct fds_iemgr_alias *alias) const
83+
{
84+
FieldType result;
85+
86+
if (alias->sources_cnt == 0) {
87+
return FieldType::none;
88+
}
89+
90+
result = get_type_of_element(alias->sources[0]);
91+
92+
for (size_t i = 1; i < alias->sources_cnt; ++i) {
93+
FieldType type = get_type_of_element(alias->sources[i]);
94+
95+
if (type != result) {
96+
// Unable to determine common type
97+
return FieldType::none;
98+
}
99+
}
100+
101+
return result;
102+
}
103+
104+
unsigned int
105+
Field::for_each(
106+
struct fds_drec *rec,
107+
std::function<void(fds_drec_field &)> cb,
108+
bool reverse)
109+
{
110+
if (m_alias) {
111+
return for_each_alias(rec, cb, reverse);
112+
} else if (m_elem) {
113+
return for_each_element(rec, cb, reverse);
114+
} else {
115+
return 0;
116+
}
117+
}
118+
119+
unsigned int
120+
Field::for_each_alias(
121+
struct fds_drec *rec,
122+
std::function<void(struct fds_drec_field &)> cb,
123+
bool reverse)
124+
{
125+
const uint16_t flags = reverse ? FDS_DREC_BIFLOW_REV : 0;
126+
struct fds_drec_iter iter;
127+
unsigned int count = 0;
128+
129+
// Currently known modes
130+
assert(m_alias->mode == FDS_ALIAS_ANY_OF || m_alias->mode == FDS_ALIAS_FIRST_OF);
131+
132+
fds_drec_iter_init(&iter, rec, flags);
133+
134+
for (size_t i = 0; i < m_alias->sources_cnt; ++i) {
135+
const struct fds_iemgr_elem *elem = m_alias->sources[i];
136+
const uint32_t pen = elem->scope->pen;
137+
const uint16_t id = elem->id;
138+
139+
while (fds_drec_iter_find(&iter, pen, id) != FDS_EOC) {
140+
cb(iter.field);
141+
count++;
142+
}
143+
144+
if (count > 0 && m_alias->mode == FDS_ALIAS_FIRST_OF) {
145+
return count;
146+
}
147+
148+
fds_drec_iter_rewind(&iter);
149+
}
150+
151+
return count;
152+
}
153+
154+
unsigned int
155+
Field::for_each_element(
156+
struct fds_drec *rec,
157+
std::function<void(struct fds_drec_field &)> cb,
158+
bool reverse)
159+
{
160+
const uint16_t flags = reverse ? FDS_DREC_BIFLOW_REV : 0;
161+
const uint32_t pen = m_elem->scope->pen;
162+
const uint16_t id = m_elem->id;
163+
struct fds_drec_iter iter;
164+
unsigned int count = 0;
165+
166+
fds_drec_iter_init(&iter, rec, flags);
167+
168+
while (fds_drec_iter_find(&iter, pen, id) != FDS_EOC) {
169+
cb(iter.field);
170+
count++;
171+
}
172+
173+
return count;
174+
}

src/tools/fdsdump/src/field.hpp

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
2+
#pragma once
3+
4+
#include <functional>
5+
#include <string>
6+
7+
#include <libfds.h>
8+
9+
#include "common.hpp"
10+
11+
/**
12+
* @brief Data type of a record field.
13+
*/
14+
enum class FieldType {
15+
none, ///< Unknown or unsupported type
16+
bytes, ///< IPFIX octetArray
17+
num_unsigned, ///< IPFIX unsigned{8,16,32,64}
18+
num_signed, ///< IPFIX signed{8,16,32,64}
19+
num_float, ///< IPFIX float{32,64}
20+
boolean, ///< IPFIX boolean
21+
macaddr, ///< IPFIX macaddr
22+
string, ///< IPFIX string
23+
datetime, ///< IPFIX dateTime{Seconds,Milliseconds,Microseconds,Nanoseconds}
24+
ipaddr, ///< IPFIX ipv4Address,ipv6Address
25+
list, ///< IPFIX basicList,subTemplateList,subTemplateMultiList
26+
};
27+
28+
/**
29+
* @brief Description of a field of an IPFIX Data Record.
30+
*
31+
* The class contains reference to either an alias for one or more IPFIX
32+
* elements or an IPFIX element, but not both at the same time.
33+
*/
34+
struct Field {
35+
public:
36+
/**
37+
* @brief Create a new getter for an alias or an IPFIX Field.
38+
*
39+
* @param name Name of alias or an IPFIX Element to lookup
40+
* @param iemgr IE manager where to look for the field
41+
* @throw std::invalid_argument If the alias or element cannot be found.
42+
*/
43+
Field(std::string name, const shared_iemgr &iemgr);
44+
~Field() = default;
45+
46+
/**
47+
* @brief Get the name of the field.
48+
*/
49+
const std::string &get_name() const { return m_name; };
50+
/**
51+
* @brief Get a reference to alias definition (might be nullptr).
52+
*/
53+
const struct fds_iemgr_alias *get_alias() const { return m_alias; };
54+
/**
55+
* @brief Get a reference to IPFIX element definition (might be nullptr).
56+
*/
57+
const struct fds_iemgr_elem *get_element() const { return m_elem; };
58+
59+
/**
60+
* @brief Get data type of the field.
61+
*
62+
* In case of an alias, it represents the common type of all elements.
63+
* However, if the common type cannot be determined, FieldType::none is
64+
* returned.
65+
*/
66+
FieldType get_type() const { return m_type; };
67+
68+
/**
69+
* @brief Test if the field is an alias for one or more IPFIX Elements.
70+
*/
71+
bool is_alias() const { return m_alias != nullptr; };
72+
/**
73+
* @brief Test if the field is an IPFIX Element.
74+
*/
75+
bool is_element() const { return m_elem != nullptr; };
76+
77+
/**
78+
* @brief For each occurence of the field in a Data Record call
79+
* a user-defined callback.
80+
*
81+
* @param rec IPFIX Data record where to look for occurences.
82+
* @param cb Callback to call on each field occurence.
83+
* @param reverse Look for the field from the reverse direction of biflow (if available)
84+
* @return Number of occurrences.
85+
*/
86+
unsigned int for_each(
87+
struct fds_drec *rec,
88+
std::function<void(fds_drec_field &)> cb,
89+
bool reverse);
90+
91+
private:
92+
// Name of the field (trimmed)
93+
std::string m_name;
94+
// Reference to the IE manager
95+
shared_iemgr m_iemgr;
96+
// Data type of the the field
97+
FieldType m_type;
98+
// Alias definition (might be nullptr)
99+
const struct fds_iemgr_alias *m_alias = nullptr;
100+
// Element definition (might be nullptr)
101+
const struct fds_iemgr_elem *m_elem = nullptr;
102+
103+
unsigned int for_each_alias(
104+
struct fds_drec *rec,
105+
std::function<void(struct fds_drec_field &)> cb,
106+
bool reverse);
107+
unsigned int for_each_element(
108+
struct fds_drec *rec,
109+
std::function<void(struct fds_drec_field &)> cb,
110+
bool reverse);
111+
112+
FieldType get_type_of_element(const struct fds_iemgr_elem *elem) const;
113+
FieldType get_type_of_alias(const struct fds_iemgr_alias *alias) const;
114+
};

0 commit comments

Comments
 (0)