update 0.0.2

This commit is contained in:
2021-10-24 12:51:25 +02:00
parent d80e285bb4
commit c2c321eb9b
30 changed files with 1689 additions and 1333 deletions

View File

@@ -1,3 +1,14 @@
/**
* @file Configurator.hpp
* @author Johannes
* @brief
* @version 0.1
* @date 2021-06-16
*
* @copyright Copyright (c) 2021
*
*/
#pragma once
#include <boost/log/trivial.hpp>
@@ -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 <typename T> 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 <typename T>
T get_value_from_config(const std::string& att_name, bool default_value);
};

View File

@@ -1,3 +1,14 @@
/**
* @file DebugHelper.hpp
* @author Tobias
* @brief
* @version 0.1
* @date 2021-07-12
*
* @copyright Copyright (c) 2021
*
*/
#pragma once
#include <iostream>

24
include/Definitions.h Normal file
View File

@@ -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

View File

@@ -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
//#define SINGLE_ITERATION
//#define LOG_PKTS_SENT
//#define SEND_ONCE
//#define SEND_PKTS_EVERY_NTH_ITERATION 1000

View File

@@ -1,4 +1,13 @@
#pragma once
/**
* @file Initializer.hpp
* @author Robert
* @brief
* @version 0.1
* @date 2021-07-12
*
* @copyright Copyright (c) 2021
*
*/
#include <rte_ethdev.h>
#include <rte_mempool.h>
@@ -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);

314
include/Inspection.hpp Normal file
View File

@@ -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 <rte_cycles.h>
#include <stdint.h>
/**
* @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<PacketInfoIpv4Tcp*>(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;
};

View File

@@ -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 <rte_ethdev.h>
@@ -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;
}

View File

@@ -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;

View File

@@ -4,12 +4,11 @@
* @brief
* @date 2021-06-16
*/
#pragma once
#include <rte_ether.h>
#include <boost/log/trivial.hpp>
#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;
}
}
};
};

View File

@@ -13,8 +13,8 @@
#include <rte_ip.h>
#include <rte_mbuf.h>
#include "Definitions.hpp"
#include "PacketDissection/PacketInfo.hpp"
#include "Definitions.hpp"
#define IP_HDR_LEN 20
#define VERSION_AND_IP_HDR_LEN 0b01000101

View File

@@ -13,37 +13,26 @@
#include <rte_byteorder.h>
#include <rte_tcp.h>
#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;
};

View File

@@ -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
*

View File

@@ -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

View File

@@ -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 <cstdlib>

View File

@@ -1,14 +1,24 @@
/**
* @file AttackThread.hpp
* @author Jakob
* @brief
* @version 0.1
* @date 2021-07-12
*
* @copyright Copyright (c) 2021
*
*/
#pragma once
#include <rte_ether.h>
#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() {

View File

@@ -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
*

View File

@@ -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

View File

@@ -1,11 +1,28 @@
/**
* @file StatisticsThread.hpp
* @author Jakob
* @brief
* @version 0.1
* @date 2021-07-12
*
* @copyright Copyright (c) 2021
*
*/
#pragma once
#include <rte_ring_core.h>
#include <rte_ring_elem.h>
#include <cstdint>
#include <cstdio>
#include <iostream>
#include <ostream>
#include <rte_errno.h>
#include <rte_lcore.h>
#include <rte_ring.h>
//#include <rte_ring_core.h>
//#include <rte_ring_elem.h>
#include <string>
#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;
};

View File

@@ -1,3 +1,14 @@
/**
* @file Thread.hpp
* @author Jakob
* @brief
* @version 0.1
* @date 2021-07-12
*
* @copyright Copyright (c) 2021
*
*/
#pragma once
#include <stdint.h>

File diff suppressed because it is too large Load Diff

44
include/Treatment/rand.h Normal file
View File

@@ -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;
}
};