Skip to content

Commit 9d759a5

Browse files
Zainullin DamirZainullin Damir
authored andcommitted
++
1 parent 7fe97c3 commit 9d759a5

File tree

8 files changed

+198
-104
lines changed

8 files changed

+198
-104
lines changed
Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,41 @@
11
# BasicPlus Plugin
22

3-
The **BasicPlus Plugin** is a module for the IPFIXprobe exporter, designed to extend flow records with additional basic network information.
3+
The **BasicPlus** plugin extends flow records with additional basic network information to provide richer visibility into network flows.
44

55
## Features
66

7-
- Extends basic flow export data.
8-
- Extracts and exports additional fields from network flows.
9-
7+
- Extends standard flow export data with additional fields.
8+
- Extracts and exports key network-level fields for both directions of a flow.
109

1110
## Output Fields
1211

13-
| Field Name | Data Type | Description |
14-
|-----------------|-----------|-------------------------------------------------------------|
15-
| IP_TTL | uint8_t | IP time-to-live in source-to-destination direction |
16-
| IP_TTL_REV | uint8_t | IP time-to-live in destination-to-source direction |
17-
| IP_FLG | uint8_t | IP flags in source-to-destination direction |
18-
| IP_FLG_REV | uint8_t | IP flags in destination-to-source direction |
19-
| TCP_WIN | uint16_t | TCP window size in source-to-destination direction |
20-
| TCP_WIN_REV | uint16_t | TCP window size in destination-to-source direction |
21-
| TCP_OPT | uint64_t | TCP options in source-to-destination direction |
22-
| TCP_OPT_REV | uint64_t | TCP options in destination-to-source direction |
23-
| TCP_MSS | uint32_t | TCP maximum segment size in source-to-destination direction |
24-
| TCP_MSS_REV | uint32_t | TCP maximum segment size in destination-to-source direction |
25-
| TCP_SYN_SIZE | uint16_t | TCP syn packet size (only one in bidirectional flow) |
12+
| Field Name | Data Type | Description |
13+
|---------------|-----------|-------------|
14+
| `IP_TTL` | `uint8_t` | IP time-to-live (source → destination) |
15+
| `IP_TTL_REV` | `uint8_t` | IP time-to-live (destination → source) |
16+
| `IP_FLG` | `uint8_t` | IP flags (source → destination) |
17+
| `IP_FLG_REV` | `uint8_t` | IP flags (destination → source) |
18+
| `TCP_WIN` | `uint16_t`| TCP window size (source → destination) |
19+
| `TCP_WIN_REV` | `uint16_t`| TCP window size (destination → source) |
20+
| `TCP_OPT` | `uint64_t`| TCP options (source → destination) |
21+
| `TCP_OPT_REV` | `uint64_t`| TCP options (destination → source) |
22+
| `TCP_MSS` | `uint32_t`| TCP maximum segment size (source → destination) |
23+
| `TCP_MSS_REV` | `uint32_t`| TCP maximum segment size (destination → source) |
24+
| `TCP_SYN_SIZE`| `uint16_t`| TCP SYN packet size (only one per bidirectional flow) |
2625

2726
## Usage
2827

29-
Once enabled, the plugin will automatically process flows and add the export fields to each record.
28+
### YAML Configuration
29+
30+
Add the plugin to your ipfixprobe YAML configuration:
31+
32+
```yaml
33+
process_plugins:
34+
- basicplus
35+
```
3036
31-
1. ``` make install ```.
32-
2. ``` ipfixprobe -p "basicplus" ... " ```
33-
3. Extracted values are exported to the output interface.
37+
### CLI Usage
3438
35-
## Support
39+
You can also enable the plugin directly from the command line:
3640
37-
For issues or feature requests, please open an issue in the [IPFIXprobe repository](https://github.com/CESNET/ipfixprobe).
41+
```ipfixprobe -p basicplus ...```
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# BurstStats Plugin
2+
3+
The **BurstStats Plugin** is a module for the IPFIXprobe exporter, designed to analyze packet burst statistics.
4+
5+
## Features
6+
7+
- Consider packet to be a part of burst if it arrives within short time interval after previous packet.
8+
- Extracts and exports burst statistics from network flows.
9+
10+
## Output Fields
11+
12+
| Field Name | Data Type | Description |
13+
|-----------------|-----------|-------------------------------------------------------------|
14+
| SBI_BRST_PACKETS| uint32_t | Array of packets in each burst in source-to-destination direction |
15+
| SBI_BRST_BYTES | uint32_t | Array of bytes in each burst in source-to-destination direction |
16+
| SBI_BRST_TIME_START | Timestamp | Array of burst start times in source-to-destination direction |
17+
| SBI_BRST_TIME_STOP | Timestamp | Array of burst end times in source-to-destination direction |
18+
| DBI_BRST_PACKETS| uint32_t | Array of packets in each burst in destination-to-source direction |
19+
| DBI_BRST_BYTES | uint32_t | Array of bytes in each burst in destination-to-source direction |
20+
| DBI_BRST_TIME_START | Timestamp | Array of burst start times in destination-to-source direction |
21+
| DBI_BRST_TIME_STOP | Timestamp | Array of burst end times in destination-to-source direction |
22+
23+
## Usage
24+
25+
Once enabled, the plugin will automatically process flows and add the export fields to each record.
26+
27+
1. ``` make install ```.
28+
2. ``` ipfixprobe -p "bstats" ... " ```
29+
3. Extracted values are exported to the output interface.
30+
31+
## Support
32+
33+
For issues or feature requests, please open an issue in the [IPFIXprobe repository](https://github.com/CESNET/ipfixprobe).

src/plugins/process/bstats/src/burst.hpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,36 @@
99

1010
#pragma once
1111

12-
#include <sys/time.h>
1312
#include <directionalField.hpp>
13+
#include <sys/time.h>
1414
#include <utils.hpp>
1515

16-
namespace ipxp
17-
{
16+
namespace ipxp {
1817

1918
/**
2019
* @struct Burst
21-
* @brief Structure representing one packet burst. Contains packets, bytes which belong to that burst with begin and end timestamps.
20+
* @brief Structure representing one packet burst. Contains packets, bytes which belong to that
21+
* burst with begin and end timestamps.
2222
*/
2323
struct Burst {
24-
constexpr static timeval MAX_INTERPACKET_TIMEDIFF = {1, 0}; ///< Maximum time difference between packets in one burst (1 second).
24+
constexpr static timeval MAX_INTERPACKET_TIMEDIFF
25+
= {1, 0}; ///< Maximum time difference between packets in one burst (1 second).
2526

26-
std::reference_wrapper<uint32_t> packets;
27+
std::reference_wrapper<uint32_t> packets;
2728
std::reference_wrapper<uint32_t> bytes;
2829
std::reference_wrapper<Timestamp> start;
2930
std::reference_wrapper<Timestamp> end;
3031

31-
/**
32+
/**
3233
* @brief Checks if the given timestamp belongs to the burst.
3334
*
3435
* @param time The timestamp to check.
35-
* @return true if the timestamp belongs to the burst, false otherwise.
36+
* @return true if the timestamp belongs to the burst, false otherwise.
3637
*/
37-
constexpr
38-
bool belongs(const timeval time) const noexcept
39-
{
40-
return Timestamp(time) - end < MAX_INTERPACKET_TIMEDIFF;
41-
}
38+
constexpr bool belongs(const timeval time) const noexcept
39+
{
40+
return Timestamp(time) - end < MAX_INTERPACKET_TIMEDIFF;
41+
}
4242
};
4343

4444
} // namespace ipxp

src/plugins/process/bstats/src/burstStats.cpp

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,19 @@
88
*
99
* Provides a plugin that extracts packet burst statistics of flows,
1010
* stores them in per-flow plugin data, and exposes fields via FieldManager.
11-
*
11+
*
1212
* @copyright Copyright (c) 2025 CESNET, z.s.p.o.
1313
*/
1414

1515
#include "burstStats.hpp"
16+
1617
#include "burstStatsData.hpp"
1718

1819
#include <iostream>
1920

20-
//#include <ipfixprobe/pluginFactory/pluginManifest.hpp>
21-
#include <ipfixprobe/pluginFactory/pluginRegistrar.hpp>
22-
23-
//#include <pluginManifest.hpp>
24-
//#include <pluginRegistrar.hpp>
25-
//#include <pluginFactory.hpp>
2621
#include <fieldGroup.hpp>
27-
//#include <fieldManager.hpp>
2822
#include <ipfixprobe/options.hpp>
23+
#include <ipfixprobe/pluginFactory/pluginRegistrar.hpp>
2924

3025
namespace ipxp {
3126

@@ -41,55 +36,77 @@ static const PluginManifest burstStatsPluginManifest = {
4136
},
4237
};
4338

44-
static FieldGroup createBurstStatsSchema(FieldManager& fieldManager, FieldHandlers<BurstStatsFields>& handlers)
39+
static FieldGroup
40+
createBurstStatsSchema(FieldManager& fieldManager, FieldHandlers<BurstStatsFields>& handlers)
4541
{
4642
FieldGroup schema = fieldManager.createFieldGroup("bstats");
4743

4844
auto [sourcePacketsField, destPacketsField] = schema.addVectorDirectionalFields(
49-
"SBI_BRST_PACKETS", "DBI_BRST_PACKETS",
50-
[](const void* context) { return reinterpret_cast<const BurstStatsData*>(context)->getPackets(Direction::Forward); },
51-
[](const void* context) { return reinterpret_cast<const BurstStatsData*>(context)->getPackets(Direction::Reverse); }
52-
);
45+
"SBI_BRST_PACKETS",
46+
"DBI_BRST_PACKETS",
47+
[](const void* context) {
48+
return reinterpret_cast<const BurstStatsData*>(context)->getPackets(Direction::Forward);
49+
},
50+
[](const void* context) {
51+
return reinterpret_cast<const BurstStatsData*>(context)->getPackets(Direction::Reverse);
52+
});
5353
handlers.insert(BurstStatsFields::SBI_BRST_PACKETS, sourcePacketsField);
5454
handlers.insert(BurstStatsFields::DBI_BRST_PACKETS, destPacketsField);
5555

5656
auto [sourceBytesField, destBytesField] = schema.addVectorDirectionalFields(
57-
"SBI_BRST_BYTES", "DBI_BRST_BYTES",
58-
[](const void* context) { return reinterpret_cast<const BurstStatsData*>(context)->getBytes(Direction::Forward); },
59-
[](const void* context) { return reinterpret_cast<const BurstStatsData*>(context)->getBytes(Direction::Reverse); }
60-
);
57+
"SBI_BRST_BYTES",
58+
"DBI_BRST_BYTES",
59+
[](const void* context) {
60+
return reinterpret_cast<const BurstStatsData*>(context)->getBytes(Direction::Forward);
61+
},
62+
[](const void* context) {
63+
return reinterpret_cast<const BurstStatsData*>(context)->getBytes(Direction::Reverse);
64+
});
6165
handlers.insert(BurstStatsFields::SBI_BRST_BYTES, sourceBytesField);
6266
handlers.insert(BurstStatsFields::DBI_BRST_BYTES, destBytesField);
6367

64-
6568
auto [sourceTimeStartField, destTimeStartField] = schema.addVectorDirectionalFields(
66-
"SBI_BRST_TIME_START", "DBI_BRST_TIME_START",
67-
[](const void* context) { return reinterpret_cast<const BurstStatsData*>(context)->getStartTimestamps(Direction::Forward); },
68-
[](const void* context) { return reinterpret_cast<const BurstStatsData*>(context)->getStartTimestamps(Direction::Reverse); }
69-
);
69+
"SBI_BRST_TIME_START",
70+
"DBI_BRST_TIME_START",
71+
[](const void* context) {
72+
return reinterpret_cast<const BurstStatsData*>(context)->getStartTimestamps(
73+
Direction::Forward);
74+
},
75+
[](const void* context) {
76+
return reinterpret_cast<const BurstStatsData*>(context)->getStartTimestamps(
77+
Direction::Reverse);
78+
});
7079
handlers.insert(BurstStatsFields::SBI_BRST_TIME_START, sourceTimeStartField);
7180
handlers.insert(BurstStatsFields::DBI_BRST_TIME_START, destTimeStartField);
7281

7382
auto [sourceTimeStopField, destTimeStopField] = schema.addVectorDirectionalFields(
74-
"SBI_BRST_TIME_STOP", "DBI_BRST_TIME_STOP",
75-
[](const void* context) { return reinterpret_cast<const BurstStatsData*>(context)->getEndTimestamps(Direction::Forward); },
76-
[](const void* context) { return reinterpret_cast<const BurstStatsData*>(context)->getEndTimestamps(Direction::Reverse); }
77-
);
83+
"SBI_BRST_TIME_STOP",
84+
"DBI_BRST_TIME_STOP",
85+
[](const void* context) {
86+
return reinterpret_cast<const BurstStatsData*>(context)->getEndTimestamps(
87+
Direction::Forward);
88+
},
89+
[](const void* context) {
90+
return reinterpret_cast<const BurstStatsData*>(context)->getEndTimestamps(
91+
Direction::Reverse);
92+
});
7893
handlers.insert(BurstStatsFields::SBI_BRST_TIME_STOP, sourceTimeStopField);
7994
handlers.insert(BurstStatsFields::DBI_BRST_TIME_STOP, destTimeStopField);
8095

8196
return schema;
8297
}
8398

84-
BurstStatsPlugin::BurstStatsPlugin([[maybe_unused]]const std::string& params, FieldManager& manager)
99+
BurstStatsPlugin::BurstStatsPlugin(
100+
[[maybe_unused]] const std::string& params,
101+
FieldManager& manager)
85102
{
86103
createBurstStatsSchema(manager, m_fieldHandlers);
87104
}
88105

89106
PluginInitResult BurstStatsPlugin::onInit(const FlowContext& flowContext, void* pluginContext)
90107
{
91108
auto* pluginData = std::construct_at(reinterpret_cast<BurstStatsData*>(pluginContext));
92-
109+
93110
std::optional<Burst> burst = pluginData->push(Direction::Forward);
94111
updateBursts(*burst, flowContext.packet);
95112

@@ -103,7 +120,7 @@ PluginInitResult BurstStatsPlugin::onInit(const FlowContext& flowContext, void*
103120
void BurstStatsPlugin::updateBursts(Burst& burst, const Packet& packet) noexcept
104121
{
105122
burst.packets++;
106-
burst.bytes += packet.ip_payload_len;
123+
burst.bytes += packet.ip_payload_len;
107124
burst.end.get() = packet.ts;
108125
if (burst.packets == 1) {
109126
burst.start.get() = packet.ts;
@@ -133,11 +150,12 @@ PluginUpdateResult BurstStatsPlugin::onUpdate(const FlowContext& flowContext, vo
133150
};
134151
}
135152

136-
PluginExportResult BurstStatsPlugin::onExport(const FlowRecord& flowRecord, [[maybe_unused]] void* pluginContext)
153+
PluginExportResult
154+
BurstStatsPlugin::onExport(const FlowRecord& flowRecord, [[maybe_unused]] void* pluginContext)
137155
{
138-
const uint32_t packetsTotal
139-
= static_cast<uint32_t>(
140-
flowRecord.directionalData[Direction::Forward].packets + flowRecord.directionalData[Direction::Reverse].packets);
156+
const uint32_t packetsTotal = static_cast<uint32_t>(
157+
flowRecord.directionalData[Direction::Forward].packets
158+
+ flowRecord.directionalData[Direction::Reverse].packets);
141159
if (packetsTotal <= MINIMAL_PACKETS_COUNT) {
142160
return {
143161
.flowAction = FlowAction::RemovePlugin,
@@ -171,6 +189,7 @@ PluginDataMemoryLayout BurstStatsPlugin::getDataMemoryLayout() const noexcept
171189
};
172190
}
173191

174-
static const PluginRegistrar<BurstStatsPlugin, ProcessPluginFactory> burstStatsRegistrar(burstStatsPluginManifest);
192+
static const PluginRegistrar<BurstStatsPlugin, ProcessPluginFactory>
193+
burstStatsRegistrar(burstStatsPluginManifest);
175194

176195
} // namespace ipxp

src/plugins/process/bstats/src/burstStats.hpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,20 @@
88
*
99
* Provides a plugin that extracts packet burst statistics of flows,
1010
* stores them in per-flow plugin data, and exposes fields via FieldManager.
11-
*
11+
*
1212
* @copyright Copyright (c) 2025 CESNET, z.s.p.o.
1313
*/
1414

1515
#pragma once
1616

17+
#include "burst.hpp"
18+
#include "burstStatsFields.hpp"
19+
1720
#include <sstream>
1821
#include <string>
19-
#include <processPlugin.hpp>
20-
//#include <fieldManager.hpp>
21-
#include <fieldHandlersEnum.hpp>
2222

23-
#include "burstStatsFields.hpp"
24-
#include "burst.hpp"
23+
#include <fieldHandlersEnum.hpp>
24+
#include <processPlugin.hpp>
2525

2626
namespace ipxp {
2727

@@ -31,7 +31,6 @@ namespace ipxp {
3131
*/
3232
class BurstStatsPlugin : public ProcessPlugin {
3333
public:
34-
3534
/**
3635
* @brief Constructs the BurstStats plugin.
3736
*
@@ -71,7 +70,7 @@ class BurstStatsPlugin : public ProcessPlugin {
7170
*
7271
* @param flowRecord The flow record containing aggregated flow data.
7372
* @param pluginContext Pointer to `BurstStatsData`.
74-
* @return RemovePlugin if packet count is less than `MINIMAL_PACKETS_COUNT`,
73+
* @return RemovePlugin if packet count is less than `MINIMAL_PACKETS_COUNT`,
7574
* else no action is required.
7675
*/
7776
PluginExportResult onExport(const FlowRecord& flowRecord, void* pluginContext) override;
@@ -89,10 +88,11 @@ class BurstStatsPlugin : public ProcessPlugin {
8988
PluginDataMemoryLayout getDataMemoryLayout() const noexcept override;
9089

9190
private:
92-
constexpr static std::size_t MINIMAL_PACKETS_COUNT = 3; ///< Minimal number of packets to consider the flow valid.
91+
constexpr static std::size_t MINIMAL_PACKETS_COUNT
92+
= 3; ///< Minimal number of packets to consider the flow valid.
9393

9494
void updateBursts(Burst& burst, const Packet& packet) noexcept;
95-
void makeAllFieldsUnavailable(FlowRecord& flowRecord) noexcept;
95+
void makeAllFieldsUnavailable(FlowRecord& flowRecord) noexcept;
9696

9797
FieldHandlers<BurstStatsFields> m_fieldHandlers;
9898
};

0 commit comments

Comments
 (0)