Skip to content

Commit 13a437e

Browse files
committed
Top 10 ports - Introduce TopPorts class
1 parent 70e7cc2 commit 13a437e

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

input/topPorts.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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+
13+
namespace ipxp {
14+
15+
TopPorts::TopPorts(size_t top_ports_count) noexcept
16+
: m_top_ports_count(top_ports_count)
17+
{
18+
}
19+
20+
void TopPorts::increment_tcp_frequency(uint16_t port) noexcept
21+
{
22+
m_tcp_port_frequencies[port]++;
23+
}
24+
25+
void TopPorts::increment_udp_frequency(uint16_t port) noexcept
26+
{
27+
m_udp_port_frequencies[port]++;
28+
}
29+
30+
std::string TopPorts::PortStats::to_string() const noexcept
31+
{
32+
return std::to_string(port) + "[" +
33+
(protocol == Protocol::TCP ? "TCP" : "UDP") + "] - " + std::to_string(frequency);
34+
}
35+
36+
std::vector<TopPorts::PortStats> TopPorts::get_top_ports() const noexcept
37+
{
38+
std::vector<PortStats> port_buffer(10);
39+
size_t ports_inserted = 0;
40+
41+
auto callback = [&, port = uint16_t{0}](size_t frequency, PortStats::Protocol protocol) mutable {
42+
auto port_pos = std::lower_bound(port_buffer.begin(), port_buffer.end(), frequency,
43+
[](const PortStats& port_frequency, size_t count) {
44+
return port_frequency.frequency >= count;
45+
});
46+
47+
if (port_pos != port_buffer.end()) {
48+
std::copy_backward(port_pos, std::prev(port_buffer.end()), port_buffer.end());
49+
*port_pos = PortStats{port, frequency, protocol};
50+
ports_inserted = std::min<size_t>(m_top_ports_count, ports_inserted + 1);
51+
}
52+
port++;
53+
};
54+
55+
std::for_each(m_tcp_port_frequencies.begin(), m_tcp_port_frequencies.end(), [callback](size_t frequency) mutable {
56+
callback(frequency, PortStats::Protocol::TCP);
57+
});
58+
std::for_each(m_udp_port_frequencies.begin(), m_udp_port_frequencies.end(), [callback](size_t frequency) mutable{
59+
callback(frequency, PortStats::Protocol::UDP);
60+
});
61+
62+
port_buffer.resize(std::min(m_top_ports_count, ports_inserted));
63+
return port_buffer;
64+
}
65+
66+
} // namespace ipxp

input/topPorts.hpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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 store.
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+
/**
35+
* \brief Increments number of times given udp port has been seen.
36+
* \param port Port to increment its frequency.
37+
*/
38+
void increment_udp_frequency(uint16_t port) noexcept;
39+
40+
/**
41+
* \brief Port frequency and protocol to which it belongs.
42+
*/
43+
struct PortStats {
44+
/**
45+
* \brief Protocol type.
46+
*/
47+
enum class Protocol {
48+
TCP,
49+
UDP
50+
};
51+
52+
uint16_t port; /**< Port number. */
53+
size_t frequency; /**< Number of times the port has been seen. */
54+
Protocol protocol; /**< Protocol to which the port belongs. */
55+
56+
/**
57+
* \brief Convert the port stats to string.
58+
* \return String representation of the port stats.
59+
*/
60+
std::string to_string() const noexcept;
61+
};
62+
63+
/**
64+
* \brief Get the top ports.
65+
* \return Vector of the most popular ports.
66+
*/
67+
std::vector<TopPorts::PortStats> get_top_ports() const noexcept;
68+
69+
private:
70+
std::array<std::size_t, std::numeric_limits<uint16_t>::max() + 1> m_tcp_port_frequencies {};
71+
std::array<std::size_t, std::numeric_limits<uint16_t>::max() + 1> m_udp_port_frequencies {};
72+
const size_t m_top_ports_count;
73+
};
74+
75+
} // namespace ipxp

0 commit comments

Comments
 (0)