Skip to content

Commit 03c4dc1

Browse files
committed
Top ports - introduce TopPorts class
1 parent 04b2f51 commit 03c4dc1

File tree

3 files changed

+154
-0
lines changed

3 files changed

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

0 commit comments

Comments
 (0)