Skip to content

Commit b811422

Browse files
author
Damir Zainullin
committed
++
1 parent 4c9b2aa commit b811422

File tree

14 files changed

+704
-8
lines changed

14 files changed

+704
-8
lines changed

include/ipfixprobe/packet.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ struct Packet : public Record {
5151
uint16_t ethertype;
5252

5353
uint16_t ip_len; /**< Length of IP header + its payload */
54+
uint16_t tcp_window;
55+
uint64_t tcp_options;
56+
uint32_t tcp_mss;
5457
uint16_t ip_payload_len; /**< Length of IP payload */
5558
uint8_t ip_version;
5659
uint8_t ip_ttl;
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
/**
2+
* \file utils.hpp
3+
* \brief Utility functions
4+
* \author Jiri Havranek <[email protected]>
5+
* \date 2021
6+
*/
7+
/*
8+
* Copyright (C) 2021 CESNET
9+
*
10+
* LICENSE TERMS
11+
*
12+
* Redistribution and use in source and binary forms, with or without
13+
* modification, are permitted provided that the following conditions
14+
* are met:
15+
* 1. Redistributions of source code must retain the above copyright
16+
* notice, this list of conditions and the following disclaimer.
17+
* 2. Redistributions in binary form must reproduce the above copyright
18+
* notice, this list of conditions and the following disclaimer in
19+
* the documentation and/or other materials provided with the
20+
* distribution.
21+
* 3. Neither the name of the Company nor the names of its contributors
22+
* may be used to endorse or promote products derived from this
23+
* software without specific prior written permission.
24+
*
25+
*
26+
*
27+
*/
28+
29+
#ifndef IPXP_UTILS_HPP
30+
#define IPXP_UTILS_HPP
31+
32+
#include <algorithm>
33+
#include <cctype>
34+
#include <cstdint>
35+
#include <limits>
36+
#include <set>
37+
#include <sstream>
38+
#include <stdexcept>
39+
#include <string>
40+
#include <type_traits>
41+
#include <utility>
42+
#include <vector>
43+
44+
#include <sys/time.h>
45+
46+
namespace ipxp {
47+
48+
void parse_range(
49+
const std::string& arg,
50+
std::string& from,
51+
std::string& to,
52+
const std::string& delim = "-");
53+
bool str2bool(std::string str);
54+
void trim_str(std::string& str);
55+
uint32_t variable2ipfix_buffer(uint8_t* buffer2write, uint8_t* buffer2read, uint16_t len);
56+
57+
template<typename T>
58+
constexpr T const& max(const T& a, const T& b)
59+
{
60+
return a > b ? a : b;
61+
}
62+
63+
/*
64+
* \brief Count number of '1' bits
65+
* \param [in] num Number to count ones in
66+
* \return Number of ones counted
67+
*/
68+
template<typename T>
69+
static constexpr unsigned bitcount(T num)
70+
{
71+
static_assert(!std::is_signed<T>(), "bitcount function is for unsigned types only");
72+
return num == 0 ? 0 : (bitcount<T>(num >> 1) + (num & 1));
73+
}
74+
75+
template<typename T>
76+
static constexpr bool is_fpoint()
77+
{
78+
return std::is_floating_point<T>();
79+
}
80+
81+
template<typename T>
82+
static constexpr bool is_uint()
83+
{
84+
return std::is_integral<T>() && std::is_unsigned<T>();
85+
}
86+
87+
template<typename T>
88+
static constexpr bool is_sint()
89+
{
90+
return std::is_integral<T>() && std::is_signed<T>();
91+
}
92+
93+
// Use of SFINAE to implement specific conversion function variants
94+
95+
template<typename T>
96+
T str2num(std::string str, typename std::enable_if<is_fpoint<T>()>::type* = nullptr)
97+
{
98+
size_t pos;
99+
double tmp;
100+
101+
trim_str(str);
102+
try {
103+
tmp = std::stold(str, &pos);
104+
} catch (std::out_of_range& e) {
105+
throw std::invalid_argument(str);
106+
}
107+
if (pos != str.size() || tmp < std::numeric_limits<T>::min()
108+
|| tmp > std::numeric_limits<T>::max()) {
109+
throw std::invalid_argument(str);
110+
}
111+
112+
return static_cast<T>(tmp);
113+
}
114+
115+
template<typename T>
116+
T str2num(std::string str, typename std::enable_if<is_sint<T>()>::type* = nullptr)
117+
{
118+
long long tmp;
119+
size_t pos;
120+
121+
trim_str(str);
122+
try {
123+
tmp = std::stoll(str, &pos, 0);
124+
} catch (std::out_of_range& e) {
125+
throw std::invalid_argument(str);
126+
}
127+
if (pos != str.size() || tmp < std::numeric_limits<T>::min()
128+
|| tmp > std::numeric_limits<T>::max()) {
129+
throw std::invalid_argument(str);
130+
}
131+
132+
return static_cast<T>(tmp);
133+
}
134+
135+
template<typename T>
136+
T str2num(std::string str, typename std::enable_if<is_uint<T>()>::type* = nullptr)
137+
{
138+
unsigned long long tmp;
139+
size_t pos;
140+
141+
trim_str(str);
142+
try {
143+
tmp = std::stoull(str, &pos, 0);
144+
} catch (std::out_of_range& e) {
145+
throw std::invalid_argument(str);
146+
}
147+
if (pos != str.size() || tmp < std::numeric_limits<T>::min()
148+
|| tmp > std::numeric_limits<T>::max()) {
149+
throw std::invalid_argument(str);
150+
}
151+
152+
return static_cast<T>(tmp);
153+
}
154+
155+
/**
156+
* @brief Convert struct Timeval to microseconds
157+
*/
158+
uint64_t timeval2usec(const struct timeval& tv);
159+
160+
/**
161+
* @brief Convert vector to string, e.g. for error messages
162+
*/
163+
template<typename T>
164+
std::string vec2str(const std::vector<T>& vec)
165+
{
166+
std::stringstream ss;
167+
bool first = true;
168+
for (auto& item : vec) {
169+
if (!first)
170+
ss << ", ";
171+
ss << item;
172+
first = false;
173+
}
174+
return ss.str();
175+
}
176+
177+
/**
178+
* @brief Copy uint32 in little endian byte order to destination in host byte order
179+
*/
180+
void memcpy_le32toh(uint32_t* dest, const uint32_t* src);
181+
182+
constexpr static inline
183+
timeval operator+(const timeval& a, const timeval& b) noexcept
184+
{
185+
constexpr time_t USEC_IN_SEC = 1'000'000;
186+
187+
timeval result{};
188+
result.tv_sec = a.tv_sec + b.tv_sec;
189+
result.tv_usec = a.tv_usec + b.tv_usec;
190+
if (result.tv_usec >= USEC_IN_SEC) {
191+
result.tv_sec++;
192+
result.tv_usec -= USEC_IN_SEC;
193+
}
194+
return result;
195+
}
196+
197+
constexpr static inline
198+
timeval operator-(const timeval& a) noexcept
199+
{
200+
timeval result{};
201+
result.tv_sec = -a.tv_sec;
202+
result.tv_usec = -a.tv_usec;
203+
return result;
204+
}
205+
206+
constexpr static inline
207+
timeval operator-(const timeval& a, const timeval& b) noexcept
208+
{
209+
return a + (-b);
210+
}
211+
212+
constexpr static inline
213+
bool operator>(const timeval& a, const timeval& b) noexcept
214+
{
215+
return std::tie(a.tv_sec, a.tv_usec) > std::tie(b.tv_sec, b.tv_usec);
216+
}
217+
218+
constexpr static inline
219+
bool operator<(const timeval& a, const timeval& b) noexcept
220+
{
221+
return std::tie(a.tv_sec, a.tv_usec) < std::tie(b.tv_sec, b.tv_usec);
222+
}
223+
224+
constexpr static inline
225+
bool operator==(const timeval& a, const timeval& b) noexcept
226+
{
227+
return not (a < b) and not (b < a);
228+
}
229+
230+
} // namespace ipxp
231+
232+
#endif /* IPXP_UTILS_HPP */

process-plugin-api/dummyProcessPlugin.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ static FieldSchema createDummySchema()
131131
}
132132

133133
class DummyPlugin
134-
: private FieldHandlers<DummyFields>
135-
, public ProcessPlugin {
134+
//: private FieldHandlers<DummyFields>,
135+
: public ProcessPlugin {
136136
public:
137137
DummyPlugin(const std::string& params, FieldManager& manager)
138138
{
@@ -164,11 +164,10 @@ class DummyPlugin
164164
return FlowAction::RequestNoData;
165165
}
166166

167-
FlowAction onFlowUpdate(FlowRecord& flowRecord, const Packet& packet, const PacketOfFlowData& data) override
167+
FlowAction onFlowUpdate(FlowRecord& flowRecord, const Packet& packet) override
168168
{
169169
(void) flowRecord;
170170
(void) packet;
171-
(void) data;
172171

173172
m_exportData.packets[Direction::Forward] = {1, 2, 3, 4, 5, 6};
174173
m_fieldHandlers[DummyFields::PACKETS].setAsAvailable(flowRecord);
@@ -194,6 +193,7 @@ class DummyPlugin
194193

195194
private:
196195
DummyExport m_exportData;
196+
FieldHandlers<DummyFields> m_fieldHandlers;
197197
};
198198

199199
} // namespace ipxp

process-plugin-api/fieldSchema.hpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,25 @@
1414

1515
namespace ipxp {
1616

17+
template<typename Field>
18+
using FieldPair = std::pair<Field, std::string_view>;
19+
20+
template<typename Field>
21+
using BiflowFieldPair = std::pair<FieldPair<Field>, FieldPair<Field>>;
22+
23+
template<typename Field>
24+
using FieldVariant = std::variant<FieldPair<Field>, BiflowFieldPair<Field>>;
25+
26+
template<typename Field>
27+
FieldVariant<Field> makeBiflowPair(FieldPair<Field> field1, FieldPair<Field> field2) {
28+
return FieldVariant<Field>(BiflowFieldPair<Field>{field1, field2});
29+
}
30+
31+
template<typename Field>
32+
FieldVariant<Field> makeFieldPair(Field field, std::string_view name) {
33+
return FieldVariant<Field>(FieldPair<Field>{field, name});
34+
}
35+
1736
/**
1837
* @brief Represents the schema of a flow record, including field definitions and biflow mappings.
1938
*
@@ -89,6 +108,17 @@ class FieldSchema {
89108
BiflowPair {std::string(forwardFieldName), std::string(reverseFieldName)});
90109
}
91110

111+
template<typename Field>
112+
void addBiflowPairs(const std::vector<FieldVariant<Field>>& pairs)
113+
{
114+
for (const FieldVariant<Field>& fieldVariant : pairs) {
115+
if (std::holds_alternative<BiflowFieldPair<Field>>(fieldVariant)) {
116+
const auto& [field1, field2] = std::get<BiflowFieldPair<Field>>(fieldVariant);
117+
addBiflowPair(field1.second, field2.second);
118+
}
119+
}
120+
}
121+
92122
/**
93123
* @brief Returns all registered fields in this schema.
94124
*

process-plugin-api/ipx

4.13 MB
Binary file not shown.

process-plugin-api/main.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ int main()
1212
ipxp::FlowRecordBuilder builder;
1313
ipxp::FieldManager manager;
1414
ipxp::Packet packet;
15-
ipxp::PacketOfFlowData data;
1615

1716
builder.addProcessPlugin("dummy", "params", manager);
1817

@@ -23,7 +22,7 @@ int main()
2322
[&](ipxp::ProcessPlugin* plugin) { plugin->onFlowCreate(flowRecord, packet); });
2423

2524
flowRecord.forEachPlugin(
26-
[&](ipxp::ProcessPlugin* plugin) { plugin->onFlowUpdate(flowRecord, packet, data); });
25+
[&](ipxp::ProcessPlugin* plugin) { plugin->onFlowUpdate(flowRecord, packet); });
2726
} catch (std::exception& ex) {
2827
std::cout << ex.what() << "\n";
2928
return 1;

process-plugin-api/packet.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ struct Packet {
1919
uint32_t tcpMss;
2020
TcpFlags tcpFlags;
2121

22-
uint32_t actualLength;
22+
uint32_t realLength;
2323
uint32_t receivedLength;
2424

25+
Direction direction;
26+
2527
};
2628

2729
} // namespace ipxp

process-plugin-api/process/basicPlus/src/basicPlus.cpp renamed to process-plugin-api/process/basicPlus/src/basicPlus.cpptttt

File renamed without changes.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#pragma once
2+
3+
#include <sys/time.h>
4+
#include <directionalField.hpp>
5+
#include <utils.hpp>
6+
7+
namespace ipxp
8+
{
9+
10+
struct Burst {
11+
12+
constexpr static timeval MAX_INTERPACKET_TIMEDIFF = {1, 0};
13+
14+
uint32_t& packets;
15+
uint32_t& bytes;
16+
timeval& start;
17+
timeval& end;
18+
19+
constexpr inline
20+
bool belongs(const timeval& time) const noexcept
21+
{
22+
return time - end < MAX_INTERPACKET_TIMEDIFF;
23+
}
24+
};
25+
26+
27+
} // namespace ipxp

0 commit comments

Comments
 (0)