From c2c321eb9bed2a13f4d858ad990542706b6eaa0f Mon Sep 17 00:00:00 2001 From: Robert Jeutter Date: Sun, 24 Oct 2021 12:51:25 +0200 Subject: [PATCH] update 0.0.2 --- VERSION | 2 +- include/Configurator.hpp | 206 +-- include/DebugHelper.hpp | 11 + include/Definitions.h | 24 + include/Definitions.hpp | 19 +- include/Initializer.hpp | 18 +- include/Inspection.hpp | 314 +++++ include/PacketDissection/PacketContainer.hpp | 44 +- include/PacketDissection/PacketInfo.hpp | 8 +- .../PacketDissection/PacketInfoCreator.hpp | 28 +- include/PacketDissection/PacketInfoIpv4.hpp | 2 +- .../PacketDissection/PacketInfoIpv4Tcp.hpp | 26 +- .../PacketDissection/PacketInfoIpv4Udp.hpp | 2 +- include/PacketDissection/PacketProtTcp.hpp | 13 + include/RandomNumberGenerator.hpp | 11 + include/Threads/AttackThread.hpp | 119 +- include/Threads/DefenseThread.hpp | 40 +- include/Threads/ForwardingThread.hpp | 12 +- include/Threads/StatisticsThread.hpp | 51 +- include/Threads/Thread.hpp | 11 + include/Treatment/Treatment.hpp | 1129 ++++++++--------- include/Treatment/rand.h | 44 + source/Attacker/main.cpp | 293 ++--- source/Configurator.cpp | 83 +- source/DebugHelper.cpp | 2 +- source/Initializer.cpp | 59 +- source/Threads/DefenseThread.cpp | 134 +- source/Threads/StatisticsThread.cpp | 150 ++- source/main.cpp | 158 +-- source/meson.build | 9 +- 30 files changed, 1689 insertions(+), 1333 deletions(-) create mode 100644 include/Definitions.h create mode 100644 include/Inspection.hpp create mode 100644 include/Treatment/rand.h diff --git a/VERSION b/VERSION index 8a9ecc2..7bcd0e3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.1 \ No newline at end of file +0.0.2 \ No newline at end of file diff --git a/include/Configurator.hpp b/include/Configurator.hpp index 9587d89..e0337ae 100644 --- a/include/Configurator.hpp +++ b/include/Configurator.hpp @@ -1,3 +1,14 @@ +/** + * @file Configurator.hpp + * @author Johannes + * @brief + * @version 0.1 + * @date 2021-06-16 + * + * @copyright Copyright (c) 2021 + * + */ + #pragma once #include @@ -10,98 +21,111 @@ using json = nlohmann::json; -class Configurator{ - public: - /** - * @brief Checks if attribute exists in either the normal or the default config file - * - * @param att_name Name of attribute that is searched for - * @return true when attribute was found - * @return false when attribute wasn't found - */ - bool entry_exists(const std::string att_name); +class Configurator { + public: + /** + * @brief The Configurator is implemented as a singleton. This method + * returns a poiter to the Configurator object + * + * @return Configurator* poiter to singleton Configurator + */ + static Configurator* instance(); - //----------------------------------------------------------------------------------- - //------------------------------- Get-Methods --------------------------------------- - //----------------------------------------------------------------------------------- - - /** - * @brief Get value from config as string object - * - * @param att_name Name of attribute that is searched for - * @param default_value When set to true the method searches in the default config (default: false) - * @return std::string value - */ - std::string get_config_as_string(const std::string& att_name, - bool default_value = false); - /** - * @brief Get value from config as unsigned integer - * - * @param att_name Name of attribute that is searched for - * @param default_value When set to true the method searches in the default config (default: false) - * @return std::string value - */ - unsigned int get_config_as_unsigned_int(const std::string& att_name, - bool default_value = false); - /** - * @brief Get value from config as boolean - * - * @param att_name Name of attribute that is searched for - * @param default_value When set to true the method searches in the default config (default: false) - * @return std::string value - */ - bool get_config_as_bool(const std::string& att_name, + /** + * @brief Reads config and default config from json files + * + * @param path Path to standard config (which can be modified by the user) + * @param default_path Path to deafult config (default: + * "../default_config.json") + */ + void read_config(std::string path, + std::string default_path = "../default_config.json"); + + //----------------------------------------------------------------------------------- + //----------------------------------------------------------------------------------- + + /** + * @brief Checks if attribute exists in either the normal or the default + * config file + * + * @param att_name Name of attribute that is searched for + * @return true when attribute was found + * @return false when attribute wasn't found + */ + bool entry_exists(const std::string att_name); + + //----------------------------------------------------------------------------------- + //------------------------------- Get-Methods + //--------------------------------------- + //----------------------------------------------------------------------------------- + + /** + * @brief Get value from config as string object + * + * @param att_name Name of attribute that is searched for + * @param default_value When set to true the method searches in the default + * config (default: false) + * @return std::string value + */ + std::string get_config_as_string(const std::string& att_name, + bool default_value = false); + /** + * @brief Get value from config as unsigned integer + * + * @param att_name Name of attribute that is searched for + * @param default_value When set to true the method searches in the default + * config (default: false) + * @return std::string value + */ + unsigned int get_config_as_unsigned_int(const std::string& att_name, + bool default_value = false); + /** + * @brief Get value from config as boolean + * + * @param att_name Name of attribute that is searched for + * @param default_value When set to true the method searches in the default + * config (default: false) + * @return std::string value + */ + bool get_config_as_bool(const std::string& att_name, + bool default_value = false); + /** + * @brief Get value from config as float + * + * @param att_name Name of attribute that is searched for + * @param default_value When set to true the method searches in the default + * config (default: false) + * @return std::string value + */ + float get_config_as_float(const std::string& att_name, + bool default_value = false); + /** + * @brief Get value from config as double + * + * @param att_name Name of attribute that is searched for + * @param default_value When set to true the method searches in the default + * config (default: false) + * @return std::string value + */ + double get_config_as_double(const std::string& att_name, bool default_value = false); - /** - * @brief Get value from config as float - * - * @param att_name Name of attribute that is searched for - * @param default_value When set to true the method searches in the default config (default: false) - * @return std::string value - */ - float get_config_as_float(const std::string& att_name, - bool default_value = false); - /** - * @brief Get value from config as double - * - * @param att_name Name of attribute that is searched for - * @param default_value When set to true the method searches in the default config (default: false) - * @return std::string value - */ - double get_config_as_double(const std::string& att_name, - bool default_value = false); - /** - * @brief Reads config and default config from json files - * - * @param path Path to standard config (which can be modified by the user) - * @param default_path Path to default config (default: "../default_config.json") - */ - void read_config(std::string path, - std::string default_path = "../default_config.json"); - - /** - * @brief The Configurator is implemented as a singleton. This method returns a poiter to the Configurator object - * - * @return Configurator* poiter to singleton Configurator - */ - static Configurator* instance(); - - private: - json _config; ///< standard config (can be modified by the user) - json _default_config; ///< default config - template T get_value_from_config(const std::string& att_name, bool default_value); - static Configurator* _instance; ///< singleton Configurator - Configurator(); - Configurator(const Configurator&); - ~Configurator(); - class CGuard{ - public: - ~CGuard(){ - if( NULL != Configurator::_instance ){ - delete Configurator::_instance; - Configurator::_instance = nullptr; - } - } - }; + private: + json _config; ///< standard config (can be modified by the user) + json _default_config; ///< default config + static Configurator* _instance; ///< singleton Configurator + Configurator(); + Configurator(const Configurator&); + ~Configurator(); + class CGuard { + public: + ~CGuard() { + if (NULL != Configurator::_instance) { + delete Configurator::_instance; + Configurator::_instance = nullptr; + } + } + }; + template + T get_value_from_config(const std::string& att_name, bool default_value); }; diff --git a/include/DebugHelper.hpp b/include/DebugHelper.hpp index 59d6c72..c6d9412 100644 --- a/include/DebugHelper.hpp +++ b/include/DebugHelper.hpp @@ -1,3 +1,14 @@ +/** + * @file DebugHelper.hpp + * @author Tobias + * @brief + * @version 0.1 + * @date 2021-07-12 + * + * @copyright Copyright (c) 2021 + * + */ + #pragma once #include diff --git a/include/Definitions.h b/include/Definitions.h new file mode 100644 index 0000000..13b7e9c --- /dev/null +++ b/include/Definitions.h @@ -0,0 +1,24 @@ +#pragma once + +#define RX_RING_SIZE 1024 +#define TX_RING_SIZE 1024 + +// only needed for mempool creation. was replaced. +// NUM_MBUF_POOL_ELEMENTS is used instead +//#define NUM_MBUFS 8191 + +// Argument "n" in rte_pktmbuf_pool_create +#define NUM_MBUF_POOL_ELEMENTS 32767 + +#define BURST_SIZE 32 + +#define RSS_HASH_KEY_LENGTH 40 + +// used in initializer +#define NUM_NON_WORKER_THREADS 2 + +// used in PacketContainer. +// predefined size of array of mbuf-arrays +#define NUM_MBUF_ARRS 5000 + +#define TCP_RX_WINDOW 16384 diff --git a/include/Definitions.hpp b/include/Definitions.hpp index 32d6d1d..2418ca1 100644 --- a/include/Definitions.hpp +++ b/include/Definitions.hpp @@ -1,3 +1,14 @@ +/** + * @file Definitions.h + * @author Jakob + * @brief + * @version 0.1 + * @date 2021-07-12 + * + * @copyright Copyright (c) 2021 + * + */ + #pragma once #define RX_RING_SIZE 1024 @@ -10,8 +21,7 @@ // Argument "n" in rte_pktmbuf_pool_create #define NUM_MBUF_POOL_ELEMENTS 32767 -#define BURST_SIZE 64 -// #define MBUF_ARR_SIZE 2 * BURST_SIZE +#define BURST_SIZE 32 #define RSS_HASH_KEY_LENGTH 40 @@ -31,4 +41,7 @@ #define LOG_END "\e[0m" // ATTACKE -//#define LOG_PKTS_SENT \ No newline at end of file +//#define SINGLE_ITERATION +//#define LOG_PKTS_SENT +//#define SEND_ONCE +//#define SEND_PKTS_EVERY_NTH_ITERATION 1000 \ No newline at end of file diff --git a/include/Initializer.hpp b/include/Initializer.hpp index f1cd818..6d3f681 100644 --- a/include/Initializer.hpp +++ b/include/Initializer.hpp @@ -1,4 +1,13 @@ -#pragma once +/** + * @file Initializer.hpp + * @author Robert + * @brief + * @version 0.1 + * @date 2021-07-12 + * + * @copyright Copyright (c) 2021 + * + */ #include #include @@ -14,7 +23,6 @@ class Initializer { * * @param[in] argc * @param[in] argv - * @param[out] mbuf_pool * @param[out] nb_worker_threads */ rte_mempool* init_dpdk(int argc, char** argv, uint16_t& nb_worker_threads); @@ -30,10 +38,13 @@ class Initializer { * Setting up TX/RX queues per ethernet port. Then starting the device and * printing MAC address * + * @param port_conf * @param port set port identifier to use * @param mbuf_pool set mempool of dpdk to use * @param[in] nb_worker_threads number of worker threads * @return 0 or error code + * + * \todo describe port_conf */ void init_port(rte_eth_conf port_conf, uint16_t port, struct rte_mempool* mbuf_pool, uint16_t nb_worker_threads); @@ -41,7 +52,10 @@ class Initializer { /** * @brief initializes number of threads * + * @param nb_non_worker_threads * @param[out] nb_worker_threads + * + * \todo nb_non_worker_threads description */ void init_number_threads(uint16_t nb_non_worker_threads, uint16_t& nb_worker_threads); diff --git a/include/Inspection.hpp b/include/Inspection.hpp new file mode 100644 index 0000000..1b16709 --- /dev/null +++ b/include/Inspection.hpp @@ -0,0 +1,314 @@ +/** + * @file Inspection.hpp + * @author Robert + * @brief the Inspection get packets polled by the PacketContainer and evaluates + * each packets legitimation. Invalid packets will be dropped while valid + * packets are forwarded to the Treatment. + * @version 0.5 + * @date 2021-06-14 + * + * @copyright Copyright (c) 2021 + * + */ + +#pragma once +#include "Configurator.hpp" +#include "PacketDissection/PacketContainer.hpp" +#include +#include + +/** + * @brief the Inspection evaluates PacketContainers and forwards valid packets + * while illegimite packets are destroyed + * + */ +class Inspection { + public: + /** + * @brief Construct a new Inspection object with default arguments from + * configuration file + * + */ + inline Inspection() + : _UDP_flood_weight( + Configurator::instance()->get_config_as_unsigned_int( + "UDP_flood_weight")), + _TCP_flood_weight( + Configurator::instance()->get_config_as_unsigned_int( + "TCP_flood_weight")), + _ICMP_flood_weight( + Configurator::instance()->get_config_as_unsigned_int( + "ICMP_flood_weight")), + _SYNFIN_weight(Configurator::instance()->get_config_as_unsigned_int( + "SYNFIN_weight")), + _SMALLWINDOW_weight( + Configurator::instance()->get_config_as_unsigned_int( + "SMALLWINDOW_weight")), + _threshold_UDP(Configurator::instance()->get_config_as_unsigned_int( + "threshold_UDP")), + _threshold_TCP(Configurator::instance()->get_config_as_unsigned_int( + "threshold_TCP")), + _threshold_ICMP(Configurator::instance()->get_config_as_unsigned_int( + "threshold_ICMP")), + _current_threshold_UDP( + Configurator::instance()->get_config_as_unsigned_int( + "threshold_UDP")), + _current_threshold_TCP( + Configurator::instance()->get_config_as_unsigned_int( + "threshold_TCP")), + _current_threshold_ICMP( + Configurator::instance()->get_config_as_unsigned_int( + "threshold_ICMP")), + _min_window_size(Configurator::instance()->get_config_as_unsigned_int( + "min_window_size")), + _attack_level(0), _packetrate_UDP(0), _packetrate_TCP(0), + _packetrate_ICMP(0), _clock_frequence(rte_get_tsc_hz()) {} + + /** + * @brief update the current stats and send them to global statistic + * + * @param udp_packets + * @param tcp_packets + * @param icmp_packets + * @param UDP_Floods + * @param TCP_Floods + * @param ICMP_Floods + * @param SYN_FINs + * @param Small_Windows + * @param duration + */ + inline void update_stats(uint16_t udp_packets, uint16_t tcp_packets, + uint16_t icmp_packets, uint16_t UDP_Floods, + uint16_t TCP_Floods, uint16_t ICMP_Floods, + uint16_t SYN_FINs, uint16_t Small_Windows, + uint64_t duration) { + duration = duration > 1 ? duration : 1; + duration = duration * _clock_frequence; + // calculate new packetrate based on relative duration + _packetrate_UDP = udp_packets / duration; + _packetrate_TCP = tcp_packets / duration; + _packetrate_ICMP = icmp_packets / duration; + + // calculate attack level based on diverent counted attacks and their + // weight on ddos + /// \todo (can) adapting weights to most occuring attacks + _attack_level = + UDP_Floods * _UDP_flood_weight + TCP_Floods * _TCP_flood_weight + + ICMP_Floods * _ICMP_flood_weight + SYN_FINs * _SYNFIN_weight + + Small_Windows * _SMALLWINDOW_weight; + + // calculate new threshold + _current_threshold_UDP = _threshold_UDP - (1 / _threshold_UDP) * + _attack_level * + _attack_level; + _current_threshold_TCP = _threshold_TCP - (1 / _threshold_TCP) * + _attack_level * + _attack_level; + _current_threshold_ICMP = _threshold_ICMP - (1 / _threshold_ICMP) * + _attack_level * + _attack_level; + + /// \todo send to global statistic + /* Stats update_statistics( + attacks = UDP_Floods + TCP_Floods + ICMP_Floods + SYN_FINs + + Small_Windows; + // bytes + // dropped + packets = udp_packets + tcp_packets + icmp_packets; + work_time = duration; + */ + } + + /** + * @brief get packet container reference and run analysis on each packet + * included in the PacketContainer + * + * @param pkt_container PacketContainer with certain amount of packets + * + * \startuml + * title analyzePacket(PacketContainer) + * start + * :create temporary counters; + * :initiate packetIndex at 0; + * while(PacketContainer size > current packetIndex) + * :extract PacketInfo from PacketContainer at packetIndex; + * if (is UDP Protocoll) then (yes) + * :increase UDP counter; + * if(UDP Threshold met) then (yes) + * #FF0000:detected UDP Flood; + * :increase attack counter; + * :drop packet; + * else (no) + * endif + * elseif (is TCP Protocoll) then (yes) + * :increase TCP counter; + * if(TCP Threshold met) then (yes) + * #FF0000:detected TCP Flood; + * :increase attack counter; + * :drop packet; + * else (no) + * endif + * if(WindowSize too small) then (yes) + * #FF0000:detected Small/Zero Window; + * :increase attack counter; + * :drop packet; + * else (no) + * endif + * if(Flag Pattern forbidden) then (yes) + * #FF0000:detected SYN-FIN(-ACK); + * :increase attack counter; + * :drop packet; + * else (no) + * endif + * elseif (is ICMP Protocoll) then (yes) + * :increase ICMP counter; + * if(ICMP Threshold met) then (yes) + * #FF0000:detected ICMP Flood; + * :increase attack counter; + * :drop packet; + * else (no) + * endif + * else (no protocoll of interest) + * endif + * :increase packetIndex; + * endwhile + * :update local threshold with temporary counters; + * :send temporary counters to global statistic; + * end + * \enduml + */ + inline void analyze_container(PacketContainer* pkt_container) { + uint16_t temp_udp_packets = 0; + uint16_t temp_tcp_packets = 0; + uint16_t temp_icmp_packets = 0; + + uint16_t temp_attack_UDP_Flood = 0; + uint16_t temp_attack_TCP_Flood = 0; + uint16_t temp_attack_ICMP_Flood = 0; + uint16_t temp_attack_SYN_FIN = 0; + uint16_t temp_attack_Small_Window = 0; + + uint64_t startTime = rte_get_tsc_cycles(); + + for (int index = 0; + index < pkt_container->get_number_of_polled_packets(); ++index) { + PacketInfo* packetInfo = pkt_container->get_packet_at_index(index); + if (packetInfo != nullptr) { + switch (packetInfo->get_type()) { + case IPv4UDP: { + ++temp_udp_packets; + if (temp_udp_packets > _current_threshold_UDP) { + // alt: if(_current_threshold_UDP > temp_udp_packets) { + ++temp_attack_UDP_Flood; + // UDP Flood + /// \todo (can) create patchmap and allow last recent + /// established connections to connect further matching + /// srcIp & dstIp + pkt_container->drop_packet(index); + break; + } + // forward packet + break; + } + case IPv4TCP: { + PacketInfoIpv4Tcp* TCP4packetInfo = + static_cast(packetInfo); + ++temp_tcp_packets; + if (temp_tcp_packets > _current_threshold_TCP) { + // TCP Flood + /// \todo (can) create patchmap and allow last recent + /// established connections to connect further matching + /// srcIp & dstIp + ++temp_attack_TCP_Flood; + pkt_container->drop_packet(index); + break; + } + if (TCP4packetInfo->get_window_size() < _min_window_size) { + // Zero/Small Window + ++temp_attack_Small_Window; + pkt_container->drop_packet(index); + break; + } + if ((uint8_t(TCP4packetInfo->get_flags()) & 0b00000011) == + 0b00000011) { + // flags in reverse format + // FIN,SYN,RST,PSH,ACK,URG,ECE,CWR SYN-FIN/SYN-FIN-ACK + ++temp_attack_SYN_FIN; + pkt_container->drop_packet(index); + break; + } + // forward packet + break; + } + case IPv4ICMP: { + ++temp_icmp_packets; + if (temp_icmp_packets > _current_threshold_ICMP) { + // ICMP Flood + ++temp_attack_ICMP_Flood; + pkt_container->drop_packet(index); + break; + } + // forward packet + break; + } + default: { // not identifyable or not of interest + // forward packet + break; + } + } + } + } + + uint64_t endTime = rte_get_tsc_cycles(); + + update_stats(temp_udp_packets, temp_tcp_packets, temp_icmp_packets, + temp_attack_UDP_Flood, temp_attack_TCP_Flood, + temp_attack_ICMP_Flood, temp_attack_SYN_FIN, + temp_attack_Small_Window, (uint64_t)endTime - startTime); + return; + } + + uint16_t get_UDP_packet_rate() { return _packetrate_UDP; }; + uint16_t get_TCP_packet_rate() { return _packetrate_TCP; }; + uint16_t get_ICMP_packet_rate() { return _packetrate_ICMP; }; + uint16_t get_UDP_threshold() { return _current_threshold_UDP; }; + uint16_t get_TCP_threshold() { return _current_threshold_TCP; }; + uint16_t get_ICMP_threshold() { return _current_threshold_ICMP; }; + uint16_t get_attack_level() { return _attack_level; }; + + private: + /// weight of UDP Flood attacks + uint8_t _UDP_flood_weight; + /// weight of TCP Flood attacks + uint8_t _TCP_flood_weight; + /// weight of ICMP Flood attacks + uint8_t _ICMP_flood_weight; + /// weight of SYN-FIN and SYN_FIN_ACK attacks + uint8_t _SYNFIN_weight; + /// weight of Zero/Small Window attacks + uint8_t _SMALLWINDOW_weight; + /// absolute threshold of udp packets + uint16_t _threshold_UDP; + /// absolute threshold of tcp packets + uint16_t _threshold_TCP; + /// absolute threshold of icmp packets + uint16_t _threshold_ICMP; + /// current threshold of udp packets + uint16_t _current_threshold_UDP; + /// current threshold of tcp packets + uint16_t _current_threshold_TCP; + /// current threshold of icmp packets + uint16_t _current_threshold_ICMP; + /// min window size for no-small-window + uint16_t _min_window_size; + /// current attack level + uint16_t _attack_level; + /// current packetrate of udp packets + uint64_t _packetrate_UDP; + /// current packetrate of tcp packets + uint64_t _packetrate_TCP; + /// current packetrate of icmp packets + uint64_t _packetrate_ICMP; + /// TSC frequency for this lcore + uint64_t _clock_frequence; +}; diff --git a/include/PacketDissection/PacketContainer.hpp b/include/PacketDissection/PacketContainer.hpp index 9029738..3017a54 100644 --- a/include/PacketDissection/PacketContainer.hpp +++ b/include/PacketDissection/PacketContainer.hpp @@ -1,3 +1,14 @@ +/** + * @file PacketContainer.hpp + * @author Jakob, Tobias + * @brief + * @version 0.1 + * @date 2021-06-26 + * + * @copyright Copyright (c) 2021 + * + */ + #pragma once #include @@ -12,6 +23,8 @@ #include "PacketDissection/PacketInfo.hpp" #include "PacketDissection/PacketInfoCreator.hpp" +class PacketInfoIpv4Tcp; + #define ERROR_STR_INDEX_OUT_OF_BOUNDS \ "index is out of bounds of PacketContainer. The highest possible index " \ "can be accessed by get_total_number_of_packets()." @@ -71,10 +84,10 @@ class PacketContainer { inline PacketContainer(struct rte_mempool* mbuf_pool, uint16_t entrance_port, uint16_t exit_port, uint16_t rx_queue_number, uint16_t tx_queue_number) - : _mempool(mbuf_pool), _entrance_port(entrance_port), - _exit_port(exit_port), _nb_pkts_polled(0), _nb_pkts_total(0), - _nb_pkts_dropped(0), _nb_pkt_arrays(1), - _rx_queue_number(rx_queue_number), _tx_queue_number(tx_queue_number) { + : _mempool(mbuf_pool), _rx_queue_number(rx_queue_number), _tx_queue_number(tx_queue_number), + _entrance_port(entrance_port), _exit_port(exit_port), _nb_pkts_polled(0), + _nb_pkts_total(0), _nb_pkt_arrays(1), _nb_pkts_dropped(0) + { for (int i = 0; i < NUM_MBUF_ARRS; ++i) { _nb_mbufs_in_mbuf_arr[i] = 0; @@ -263,9 +276,12 @@ class PacketContainer { * be adopted. These are set as * parameter of the function call. * - * @param[in] pkt_container packet container pointer to the packet to be - * added + * @param[in] pkt_container packet container pointer to the packet to be added + * @param pkt_info * @return index of the newly added packet + * \todo warning: parameter 'pkt_info' is not documented + * \todo pkt_container remove description? + */ inline int add_packet(PacketInfo* pkt_info) { int i, j; @@ -452,7 +468,7 @@ class PacketContainer { * will be given to the send_packets_to_port method of the * NetworkPacketHandler. */ - inline void reorder_mbuf_arrays() { + void reorder_mbuf_arrays() { if (likely(_nb_pkts_total > 0)) { for (int i = 0; i < _nb_pkt_arrays; ++i) { @@ -486,8 +502,7 @@ class PacketContainer { * @param[out] i * @param[out] j */ - inline void calculate_array_coordinates_from_index(int index, int& i, - int& j) { + void calculate_array_coordinates_from_index(int index, int& i, int& j) { i = (index - (index % BURST_SIZE)) / BURST_SIZE; j = index % BURST_SIZE; } @@ -503,8 +518,7 @@ class PacketContainer { * @param[in] j second dimension index * @param[out] index */ - inline void calculate_index_from_array_coordinates(int i, int j, - int& index) { + void calculate_index_from_array_coordinates(int i, int j, int& index) { index = i * BURST_SIZE + j; } @@ -512,8 +526,8 @@ class PacketContainer { * @brief Set the _state of the container to EMPTY * and assign variables to 0. */ - inline void empty_container() { - int nb_pkts_remaining = _nb_pkts_total; + void empty_container() { + //int nb_pkts_remaining = _nb_pkts_total; for (int i = 0; i < _nb_pkt_arrays; ++i) { int len = _nb_mbufs_in_mbuf_arr[i]; @@ -542,7 +556,7 @@ class PacketContainer { * corresponding index in PacketInfo Array * */ - inline void extract_header_info() { + void extract_header_info() { for (int i = 0; i < _nb_pkts_polled; ++i) { _pkt_info_arrs[0][i] = fill_info(_mbuf_arrs[0][i], _pkt_info_arrs[0][i]); @@ -556,7 +570,7 @@ class PacketContainer { * for which a PacketInfo should be created * @param[out] pkt_inf newly created PacketInfo */ - inline PacketInfo* fill_info(rte_mbuf* mbuf, PacketInfo* pkt_inf) { + PacketInfo* fill_info(rte_mbuf* mbuf, PacketInfo* pkt_inf) { pkt_inf = PacketInfoCreator::create_pkt_info(mbuf); return pkt_inf; } diff --git a/include/PacketDissection/PacketInfo.hpp b/include/PacketDissection/PacketInfo.hpp index 2e827d6..e0e63dd 100644 --- a/include/PacketDissection/PacketInfo.hpp +++ b/include/PacketDissection/PacketInfo.hpp @@ -26,10 +26,10 @@ enum PacketType { class PacketInfo { public: - inline PacketInfo() : _type(NONE), _mbuf(nullptr), _eth_hdr(nullptr) {} + inline PacketInfo() : _type(NONE), _eth_hdr(nullptr), _mbuf(nullptr) {} inline PacketInfo(rte_mbuf* const mbuf, rte_ether_hdr* const eth_hdr) - : _type(NONE), _mbuf(mbuf), _eth_hdr(eth_hdr) {} + : _type(NONE), _eth_hdr(eth_hdr), _mbuf(mbuf) {} inline ~PacketInfo() { //_mbuf = nullptr; @@ -66,10 +66,10 @@ class PacketInfo { protected: inline PacketInfo(PacketType const type, rte_mbuf* const mbuf, rte_ether_hdr* const eth_hdr) - : _type(type), _mbuf(mbuf), _eth_hdr(eth_hdr) {} + : _type(type), _eth_hdr(eth_hdr), _mbuf(mbuf) {} inline PacketInfo(PacketType const type, rte_mbuf* const mbuf) - : _type(type), _mbuf(mbuf), _eth_hdr(nullptr) {} + : _type(type), _eth_hdr(nullptr), _mbuf(mbuf) {} PacketType const _type; rte_ether_hdr* const _eth_hdr; diff --git a/include/PacketDissection/PacketInfoCreator.hpp b/include/PacketDissection/PacketInfoCreator.hpp index 7173174..7b98f9d 100644 --- a/include/PacketDissection/PacketInfoCreator.hpp +++ b/include/PacketDissection/PacketInfoCreator.hpp @@ -4,12 +4,11 @@ * @brief * @date 2021-06-16 */ + #pragma once #include - #include - #include "Definitions.hpp" #include "PacketDissection/PacketInfo.hpp" #include "PacketDissection/PacketInfoIpv4.hpp" @@ -31,7 +30,7 @@ class PacketInfoCreator { */ inline static PacketInfo* create_pkt_info(rte_mbuf* mbuf) { struct rte_ether_hdr* eth_hdr; - eth_hdr = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr*); + eth_hdr = rte_pktmbuf_mtod(mbuf, rte_ether_hdr*); uint16_t offset = (uint16_t)sizeof(struct rte_ether_hdr); /// from here on we know the l3 type @@ -266,25 +265,4 @@ class PacketInfoCreator { break; } } - - inline static bool is_ipv4_tcp(rte_mbuf* mbuf) { - struct rte_ether_hdr* eth_hdr; - eth_hdr = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr*); - - if (rte_be_to_cpu_16(eth_hdr->ether_type) == ETHER_TYPE_IPv4) { - uint16_t offset = (uint16_t)sizeof(struct rte_ether_hdr); - struct rte_ipv4_hdr* ip4_hdr; - ip4_hdr = - rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr*, offset); - uint8_t protocol_id = ip4_hdr->next_proto_id; - - if (protocol_id == 6) { // TCP - return true; - } else { - return false; - } - } else { - return false; - } - } -}; \ No newline at end of file +}; diff --git a/include/PacketDissection/PacketInfoIpv4.hpp b/include/PacketDissection/PacketInfoIpv4.hpp index a160961..6261df4 100644 --- a/include/PacketDissection/PacketInfoIpv4.hpp +++ b/include/PacketDissection/PacketInfoIpv4.hpp @@ -13,8 +13,8 @@ #include #include -#include "Definitions.hpp" #include "PacketDissection/PacketInfo.hpp" +#include "Definitions.hpp" #define IP_HDR_LEN 20 #define VERSION_AND_IP_HDR_LEN 0b01000101 diff --git a/include/PacketDissection/PacketInfoIpv4Tcp.hpp b/include/PacketDissection/PacketInfoIpv4Tcp.hpp index de21a11..ea7ffc3 100644 --- a/include/PacketDissection/PacketInfoIpv4Tcp.hpp +++ b/include/PacketDissection/PacketInfoIpv4Tcp.hpp @@ -13,37 +13,26 @@ #include #include -#include "DebugHelper.hpp" -#include "Definitions.hpp" #include "PacketDissection/PacketInfoIpv4.hpp" #include "PacketDissection/PacketProtTcp.hpp" +#include "DebugHelper.hpp" +#include "Definitions.hpp" class PacketInfoIpv4Tcp : public PacketInfoIpv4 { public: inline PacketInfoIpv4Tcp(); - inline PacketInfoIpv4Tcp(rte_mbuf* mbuf) - : PacketInfoIpv4( - IPv4TCP, mbuf, rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr*), - rte_pktmbuf_mtod_offset(mbuf, struct rte_ipv4_hdr*, - (uint16_t)sizeof(struct rte_ether_hdr))) - , _tcp_hdr(rte_pktmbuf_mtod_offset( - mbuf, struct rte_tcp_hdr*, - (sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr)))) {} - inline PacketInfoIpv4Tcp(rte_mbuf* mbuf, rte_ether_hdr* eth_hdr, rte_ipv4_hdr* ip_hdr, rte_tcp_hdr* l4_hdr) - : PacketInfoIpv4(IPv4TCP, mbuf, eth_hdr, ip_hdr) - , _tcp_hdr(l4_hdr) {} + : PacketInfoIpv4(IPv4TCP, mbuf, eth_hdr, ip_hdr), _tcp_hdr(l4_hdr) {} inline PacketInfoIpv4Tcp(rte_mbuf* mbuf, rte_ipv4_hdr* ip_hdr, rte_tcp_hdr* l4_hdr) - : PacketInfoIpv4(IPv4TCP, mbuf, ip_hdr) - , _tcp_hdr(l4_hdr) {} + : PacketInfoIpv4(IPv4TCP, mbuf, ip_hdr), _tcp_hdr(l4_hdr) {} inline ~PacketInfoIpv4Tcp() { // PacketInfoIpv4::~PacketInfoIpv4(); - // _tcp_hdr = nullptr; + _tcp_hdr = nullptr; } /** @@ -88,7 +77,7 @@ class PacketInfoIpv4Tcp : public PacketInfoIpv4 { * @return uint8_t */ inline uint8_t get_flags() { - const char desc[] = "mbuf"; + //const char desc[] = "mbuf"; return PacketProtTcp::get_flags( _tcp_hdr); // these are FIN to CWR flag, but // i am not shure in which order @@ -185,6 +174,7 @@ class PacketInfoIpv4Tcp : public PacketInfoIpv4 { rte_ether_addr src_mac, rte_ether_addr dst_mac, uint32_t src_ip, uint32_t dst_ip, uint16_t src_port, uint16_t dst_port, uint32_t seq_num, uint32_t ack_num, uint8_t flags, uint16_t tcp_window) { + // const char desc[] = "mbuf"; // let PacketInfo handle ethernet filling @@ -214,6 +204,7 @@ class PacketInfoIpv4Tcp : public PacketInfoIpv4 { } inline void prepare_offloading_checksums() { + rte_mbuf* mbuf = get_mbuf(); mbuf->ol_flags = PKT_TX_IPV4 | PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM; mbuf->l4_len = sizeof(struct rte_tcp_hdr); @@ -228,4 +219,5 @@ class PacketInfoIpv4Tcp : public PacketInfoIpv4 { private: rte_tcp_hdr* _tcp_hdr; + }; \ No newline at end of file diff --git a/include/PacketDissection/PacketInfoIpv4Udp.hpp b/include/PacketDissection/PacketInfoIpv4Udp.hpp index 9c263af..8b3271f 100644 --- a/include/PacketDissection/PacketInfoIpv4Udp.hpp +++ b/include/PacketDissection/PacketInfoIpv4Udp.hpp @@ -1,6 +1,6 @@ /** * @file PacketInfoIpv4Udp.hpp - * @author @Tobias + * @author Tobias * @brief class to provide packets IPv4 and UDP header information * @date 2021-06-08 * diff --git a/include/PacketDissection/PacketProtTcp.hpp b/include/PacketDissection/PacketProtTcp.hpp index ac2a788..65f85b8 100644 --- a/include/PacketDissection/PacketProtTcp.hpp +++ b/include/PacketDissection/PacketProtTcp.hpp @@ -25,7 +25,9 @@ class PacketProtTcp { /** * @brief Set packets TCP sequence number * + * @param tcp_hdr * @param seq_num + * \todo describe param tcp_hdr */ inline static void set_seq_num(rte_tcp_hdr* tcp_hdr, uint32_t seq_num) { tcp_hdr->sent_seq = rte_cpu_to_be_32(seq_num); @@ -34,7 +36,9 @@ class PacketProtTcp { /** * @brief Set packets TCP acknowledgment number * + * @param tcp_hdr * @param ack_num + * \todo describe param tcp_hdr */ inline static void set_ack_num(rte_tcp_hdr* tcp_hdr, uint32_t ack_num) { tcp_hdr->recv_ack = rte_cpu_to_be_32(ack_num); @@ -43,7 +47,10 @@ class PacketProtTcp { /** * @brief Get packets TCP destination port * + * @param tcp_hdr * @return uint16_t + * + * \todo describe param tcp_hdr */ inline static uint16_t get_dst_port(rte_tcp_hdr* tcp_hdr) { return rte_be_to_cpu_16(tcp_hdr->dst_port); @@ -52,7 +59,9 @@ class PacketProtTcp { /** * @brief Get packets TCP source port * + * @param tcp_hdr * @return uint16_t + * \todo describe param tcp_hdr */ inline static uint16_t get_src_port(rte_tcp_hdr* tcp_hdr) { return rte_be_to_cpu_16(tcp_hdr->src_port); @@ -61,7 +70,9 @@ class PacketProtTcp { /** * @brief Get packets TCP flags * MSB is CWR flag, LSB is FIN flag, NS flag not included + * @param tcp_hdr * @return uint8_t + * \todo describe param tcp_hdr */ inline static uint8_t get_flags(rte_tcp_hdr* tcp_hdr) { return tcp_hdr->tcp_flags; // these are FIN to CWR flag, but i am not @@ -165,6 +176,8 @@ class PacketProtTcp { * If this PacketInfo has a _mbuf and this _mbuf is empty, * then all IP and TCP header information is filled in. * This function doesn't create a new mbuf. + * @param tcp_hdr + * @param mbuf * @param src_ip IP address packet originally originated from * @param dst_ip IP address packet is going to be send to * @param src_port TCP port packet originally was send from diff --git a/include/RandomNumberGenerator.hpp b/include/RandomNumberGenerator.hpp index c887a1b..3d52c18 100644 --- a/include/RandomNumberGenerator.hpp +++ b/include/RandomNumberGenerator.hpp @@ -1,3 +1,14 @@ +/** + * @file RandomNumberGenerator.hpp + * @author Jakob, Tim + * @brief + * @version 0.1 + * @date 2021-07-12 + * + * @copyright Copyright (c) 2021 + * + */ + #pragma once #include diff --git a/include/Threads/AttackThread.hpp b/include/Threads/AttackThread.hpp index 733ce4d..9d09ff1 100644 --- a/include/Threads/AttackThread.hpp +++ b/include/Threads/AttackThread.hpp @@ -1,14 +1,24 @@ +/** + * @file AttackThread.hpp + * @author Jakob + * @brief + * @version 0.1 + * @date 2021-07-12 + * + * @copyright Copyright (c) 2021 + * + */ #pragma once #include -#include "PacketDissection/PacketContainerLean.hpp" +#include "PacketDissection/PacketContainer.hpp" #include "PacketDissection/PacketInfo.hpp" #include "PacketDissection/PacketInfoIpv4Tcp.hpp" #include "RandomNumberGenerator.hpp" #include "Threads/ForwardingThread.hpp" -class AttackThread : public Thread { +class AttackThread : public ForwardingThread { private: inline void run() { std::cout << "\nRunning on lcore " << rte_lcore_id() @@ -16,7 +26,6 @@ class AttackThread : public Thread { << std::endl; while (likely(_quit == false)) { - // have skip iterate field in config and skip for nb of packets iterate(); #ifdef SINGLE_ITERATION _quit = false; @@ -50,15 +59,16 @@ class AttackThread : public Thread { uint64_t _data_rate_per_cycle; uint64_t _delta_cycles_mean; - uint64_t _total_nb_pkts_to_dave; - uint64_t _total_nb_pkts_from_dave; - uint64_t _total_nb_pkts_to_alice; + uint64_t _total_nb_atk_pkts; + uint64_t _total_nb_pkts_to_alcie; uint64_t _total_data_volume_to_alice; uint64_t _total_nb_pkts_from_alice; uint64_t _total_data_volume_from_alice; + // ============ needed for special define options + int _iterations; - uint _call_send_pkts_every_nth_iteration; + bool _send; // ============ not needed @@ -80,12 +90,6 @@ class AttackThread : public Thread { * variables. * * @param[in] pkt_size - * @param[in] cycles - * @param[in] delta_cycles - * @param[in] cycles_old - * @param[in] data_volume - * @param[in] data_rate_per_cycle - * @param[out] nb_attack_packets */ inline void calculate_nb_attack_packets(int pkt_size) { @@ -126,7 +130,7 @@ class AttackThread : public Thread { */ inline uint32_t calculate_ipv4_address(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4) { - return byte1 * 2 ^ 24 + byte2 * 2 ^ 16 + byte3 * 2 ^ 8 + byte4; + return (byte1 * 2 ^ 24) + (byte2 * 2 ^ 16) + (byte3 * 2 ^ 8) + byte4; } /** @@ -140,7 +144,7 @@ class AttackThread : public Thread { rte_mbuf* m_copy; - for (int i = 0; i < nb_pkts; ++i) { + for (u_int32_t i = 0; i < nb_pkts; ++i) { m_copy = rte_pktmbuf_copy(_mbuf_origin, mempool, 0, UINT32_MAX); if (unlikely(m_copy == nullptr)) { @@ -173,7 +177,7 @@ class AttackThread : public Thread { rte_mbuf* m_copy; - for (int i = 0; i < nb_pkts; ++i) { + for (uint32_t i = 0; i < nb_pkts; ++i) { m_copy = rte_pktmbuf_copy(_mbuf_origin, mempool, 0, UINT32_MAX); if (unlikely(m_copy == nullptr)) { @@ -217,30 +221,20 @@ class AttackThread : public Thread { } public: - bool _do_attack; - - inline AttackThread(PacketContainerLean* pkt_container_to_dave, - PacketContainerLean* pkt_container_to_alice, + inline AttackThread(PacketContainerLean* pkt_container_to_inside, + PacketContainerLean* pkt_container_to_outside, unsigned int nb_worker_threads) - - : Thread(), _nb_worker_threads(nb_worker_threads), _iterations(0), - _call_send_pkts_every_nth_iteration(0), - _pkt_container_to_dave(pkt_container_to_dave), - _pkt_container_to_alice(pkt_container_to_alice), _nb_pkts_to_dave(0), - _nb_pkts_to_alice(0), _total_nb_pkts_to_dave(0), - _total_nb_pkts_from_dave(0), _total_nb_pkts_to_alice(0), - _total_data_volume_to_alice(0), _total_nb_pkts_from_alice(0), - _total_data_volume_from_alice(0), _pkt_type(NONE), _cycles(0), - _delta_cycles(0), _data_volume(0), _nb_attack_packets(0), - _hz(rte_get_tsc_hz()), _delta_cycles_mean(0), _n(1), + : ForwardingThread(pkt_container_to_inside, pkt_container_to_outside), + _pkt_container_to_dave(pkt_container_to_inside), + _pkt_container_to_alice(pkt_container_to_outside), + _nb_worker_threads(nb_worker_threads), _bob_mac({.addr_bytes = {60, 253, 254, 163, 231, 48}}), _src_mac({.addr_bytes = {60, 253, 254, 163, 231, 88}}), - _bob_ip(167772162), _alice_ip(167772161), _tcp_flags(0), - _mbuf_origin(nullptr), _do_attack(false) { - - // ===== calculate stuff regarding clock calculation ===== // - - /* + _bob_ip(167772162), _alice_ip(167772161), _nb_attack_packets(0), + _delta_cycles_mean(0), _iterations(0), _send(true), + _nb_pkts_to_dave(0), _nb_pkts_to_alice(0), _pkt_type(NONE), + _cycles(0), _delta_cycles(0), _data_volume(0), _hz(rte_get_tsc_hz()), + _n(1) { _data_rate = int((std::stoi(Configurator::instance()->get_config_as_string( "attack_rate")) * @@ -255,7 +249,6 @@ class AttackThread : public Thread { } _cycles_old = rte_get_tsc_cycles(); - */ // ===== read and set attack type ===== // @@ -286,14 +279,10 @@ class AttackThread : public Thread { // ===== set number of attack packets ===== // _nb_attack_packets = - Configurator::instance()->get_config_as_unsigned_int( - "number_of_attack_packets_per_thread_per_send_call"); + std::stoi(Configurator::instance()->get_config_as_string( + "number_of_attack_packets_per_thread_per_iteration")); - _call_send_pkts_every_nth_iteration = - Configurator::instance()->get_config_as_unsigned_int( - "call_send_pkts_every_nth_iteration"); - - LOG_INFO << "number_of_attack_packets_per_thread_per_send_call : " + LOG_INFO << "number_of_attack_packets_per_thread_per_iteration : " << _nb_attack_packets << LOG_END; // ===== create origin attack packet ===== // @@ -336,8 +325,6 @@ class AttackThread : public Thread { delete pkt_info_origin; pkt_info_origin = nullptr; } - - // ===== attack rate } inline ~AttackThread() { rte_pktmbuf_free(_mbuf_origin); } @@ -354,7 +341,6 @@ class AttackThread : public Thread { // ===== ALICE <--[MALLORY]-- DAVE/BOB ===== // _pkt_container_to_alice->poll_mbufs(_nb_pkts_to_alice); - _total_nb_pkts_from_dave += _nb_pkts_to_alice; // continue if no packets are received if (likely(_nb_pkts_to_alice > 0)) { @@ -372,7 +358,7 @@ class AttackThread : public Thread { _total_data_volume_to_alice += rte_pktmbuf_pkt_len(mbuf); } } - _total_nb_pkts_to_alice += _pkt_container_to_alice->send_mbufs(); + _total_nb_pkts_to_alcie += _pkt_container_to_alice->send_mbufs(); } // ===== ALICE --[MALLORY]--> DAVE/BOB ===== // @@ -384,11 +370,13 @@ class AttackThread : public Thread { _pkt_container_to_dave->get_mbuf_at_index(i)); } - if (unlikely(_iterations == _call_send_pkts_every_nth_iteration)) { +#ifdef SEND_PKTS_EVERY_NTH_ITERATION + if (_iterations == SEND_PKTS_EVERY_NTH_ITERATION) { _iterations = 0; +#endif // create attack packets - if (likely(_do_attack)) { + if (likely(_send == true)) { if (_attack_type == SYN_FLOOD || _attack_type == SYN_FIN || _attack_type == SYN_FIN_ACK) { create_attack_packet_burst_tcp(_nb_attack_packets, @@ -396,34 +384,29 @@ class AttackThread : public Thread { } else if (_attack_type == UDP_FLOOD) { create_attack_packet_burst_udp(_nb_attack_packets); } - } else{ - _total_nb_pkts_to_dave = 0; - _total_nb_pkts_from_dave = 0; - _total_nb_pkts_to_alice = 0; - _total_data_volume_to_alice = 0; - _total_nb_pkts_from_alice = 0; - _total_data_volume_from_alice = 0; } + +#ifdef SEND_PKTS_EVERY_NTH_ITERATION } ++_iterations; +#endif - _total_nb_pkts_to_dave = _total_nb_pkts_to_dave + - _pkt_container_to_dave->send_mbufs(); + _total_nb_atk_pkts = _total_nb_atk_pkts + + _pkt_container_to_dave->send_mbufs() - + _nb_pkts_to_dave; + +#ifdef SEND_ONCE + _send = false; +#endif // calculate_cycles(); } - inline uint64_t get_total_nb_pkts_to_dave() { - return _total_nb_pkts_to_dave; - } - - inline uint64_t get_total_nb_pkts_from_dave() { - return _total_nb_pkts_from_dave; - } + inline uint64_t get_total_nb_atk_pkts() { return _total_nb_atk_pkts; } inline uint64_t get_total_nb_pkts_to_alice() { - return _total_nb_pkts_to_alice; + return _total_nb_pkts_to_alcie; } inline uint64_t get_total_data_volume_to_alice() { diff --git a/include/Threads/DefenseThread.hpp b/include/Threads/DefenseThread.hpp index 00ba42f..04c9b06 100644 --- a/include/Threads/DefenseThread.hpp +++ b/include/Threads/DefenseThread.hpp @@ -1,24 +1,26 @@ +/** + * @file DefenseThread.hpp + * @author Jakob + * @brief + * @version 0.1 + * @date 2021-07-12 + * + * @copyright Copyright (c) 2021 + * + */ #pragma once #include "PacketDissection/PacketContainer.hpp" +#include "Inspection.hpp" #include "Treatment/Treatment.hpp" - +#include "Threads/StatisticsThread.hpp" #include "Threads/ForwardingThread.hpp" -class DefenseThread : public Thread { +class DefenseThread : public ForwardingThread { public: - DefenseThread(MbufContainerReceiving* mbuf_container_from_inside, - MbufContainerReceiving* mbuf_container_from_outside, - MbufContainerTransmitting* mbuf_container_to_inside, - MbufContainerTransmitting* mbuf_container_to_outside); - - ~DefenseThread() { delete _treatment; } - - void start_treat() { _do_treat = true; } - - void stop_treat() { _do_treat = false; } - - bool _do_treat; + DefenseThread(PacketContainer* pkt_container_to_inside, + PacketContainer* pkt_container_to_outside, + StatisticsThread* stat_thread); /** * @brief Wrapper for the run-method @@ -34,13 +36,9 @@ class DefenseThread : public Thread { static int s_run(void* thread_obj); private: - Treatment* _treatment; - - MbufContainerReceiving* _mbuf_container_from_outside; - MbufContainerReceiving* _mbuf_container_from_inside; - MbufContainerTransmitting* _mbuf_container_to_outside; - MbufContainerTransmitting* _mbuf_container_to_inside; - + Inspection _inspection; + Treatment _treatment; + StatisticsThread* _statistics_thread; /** * @brief Run thread * diff --git a/include/Threads/ForwardingThread.hpp b/include/Threads/ForwardingThread.hpp index a44c1b9..2254c4f 100644 --- a/include/Threads/ForwardingThread.hpp +++ b/include/Threads/ForwardingThread.hpp @@ -1,3 +1,14 @@ +/** + * @file ForwardingThread.hpp + * @author Jakob + * @brief + * @version 0.1 + * @date 2021-07-12 + * + * @copyright Copyright (c) 2021 + * + */ + #pragma once #include "PacketDissection/PacketContainer.hpp" @@ -31,7 +42,6 @@ class ForwardingThread : public Thread { */ PacketContainer* _pkt_container_to_inside; PacketContainerLean* _pkt_container_to_inside_lean; - // PacketContainerLean* _pkt_container_from_outside_lean; /** * @brief in AttackThread: to alice diff --git a/include/Threads/StatisticsThread.hpp b/include/Threads/StatisticsThread.hpp index 0853cfd..0a50618 100644 --- a/include/Threads/StatisticsThread.hpp +++ b/include/Threads/StatisticsThread.hpp @@ -1,11 +1,28 @@ +/** + * @file StatisticsThread.hpp + * @author Jakob + * @brief + * @version 0.1 + * @date 2021-07-12 + * + * @copyright Copyright (c) 2021 + * + */ #pragma once -#include -#include - +#include +#include +#include +#include +#include +#include +#include +//#include +//#include #include #include "Threads/Thread.hpp" +#include "Definitions.hpp" struct Stats { uint64_t attacks; @@ -13,11 +30,12 @@ struct Stats { uint64_t dropped; uint64_t packets; uint64_t work_time; - uint64_t syn_level; - Stats* operator+=(const Stats* new_stats); + Stats& operator+=(const Stats& new_stats); + void reset_stats(); }; +// all current stats which can be displayed struct StatsMonitor { double attacks_per_second; double attacks_percent; @@ -25,19 +43,32 @@ struct StatsMonitor { double dropped_per_second; double dropped_percent; double packets_per_second; - double proc_speed; // process speed + double process_speed; double total_time; }; class StatisticsThread : public Thread { public: + StatisticsThread(); static int s_run(void* thread_vptr); - void enqueue_statistics(int& id, Stats* new_stats); - void update_statistics(Stats* new_stats); + void enqueue_statistics(const unsigned int& id, Stats* new_stats); + void update_statistics_monitor(); + void print_stats_monitor(); private: void run(); - static rte_ring* _s_queue[16]; - static Stats* _s_stats; + static rte_ring* _s_queue[16]; // todo : dynamic + Stats* _s_stats; + StatsMonitor* _s_stats_monitor; + + uint64_t timer_get_seconds(); + void timer_reset(); + + // timer variables + uint64_t cycles_old = 0; + uint64_t cycles = 0; + uint64_t seconds = 0; + uint64_t delta_t = 0; + uint64_t hz; }; diff --git a/include/Threads/Thread.hpp b/include/Threads/Thread.hpp index 87f0626..e48450a 100644 --- a/include/Threads/Thread.hpp +++ b/include/Threads/Thread.hpp @@ -1,3 +1,14 @@ +/** + * @file Thread.hpp + * @author Jakob + * @brief + * @version 0.1 + * @date 2021-07-12 + * + * @copyright Copyright (c) 2021 + * + */ + #pragma once #include diff --git a/include/Treatment/Treatment.hpp b/include/Treatment/Treatment.hpp index 81921fe..7ee34a3 100644 --- a/include/Treatment/Treatment.hpp +++ b/include/Treatment/Treatment.hpp @@ -1,39 +1,40 @@ -#pragma once +/** + * @file Treatment.hpp + * @author Fabienne, Felix, Tim + * @brief This header file includes the class structure, structs and needed includes + * @version 0.1 + * @date 2021-06-10 + * + * @copyright Copyright (c) 2021 + * + */ -#include "PacketDissection/MbufContainer.hpp" -#include "PacketDissection/MbufContainerReceiving.hpp" -#include "PacketDissection/MbufContainerTransmitting.hpp" +#pragma once + +// TEST 0: Normal (No Testing) +// Test 1: Unit Test without DPDK +// Test 2: Unit Test with DPDK +#define TEST 1 +#include +#include +#include +#include +#include "rand.h" #include "PacketDissection/PacketContainer.hpp" #include "PacketDissection/PacketInfo.hpp" #include "PacketDissection/PacketInfoIpv4Tcp.hpp" -#include "rand.hpp" -#include "xxh3.hpp" -#include "xxhash.hpp" -#include -#include -#include -#include +#include "Treatment/xxh3.hpp" +#include "Treatment/xxhash.hpp" +#include "Treatment/random.hpp" -/** - * @file Treatment.h - * @author Fabienne, Felix, Tim - * @brief This header file includes the class structure, structs and needed - * includes - * @version 0.1 - * @date 2021-06-10 - * - * @copyright Copyright (c) 2021 - * - */ -enum _flag_enum { +enum _flags { SYN = 0b00000010, RST = 0b00000100, FIN = 0b00000001, ACK = 0b00010000, FINACK = 0b00010001, - SYNACK = 0b00010010, - SYNFIN = 0b00000011 + SYNACK = 0b00010010 }; /** @@ -58,11 +59,7 @@ class Data { * @brief Construct a new Data object from scratch * */ - Data() - : _extip(0) - , _intip(0) - , _extport(0) - , _intport(0) {} + Data() : _extip(0), _intip(0), _extport(0), _intport(0) {} /** * @brief Construct a new Data object * @@ -73,10 +70,8 @@ class Data { */ Data(u_int32_t _extip, u_int32_t _intip, u_int16_t _extport, u_int16_t _intport) - : _extip(_extip) - , _intip(_intip) - , _extport(_extport) - , _intport(_intport) {} + : _extip(_extip), _intip(_intip), _extport(_extport), + _intport(_intport) {} /** * @brief Redefinition of operator== @@ -117,38 +112,34 @@ class Info { * */ Info() - : _offset(0) - , _finseen_to_inside(false) - , _finseen_to_outside(false) - , _ack_to_inside_expected(false) - , _ack_to_outside_expected(false) - , _pkt_inf_list() {} + : _offset(0), _finseen_to_inside(false), _finseen_to_outside(false), + _ack_to_inside_expected(false), _ack_to_outside_expected(false), + _pkt_inf_list() {} /** - * @brief Construct a new Info object - * @param _offset Stores the difference between Sequence- and ACK-Numbers - * @param _finseen Stores if a fin has already been seen - * @param _pkt_inf Stores the PacketInfo for an ACK from connection - * establishment + * @brief Construct a new Info object with member initializer lists + * + * @param offset Stores the difference between Sequence- and ACK-Numbers + * @param finseen Stores if a fin has already been seen + * @param pkt_inf Stores the PacketInfo for an ACK from connection establishment + * */ Info(int offset, bool finseen_to_inside, bool finseen_to_outside, bool ack_to_inside, bool ack_to_outside, PacketInfoIpv4Tcp* pkt_inf) - : _offset(offset) - , _finseen_to_inside(finseen_to_inside) - , _finseen_to_outside(finseen_to_outside) - , _ack_to_inside_expected(ack_to_inside) - , _ack_to_outside_expected(ack_to_outside) { - if (pkt_inf != nullptr) { - _pkt_inf_list.push_back(pkt_inf); - } + : _offset(offset), _finseen_to_inside(finseen_to_inside), + _finseen_to_outside(finseen_to_outside), + _ack_to_inside_expected(ack_to_inside), + _ack_to_outside_expected(ack_to_outside) { + + _pkt_inf_list.push_back(pkt_inf); } }; /** - * @brief TreatmentHash manages the calculation of the hashvalue over a Data + * @brief MyHashFunction manages the calculation of the hashvalue over a Data * Struct and is used in the _densemap * */ -class TreatmentHash { +class MyHashFunction { public: /** * @brief Redefinition of the operator() used in the _densemap and _ackmap @@ -192,18 +183,14 @@ class Treatment { * @param pkt_to_outside PacketContainer containing the packets with the * destination being the internet */ - inline Treatment(MbufContainerTransmitting* pkt_send_to_outside, - MbufContainerTransmitting* pkt_send_to_inside, - u_int8_t syn_thresh) - : _cookie_secret(Rand::get_random_64bit_value()) - , _packet_to_inside(pkt_send_to_inside) - , _packet_to_outside(pkt_send_to_outside) - , _syn_thresh(syn_thresh) - , _skip_syn(0) { + inline Treatment(PacketContainer* pkt_to_inside, + PacketContainer* pkt_to_outside) + : _cookie_secret(Rand::get_random_64bit_value()), + _packet_to_inside(pkt_to_inside), _packet_to_outside(pkt_to_outside) { // disables logging - /* auto corehandle = boost::log::core::get(); - corehandle->set_logging_enabled(false); */ + /* auto corehandle = boost::log::core::get(); + corehandle->set_logging_enabled(false); */ // Densemap requires you to set an empty key, which is never used by // legit connections Dense_hash_map requires you call set_empty_key() @@ -212,9 +199,9 @@ class Treatment { // immediately after constructing the hash_map, and before calling any // other dense_hash_map method _densemap.set_deleted_key(Data(0, 0, 1, 1)); - // BOOST_LOG_TRIVIAL(info) << "|---Init of Treatment done. Created - // cookie_secret, " "_s_timestamp and inserted empty and deleted - // key---|"; + BOOST_LOG_TRIVIAL(info) + << "|---Init of Treatment done. Created cookie_secret, " + "_s_timestamp and inserted empty and deleted key---|"; } /** @@ -241,321 +228,320 @@ class Treatment { * and checking syn-cookies. Depending on internal rules packets can be * forwarded, adjusted, stored and dropped on their way through the system. */ - inline bool treat_packets_to_inside(PacketInfoIpv4Tcp* _pkt_info) { + inline void treat_packets_to_inside() { - // BOOST_LOG_TRIVIAL(info)<< "Size of densemap before to inside: " << - // _densemap.size(); + BOOST_LOG_TRIVIAL(info) + << "Size of densemap before to inside: " << _densemap.size(); - /************************************************************************ - ****Treatment of packets with direction towards the internal - *network**** - ************************************************************************/ - // get packetInfo at current position - // check if packet has been deleted - // check wether packet is IPv4TCP - // get the flags of packet i as they will be needed a few times - u_int8_t _flags = _pkt_info->get_flags(); - // SYN-ACK is set, simply forward the packet to the internal - // network and create an entry in the _densemap - if ((_flags & _flag_enum::SYNFIN) == _flag_enum::SYNFIN) { - rte_pktmbuf_free(_pkt_info->get_mbuf()); - } else if ((_flags & _flag_enum::SYNACK) == - _flag_enum::SYNACK) { // check wether the syn and ack - // flag is set - // BOOST_LOG_TRIVIAL(info) << "|---Received SYN-ACK from - // outside---|"; - // just simply forward the packet to the internal network - // also create entry in the _densemap, with _offset - // difference = - // 0 - Data insert(_pkt_info->get_src_ip(), _pkt_info->get_dst_ip(), - _pkt_info->get_src_port(), _pkt_info->get_dst_port()); - Info info(0, false, false, false, false, nullptr); - _densemap.insert(std::make_pair(insert, info)); - // BOOST_LOG_TRIVIAL(info) << "|---Created new entry for - // connection: _extip " << _pkt_info->get_src_ip() << " _extport: " - // << _pkt_info->get_src_port()<< " _intip: " << - // _pkt_info->get_dst_ip() << " _intport: " << - // _pkt_info->get_dst_port() << "---|"; place packet in the sending - // container to inside - _packet_to_inside->add_mbuf(_pkt_info->get_mbuf()); + for (int i = 0; i < _packet_to_inside->get_number_of_polled_packets(); + ++i) { - } - // SYN is set, generate cookie hash - else if ((_flags & _flag_enum::SYN) == _flag_enum::SYN) { - - if (_skip_syn < _syn_thresh) { - ++_skip_syn; - } else { // SYN to INSIDE - // BOOST_LOG_TRIVIAL(info) << "|---Received SYN to inside---|"; - // BOOST_LOG_TRIVIAL(info) << "|---Mbuf is: " << - // _pkt_info->get_mbuf() << "---|"; - /* use this part to calculate the syn-cookie, create a new - * packet and send it back to the same side it came from */ - u_int32_t _cookie = calc_cookie_hash( - _s_timestamp, _pkt_info->get_src_ip(), - _pkt_info->get_dst_ip(), _pkt_info->get_src_port(), - _pkt_info->get_dst_port()); - // BOOST_LOG_TRIVIAL(info) << "|---Calculated cookie is: " << - // _cookie << "---|"; - - _cookie = _cookie & 0xFFFFFF00; // got upper bits - u_int32_t _seqnum = - _cookie | - _s_timestamp; // got cookie + 8 bit _s_timestamp - // BOOST_LOG_TRIVIAL(info)<< - // "|---Calculated cookie with timestamp - // is: " << _seqnum << "---|"; - - // create the reply for the external connection/host - rte_mbuf* reply_mbuf = _packet_to_outside->get_empty_mbuf(); - if (reply_mbuf == nullptr) { - return false; - } - rte_pktmbuf_append(reply_mbuf, sizeof(struct rte_ether_hdr) + - sizeof(struct rte_ipv4_hdr) + - sizeof(struct rte_tcp_hdr)); - PacketInfoIpv4Tcp* reply = new PacketInfoIpv4Tcp(reply_mbuf); - // BOOST_LOG_TRIVIAL(info) << "|---The reply is of type: " << - // reply->get_type() << "---|"; - - reply->fill_payloadless_tcp_packet( - _pkt_info->get_dst_mac(), _pkt_info->get_src_mac(), - _pkt_info->get_dst_ip(), _pkt_info->get_src_ip(), - _pkt_info->get_dst_port(), _pkt_info->get_src_port(), - _seqnum, _pkt_info->get_seq_num() + 1, _flag_enum::SYNACK, - _pkt_info->get_window_size()); - reply->prepare_offloading_checksums(); - // BOOST_LOG_TRIVIAL(info) << "|---Created SYN-ACK with Cookie: - // " << reply->get_seq_num()<< "---|"; BOOST_LOG_TRIVIAL(info) - // << " |---The new SYN-ACK goes with: extip: " << - // reply->get_dst_ip()<< " extport: " << reply->get_dst_port()<< - // " intip: " << reply->get_src_ip() << " intport: " << - // reply->get_src_port() << "---|"; delete/drop received - rte_pktmbuf_free(_pkt_info->get_mbuf()); - // BOOST_LOG_TRIVIAL(info) << "|---Dropped incoming packet---|"; - // now packet is getting send out in the next burst cycle - - delete reply; - _skip_syn = 0; - } - - } - // Case: RST received from outside - else if ((_flags & _flag_enum::RST) == _flag_enum::RST) { - // BOOST_LOG_TRIVIAL(info) << "|---Received RST from outside, - // ""deleting entry in densemap---|"; erase entry in _densemap with - // key = hash(AliceIP, AlicePort, BobIP, BobPort) Send packet to - // inside with destIP = BobIP, destPort = BobPort, srcIP = AliceIP, - // srcPort = AlicePort erased entry in _densemap - _densemap.erase( - Data(_pkt_info->get_src_ip(), _pkt_info->get_dst_ip(), - _pkt_info->get_src_port(), _pkt_info->get_dst_port())); - - _packet_to_inside->add_mbuf(_pkt_info->get_mbuf()); - - } - // Case: Received FIN, no FIN-ACK from outside - else if (((_flags & _flag_enum::FIN) == _flag_enum::FIN)) { - // BOOST_LOG_TRIVIAL(info) << "|---Received a FIN from outside---|"; - // create Data fin for the packet - // find the entry in our map - auto iter = _densemap.find( - Data(_pkt_info->get_src_ip(), _pkt_info->get_dst_ip(), - _pkt_info->get_src_port(), _pkt_info->get_dst_port())); - // Catch case, that we dont interact on empty map - if (iter == _densemap.end()) { - // drop packet - rte_pktmbuf_free(_pkt_info->get_mbuf()); - // BOOST_LOG_TRIVIAL(info)<< "|---Dropped Packet comming from - // outside---|"; - } - - // Check if fin has already been seen, and we do not have an - // finack - else if (iter->second._finseen_to_outside == true) { - // BOOST_LOG_TRIVIAL(info) << "|---FIN-ACK to FIN received from - // outside---|"; change the packets ack number tweak by adding - // into one line - iter->second._finseen_to_inside = true; - iter->second._ack_to_outside_expected = true; - _pkt_info->set_ack_num(_pkt_info->get_ack_num() - - iter->second._offset); - _pkt_info->prepare_offloading_checksums(); - - // delete the entry - /* _densemap.erase(Data( - _pkt_info->get_src_ip(), _pkt_info->get_dst_ip(), - _pkt_info->get_src_port(), - _pkt_info->get_dst_port())); - //BOOST_LOG_TRIVIAL(info) << "Deleted entry in densemap"; - */ - - // send packet to inside // aka. do nothing - _packet_to_inside->add_mbuf(_pkt_info->get_mbuf()); - - } else if (iter->second._finseen_to_inside == false) { - // change status _finseen to true - iter->second._finseen_to_inside = true; - // change the packets ack number - _pkt_info->set_ack_num(_pkt_info->get_ack_num() - - iter->second._offset); - // refresh the checksums - _pkt_info->prepare_offloading_checksums(); - // BOOST_LOG_TRIVIAL(info) << "|---Changed Finseen to true for - // connection: ""extip: " << _pkt_info->get_src_ip() - //<< " extport: " << _pkt_info->get_src_port() - //<< " intip: " << _pkt_info->get_dst_ip() - //<< " intport: " << _pkt_info->get_dst_port() << "---|"; - - _packet_to_inside->add_mbuf(_pkt_info->get_mbuf()); - } else { - // BOOST_LOG_TRIVIAL(info) << "|---Duplicate FIN from - // Outside---|"; - _pkt_info->set_ack_num(_pkt_info->get_ack_num() - - iter->second._offset); - // refresh the checksums - _pkt_info->prepare_offloading_checksums(); - _packet_to_inside->add_mbuf(_pkt_info->get_mbuf()); - } - - } - // CASE: ACK RECEIVED from Alice - else if ((_flags & _flag_enum::ACK) == _flag_enum::ACK && - ((_flags & _flag_enum::FINACK) != _flag_enum::FINACK)) { - // BOOST_LOG_TRIVIAL(info) << "|---Received ACK from outside---|"; - Data ack(_pkt_info->get_src_ip(), _pkt_info->get_dst_ip(), - _pkt_info->get_src_port(), _pkt_info->get_dst_port()); - auto id = _densemap.find(ack); - if (id == _densemap.end()) { // no entry is here yet - // BOOST_LOG_TRIVIAL(info) - // << "|---Received ACK to SYN-ACK from outside---|"; - // BOOST_LOG_TRIVIAL(info) << "|---Checking the SYN-COOKIE---|"; - u_int32_t _cookie_val = - _pkt_info->get_ack_num(); // get acknowledgementnumber - // from packet - bool _legit = - check_syn_cookie(_cookie_val - 1, - ack); // check for the correkt cookie - if (_legit == true) { // the connection is to be established - // Take the packet and save it, till the connection - // to the internal host is established Use the - // densemap for this purpose by setting the pointer - // in info to taken_packet - rte_mbuf* reply_mbuf = _packet_to_inside->get_empty_mbuf(); - if (reply_mbuf == nullptr) { - return false; - } - rte_pktmbuf_append(reply_mbuf, - sizeof(struct rte_ether_hdr) + - sizeof(struct rte_ipv4_hdr) + - sizeof(struct rte_tcp_hdr)); - PacketInfoIpv4Tcp* reply = - new PacketInfoIpv4Tcp(reply_mbuf); - - if (reply == nullptr) { - // BOOST_LOG_TRIVIAL(fatal) << "created a nullptr"; - } - _densemap.insert(std::make_pair( - ack, Info(0, false, false, false, false, _pkt_info))); - // Still need to send that syn to inside - - // TO-DO check if _pkt_info is legit there - reply->fill_payloadless_tcp_packet( - _pkt_info->get_src_mac(), _pkt_info->get_dst_mac(), + /************************************************************************ + ****Treatment of packets with direction towards the internal + *network**** + ************************************************************************/ + // get packetInfo at current position + PacketInfo* _pkt_info_plain = + _packet_to_inside->get_packet_at_index(i); + BOOST_LOG_TRIVIAL(info) + << "|---Got plain packet from outside with type: " + << _pkt_info_plain->get_type() << "---|"; + // check if packet has been deleted + // check wether packet is IPv4TCP + if (_pkt_info_plain != nullptr && + _pkt_info_plain->get_type() == IPv4TCP) { + PacketInfoIpv4Tcp* _pkt_info = + static_cast(_pkt_info_plain); + // get the flags of packet i as they will be needed a few times + u_int8_t _flags = _pkt_info->get_flags(); + // SYN-ACK is set, simply forward the packet to the internal + // network and create an entry in the _densemap + if ((_flags & _flags::SYNACK) == + _flags::SYNACK) { // check wether the syn and ack flag is + // set + BOOST_LOG_TRIVIAL(info) + << "|---Received SYN-ACK from outside---|"; + // just simply forward the packet to the internal network + // also create entry in the _densemap, with _offset + // difference = + // 0 + Data insert( _pkt_info->get_src_ip(), _pkt_info->get_dst_ip(), - _pkt_info->get_src_port(), _pkt_info->get_dst_port(), - _pkt_info->get_seq_num() - 1, 123, _flag_enum::SYN, - _pkt_info->get_window_size()); - reply->prepare_offloading_checksums(); - // BOOST_LOG_TRIVIAL(info) - // << "|---Cookie " << _pkt_info->get_ack_num() - 1 - // << " correct, sending SYN to inside---|"; - // BOOST_LOG_TRIVIAL(info) - //<< "|---SYN to inside goes from " << reply->get_src_ip() - // << " to: " << reply->get_dst_ip() << " ---|"; + _pkt_info->get_src_port(), _pkt_info->get_dst_port()); + Info info(0, false, false, false, false, nullptr); + _densemap.insert(std::make_pair(insert, info)); + BOOST_LOG_TRIVIAL(info) + << "|---Created new entry for connection: _extip " + << _pkt_info->get_src_ip() + << " _extport: " << _pkt_info->get_src_port() + << " _intip: " << _pkt_info->get_dst_ip() + << " _intport: " << _pkt_info->get_dst_port() << "---|"; + // place packet in the sending container to inside - // now packet is getting send out in the next burst - // cycle - _packet_to_outside->add_mbuf(reply_mbuf); - delete reply; - return true; - - } else if (_legit == false) { // the connection is closed - // with an rst, drop packet - // BOOST_LOG_TRIVIAL(info) - // << "|---Cookie incorrect, dropped packet---|"; - - // Send RST if (diff>1 XOR hash!=cookie_value) - rte_mbuf* rst_mbuf = _packet_to_inside->get_empty_mbuf(); - if (rst_mbuf == nullptr) { - return false; - } - PacketInfo* rst = - PacketInfoCreator::create_pkt_info(rst_mbuf, IPv4TCP); - PacketInfoIpv4Tcp* rst4 = - static_cast(rst); - - rst4->fill_payloadless_tcp_packet( - _pkt_info->get_dst_mac(), _pkt_info->get_src_mac(), - ack._extip, ack._intip, ack._extport, ack._intport, - _pkt_info->get_ack_num(), 0, _flag_enum::RST, - _pkt_info - ->get_window_size()); // fill_payloadless_tcp_packet - // already exists, we - // just need it from - // Tobias - rst4->prepare_offloading_checksums(); - _packet_to_outside->add_mbuf(rst4->get_mbuf()); - - rte_pktmbuf_free(_pkt_info->get_mbuf()); } + // SYN is set, generate cookie hash + else if ((_flags & _flags::SYN) == + _flags::SYN) { // SYN to INSIDE + BOOST_LOG_TRIVIAL(info) << "|---Received SYN to inside---|"; + /* use this part to calculate the syn-cookie, create a new + * packet and send it back to the same side it came from */ + u_int32_t _cookie = calc_cookie_hash( + _s_timestamp, _pkt_info->get_src_ip(), + _pkt_info->get_dst_ip(), _pkt_info->get_src_port(), + _pkt_info->get_dst_port()); + BOOST_LOG_TRIVIAL(info) + << "|---Calculated cookie is: " << _cookie << "---|"; - } - // No entry in _densemap -> It is an ACK as a reply to - // SYN-ACK entry can be found and its not a reply to an fin - // ack - else if (unlikely(id->second._finseen_to_inside == true && - id->second._finseen_to_outside == true && - id->second._ack_to_inside_expected == true)) { - // BOOST_LOG_TRIVIAL(info) - // << "|---ACK to FIN-ACK, Connection Closed---|"; - // simply manage _offset and thats it - _pkt_info->set_ack_num(_pkt_info->get_ack_num() - - id->second._offset); - _pkt_info->prepare_offloading_checksums(); + _cookie = _cookie & 0xFFFFFF00; // got upper bits + u_int32_t _seqnum = + _cookie | + _s_timestamp; // got cookie + 8 bit _s_timestamp + BOOST_LOG_TRIVIAL(info) + << "|---Calculated cookie with timestamp is: " + << _seqnum << "---|"; - // delete the entry - _densemap.erase(id); - // BOOST_LOG_TRIVIAL(info) << "|---Deleted entry in - // densemap---|"; + // create the reply for the external connection/host + PacketInfo* _reply = _packet_to_outside->get_empty_packet(); + BOOST_LOG_TRIVIAL(info) + << "|---The reply is of type: " << _reply->get_type() + << "---|"; + PacketInfoIpv4Tcp* _reply4 = + static_cast(_reply); + BOOST_LOG_TRIVIAL(info) + << "|---The reply4 is of type: " << _reply4->get_type() + << "---|"; + // fill packet with calculated seqnum + _reply4->fill_payloadless_tcp_packet( + _pkt_info->get_dst_mac(), _pkt_info->get_src_mac(), + _pkt_info->get_dst_ip(), _pkt_info->get_src_ip(), + _pkt_info->get_dst_port(), _pkt_info->get_src_port(), + _seqnum, _pkt_info->get_seq_num() + 1, _flags::SYNACK, + _pkt_info->get_window_size()); + _reply4->recalculate_checksums(); + BOOST_LOG_TRIVIAL(info) + << "|---Created SYN-ACK with Cookie: " + << _reply4->get_seq_num() << "---|"; + BOOST_LOG_TRIVIAL(info) + << " |---The new SYN-ACK goes with: extip: " + << _reply4->get_dst_ip() + << " extport: " << _reply4->get_dst_port() + << " intip: " << _reply4->get_src_ip() + << " intport: " << _reply4->get_src_port() << "---|"; + // delete/drop received + _packet_to_inside->drop_packet(i, _pkt_info); + BOOST_LOG_TRIVIAL(info) + << "|---Dropped incoming packet---|"; + // now packet is getting send out in the next burst cycle - _packet_to_inside->add_mbuf(_pkt_info->get_mbuf()); + } + // Case: RST received from outside + else if ((_flags & _flags::RST) == _flags::RST) { + BOOST_LOG_TRIVIAL(info) << "|---Received RST from outside, " + "deleting entry in densemap---|"; + // erase entry in _densemap with key = hash(AliceIP, + // AlicePort, BobIP, BobPort) Send packet to inside with + // destIP = BobIP, destPort = BobPort, srcIP = AliceIP, + // srcPort = AlicePort erased entry in _densemap + _densemap.erase(Data( + _pkt_info->get_src_ip(), _pkt_info->get_dst_ip(), + _pkt_info->get_src_port(), _pkt_info->get_dst_port())); - } - // If the connection from inside is not fully established - // yet, i need to add it to the queue first - else if (unlikely(id->second._pkt_inf_list.empty() == false)) { - // now add it to the queue - // BOOST_LOG_TRIVIAL(info) << "|---Put early ack into - // queue---|"; - id->second._pkt_inf_list.push_back(_pkt_info); - return true; + } + // Case: Received FIN, no FIN-ACK from outside + else if (((_flags & _flags::FIN) == _flags::FIN)) { + BOOST_LOG_TRIVIAL(info) + << "|---Received a FIN from outside---|"; + // create Data fin for the packet + // find the entry in our map + auto iter = _densemap.find(Data( + _pkt_info->get_src_ip(), _pkt_info->get_dst_ip(), + _pkt_info->get_src_port(), _pkt_info->get_dst_port())); + // Catch case, that we dont interact on nullpointer + if (iter == _densemap.end()) { + // drop packet + _packet_to_inside->drop_packet(i, _pkt_info); + BOOST_LOG_TRIVIAL(info) + << "|---Dropped Packet comming from outside---|"; + } - } else { - // BOOST_LOG_TRIVIAL(info) << "|---Regular ACK, simply - // send---|"; - // simply manage _offset and thats it - _pkt_info->set_ack_num(_pkt_info->get_ack_num() - - id->second._offset); - _pkt_info->prepare_offloading_checksums(); + // Check if fin has already been seen, and we do not have an + // finack + else if (iter->second._finseen_to_outside == true) { + BOOST_LOG_TRIVIAL(info) + << "|---FIN-ACK to FIN received from outside---|"; + // change the packets ack number + // tweak by adding into one line + iter->second._finseen_to_inside = true; + iter->second._ack_to_outside_expected = true; + _pkt_info->set_ack_num(_pkt_info->get_ack_num() - + iter->second._offset); + _pkt_info->recalculate_checksums(); - _packet_to_inside->add_mbuf(_pkt_info->get_mbuf()); + // delete the entry + /* _densemap.erase(Data( + _pkt_info->get_src_ip(), _pkt_info->get_dst_ip(), + _pkt_info->get_src_port(), + _pkt_info->get_dst_port())); + BOOST_LOG_TRIVIAL(info) << "Deleted entry in densemap"; + */ + + // send packet to inside // aka. do nothing + + } else if (iter->second._finseen_to_inside == false) { + // change status _finseen to true + iter->second._finseen_to_inside = true; + // change the packets ack number + _pkt_info->set_ack_num(_pkt_info->get_ack_num() - + iter->second._offset); + // refresh the checksums + _pkt_info->recalculate_checksums(); + BOOST_LOG_TRIVIAL(info) + << "|---Changed Finseen to true for connection: " + "extip: " + << _pkt_info->get_src_ip() + << " extport: " << _pkt_info->get_src_port() + << " intip: " << _pkt_info->get_dst_ip() + << " intport: " << _pkt_info->get_dst_port() + << "---|"; + } + + } + // CASE: ACK RECEIVED from Alice + else if ((_flags & _flags::ACK) == _flags::ACK && + ((_flags & _flags::FINACK) != _flags::FINACK)) { + BOOST_LOG_TRIVIAL(info) + << "|---Received ACK from outside---|"; + Data ack(_pkt_info->get_src_ip(), _pkt_info->get_dst_ip(), + _pkt_info->get_src_port(), + _pkt_info->get_dst_port()); + auto id = _densemap.find(ack); + if (id == _densemap.end()) { // no entry is here yet + BOOST_LOG_TRIVIAL(info) + << "|---Received ACK to SYN-ACK from outside---|"; + BOOST_LOG_TRIVIAL(info) + << "|---Checking the SYN-COOKIE---|"; + u_int32_t _cookie_val = + _pkt_info + ->get_ack_num(); // get acknowledgementnumber + // from packet + bool _legit = check_syn_cookie( + _cookie_val - 1, + ack); // check for the correkt cookie + if (_legit == + true) { // the connection is to be established + // Take the packet and save it, till the connection + // to the internal host is established Use the + // densemap for this purpose by setting the pointer + // in info to taken_packet + PacketInfo* _reply = + _packet_to_inside->get_empty_packet(); + PacketInfoIpv4Tcp* taken_packet = + static_cast( + _packet_to_inside->take_packet(i)); + + if (_reply == nullptr) { + BOOST_LOG_TRIVIAL(fatal) + << "inserted a nullptr in our map, this is " + " stupid"; + } + _densemap.insert( + std::make_pair(ack, Info(0, false, false, false, + false, taken_packet))); + // Still need to send that syn to inside + PacketInfoIpv4Tcp* _reply4 = + static_cast(_reply); + // TO-DO check if _pkt_info is legit there + _reply4->fill_payloadless_tcp_packet( + _pkt_info->get_src_mac(), + _pkt_info->get_dst_mac(), + _pkt_info->get_src_ip(), + _pkt_info->get_dst_ip(), + _pkt_info->get_src_port(), + _pkt_info->get_dst_port(), + _pkt_info->get_seq_num() - 1, 123, _flags::SYN, + _pkt_info->get_window_size()); + _reply4->recalculate_checksums(); + BOOST_LOG_TRIVIAL(info) + << "|---Cookie " << _pkt_info->get_ack_num() - 1 + << " correct, sending SYN to inside---|"; + BOOST_LOG_TRIVIAL(info) + << "|---SYN to inside goes from " + << _reply4->get_src_ip() + << " to: " << _reply4->get_dst_ip() << " ---|"; + + // now packet is getting send out in the next burst + // cycle + + } else if (_legit == + false) { // the connection is closed + // with an rst, drop packet + BOOST_LOG_TRIVIAL(info) + << "|---Cookie incorrect, dropped packet---|"; + + // Send RST if (diff>1 XOR hash!=cookie_value) + PacketInfo* _rst = + _packet_to_inside->get_empty_packet(); + PacketInfoIpv4Tcp* _rst4 = + static_cast(_rst); + + _rst4->fill_payloadless_tcp_packet( + _pkt_info->get_dst_mac(), + _pkt_info->get_src_mac(), ack._extip, + ack._intip, ack._extport, ack._intport, + _pkt_info->get_ack_num(), 0, _flags::RST, + _pkt_info + ->get_window_size()); // fill_payloadless_tcp_packet + // already exists, we + // just need it from + // Tobias + _rst4->recalculate_checksums(); + + _packet_to_inside->drop_packet(i, _pkt_info); + } + + } + // No entry in _densemap -> It is an ACK as a reply to + // SYN-ACK entry can be found and its not a reply to an fin + // ack + else if (id->second._finseen_to_inside == true && + id->second._finseen_to_outside == true && + id->second._ack_to_inside_expected == true) { + BOOST_LOG_TRIVIAL(info) + << "|---ACK to FIN-ACK, Connection Closed---|"; + // simply manage _offset and thats it + _pkt_info->set_ack_num(_pkt_info->get_ack_num() - + id->second._offset); + _pkt_info->recalculate_checksums(); + + // delete the entry + _densemap.erase(id); + BOOST_LOG_TRIVIAL(info) + << "|---Deleted entry in densemap---|"; + + } + // If the connection from inside is not fully established + // yet, i need to add it to the queue first + else if (!id->second._pkt_inf_list.empty()) { + // now add it to the queue + BOOST_LOG_TRIVIAL(info) + << "|---Put early ack into queue---|"; + id->second._pkt_inf_list.push_back( + static_cast( + _packet_to_inside->take_packet(i))); + + } else { + BOOST_LOG_TRIVIAL(info) + << "|---Regular ACK, simply send---|"; + // simply manage _offset and thats it + _pkt_info->set_ack_num(_pkt_info->get_ack_num() - + id->second._offset); + _pkt_info->recalculate_checksums(); + } + } } } - // BOOST_LOG_TRIVIAL(info) << "Size of densemap after to inside: " << - // _densemap.size(); - return false; + BOOST_LOG_TRIVIAL(info) + << "Size of densemap after to inside: " << _densemap.size(); } /** * @brief This method checks if the packet to outside is suitable for @@ -571,225 +557,230 @@ class Treatment { * and checking syn-cookies. Depending on internal rules packets can be * forwarded, adjusted, stored and dropped on their way through the system. */ - inline bool treat_packets_to_outside(PacketInfoIpv4Tcp* _pkt_info) { + inline void treat_packets_to_outside() { - // BOOST_LOG_TRIVIAL(info) << "Size of densemap before to outside: " << - // _densemap.size(); + BOOST_LOG_TRIVIAL(info) + << "Size of densemap before to outside: " << _densemap.size(); /************************************************************************ ****Treatment of packets with direction towards the external network**** ************************************************************************/ - u_int8_t _flags = - _pkt_info->get_flags(); // get the flags of packet as - // they will be needed a few times - // BOOST_LOG_TRIVIAL(info) << "THE TYPE IS" << std::to_string(_flags); - if ((_flags & _flag_enum::SYNFIN) == _flag_enum::SYNFIN) { - rte_pktmbuf_free(_pkt_info->get_mbuf()); - } else if ((_flags & _flag_enum::SYNACK) == - _flag_enum::SYNACK) { // check wether the syn&ack flag is - // set - // BOOST_LOG_TRIVIAL(info) << "|---Got - // a SYN-ACK comming from inside---|"; - // Create entry in the Densemap - // Reply with the ack stored in _densemap for this specific - // connection... + for (int i = 0; i < _packet_to_outside->get_number_of_polled_packets(); + ++i) { - // Get Data from connection in order to create entry in - // _densemap and check _densemap - Data dfirst(_pkt_info->get_dst_ip(), _pkt_info->get_src_ip(), + PacketInfo* _pkt_info_plain = + _packet_to_outside->get_packet_at_index(i); + BOOST_LOG_TRIVIAL(info) + << "|---Got plain packet from inside with type: " + << _pkt_info_plain->get_type() << "---|"; + if ((_pkt_info_plain != nullptr) && + (_pkt_info_plain->get_type() == IPv4TCP)) { + PacketInfoIpv4Tcp* _pkt_info = + static_cast(_pkt_info_plain); + + u_int8_t _flags = + _pkt_info->get_flags(); // get the flags of packet i as they + // will be needed a few times + if ((_flags & _flags::SYNACK) == + _flags::SYNACK) { // check wether the syn&ack flag is set + BOOST_LOG_TRIVIAL(info) + << "|---Got a SYN-ACK comming from inside---|"; + // Create entry in the Densemap + // Reply with the ack stored in _densemap for this specific + // connection... + + // Get Data from connection in order to create entry in + // _densemap and check _densemap + Data dfirst( + _pkt_info->get_dst_ip(), _pkt_info->get_src_ip(), _pkt_info->get_dst_port(), _pkt_info->get_src_port()); - // find according value in _densemap - auto id = _densemap.find(dfirst); - // unsure about that, was to catch the case, that no ack has - // ever been held - if (id == _densemap.end()) { - // drop packet and delete connection info - rte_pktmbuf_free(_pkt_info->get_mbuf()); - } else if (id->second._pkt_inf_list.empty() == false) { - // cast into an ipv4 packet + // find according value in _densemap + auto id = _densemap.find(dfirst); + // unsure about that, was to catch the case, that no ack has + // ever been held + if (id == _densemap.end()) { + // drop packet and delete connection info + _packet_to_outside->drop_packet(i, _pkt_info); - bool first_packet = true; - for (auto elem : id->second._pkt_inf_list) { + } else if (id->second._pkt_inf_list.empty() == false) { + // cast into an ipv4 packet - if (first_packet) { + bool first_packet = true; + for (auto elem : (id->second._pkt_inf_list)) { - // calculate _offset by substracting - // internal_ack_num from external_ack_num - int offset = - elem->get_ack_num() - _pkt_info->get_seq_num() - 1; + if (first_packet) { - // BOOST_LOG_TRIVIAL(info) << "|---The offset is:" << - // offset << ", the external acknum is: " << - // elem->get_ack_num() << " the internal seqnum is: " << - // _pkt_info->get_seq_num() << " --- |"; + // calculate _offset by substracting + // internal_ack_num from external_ack_num + int offset = elem->get_ack_num() - + _pkt_info->get_seq_num() - 1; - id->second._offset = offset; - // adjust the acknum of the ack as a response to - // syn ack - // outside->set_ack_num(outside->get_ack_num() - - // offset); - elem->set_ack_num(_pkt_info->get_seq_num() + 1); - // refresh checksum - elem->prepare_offloading_checksums(); - // send received ack with adjusted acknum, this - // may already contain data - _packet_to_inside->add_mbuf(elem->get_mbuf()); - // erase entry in _pkt_inf + BOOST_LOG_TRIVIAL(info) + << "|---The offset is:" << offset + << ", the external acknum is: " + << elem->get_ack_num() + << " the internal seqnum is: " + << _pkt_info->get_seq_num() << " --- |"; - first_packet = false; + id->second._offset = offset; + // adjust the acknum of the ack as a response to + // syn ack + // outside->set_ack_num(outside->get_ack_num() - + // offset); + elem->set_ack_num(_pkt_info->get_seq_num() + 1); + // refresh checksum + elem->recalculate_checksums(); + // send received ack with adjusted acknum, this + // may already contain data + _packet_to_inside->add_packet(elem); + // erase entry in _pkt_inf + + first_packet = false; + } else { + + elem->set_ack_num(elem->get_ack_num() - + id->second._offset); + + elem->recalculate_checksums(); + } + } + id->second._pkt_inf_list.clear(); } else { - - elem->set_ack_num(elem->get_ack_num() - - id->second._offset); - - elem->prepare_offloading_checksums(); - _packet_to_inside->add_mbuf(elem->get_mbuf()); + BOOST_LOG_TRIVIAL(fatal) << "No element in the list"; } - delete elem; + } - id->second._pkt_inf_list.clear(); - } else { - // BOOST_LOG_TRIVIAL(fatal) << "No element in the list"; - } - } - // check wether the syn flag is set - else if ((_flags & _flag_enum::SYN) == _flag_enum::SYN) { - // Simply forward the packet - // BOOST_LOG_TRIVIAL(info) << "|---Forwarding the " "SYN from - // internal to external ---|"; - _packet_to_outside->add_mbuf(_pkt_info->get_mbuf()); - } - // RST received from inside_pkt_ - else if ((_flags & _flag_enum::RST) == _flag_enum::RST) { - // BOOST_LOG_TRIVIAL(info) << "|---Received an RST from inside---|"; - Data erase(_pkt_info->get_dst_ip(), _pkt_info->get_src_ip(), - _pkt_info->get_dst_port(), _pkt_info->get_src_port()); - auto id = _densemap.find(erase); - if (id == _densemap.end()) { - // drop packet - rte_pktmbuf_free(_pkt_info->get_mbuf()); + // check wether the syn flag is set + else if ((_flags & _flags::SYN) == _flags::SYN) { + // Simply forward the packet + BOOST_LOG_TRIVIAL(info) + << "|---Forwarding the " + "SYN from internal to external ---|"; - } else { - _pkt_info->set_seq_num(_pkt_info->get_seq_num() + - id->second._offset); - _pkt_info->prepare_offloading_checksums(); + } + // RST received from inside_pkt_ + else if ((_flags & _flags::RST) == _flags::RST) { + BOOST_LOG_TRIVIAL(info) + << "|---Received an RST from inside---|"; + Data erase(_pkt_info->get_dst_ip(), _pkt_info->get_src_ip(), + _pkt_info->get_dst_port(), + _pkt_info->get_src_port()); + auto id = _densemap.find(erase); + if (id == _densemap.end()) { + // drop packet + _packet_to_outside->drop_packet(i, _pkt_info); - _packet_to_outside->add_mbuf(_pkt_info->get_mbuf()); + } else { + _pkt_info->set_seq_num(_pkt_info->get_seq_num() + + id->second._offset); + _pkt_info->recalculate_checksums(); + _densemap.erase(erase); + } - _densemap.erase(erase); - } - } - // FIN received from inside_pkt - else if (((_flags & _flag_enum::FIN) == _flag_enum::FIN)) { - // BOOST_LOG_TRIVIAL(info) << "|---Recevied a FIN from inside---|"; - // create Data fin for the packet + } + // FIN received from inside_pkt + else if (((_flags & _flags::FIN) == _flags::FIN)) { + BOOST_LOG_TRIVIAL(info) + << "|---Recevied a FIN from inside---|"; + // create Data fin for the packet - // find the entry in our map - auto iter = _densemap.find( - Data(_pkt_info->get_dst_ip(), _pkt_info->get_src_ip(), - _pkt_info->get_dst_port(), _pkt_info->get_src_port())); - if (iter == _densemap.end()) { - // drop packet - rte_pktmbuf_free(_pkt_info->get_mbuf()); - } - else if ((iter->second._finseen_to_inside == true) /* && + // find the entry in our map + auto iter = _densemap.find(Data( + _pkt_info->get_dst_ip(), _pkt_info->get_src_ip(), + _pkt_info->get_dst_port(), _pkt_info->get_src_port())); + if (iter == _densemap.end()) { + // drop packet + _packet_to_outside->drop_packet(i, _pkt_info); + } + // it is a fin-ack fin-ack + else if ((iter->second._finseen_to_inside == true) /* && ((_flags & _flags::FINACK) == _flags::FINACK)*/) { - // Check if fin has already been seen and we are not - // looking for the reply - // BOOST_LOG_TRIVIAL(info) << "|---FIN-ACK for FIN---|"; - // change the packets seq number - iter->second._finseen_to_outside = true; - iter->second._ack_to_inside_expected = true; - _pkt_info->set_seq_num(_pkt_info->get_seq_num() + - iter->second._offset); - _pkt_info->prepare_offloading_checksums(); - // delete the entry - /* _densemap.erase(Data( - _pkt_info->get_dst_ip(), _pkt_info->get_src_ip(), - _pkt_info->get_dst_port(), - _pkt_info->get_src_port())); - */ - // send packet to inside // aka. do nothing + // Check if fin has already been seen and we are not + // looking for the reply + BOOST_LOG_TRIVIAL(info) << "|---FIN-ACK for FIN---|"; + // change the packets seq number + iter->second._finseen_to_outside = true; + iter->second._ack_to_inside_expected = true; + _pkt_info->set_seq_num(_pkt_info->get_seq_num() + + iter->second._offset); + _pkt_info->recalculate_checksums(); + // delete the entry + /* _densemap.erase(Data( + _pkt_info->get_dst_ip(), _pkt_info->get_src_ip(), + _pkt_info->get_dst_port(), + _pkt_info->get_src_port())); + */ + // send packet to inside // aka. do nothing - _packet_to_outside->add_mbuf(_pkt_info->get_mbuf()); - } + } + // Case: its the first FIN with piggybagged ack + else if (iter->second._finseen_to_outside == false) { + BOOST_LOG_TRIVIAL(info) + << "|---Recevied the first FIN from inside---|"; + // change status _finseen to true + iter->second._finseen_to_outside = true; + // get _offset + // change the packets seq number + _pkt_info->set_seq_num(_pkt_info->get_seq_num() + + iter->second._offset); + _pkt_info->recalculate_checksums(); + BOOST_LOG_TRIVIAL(info) + << "|---Changed Finseen to true for connection: " + "extip: " + << _pkt_info->get_dst_ip() + << " extport: " << _pkt_info->get_dst_port() + << " intip: " << _pkt_info->get_src_ip() + << " intport: " << _pkt_info->get_src_port() + << "---|"; + } + } - // Case: its the first FIN with piggybagged ack - else if (iter->second._finseen_to_outside == false) { - // BOOST_LOG_TRIVIAL(info)<< "|---Recevied the first FIN from - // inside---|"; change status _finseen to true - iter->second._finseen_to_outside = true; - // get _offset - // change the packets seq number - _pkt_info->set_seq_num(_pkt_info->get_seq_num() + - iter->second._offset); - _pkt_info->prepare_offloading_checksums(); - // BOOST_LOG_TRIVIAL(info) << "|---Changed Finseen to true for - // connection: " "extip: " - /* << _pkt_info->get_dst_ip() - << " extport: " << _pkt_info->get_dst_port() - << " intip: " << _pkt_info->get_src_ip() - << " intport: " << _pkt_info->get_src_port() << "---|"; */ + // CASE: ACK RECEIVED from Bob + else if (((_flags & _flags::ACK) == _flags::ACK) && + ((_flags & _flags::FINACK) != _flags::FINACK)) { - _packet_to_outside->add_mbuf(_pkt_info->get_mbuf()); - } else { - // BOOST_LOG_TRIVIAL(info) << "|--- Saw duplicate FIN from - // outside----|"; + BOOST_LOG_TRIVIAL(info) + << "|---Received an ACK from inside---|"; + Data ack(_pkt_info->get_dst_ip(), _pkt_info->get_src_ip(), + _pkt_info->get_dst_port(), + _pkt_info->get_src_port()); + auto id = _densemap.find(ack); + // no entry in _densemap, create one and adjust value + // accordingly + if (id == _densemap.end()) { + BOOST_LOG_TRIVIAL(info) + << "|---Created new entry in the densemap---|"; + Info info(0, false, false, false, false, nullptr); + _densemap.insert(std::make_pair(ack, info)); + // send out packet, aka do nothing - _pkt_info->set_seq_num(_pkt_info->get_seq_num() + - iter->second._offset); - _pkt_info->prepare_offloading_checksums(); - _packet_to_outside->add_mbuf(_pkt_info->get_mbuf()); + } else if (id->second._finseen_to_inside == true && + id->second._finseen_to_outside == true && + id->second._ack_to_outside_expected == true) { + BOOST_LOG_TRIVIAL(info) + << "|---ACK to FIN-ACK-Packet---|"; + + _pkt_info->set_seq_num(_pkt_info->get_seq_num() + + id->second._offset); + _pkt_info->recalculate_checksums(); + + _densemap.erase(id); + BOOST_LOG_TRIVIAL(info) + << "|---Deleted entry in densemap--|"; + + } else { + BOOST_LOG_TRIVIAL(info) + << "|---Just a regular ACK-Packet---|"; + // it is just a regular packet, simply adjust with + // _offset and you are done. + _pkt_info->set_seq_num(_pkt_info->get_seq_num() + + id->second._offset); + _pkt_info->recalculate_checksums(); + } + } } } - - // CASE: ACK RECEIVED from Bob - else if (((_flags & _flag_enum::ACK) == _flag_enum::ACK) && - ((_flags & _flag_enum::FINACK) != _flag_enum::FINACK)) { - - // BOOST_LOG_TRIVIAL(info) << "|---Received an ACK from inside---|"; - Data ack(_pkt_info->get_dst_ip(), _pkt_info->get_src_ip(), - _pkt_info->get_dst_port(), _pkt_info->get_src_port()); - auto id = _densemap.find(ack); - // no entry in _densemap, create one and adjust value - // accordingly - if (id == _densemap.end()) { - // BOOST_LOG_TRIVIAL(info) << "|---Created new entry in the - // densemap---|"; - Info info(0, false, false, false, false, nullptr); - _densemap.insert(std::make_pair(ack, info)); - - // send out packet, aka do nothing - _packet_to_outside->add_mbuf(_pkt_info->get_mbuf()); - - } else if (unlikely(id->second._finseen_to_inside == true && - id->second._finseen_to_outside == true && - id->second._ack_to_outside_expected == true)) { - // BOOST_LOG_TRIVIAL(info) << "|---ACK to FIN-ACK-Packet---|"; - - _pkt_info->set_seq_num(_pkt_info->get_seq_num() + - id->second._offset); - _pkt_info->prepare_offloading_checksums(); - - _densemap.erase(id); - // BOOST_LOG_TRIVIAL(info) << "|---Deleted entry in - // densemap--|"; - _packet_to_outside->add_mbuf(_pkt_info->get_mbuf()); - - } else { - // BOOST_LOG_TRIVIAL(info) << "|---Just a regular - // ACK-Packet---|"; - // it is just a regular packet, simply adjust with - // _offset and you are done. - _pkt_info->set_seq_num(_pkt_info->get_seq_num() + - id->second._offset); - _pkt_info->prepare_offloading_checksums(); - - _packet_to_outside->add_mbuf(_pkt_info->get_mbuf()); - } - } - // BOOST_LOG_TRIVIAL(info) << "Size of densemap after to outside: " << - // _densemap.size(); - return false; + BOOST_LOG_TRIVIAL(info) + << "Size of densemap after to outside: " << _densemap.size(); } /** @@ -875,6 +866,7 @@ class Treatment { return true; } } + // return false, so that treat_packets is able to continue return false; } @@ -884,19 +876,16 @@ class Treatment { u_int64_t _cookie_secret; ///< cookie_secret used to enhance the efficency ///< of SYN-cookies - u_int8_t _skip_syn; - u_int8_t _syn_thresh; - - MbufContainerTransmitting* - _packet_to_inside; ///< MbufContainer containing packets with + PacketContainer* + _packet_to_inside; ///< PacketContainer containing packets with ///< destination being the internal network - MbufContainerTransmitting* - _packet_to_outside; ///< MbufContainer containing packets with + PacketContainer* + _packet_to_outside; ///< PacketContainer containing packets with ///< destination being the extern network - google::dense_hash_map + google::dense_hash_map _densemap; ///< Map to store information about connections including ///< _offset and if a fin has been seen diff --git a/include/Treatment/rand.h b/include/Treatment/rand.h new file mode 100644 index 0000000..1f32884 --- /dev/null +++ b/include/Treatment/rand.h @@ -0,0 +1,44 @@ +#pragma once + +/** + * @file rand.h + * @author Felix, Fabienne + * @brief This header includes only one method which returns a random 64bit + * unsigned integer + * @version 0.1 + * @date 2021-07-06 + * + * @copyright Copyright (c) 2021 + * + */ + +/** + * @brief Rand itself provides a method to get a random number. This number is + * used in Treatment as cookie_secret + * + */ +class Rand { + + public: + /** + * @brief Get a random 64bit unsigned integer + * + * @return u_int64_t + */ + static u_int64_t get_random_64bit_value() { + u_int64_t random64BitNumber = 0; + + u_int64_t value1 = (uint16_t)std::rand(); + value1 = (value1 << 48); + random64BitNumber |= value1; + + u_int64_t value2 = (uint16_t)rand(); + value2 = (value2 << 32); + random64BitNumber |= value2; + + u_int64_t value3 = (uint16_t)rand(); + random64BitNumber |= value3; + + return random64BitNumber; + } +}; \ No newline at end of file diff --git a/source/Attacker/main.cpp b/source/Attacker/main.cpp index 5fa4360..a193d8d 100644 --- a/source/Attacker/main.cpp +++ b/source/Attacker/main.cpp @@ -1,27 +1,16 @@ #include -#include #include #include -#include "Cli.hpp" -#include "ConfigurationManagement/Configurator.hpp" +#include "Configurator.hpp" #include "Initializer.hpp" #include "PacketDissection/PacketContainer.hpp" #include "Threads/AttackThread.hpp" +int main(int argc, char** argv); void handle_quit(int signum); -void terminate(AttackThread** thread_arr, uint16_t nb_worker_threads); bool quit = false; -std::chrono::time_point start, end; -uint64_t nb_pkts_to_dave = 0; -uint64_t nb_pkts_from_dave = 0; -uint64_t nb_atk_pkts = 0; -uint64_t nb_pkts_to_alice = 0; -uint64_t nb_pkts_from_alice = 0; -uint64_t data_volume_to_alice = 0; -uint64_t data_volume_from_alice = 0; -int pkt_type_used = 0; int main(int argc, char** argv) { @@ -29,7 +18,7 @@ int main(int argc, char** argv) { // Register signal and signal handler signal(SIGINT, handle_quit); - Configurator::instance()->read_config("../test/config_attacker.json"); + Configurator::instance()->read_config("../test/Attacker_config.json"); Initializer* init = new Initializer(); unsigned int lcore_id; @@ -60,189 +49,64 @@ int main(int argc, char** argv) { lcore_id = rte_lcore_id(); // run every thread except the last one - for (int i = 0; i < nb_worker_threads; ++i) { + for (int i = 0; i < nb_worker_threads - 1; ++i) { lcore_id = rte_get_next_lcore(lcore_id, true, true); rte_eal_remote_launch( static_cast(AttackThread::s_run), thread_arr[i], lcore_id); } + // start measuring time running + std::chrono::time_point start, end; + start = std::chrono::system_clock::now(); - std::cout << "\nRunning. [Ctrl+C to quit]\n" << std::endl; + // ===== RUN ===== // + std::cout << "\nRunning on lcore " << rte_lcore_id() + << ". [Ctrl+C to quit]\n" + << std::endl; - // =================== START CLI ==================== // + while (quit == false) { + thread_arr[nb_worker_threads - 1]->iterate(); +#ifdef SINGLE_ITERATION + quit = true; +#endif + } - std::string input = ""; - const std::string NAME = "syntflut"; - const char* PATH_ATTACKING_FILE = "/home/guru/is_attacking/attacking"; + // ===== TERMINATE ===== // + std::cout << "\nterminating..." << std::endl; - enum State { RUNNING, IDLE }; - State state = IDLE; + for (int i = 0; i < nb_worker_threads - 1; ++i) { +#ifndef SINGLE_ITERATION + thread_arr[i]->quit(); +#endif + } + // stop measuring time running + end = std::chrono::system_clock::now(); + // calculate total number of attack packets + uint64_t nb_atk_pkts = 0; + uint64_t nb_pkts_to_alice = 0; + uint64_t nb_pkts_from_alice = 0; + uint64_t data_volume_to_alice = 0; + uint64_t data_volume_from_alice = 0; + int pkt_type_used = 0; - while (input != "exit") { - - std::cout << NAME << "> "; - std::cin >> input; - std::cout << std::endl; - - if (input == "start") { - if (state == IDLE) { - - for (int i = 0; i < nb_worker_threads; ++i) { - thread_arr[i]->_do_attack = true; - } - - // start measuring time running - - start = std::chrono::system_clock::now(); - - // Start GUI - - std::ofstream outfile(PATH_ATTACKING_FILE); - outfile.close(); - - // ===== RUN ===== // - - state = RUNNING; - - } else { // state == RUNNING - std::cout << "Cannot start if program is already running." - << std::endl; - } - - } else if (input == "stop") { - if (state == IDLE) { - std::cout << "Cannot stop if program is not running." - << std::endl; - - } else { // state == RUNNING - - // Stop GUI - std::remove(PATH_ATTACKING_FILE); - - end = std::chrono::system_clock::now(); - - nb_pkts_to_dave = 0; - nb_pkts_from_dave = 0; - nb_pkts_to_alice = 0; - nb_pkts_from_alice = 0; - data_volume_to_alice = 0; - data_volume_from_alice = 0; - pkt_type_used = 0; - - for (int i = 0; i < nb_worker_threads; ++i) { - // rescue Informations - nb_pkts_to_dave += - thread_arr[i]->get_total_nb_pkts_to_dave(); - nb_pkts_from_dave += - thread_arr[i]->get_total_nb_pkts_from_dave(); - nb_pkts_to_alice += - thread_arr[i]->get_total_nb_pkts_to_alice(); - nb_pkts_from_alice += - thread_arr[i]->get_total_nb_pkts_from_alice(); - data_volume_to_alice += - thread_arr[i]->get_total_data_volume_to_alice(); - data_volume_from_alice += - thread_arr[i]->get_total_data_volume_from_alice(); - pkt_type_used += thread_arr[i]->get_atk_pkt_type(); - - thread_arr[i]->_do_attack = false; - } - - // print attack statistics - std::chrono::duration elapsed_seconds = end - start; - std::cout << "\nduration of attack:\t\t\t\t" - << elapsed_seconds.count() << " seconds" << std::endl; - int pkt_size = -1; - if (pkt_type_used > 1) { // TCP: tcp + ip + ether - pkt_size = 20 + 20 + 14; - } else { // UDP: udp + ip + ether - pkt_size = 8 + 20 + 14; - } - nb_atk_pkts = nb_pkts_to_dave - nb_pkts_from_alice; - std::cout << "attack packets sent:\t\t\t\t" << nb_atk_pkts - << std::endl; - - std::cout << "data volume sent (without L1 header):\t\t" - << nb_atk_pkts * pkt_size / 1048576 << " MByte" - << std::endl; - - std::cout << "data volume sent (with L1 header):\t\t" - << nb_atk_pkts * 84 / 1048576 << " MByte" - << std::endl; - - std::cout << "average attack rate (without L1 header):\t" - << nb_atk_pkts * pkt_size / elapsed_seconds.count() / - 1048576 * 8 - << " Mbps" << std::endl; - - std::cout << "average attack rate (with L1 header):\t\t" - << nb_atk_pkts * 84 / elapsed_seconds.count() / - 1048576 * 8 - << " Mbps" << std::endl; - - std::cout << "average attack packet rate:\t\t\t" - << nb_atk_pkts / elapsed_seconds.count() / 1000 - << " Kpps" << std::endl; - - std::cout << "\nnumber packets sent from alice:\t\t\t" - << nb_pkts_from_alice << std::endl; - - std::cout << "number packets recieved by alice:\t\t" - << nb_pkts_to_alice << std::endl; - - std::cout << "average data rate sent from alice:\t\t" - << data_volume_from_alice / elapsed_seconds.count() / - 1024 * 8 - << " Kbps" << std::endl; - - std::cout << "average data rate recieved by alice:\t\t" - << data_volume_to_alice / elapsed_seconds.count() / - 1024 * 8 - << " Kbps" << std::endl - << std::endl; - - /* - std::cout << "\nstats for testing:" << std::endl; - - std::cout << "number packets sent from dave:\t\t\t" - << nb_pkts_from_dave << std::endl; - - std::cout << "number packets recieved by dave:\t\t\t" - << nb_pkts_to_dave << std::endl; - - std::cout << "attack time:\t\t\t\t\t\t\t\t" - << elapsed_seconds.count() <<"s" << std::endl; -*/ - - state = IDLE; - } - - } else if (input == "exit") { - - // Stop GUI - if (state == RUNNING) { - std::remove(PATH_ATTACKING_FILE); - } - - } else if (input == "help" || input == "h") { - std::cout << "start\tstart " << NAME << std::endl - << "stop\tstop " << NAME << std::endl - << "help, h\tprint commands " << std::endl - << "exit\texit " << NAME << std::endl - << std::endl; - } else { - std::cout << "Command unknown. Try 'h' or 'help'." << std::endl; + // wait for threads to end + for (int i = 0; i < nb_worker_threads - 1; ++i) { + while (thread_arr[i]->is_running()) { + // wait } } - // ==================== END CLI ==================== // - - // ===== TERMINATE ===== // - terminate(thread_arr, nb_worker_threads); - // destruct objects on heap for (int i = 0; i < nb_worker_threads; ++i) { + // rescue Informations + nb_atk_pkts += thread_arr[i]->get_total_nb_atk_pkts(); + nb_pkts_to_alice += thread_arr[i]->get_total_nb_pkts_to_alice(); + nb_pkts_from_alice += thread_arr[i]->get_total_nb_pkts_from_alice(); + data_volume_to_alice += thread_arr[i]->get_total_data_volume_to_alice(); + data_volume_from_alice += + thread_arr[i]->get_total_data_volume_from_alice(); + pkt_type_used += thread_arr[i]->get_atk_pkt_type(); delete thread_arr[i]; thread_arr[i] = nullptr; @@ -254,6 +118,52 @@ int main(int argc, char** argv) { pkt_containers_to_alice[i] = nullptr; } + // print attack statistics + std::chrono::duration elapsed_seconds = end - start; + std::cout << "\nduration of attack:\t\t\t\t" << elapsed_seconds.count() + << " seconds" << std::endl; + int pkt_size = -1; + if (pkt_type_used > 1) { // TCP: tcp + ip + ether + pkt_size = 20 + 20 + 14; + } else { // UDP: udp + ip + ether + pkt_size = 8 + 20 + 14; + } + std::cout << "attack packets sent:\t\t\t\t" << nb_atk_pkts << std::endl; + + std::cout << "data volume sent (without L1 header):\t\t" + << nb_atk_pkts * pkt_size / 1073741824 << " GByte" << std::endl; + + std::cout << "data volume sent (with L1 header):\t\t" + << nb_atk_pkts * 84 / 1073741824 << " GByte" << std::endl; + + std::cout << "average attack rate (without L1 header):\t" + << nb_atk_pkts * pkt_size / elapsed_seconds.count() / 1073741824 * + 8 + << " Gbps" << std::endl; + + std::cout << "average attack rate (with L1 header):\t\t" + << nb_atk_pkts * 84 / elapsed_seconds.count() / 1073741824 * 8 + << " Gbps" << std::endl; + + std::cout << "average attack packet rate:\t\t\t" + << nb_atk_pkts / elapsed_seconds.count() / 1000000 << " Mpps" + << std::endl; + + std::cout << "\nnumber packets sent from alice:\t\t\t" << nb_pkts_from_alice + << std::endl; + + std::cout << "number packets recieved by alice:\t\t" << nb_pkts_to_alice + << std::endl; + + std::cout << "average data rate sent from alice:\t\t" + << data_volume_from_alice / elapsed_seconds.count() / 1024 * 8 + << " Kbps" << std::endl; + + std::cout << "average data rate recieved by alice:\t\t" + << data_volume_to_alice / elapsed_seconds.count() / 1024 * 8 + << " Kbps" << std::endl + << std::endl; + delete init; init = nullptr; @@ -264,23 +174,4 @@ int main(int argc, char** argv) { // YOU ARE TERMINATED } -void handle_quit(int signum) { - // do nothing -} - -void terminate(AttackThread** thread_arr, uint16_t nb_worker_threads) { - std::cout << "\nterminating..." << std::endl; - - for (int i = 0; i < nb_worker_threads - 1; ++i) { -#ifndef SINGLE_ITERATION - thread_arr[i]->quit(); -#endif - } - - // wait for threads to end - for (int i = 0; i < nb_worker_threads - 1; ++i) { - while (thread_arr[i]->is_running()) { - // wait - } - } -} \ No newline at end of file +void handle_quit(int signum) { quit = true; } \ No newline at end of file diff --git a/source/Configurator.cpp b/source/Configurator.cpp index 7d3cf80..f055a97 100644 --- a/source/Configurator.cpp +++ b/source/Configurator.cpp @@ -2,88 +2,99 @@ #include #include -//------------------------------------------------------------------------------- -//------------------------- Constructor/ Destructor ----------------------------- -//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ +//------------------------- Constructor/ Destructor ---------------------------- +//------------------------------------------------------------------------------ -Configurator::Configurator(){} +Configurator::Configurator() {} Configurator* Configurator::_instance = nullptr; -Configurator* Configurator::instance(){ // Speicherbereinigung +Configurator* Configurator::instance() { // Speicherbereinigung static CGuard g; - if (!_instance){ - _instance = new Configurator (); + if (!_instance) { + _instance = new Configurator(); } return _instance; } -Configurator::~Configurator(){} +Configurator::~Configurator() {} -//------------------------------------------------------------------------------- -//-------------------------------- Read Config ---------------------------------- -//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ +//-------------------------------- Read Config --------------------------------- +//------------------------------------------------------------------------------ -void Configurator::read_config(std::string path, - std::string default_path){ +void Configurator::read_config(std::string path, std::string default_path) { // Read Standard Config std::ifstream config_file(path); - if(config_file.is_open()){ + if (config_file.is_open()) { config_file >> _config; LOG_INFO << "Config loaded Succesfully" << LOG_END; - } - else { + } else { LOG_INFO << "No Config-File found at " + path << LOG_END; throw std::runtime_error("No Config-File found at " + path); } // Read Default Config std::ifstream default_config_file(default_path); - if(default_config_file.is_open()){ + if (default_config_file.is_open()) { default_config_file >> _default_config; LOG_INFO << "Default Config loaded Succesfully" << LOG_END; - } - else { - LOG_ERROR << "No Config-File found at default path " + default_path << LOG_END; - throw std::runtime_error("No Config-File found at deafult path " + default_path); + } else { + LOG_ERROR << "No Config-File found at default path " + default_path + << LOG_END; + throw std::runtime_error("No Config-File found at deafult path " + + default_path); } } -//------------------------------------------------------------------------------- -//-------------------------------- Get-Methods ---------------------------------- -//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------ +//-------------------------------- Get-Methods --------------------------------- +//------------------------------------------------------------------------------ bool Configurator::entry_exists(const std::string att_name) { - bool in_default_config = _default_config.find(att_name) != _default_config.end(); + bool in_default_config = + _default_config.find(att_name) != _default_config.end(); bool in_standard_config = _config.find(att_name) != _config.end(); return in_default_config || in_standard_config; } -std::string Configurator::get_config_as_string(const std::string& att_name, bool default_value) { - return Configurator::get_value_from_config(att_name, default_value); +std::string Configurator::get_config_as_string(const std::string& att_name, + bool default_value) { + return Configurator::get_value_from_config(att_name, + default_value); } -unsigned int Configurator::get_config_as_unsigned_int(const std::string& att_name, bool default_value) { +unsigned int +Configurator::get_config_as_unsigned_int(const std::string& att_name, + bool default_value) { return Configurator::get_value_from_config(att_name, default_value); } -bool Configurator::get_config_as_bool(const std::string& att_name, bool default_value) { +bool Configurator::get_config_as_bool(const std::string& att_name, + bool default_value) { return Configurator::get_value_from_config(att_name, default_value); } -float Configurator::get_config_as_float(const std::string& att_name, bool default_value) { +float Configurator::get_config_as_float(const std::string& att_name, + bool default_value) { return Configurator::get_value_from_config(att_name, default_value); } -double Configurator::get_config_as_double(const std::string& att_name, bool default_value) { +double Configurator::get_config_as_double(const std::string& att_name, + bool default_value) { return Configurator::get_value_from_config(att_name, default_value); } -template -T Configurator::get_value_from_config(const std::string& att_name, bool default_value) { - bool search_in_default_config = !(_config.find(att_name) != _config.end()) || default_value; - if (!search_in_default_config) { return _config[att_name]; } +template +T Configurator::get_value_from_config(const std::string& att_name, + bool default_value) { + bool search_in_default_config = + !(_config.find(att_name) != _config.end()) || default_value; + if (!search_in_default_config) { + return _config[att_name]; + } return _default_config[att_name]; } -//TODO Mehrdimensionale Attribute suchen +// TODO Mehrdimensionale Attribute suchen diff --git a/source/DebugHelper.cpp b/source/DebugHelper.cpp index 577a2ac..56a7998 100644 --- a/source/DebugHelper.cpp +++ b/source/DebugHelper.cpp @@ -57,7 +57,7 @@ void DebugHelper::hex_dump_raw(const void *addr, int len) { unsigned char res[2 * len + 1]; res[2 * len] = '\0'; - for(unsigned int i = 0; i < len; i++) { + for(int i = 0; i < len; i++) { printf((char *)res + i * 2, "%02X", pc[i]); } printf ("%s\n", res); diff --git a/source/Initializer.cpp b/source/Initializer.cpp index 99f849b..2d19d21 100644 --- a/source/Initializer.cpp +++ b/source/Initializer.cpp @@ -4,7 +4,7 @@ #include -#include "ConfigurationManagement/Configurator.hpp" +#include "Configurator.hpp" #include "Definitions.hpp" #include "Initializer.hpp" @@ -20,15 +20,19 @@ rte_mempool* Initializer::init_dpdk(int argc, char** argv, }; rte_eth_conf port_conf = { - .rxmode = {.mq_mode = ETH_MQ_RX_RSS, - .max_rx_pkt_len = RTE_ETHER_MAX_LEN, - .offloads = DEV_RX_OFFLOAD_CHECKSUM}, + .rxmode = + { + .mq_mode = ETH_MQ_RX_RSS, + .max_rx_pkt_len = RTE_ETHER_MAX_LEN, + .offloads = + DEV_RX_OFFLOAD_CHECKSUM + }, .txmode = { .offloads = (DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_UDP_CKSUM | - DEV_TX_OFFLOAD_TCP_CKSUM), - }, + DEV_TX_OFFLOAD_TCP_CKSUM), + }, .rx_adv_conf = {.rss_conf = { .rss_key = hash_key, @@ -53,8 +57,8 @@ rte_mempool* Initializer::init_dpdk_attacker(int argc, char** argv, { .offloads = (DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_UDP_CKSUM | - DEV_TX_OFFLOAD_TCP_CKSUM), - }, + DEV_TX_OFFLOAD_TCP_CKSUM), + }, }; return init_dpdk_template(0, port_conf, argc, argv, nb_worker_threads); @@ -66,7 +70,7 @@ rte_mempool* Initializer::init_dpdk_template(uint16_t nb_non_worker_threads, uint16_t& nb_worker_threads) { int ret; unsigned int nb_ports; - uint16_t portid; + uint16_t portid; //< init portid struct rte_mempool* mbuf_pool; // initialize eal @@ -100,21 +104,22 @@ rte_mempool* Initializer::init_dpdk_template(uint16_t nb_non_worker_threads, cache_size -= 1; } - mbuf_pool = - rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUF_POOL_ELEMENTS, cache_size, - 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); + mbuf_pool = rte_pktmbuf_pool_create( + "MBUF_POOL", NUM_MBUF_POOL_ELEMENTS, 0 /*cache_size*/, 0, + RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); if (mbuf_pool == nullptr) { rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); } // Initialize all ports. - try { - RTE_ETH_FOREACH_DEV(portid) { + RTE_ETH_FOREACH_DEV(portid) { + try { init_port(port_conf, portid, mbuf_pool, nb_worker_threads); + } + catch (std::exception& e) { + rte_exit(EXIT_FAILURE, "Cannot init port %" PRIu16 "\n", portid); } - } catch (std::exception& e) { - rte_exit(EXIT_FAILURE, "Cannot init port %" PRIu16 "\n", portid); } return mbuf_pool; @@ -150,23 +155,17 @@ void Initializer::init_port(rte_eth_conf port_conf, uint16_t port, // |= is not allowed operator. negation of DEV_TX_OFFL... port_conf.txmode.offloads |= DEV_TX_OFFLOAD_MBUF_FAST_FREE; // test if checksum offloading is possible - if (((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM) == - DEV_TX_OFFLOAD_TCP_CKSUM) && - ((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM) == - DEV_TX_OFFLOAD_IPV4_CKSUM)) { - std::cout << "ethernet device is checksum offloading capable" - << std::endl; + if (((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM) == DEV_TX_OFFLOAD_TCP_CKSUM) && + ((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM) == DEV_TX_OFFLOAD_IPV4_CKSUM) ){ + std::cout << "ethernet device is checksum offloading capabel" << std::endl; } else { - std::cout << "ethernet device is not checksum offloading capable" - << std::endl; + std::cout << "ethernet device is not checksum offloading capabel" << std::endl; } - if (((dev_info.tx_queue_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM) == - DEV_TX_OFFLOAD_IPV4_CKSUM) && - ((dev_info.tx_queue_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM) == - DEV_TX_OFFLOAD_TCP_CKSUM)) { - std::cout << "queue is checksum offloading capable" << std::endl; + if (((dev_info.tx_queue_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM) == DEV_TX_OFFLOAD_IPV4_CKSUM) && + ((dev_info.tx_queue_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM) == DEV_TX_OFFLOAD_TCP_CKSUM)) { + std::cout << "queue is checksum offloading capabel" << std::endl; } else { - std::cout << "queue is not checksum offloading capable" << std::endl; + std::cout << "queue is not checksum offloading capabel" << std::endl; } // Configure the Ethernet device. diff --git a/source/Threads/DefenseThread.cpp b/source/Threads/DefenseThread.cpp index 153ea6c..8045dd8 100644 --- a/source/Threads/DefenseThread.cpp +++ b/source/Threads/DefenseThread.cpp @@ -1,28 +1,20 @@ +#include #include #include #include #include "Definitions.hpp" - #include "Threads/DefenseThread.hpp" +#include "Threads/StatisticsThread.hpp" // ===== PUBLIC ===== // -DefenseThread::DefenseThread( - MbufContainerReceiving* mbuf_container_from_inside, - MbufContainerReceiving* mbuf_container_from_outside, - MbufContainerTransmitting* mbuf_container_to_inside, - MbufContainerTransmitting* mbuf_container_to_outside) - : Thread() - , _mbuf_container_from_inside(mbuf_container_from_inside) - , _mbuf_container_from_outside(mbuf_container_from_outside) - , _mbuf_container_to_inside(mbuf_container_to_inside) - , _mbuf_container_to_outside(mbuf_container_to_outside) - , _do_treat(false) { - - _treatment = - new Treatment(_mbuf_container_to_outside, _mbuf_container_to_inside, 0); -} +DefenseThread::DefenseThread(PacketContainer* pkt_container_to_inside, + PacketContainer* pkt_container_to_outside, + StatisticsThread* stat_thread) + : ForwardingThread(pkt_container_to_inside, pkt_container_to_outside), + _treatment(pkt_container_to_inside, pkt_container_to_outside), + _statistics_thread(stat_thread) {} int DefenseThread::s_run(void* thread_vptr) { DefenseThread* thread = static_cast(thread_vptr); @@ -33,94 +25,54 @@ int DefenseThread::s_run(void* thread_vptr) { // ===== PRIVATE ===== // void DefenseThread::run() { - /* - LOG_INFO << "\nRunning on lcore " << rte_lcore_id() << ". [Ctrl+C to quit]" - << LOG_END; - */ + uint16_t nb_pkts_to_inside; + uint16_t nb_pkts_to_outside; + + BOOST_LOG_TRIVIAL(info) + << "\nRunning on lcore " << rte_lcore_id() << ". [Ctrl+C to quit]\n"; + + // stats for StatisticThread_testing + Stats* thread_statistics = new Stats(); + thread_statistics->attacks = rte_lcore_id(); + thread_statistics->bytes = rte_lcore_id(); + thread_statistics->dropped = rte_lcore_id(); + thread_statistics->packets = rte_lcore_id(); + thread_statistics->work_time = rte_lcore_id(); // Run until the application is quit or killed. while (likely(_quit == false)) { + _statistics_thread->enqueue_statistics(rte_lcore_id(), + thread_statistics); - // std::cout << _do_treat << std::endl; + // ===== ALICE --[DAVE]--> BOB ===== // // continue if no packets are received - int mbufs_from_inside = _mbuf_container_from_inside->poll_mbufs(); - /* if (mbufs_from_inside != 0) { - BOOST_LOG_TRIVIAL(info) - << "Number of packets received from inside: " - << mbufs_from_inside; - } */ - bool keep = true; - for (int i = 0; i < mbufs_from_inside; ++i) { - rte_mbuf* mbuf = _mbuf_container_from_inside->get_mbuf_at_index(i); + _pkt_container_to_inside->poll_packets(nb_pkts_to_inside); + if (likely(nb_pkts_to_inside > 0)) { - if (PacketInfoCreator::is_ipv4_tcp(mbuf) == true && - _do_treat == true) { - PacketInfoIpv4Tcp* pkt_info = new PacketInfoIpv4Tcp(mbuf); - keep = _treatment->treat_packets_to_outside(pkt_info); - if (keep == false) { - // delete PacketInfo - delete pkt_info; - } - } else { - // fwd - // std::cout << _do_treat; - _mbuf_container_to_outside->add_mbuf(mbuf); - } + /// TODO: implement pipeline + + _treatment.treat_packets_to_inside(); + _pkt_container_to_inside->send_packets(); + _pkt_container_to_outside->send_packets(); } - - _mbuf_container_to_inside->send_mbufs(); - _mbuf_container_to_outside->send_mbufs(); - - // _mbuf_container_to_inside->send_mbufs(); - // _mbuf_container_to_outside->send_mbufs(); - - // for mbuf in pktsFromOutside - // pktInfoCreator::determinePacketType without creating a pktinfo - // create packetInfo with obtained type - // if tcp: treat - // else: fwd - // destroy pktInfo - // Pakete von innen, auch die selbsterzeugten bevorzugen + // ===== ALICE <--[DAVE]-- BOB ===== // // continue if no packets are received + _pkt_container_to_outside->poll_packets(nb_pkts_to_outside); + if (likely(nb_pkts_to_outside > 0)) { - int mbufs_from_outside = _mbuf_container_from_outside->poll_mbufs(); - /* if (mbufs_from_outside != 0) { - BOOST_LOG_TRIVIAL(info) - << "Number of packets received from outside: " - << mbufs_from_outside; - } */ - for (int i = 0; i < mbufs_from_outside; ++i) { - rte_mbuf* mbuf = _mbuf_container_from_outside->get_mbuf_at_index(i); - - if (PacketInfoCreator::is_ipv4_tcp(mbuf) == true && - _do_treat == true) { - PacketInfoIpv4Tcp* pkt_info = new PacketInfoIpv4Tcp(mbuf); - keep = _treatment->treat_packets_to_inside( - static_cast(pkt_info)); - if (keep == false) { - // delete PacketInfo - delete pkt_info; - } - } else { - // std::cout << _do_treat; - _mbuf_container_to_inside->add_mbuf(mbuf); - } + /// TODO: implement pipeline + _treatment.treat_packets_to_outside(); + _pkt_container_to_inside->send_packets(); + _pkt_container_to_outside->send_packets(); } - /* if (_mbuf_container_to_inside->get_number_of_mbufs() > 0) { - BOOST_LOG_TRIVIAL(info) - << "Number of packets sent to inside: " - << _mbuf_container_to_inside->get_number_of_mbufs(); - } - if (_mbuf_container_to_outside->get_number_of_mbufs() > 0) { - BOOST_LOG_TRIVIAL(info) - << "Number of packets sent to outside: " - << _mbuf_container_to_outside->get_number_of_mbufs(); - } */ - _mbuf_container_to_inside->send_mbufs(); - _mbuf_container_to_outside->send_mbufs(); + if (likely(nb_pkts_to_inside != 0 || nb_pkts_to_outside != 0)) { + BOOST_LOG_TRIVIAL(info) + << "pkts_to_inside = " << nb_pkts_to_inside + << "\tpkts_to_outside = " << nb_pkts_to_outside << "\n"; + } } _running = false; diff --git a/source/Threads/StatisticsThread.cpp b/source/Threads/StatisticsThread.cpp index ae02550..a82ab8f 100644 --- a/source/Threads/StatisticsThread.cpp +++ b/source/Threads/StatisticsThread.cpp @@ -1,9 +1,58 @@ #include "Threads/StatisticsThread.hpp" +#include //------------------------------------------------------------------------- //-------------------------- StatisticsThread ----------------------------- //------------------------------------------------------------------------- +StatisticsThread::StatisticsThread() { + std::string name; + unsigned int lcore_id = rte_lcore_id(); + for (int i = 0; i < 16; ++i) { + lcore_id = rte_get_next_lcore(lcore_id, true, true); + + name = "RTE_RING_THREAD_"; + name += i + 1; + const char* c = + name.c_str(); // wrap string to char pointer //TODO: good name + + lcore_id = rte_get_next_lcore(lcore_id, true, true); + _s_queue[i] = rte_ring_create(c, 4, rte_lcore_to_socket_id(lcore_id), + RING_F_SP_ENQ | RING_F_SC_DEQ); + + // checking for errors in creating rte rings + if (_s_queue[i] == NULL) { + if (rte_errno == E_RTE_NO_CONFIG) { + std::cout << "Error during RTE_RING creation at Ring " << i + 1 + << ", return Value = E_RTE_NO_CONFIG" << std::endl; + } + if (rte_errno == E_RTE_SECONDARY) { + std::cout << "Error during RTE_RING creation at Ring " << i + 1 + << ", return Value = E_RTE_SECONDARY" << std::endl; + } + if (rte_errno == EINVAL) { + std::cout << "Error during RTE_RING creation at Ring " << i + 1 + << ", return Value = EINVAL" << std::endl; + } + if (rte_errno == ENOSPC) { + std::cout << "Error during RTE_RING creation at Ring " << i + 1 + << ", return Value = ENOSPC" << std::endl; + } + if (rte_errno == EEXIST) { + std::cout << "Error during RTE_RING creation at Ring " << i + 1 + << ", return Value = EEXIST" << std::endl; + } + if (rte_errno == ENOMEM) { + std::cout << "Error during RTE_RING creation at Ring " << i + 1 + << ", return Value = ENOMEM" << std::endl; + } + } + } // rte_lcore_to_socket_id + _s_stats_monitor = new StatsMonitor; + _s_stats = new Stats; + _s_stats_monitor->total_time = 0; +} + rte_ring* StatisticsThread::_s_queue[16]; int StatisticsThread::s_run(void* thread_vptr) { @@ -14,42 +63,97 @@ int StatisticsThread::s_run(void* thread_vptr) { void StatisticsThread::run() { // Check for new statistics in each rte_ring - while (_quit != false) { - for (rte_ring* ring : _s_queue) { - // Get stats from queue and update them + std::cout << "\n StatisticThread running on lcore " << rte_lcore_id() + << ". [Ctrl+C to quit]\n" + << std::endl; + cycles_old = rte_get_tsc_cycles(); + while (likely(_quit == false)) { + // Timer -> update_statistics_monitor + if (timer_get_seconds() >= + 1) { // every second updating the stats monitor + timer_reset(); + update_statistics_monitor(); + } + for (struct rte_ring* ring : _s_queue) { + // get stats from each Thread and put them into _s_stats Stats* out; - rte_ring_dequeue(ring, (void**)&out); + if (rte_ring_dequeue(ring, (void**)&out) == + 0) { // taking existing stats from ring + *_s_stats += *out; // updating _s_stats - if (true) { // \TODO test if empty - update_statistics(out); + /*delete out; + out = nullptr;*/ } } } } -void StatisticsThread::enqueue_statistics(int& id, Stats* new_stats) { - // enqueue statistics - rte_ring* ring = _s_queue[id]; - rte_ring_enqueue(ring, new_stats); +void StatisticsThread::enqueue_statistics(const unsigned int& id, + Stats* new_stats) { + // enqueue statistics (checked and working) + rte_ring_enqueue(_s_queue[id], (void*)new_stats); } -Stats* StatisticsThread::_s_stats; +void StatisticsThread::update_statistics_monitor() { + // called once per second + _s_stats_monitor->attacks_per_second = _s_stats->attacks; + _s_stats_monitor->attacks_percent = + ((double)_s_stats->attacks / (double)_s_stats->packets) * 100; + _s_stats_monitor->bytes_per_second = _s_stats->bytes; + _s_stats_monitor->dropped_per_second = _s_stats->dropped; + _s_stats_monitor->attacks_percent = + ((double)_s_stats->dropped / (double)_s_stats->packets) * 100; + _s_stats_monitor->packets_per_second = _s_stats->packets; + //_s_stats_monitor->process_speed = ; + ++_s_stats_monitor->total_time; -void StatisticsThread::update_statistics(Stats* new_stats) { - //_s_stats += new_stats; + // delete old _s_stats + _s_stats->reset_stats(); +} + +void StatisticsThread::print_stats_monitor(){ + + std::cout << "Total runtime = " << _s_stats_monitor->total_time << "s" << std::endl; + std::cout << "Bytes per second = " << _s_stats_monitor->bytes_per_second << std::endl; + std::cout << "Packets per second = " << _s_stats_monitor->packets_per_second << std::endl; + std::cout << "Attacks per Second = " << _s_stats_monitor->attacks_per_second << std::endl; + std::cout << "Attacks in percent = " << _s_stats_monitor->attacks_percent << "%" << std::endl; + std::cout << "Dropped packets per second = " << _s_stats_monitor->dropped_per_second << std::endl; + std::cout << "Dropped packets in percent = " << _s_stats_monitor->dropped_percent << "%" << std::endl; + std::cout << "Prozess speed = " << _s_stats_monitor->process_speed << std::endl; +} + +uint64_t StatisticsThread::timer_get_seconds() { + + cycles = rte_get_tsc_cycles(); + hz = rte_get_tsc_hz(); + + // calculate + seconds = (cycles - cycles_old) / hz; + + return seconds; +} + +void StatisticsThread::timer_reset() { + seconds = 0; + cycles_old = cycles; } //------------------------------------------------------------------------- -//-------------------------- Stats ---------------------------------------- +//------------------------------- Stats ----------------------------------- //------------------------------------------------------------------------- -Stats* Stats::operator+=(const Stats* new_stats) { - this->attacks += new_stats->attacks; - this->bytes += new_stats->bytes; - this->dropped += new_stats->dropped; - this->packets += new_stats->packets; - this->work_time += new_stats->work_time; - this->syn_level += new_stats->syn_level; - - return this; +Stats& Stats::operator+=(const Stats& new_stats) { + attacks += new_stats.attacks; + bytes += new_stats.bytes; + dropped += new_stats.dropped; + packets += new_stats.packets; + work_time += new_stats.work_time; } +void Stats::reset_stats() { + attacks = 0; + bytes = 0; + dropped = 0; + packets = 0; + work_time = 0; +} \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index 1757645..1031c5c 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,12 +1,13 @@ #include -#include "ConfigurationManagement/Configurator.hpp" +#include "Configurator.hpp" #include "Initializer.hpp" #include "PacketDissection/PacketContainer.hpp" #include "Threads/DefenseThread.hpp" +#include "Threads/StatisticsThread.hpp" +int main(int argc, char** argv); void handle_quit(int signum); -void terminate(DefenseThread** thread_arr, uint16_t nb_worker_threads); bool quit = false; @@ -20,39 +21,34 @@ int main(int argc, char** argv) { Initializer* init = new Initializer(); unsigned int lcore_id; - uint16_t inside_port = 1; - uint16_t outside_port = 0; + uint16_t inside_port = 0; + uint16_t outside_port = 1; uint16_t nb_worker_threads = 0; struct rte_mempool* mbuf_pool = init->init_dpdk(argc, argv, nb_worker_threads); // create thread objects - DefenseThread* thread_arr[nb_worker_threads]; - MbufContainerReceiving* pkt_containers_from_outside[nb_worker_threads]; - MbufContainerReceiving* pkt_containers_from_inside[nb_worker_threads]; - MbufContainerTransmitting* pkt_containers_to_inside[nb_worker_threads]; - MbufContainerTransmitting* pkt_containers_to_outside[nb_worker_threads]; + StatisticsThread* stat_thread = new StatisticsThread(); + DefenseThread* thread_arr[nb_worker_threads]; + PacketContainer* pkt_containers_to_outside[nb_worker_threads]; + PacketContainer* pkt_containers_to_inside[nb_worker_threads]; for (int i = 0; i < nb_worker_threads; i++) { - pkt_containers_from_outside[i] = - new MbufContainerReceiving(mbuf_pool, outside_port, i); - pkt_containers_from_inside[i] = - new MbufContainerReceiving(mbuf_pool, inside_port, i); - pkt_containers_to_inside[i] = - new MbufContainerTransmitting(mbuf_pool, inside_port, i); pkt_containers_to_outside[i] = - new MbufContainerTransmitting(mbuf_pool, outside_port, i); + new PacketContainer(mbuf_pool, inside_port, outside_port, i, i); + pkt_containers_to_inside[i] = + new PacketContainer(mbuf_pool, outside_port, inside_port, i, i); - thread_arr[i] = new DefenseThread( - pkt_containers_from_inside[i], pkt_containers_from_outside[i], - pkt_containers_to_inside[i], pkt_containers_to_outside[i]); + thread_arr[i] = new DefenseThread(pkt_containers_to_outside[i], + pkt_containers_to_inside[i], stat_thread); } - // start each thread on an own lcore - lcore_id = rte_lcore_id(); + // start DefenseThreads + // ..start each thread on an own lcore + lcore_id = rte_lcore_id(); for (int i = 0; i < nb_worker_threads; ++i) { lcore_id = rte_get_next_lcore(lcore_id, true, true); @@ -61,100 +57,41 @@ int main(int argc, char** argv) { lcore_id); } - /* - uint64_t hz = rte_get_tsc_hz(); - u_int64_t cycles = rte_get_tsc_cycles(); - u_int64_t old_cycles = cycles; - while (likely(quit == false)) { - cycles = rte_get_tsc_cycles(); - if (cycles - old_cycles > 64 * hz) { - Treatment::s_increment_timestamp(); - old_cycles = cycles; - } - } - */ - - // =================== START CLI ==================== // - - std::string input = ""; - const std::string NAME = "aegis"; - - enum State { RUNNING, IDLE }; - State state = IDLE; - - while (input != "exit") { - - std::cout << std::endl; - std::cout << NAME << "> " << std::flush; - std::cin >> input; - std::cout << std::endl; - - if (input == "start") { - if (state == IDLE) { - - for (int i = 0; i < nb_worker_threads; ++i) { - thread_arr[i]->start_treat(); - } - - state = RUNNING; - - } else { // state == RUNNING - std::cout << "Cannot start if program is already running." - << std::endl; - } - - } else if (input == "stop") { - if (state == IDLE) { - std::cout << "Cannot stop if program is not running." - << std::endl; - - } else { // state == RUNNING - - for (int i = 0; i < nb_worker_threads; ++i) { - thread_arr[i]->stop_treat(); - } - - state = IDLE; - } - - } else if (input == "exit") { - - // do nothing; while loop stops - - } else if (input == "help" || input == "h") { - std::cout << "start\tstart " << NAME << std::endl - << "stop\tstop " << NAME << std::endl - << "help, h\tprint commands " << std::endl - << "exit\texit " << NAME << std::endl - << std::endl; - } else { - std::cout << "Command unknown. Try 'h' or 'help'." << std::endl; + uint64_t hz = rte_get_tsc_hz(); + u_int64_t cycles = rte_get_tsc_cycles(); + u_int64_t old_cycles = cycles; + while (likely(quit == false)) { + cycles = rte_get_tsc_cycles(); + if (cycles - old_cycles > 64 * hz) { + Treatment::s_increment_timestamp(); + old_cycles = cycles; } } - // ==================== END CLI ==================== // - // ===== TERMINATE ===== // - terminate(thread_arr, nb_worker_threads); + std::cout << "\nterminating..." << std::endl; + + for (int i = 0; i < nb_worker_threads; ++i) { + thread_arr[i]->quit(); + } + + stat_thread->quit(); // destruct objects on heap for (int i = 0; i < nb_worker_threads; ++i) { delete thread_arr[i]; thread_arr[i] = nullptr; - delete pkt_containers_from_inside[i]; - pkt_containers_from_inside[i] = nullptr; - - delete pkt_containers_from_outside[i]; - pkt_containers_from_outside[i] = nullptr; - delete pkt_containers_to_inside[i]; pkt_containers_to_inside[i] = nullptr; - delete pkt_containers_to_inside[i]; - pkt_containers_to_inside[i] = nullptr; + delete pkt_containers_to_outside[i]; + pkt_containers_to_outside[i] = nullptr; } + delete stat_thread; + stat_thread = nullptr; + delete init; init = nullptr; @@ -166,22 +103,7 @@ int main(int argc, char** argv) { } void handle_quit(int signum) { - // do nothing - // quit = true; + // + quit = true; } -// - -void terminate(DefenseThread** thread_arr, uint16_t nb_worker_threads) { - std::cout << "\nterminating..." << std::endl; - - for (int i = 0; i < nb_worker_threads; ++i) { - thread_arr[i]->quit(); - } - - // wait for threads to end - for (int i = 0; i < nb_worker_threads - 1; ++i) { - while (thread_arr[i]->is_running()) { - // wait - } - } -} \ No newline at end of file +// \ No newline at end of file diff --git a/source/meson.build b/source/meson.build index 984a0b5..72f2579 100644 --- a/source/meson.build +++ b/source/meson.build @@ -1,11 +1,14 @@ +# Please keep all alphabetically sorted sources = [ 'source/main.cpp', 'source/Initializer.cpp', 'source/DebugHelper.cpp', - 'source/ConfigurationManagement/Configurator.cpp', + 'source/Configurator.cpp', 'source/Threads/DefenseThread.cpp', - 'source/Cli.cpp', - #'source/Threads/StatisticsThread.cpp', + 'source/Threads/StatisticsThread.cpp', + 'source/DebugHelper.cpp', + 'source/Initializer.cpp', + 'source/main.cpp', ] # Attacker