Skip to content

Commit c8ab34b

Browse files
ZadamsaDamir Zainullin
authored andcommitted
Top ports - introduce TopPorts class
1 parent a24b8e2 commit c8ab34b

File tree

3 files changed

+157
-0
lines changed

3 files changed

+157
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
add_library(top-ports STATIC
2+
topPorts.cpp
3+
topPorts.hpp
4+
)
5+
6+
target_include_directories(top-ports PUBLIC
7+
${CMAKE_SOURCE_DIR}/include
8+
${CMAKE_BINARY_DIR}/src
9+
)
10+
11+
target_compile_options(top-ports PRIVATE -fPIC)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/**
2+
* \file topPorts.cpp
3+
* \brief TopPorts class implementation.
4+
* \author Damir Zainullin <[email protected]>
5+
* \date 2024
6+
*/
7+
8+
#include "topPorts.hpp"
9+
10+
#include <algorithm>
11+
#include <array>
12+
#include <cstdint>
13+
#include <functional>
14+
#include <limits>
15+
#include <string>
16+
#include <vector>
17+
18+
namespace ipxp {
19+
20+
TopPorts::TopPorts(size_t top_ports_count) noexcept
21+
: m_top_ports_count(top_ports_count)
22+
{
23+
}
24+
25+
std::string TopPorts::PortStats::to_string() const noexcept
26+
{
27+
return std::to_string(port) + "[" + (protocol == Protocol::TCP ? "TCP" : "UDP") + "] - "
28+
+ std::to_string(frequency);
29+
}
30+
31+
bool update_port_buffer(
32+
std::vector<TopPorts::PortStats>& port_buffer,
33+
TopPorts::PortStats port_stats) noexcept
34+
{
35+
auto port_pos = std::lower_bound(
36+
port_buffer.begin(),
37+
port_buffer.end(),
38+
port_stats.frequency,
39+
[](const TopPorts::PortStats& port_frequency, size_t count) {
40+
return port_frequency.frequency >= count;
41+
});
42+
43+
if (port_pos != port_buffer.end()) {
44+
std::copy_backward(port_pos, std::prev(port_buffer.end()), port_buffer.end());
45+
*port_pos = port_stats;
46+
return true;
47+
}
48+
return false;
49+
};
50+
51+
std::vector<TopPorts::PortStats> TopPorts::get_top_ports() const noexcept
52+
{
53+
std::vector<PortStats> port_buffer(m_top_ports_count);
54+
size_t ports_inserted = 0;
55+
56+
std::for_each(
57+
m_tcp_port_frequencies.begin(),
58+
m_tcp_port_frequencies.end(),
59+
[&, port = uint16_t {0}](size_t frequency) mutable {
60+
ports_inserted
61+
+= update_port_buffer(port_buffer, {port++, frequency, PortStats::Protocol::TCP});
62+
});
63+
std::for_each(
64+
m_udp_port_frequencies.begin(),
65+
m_udp_port_frequencies.end(),
66+
[&, port = uint16_t {0}](size_t frequency) mutable {
67+
ports_inserted
68+
+= update_port_buffer(port_buffer, {port++, frequency, PortStats::Protocol::UDP});
69+
});
70+
71+
port_buffer.resize(std::min(m_top_ports_count, ports_inserted));
72+
return port_buffer;
73+
}
74+
75+
} // namespace ipxp
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* \file topPorts.hpp
3+
* \brief TopPorts class declaration implementing the most popular ports.
4+
* \author Damir Zainullin <[email protected]>
5+
* \date 2024
6+
*/
7+
#pragma once
8+
9+
#include <array>
10+
#include <cstdint>
11+
#include <limits>
12+
#include <string>
13+
#include <vector>
14+
15+
namespace ipxp {
16+
/**
17+
* \brief Top ports counter.
18+
*/
19+
class TopPorts {
20+
public:
21+
/**
22+
* \brief Constructor.
23+
* \param top_ports_count Number of the most popular ports to track.
24+
*/
25+
TopPorts(size_t top_ports_count) noexcept;
26+
27+
/**
28+
* \brief Increments number of times given tcp port has been seen.
29+
* \param port Port to increment its frequency.
30+
*/
31+
void increment_tcp_frequency(uint16_t port) noexcept { m_tcp_port_frequencies[port]++; }
32+
33+
/**
34+
* \brief Increments number of times given udp port has been seen.
35+
* \param port Port to increment its frequency.
36+
*/
37+
void increment_udp_frequency(uint16_t port) noexcept { m_udp_port_frequencies[port]++; }
38+
39+
/**
40+
* \brief Port frequency and protocol to which it belongs.
41+
*/
42+
struct PortStats {
43+
/**
44+
* \brief Protocol type.
45+
*/
46+
enum class Protocol { TCP, UDP };
47+
48+
uint16_t port; /**< Port number. */
49+
size_t frequency; /**< Number of times the port has been seen. */
50+
Protocol protocol; /**< Protocol to which the port belongs. */
51+
52+
/**
53+
* \brief Convert the port stats to string.
54+
* \return String representation of the port stats.
55+
*/
56+
std::string to_string() const noexcept;
57+
};
58+
59+
/**
60+
* \brief Get the top ports.
61+
* \return Vector of the most popular ports.
62+
*/
63+
std::vector<TopPorts::PortStats> get_top_ports() const noexcept;
64+
65+
private:
66+
std::array<std::size_t, std::numeric_limits<uint16_t>::max() + 1> m_tcp_port_frequencies {};
67+
std::array<std::size_t, std::numeric_limits<uint16_t>::max() + 1> m_udp_port_frequencies {};
68+
const size_t m_top_ports_count;
69+
};
70+
71+
} // namespace ipxp

0 commit comments

Comments
 (0)