diff --git a/test/Attacker_config.json b/test/Attacker_config.json new file mode 100644 index 0000000..bf22b5d --- /dev/null +++ b/test/Attacker_config.json @@ -0,0 +1,5 @@ +{ + "number_of_attack_packets_per_thread_per_iteration": "20", + "attack_type": "udp_flood", + "attack_rate": "5" +} \ No newline at end of file diff --git a/test/Attacker_test.cpp b/test/Attacker_test.cpp new file mode 100644 index 0000000..c34923b --- /dev/null +++ b/test/Attacker_test.cpp @@ -0,0 +1,37 @@ +#include +#include + +#include + +TEST_CASE("tsc timer", "[]") { + // count and print seconds since test started + // stop at 30 seconds + // const std::string clear(100, '\n'); + const uint64_t MAX_SECONDS = 30; + uint64_t cycles_old = 0; + uint64_t cycles = 0; + uint64_t hz = rte_get_tsc_hz(); + uint64_t seconds = 0; + uint64_t delta_t = 0; + + // print initial message + std::cout << "cycles : " << cycles << "\t" + << "hz : " << hz << "\t" + << "seconds : " << seconds << "\t" << std::endl; + + while (seconds < MAX_SECONDS) { + cycles_old = cycles; + cycles = rte_get_tsc_cycles(); + hz = rte_get_tsc_hz(); + + // calculate + delta_t = uint64_t(1 / hz * (cycles - cycles_old)); + seconds += delta_t; + + // print + // std::cout << clear; + std::cout << "cycles : " << cycles << "\t" + << "hz : " << hz << "\t" + << "seconds : " << seconds << "\t" << std::endl; + } +} \ No newline at end of file diff --git a/test/Configurator_config.json b/test/Configurator_config.json new file mode 100644 index 0000000..f6f15b3 --- /dev/null +++ b/test/Configurator_config.json @@ -0,0 +1,7 @@ +{ + "STRING" : "Hello World.", + "BOOLEAN" : true, + "UNSIGNED_INT" : 42, + "FLOAT" : 1.337, + "DOUBLE" : -3.001 +} diff --git a/test/Configurator_default_config.json b/test/Configurator_default_config.json new file mode 100644 index 0000000..61f0a61 --- /dev/null +++ b/test/Configurator_default_config.json @@ -0,0 +1,4 @@ +{ + "UNSIGNED_INT": 666, + "X": "80085" +} \ No newline at end of file diff --git a/test/Configurator_test.cpp b/test/Configurator_test.cpp new file mode 100644 index 0000000..d3ff33a --- /dev/null +++ b/test/Configurator_test.cpp @@ -0,0 +1,52 @@ +#include "ConfigurationManagement/Configurator.hpp" +#include +#include +#include +#include + +TEST_CASE("Json Datei einlesen", "[]") { + + REQUIRE_NOTHROW(Configurator::instance()->read_config( + "../test/Configurator_config.json")); + + REQUIRE(Configurator::instance()->get_config_as_bool("BOOLEAN") == true); + REQUIRE(Configurator::instance()->get_config_as_unsigned_int( + "UNSIGNED_INT") == 42); + REQUIRE(Configurator::instance()->get_config_as_string("STRING") == + "Hello World."); + REQUIRE(Configurator::instance()->get_config_as_float("FLOAT") == 1.337f); + REQUIRE(Configurator::instance()->get_config_as_double("DOUBLE") == -3.001); +} + +TEST_CASE("nicht existierende Json-Datei", "[]") { + REQUIRE_THROWS(Configurator::instance()->read_config("non-existent.json")); + REQUIRE_THROWS(Configurator::instance()->read_config("non-existent.json", + "typo.json")); +} + +TEST_CASE("Boost-Beispiel") { + LOG_INFO << "Dies ist eine Info Message" << LOG_END; + LOG_WARNING << "Dies ist eine Warn-Nachricht" << LOG_END; +} + +TEST_CASE("Entry does (not) exist") { + REQUIRE_NOTHROW(Configurator::instance()->read_config( + "../test/Configurator_config.json", + "../test/Configurator_default_config.json")); + + REQUIRE(Configurator::instance()->entry_exists("fhk4bhf1mx0f") == false); + REQUIRE(Configurator::instance()->entry_exists("STRING") == true); + REQUIRE(Configurator::instance()->entry_exists("X") == true); +} + +TEST_CASE("Default Config") { + REQUIRE_NOTHROW(Configurator::instance()->read_config( + "../test/Configurator_config.json", + "../test/Configurator_default_config.json")); + + REQUIRE(Configurator::instance()->get_config_as_unsigned_int( + "UNSIGNED_INT") == 42); + REQUIRE(Configurator::instance()->get_config_as_unsigned_int("UNSIGNED_INT", + true) == 666); + REQUIRE(Configurator::instance()->get_config_as_string("X") == "80085"); +} \ No newline at end of file diff --git a/test/Initializer_config.json b/test/Initializer_config.json new file mode 100644 index 0000000..fbe5d81 --- /dev/null +++ b/test/Initializer_config.json @@ -0,0 +1,9 @@ +{ + "STRING" : "Hello World.", + "BOOLEAN" : true, + "UNSIGNED_INT" : 666, + "FLOAT" : 1.337, + "DOUBLE" : -3.001, + "X" : "80085", + "Y" : "Hi" +} diff --git a/test/Initializer_test.cpp b/test/Initializer_test.cpp index 458ace8..80f5de2 100644 --- a/test/Initializer_test.cpp +++ b/test/Initializer_test.cpp @@ -6,7 +6,7 @@ TEST_CASE("Calculate number of threads", "[]") { /* - Configurator::instance()->read_config("../test/config.json"); + Configurator::instance()->read_config("../test/Initializer_config.json"); uint16_t nb_worker_threads = 0; // calculate default value of worker threads diff --git a/test/Inspection_config.json b/test/Inspection_config.json new file mode 100644 index 0000000..bd6ec11 --- /dev/null +++ b/test/Inspection_config.json @@ -0,0 +1,11 @@ +{ + "UDP_flood_weight" : 1, + "TCP_flood_weight": 1, + "ICMP_flood_weight": 1, + "SYNFIN_weight": 1, + "SMALLWINDOW_weight": 1, + "threshold_UDP": 5, + "threshold_TCP": 5, + "threshold_ICMP": 5, + "min_window_size": 5 +} \ No newline at end of file diff --git a/test/Inspection_test.cpp b/test/Inspection_test.cpp new file mode 100644 index 0000000..3c57810 --- /dev/null +++ b/test/Inspection_test.cpp @@ -0,0 +1,231 @@ +#include "Inspection.hpp" + +#include "ConfigurationManagement/Configurator.hpp" +#include "PacketDissection/PacketContainer.hpp" +#include "PacketDissection/PacketInfo.hpp" +#include "PacketDissection/PacketInfoCreator.hpp" +#include "PacketDissection/PacketInfoIpv4Icmp.hpp" +#include "PacketDissection/PacketInfoIpv4Tcp.hpp" +#include "PacketDissection/PacketInfoIpv4Udp.hpp" +#include "Threads/AttackThread.h" + +#include +#include + +TEST_CASE("init Inspection", "[]") { + Inspection testInspection; + REQUIRE_NOTHROW(testInspection.update_stats(0, 0, 0, 0, 0, 0, 0, 0, 0)); +} + +// Für folgende wird eine funktionierende Packet Dissection benötigt +TEST_CASE("check attack detection", "[]") { + // setup config + Configurator::instance()->read_config("../test/Inspection_config.json"); + // create packet container + uint16_t inside_port = 0; + uint16_t outside_port = 1; + struct rte_mempool mbuf_pool_struct; + struct rte_mempool* mbuf_pool = &mbuf_pool_struct; + CHECK(mbuf_pool != nullptr); + + NetworkPacketHandler* pkt_handler = new NetworkPacketHandler(0, 0); + CHECK(pkt_handler != nullptr); + + PacketContainer* pkt_container = + new PacketContainer(pkt_handler, mbuf_pool, inside_port, outside_port); + CHECK(pkt_container != nullptr); + // inspection class + Inspection testInspection; + + /// test SYN-FIN attack + SECTION("SYN-FIN Attack", "[]") { + PacketInfo* pkt_info = nullptr; + for (int i = 0; i < 5; ++i) { + pkt_info = pkt_container->get_empty_packet(IPv4TCP); + PacketInfoIpv4Tcp* pkt_info = + static_cast(pkt_info); + // create packet with SYN-FIN Flag into packet container + pkt_info->fill_payloadless_tcp_packet( + {00, 00, 00, 00, 00, 00}, {00, 00, 00, 00, 00, 00}, 0, 0, 0, 0, + 0, 0, 0b00000011, 100); + } + // packet container to inspection + testInspection.analyze_container(pkt_container); + // Check if packetcontainer empty + CHECK(pkt_container->get_total_number_of_packets() == 0); + } + + /// test SYN-FIN-ACK attack + SECTION("SYN-FIN-ACK Attack", "[]") { + PacketInfo* pkt_info = nullptr; + for (int i = 0; i < 5; ++i) { + pkt_info = pkt_container->get_empty_packet(IPv4TCP); + PacketInfoIpv4Tcp* pkt_info = + static_cast(pkt_info); + // create packet with SYN-FIN-ACK Flag into packet container + pkt_info->fill_payloadless_tcp_packet( + {00, 00, 00, 00, 00, 00}, {00, 00, 00, 00, 00, 00}, 0, 0, 0, 0, + 0, 0, 0b00010011, 100); + } + // packet container to inspection + testInspection.analyze_container(pkt_container); + // Check if packetcontainer empty + CHECK(pkt_container->get_total_number_of_packets() == 0); + } + + /// test Zero Window attack + SECTION("Zero Window Attack", "[]") { + PacketInfo* pkt_info = nullptr; + for (int i = 0; i < 5; ++i) { + pkt_info = pkt_container->get_empty_packet(IPv4TCP); + PacketInfoIpv4Tcp* pkt_info = + static_cast(pkt_info); + // create packet with 0 window into packet container + pkt_info->fill_payloadless_tcp_packet({00, 00, 00, 00, 00, 00}, + {00, 00, 00, 00, 00, 00}, 0, + 0, 0, 0, 0, 0, 0, 0); + } + // packet container to inspection + testInspection.analyze_container(pkt_container); + // Check if packetcontainer empty + CHECK(pkt_container->get_total_number_of_packets() == 0); + } + + /// test Small Window attack + SECTION("Small Window Attack", "[]") { + PacketInfo* pkt_info = nullptr; + for (int i = 0; i < 5; ++i) { + pkt_info = pkt_container->get_empty_packet(IPv4TCP); + PacketInfoIpv4Tcp* pkt_info = + static_cast(pkt_info); + // create packet with small Windows into packet container + pkt_info->fill_payloadless_tcp_packet({00, 00, 00, 00, 00, 00}, + {00, 00, 00, 00, 00, 00}, 0, + 0, 0, 0, 0, 0, 0, i); + } + // packet container to inspection + testInspection.analyze_container(pkt_container); + // Check if packetcontainer empty + CHECK(pkt_container->get_total_number_of_packets() == 0); + } + + /// test UDP Flood attack + SECTION("UDP Flood Attack", "[]") { + PacketInfo* pkt_info = nullptr; + // create udp packets into packet container + for (int i = 0; i < 25; ++i) { + pkt_info = pkt_container->get_empty_packet(IPv4UDP); + PacketInfoIpv4Udp* pkt_info = + static_cast(pkt_info); + } + // packet container to inspection + testInspection.analyze_container(pkt_container); + // Check if packetcontainer only has threshold packets left + CHECK(pkt_container->get_total_number_of_packets() == 5); + } + + /// test TCP Flood attack + SECTION("TCP Flood Attack", "[]") { + PacketInfo* pkt_info = nullptr; + // create tcp packets into packet container + for (int i = 0; i < 25; ++i) { + pkt_info = pkt_container->get_empty_packet(IPv4TCP); + PacketInfoIpv4Tcp* pkt_info = + static_cast(pkt_info); + pkt_info->fill_payloadless_tcp_packet({00, 00, 00, 00, 00, 00}, + {00, 00, 00, 00, 00, 00}, 0, + 0, 0, 0, i, 0, 0, 100); + } + // packet container to inspection + testInspection.analyze_container(pkt_container); + // Check if packetcontainer only has threshold packets left + CHECK(pkt_container->get_total_number_of_packets() == 5); + } + + /// \todo test ICMP Flood attack + SECTION("ICMP Flood Attack", "[]") { + PacketInfo* pkt_info = nullptr; + // create icmp packets into packet container + for (int i = 0; i < 25; ++i) { + pkt_info = pkt_container->get_empty_packet(IPv4ICMP); + PacketInfoIpv4Icmp* pkt_info = + static_cast(pkt_info); + } + // packet container to inspection + testInspection.analyze_container(pkt_container); + // Check if packetcontainer only has threshold packets left + CHECK(pkt_container->get_total_number_of_packets() == 5); + } +} + +TEST_CASE("check update function", "[]") { + Inspection testInspection; + + SECTION("Null", "[]") { + // update statistic with given numbers + REQUIRE_NOTHROW(testInspection.update_stats(0, 0, 0, 0, 0, 0, 0, 0, 0)); + // check correct formulas + CHECK(testInspection.get_UDP_packet_rate() == 0); //< udp_pkt/duration + CHECK(testInspection.get_TCP_packet_rate() == 0); //< tcp_pkt/duration + CHECK(testInspection.get_ICMP_packet_rate() == 0); //< icmp_pkt/duration + CHECK(testInspection.get_attack_level() == 0); //< no attacks + CHECK(testInspection.get_UDP_threshold() == 5); //< _threshold_UDP + CHECK(testInspection.get_TCP_threshold() == 5); //< _threshold_TCP + CHECK(testInspection.get_ICMP_threshold() == 5); //< _threshold_ICMP + } + + SECTION("UDP rate", "[]") { + REQUIRE_NOTHROW( + testInspection.update_stats(10, 0, 0, 0, 0, 0, 0, 0, 1)); + CHECK(testInspection.get_UDP_packet_rate() == 10); + } + SECTION("TCP rate", "[]") { + REQUIRE_NOTHROW( + testInspection.update_stats(0, 10, 0, 0, 0, 0, 0, 0, 1)); + CHECK(testInspection.get_TCP_packet_rate() == 10); + } + SECTION("ICMP rate", "[]") { + REQUIRE_NOTHROW( + testInspection.update_stats(0, 0, 0, 10, 0, 0, 0, 0, 1)); + CHECK(testInspection.get_ICMP_packet_rate() == 10); + } + SECTION("UDP Flood", "[]") { + REQUIRE_NOTHROW( + testInspection.update_stats(10, 0, 0, 5, 0, 0, 0, 0, 1)); + CHECK(testInspection.get_UDP_packet_rate() == 10); + CHECK(testInspection.get_attack_level() == + 5); //< UDP_Floods * _UDP_flood_weight + CHECK(testInspection.get_UDP_threshold() == 0); //< 5-1/5*5*5 + } + SECTION("TCP Flood", "[]") { + REQUIRE_NOTHROW( + testInspection.update_stats(0, 10, 0, 0, 5, 0, 0, 0, 1)); + CHECK(testInspection.get_TCP_packet_rate() == 10); + CHECK(testInspection.get_attack_level() == 5); + CHECK(testInspection.get_TCP_threshold() == 0); + } + SECTION("ICMP Flood", "[]") { + REQUIRE_NOTHROW( + testInspection.update_stats(0, 0, 10, 0, 0, 5, 0, 0, 1)); + CHECK(testInspection.get_ICMP_packet_rate() == 10); + CHECK(testInspection.get_attack_level() == 5); + CHECK(testInspection.get_ICMP_threshold() == 0); + } + SECTION("SYN-FIN Attack", "[]") { + REQUIRE_NOTHROW( + testInspection.update_stats(0, 10, 0, 0, 0, 0, 5, 0, 1)); + CHECK(testInspection.get_TCP_packet_rate() == 10); + CHECK(testInspection.get_attack_level() == 5); + CHECK(testInspection.get_TCP_threshold() == 0); + } + SECTION("SmallWindow Attack", "[]") { + REQUIRE_NOTHROW( + testInspection.update_stats(0, 10, 0, 0, 0, 0, 0, 5, 1)); + CHECK(testInspection.get_TCP_packet_rate() == 10); + CHECK(testInspection.get_attack_level() == 5); + CHECK(testInspection.get_TCP_threshold() == 0); + } + SECTION("send to global Statisic", "[]") { + // sending to global statistic not implemented yet in main + } +} \ No newline at end of file diff --git a/test/PacketContainer_test.cpp b/test/PacketContainer_test.cpp new file mode 100644 index 0000000..b26eb78 --- /dev/null +++ b/test/PacketContainer_test.cpp @@ -0,0 +1,292 @@ +#include + +#include +#include + +#include "Definitions.hpp" +#include "PacketDissection/PacketContainer.hpp" +#include "PacketDissection/PacketInfo.hpp" +#include "PacketDissection/PacketInfoCreator.hpp" +#include "PacketDissection/PacketInfoIpv4Icmp.hpp" +#include "PacketDissection/PacketInfoIpv4Tcp.hpp" +#include "PacketDissection/PacketInfoIpv4Udp.hpp" +#include "PacketDissection/PacketInfoIpv6Icmp.hpp" +#include "PacketDissection/PacketInfoIpv6Tcp.hpp" +#include "PacketDissection/PacketInfoIpv6Udp.hpp" + +TEST_CASE("PacketContainer", "[]") { + // === I N I T === // + uint16_t inside_port = 0; + uint16_t outside_port = 1; + struct rte_mempool mbuf_pool_struct; + struct rte_mempool* mbuf_pool = &mbuf_pool_struct; + CHECK(mbuf_pool != nullptr); + + PacketContainer* pkt_container = + new PacketContainer(mbuf_pool, inside_port, outside_port, 0, 0); + CHECK(pkt_container != nullptr); + + // === S E C T I O N S == // + SECTION("get_empty_packet", "[]") { + + SECTION("default", "[]") { + CHECK(pkt_container->get_number_of_polled_packets() == 0); + CHECK(pkt_container->get_total_number_of_packets() == 0); + + PacketInfo* pkt_info = pkt_container->get_empty_packet(); + CHECK(pkt_info != nullptr); + CHECK(pkt_info->get_mbuf() != nullptr); + CHECK(pkt_info->get_type() == IPv4TCP); + + CHECK(pkt_container->get_total_number_of_packets() >= + pkt_container->get_number_of_polled_packets()); + CHECK(pkt_container->get_total_number_of_packets() == 1); + CHECK(pkt_container->get_number_of_polled_packets() == 0); + } + + SECTION("IPv4TCP", "[]") { + CHECK(pkt_container->get_number_of_polled_packets() == 0); + CHECK(pkt_container->get_total_number_of_packets() == 0); + + PacketInfo* pkt_info = pkt_container->get_empty_packet(IPv4TCP); + CHECK(pkt_info != nullptr); + CHECK(pkt_info->get_mbuf() != nullptr); + CHECK(pkt_info->get_type() == IPv4TCP); + + CHECK(pkt_container->get_total_number_of_packets() >= + pkt_container->get_number_of_polled_packets()); + CHECK(pkt_container->get_total_number_of_packets() == 1); + CHECK(pkt_container->get_number_of_polled_packets() == 0); + } + } + + SECTION("create more packets than burst size", "[]") { + + SECTION("fill till BURST_SIZE", "[]") { + for (int i = 0; i < BURST_SIZE; ++i) { + PacketInfo* pkt_info = pkt_container->get_empty_packet(); + CHECK(pkt_info != nullptr); + } + + CHECK(pkt_container->get_total_number_of_packets() == BURST_SIZE); + } + + SECTION("fill till BURST_SIZE + 1", "[]") { + for (int i = 0; i < BURST_SIZE + 1; ++i) { + PacketInfo* pkt_info = pkt_container->get_empty_packet(); + CHECK(pkt_info != nullptr); + } + + CHECK(pkt_container->get_total_number_of_packets() == + BURST_SIZE + 1); + } + + CHECK(pkt_container->get_total_number_of_packets() >= + pkt_container->get_number_of_polled_packets()); + } + + SECTION("get_packet_at_index", "[]") { + + SECTION("general", "[]") { + // add empty packet + PacketInfo* pkt_info_0 = pkt_container->get_empty_packet(); + CHECK(pkt_container->get_number_of_polled_packets() == 0); + CHECK(pkt_container->get_total_number_of_packets() == 1); + + PacketInfo* pkt_info_1 = pkt_container->get_packet_at_index( + pkt_container->get_total_number_of_packets() - 1); + CHECK(pkt_info_0 == pkt_info_1); + CHECK(pkt_info_1 != nullptr); + CHECK(pkt_info_1->get_mbuf() != nullptr); + CHECK(pkt_info_1->get_type() == IPv4TCP); + + CHECK(pkt_container->get_total_number_of_packets() >= + pkt_container->get_number_of_polled_packets()); + CHECK_NOTHROW(pkt_container->get_packet_at_index( + pkt_container->get_total_number_of_packets() - 1)); + CHECK_THROWS(pkt_container->get_packet_at_index( + pkt_container->get_total_number_of_packets())); + } + + SECTION("test out of bounds error", "[]") { + for (int i = 0; i < int(BURST_SIZE / 2); ++i) { + pkt_container->get_empty_packet(); + } + + CHECK(pkt_container->get_total_number_of_packets() == + int(BURST_SIZE / 2)); + + for (int i = 0; i < int(BURST_SIZE / 2); ++i) { + CHECK_NOTHROW(pkt_container->get_packet_at_index(i)); + } + + for (int i = int(BURST_SIZE / 2); i < BURST_SIZE; ++i) { + CHECK_THROWS(pkt_container->get_packet_at_index(i)); + } + + CHECK_THROWS(pkt_container->get_packet_at_index( + pkt_container->get_total_number_of_packets())); + CHECK_NOTHROW(pkt_container->get_packet_at_index( + pkt_container->get_total_number_of_packets() - 1)); + } + } + + SECTION("take_packet and add_packet", "[]") { + + PacketInfo* pkt_info_0 = pkt_container->get_empty_packet(); + CHECK(pkt_container->get_number_of_polled_packets() == 0); + CHECK(pkt_container->get_total_number_of_packets() == 1); + + PacketInfo* pkt_info_1 = pkt_container->take_packet(0); + CHECK(pkt_info_0 == pkt_info_1); + CHECK(pkt_info_1 != nullptr); + CHECK(pkt_info_1->get_mbuf() != nullptr); + CHECK(pkt_container->get_packet_at_index(0) == nullptr); + CHECK(pkt_container->get_total_number_of_packets() == 1); + CHECK(pkt_container->get_total_number_of_packets() >= + pkt_container->get_number_of_polled_packets()); + + pkt_container->add_packet(pkt_info_1); + CHECK(pkt_container->get_total_number_of_packets() >= + pkt_container->get_number_of_polled_packets()); + CHECK(pkt_container->get_number_of_polled_packets() == 0); + CHECK(pkt_container->get_total_number_of_packets() == 2); + CHECK(pkt_container->get_packet_at_index(1) == pkt_info_1); + CHECK(pkt_container->get_packet_at_index(0) == nullptr); + } + + SECTION("drop_packet", "[]") { + + SECTION("default") { + PacketInfo* pkt_info_0 = pkt_container->get_empty_packet(); + CHECK(pkt_container->get_number_of_polled_packets() == 0); + CHECK(pkt_container->get_total_number_of_packets() == 1); + + pkt_container->drop_packet(0); + CHECK(pkt_container->get_total_number_of_packets() >= + pkt_container->get_number_of_polled_packets()); + CHECK(pkt_container->get_number_of_polled_packets() == 0); + CHECK(pkt_container->get_total_number_of_packets() == 1); + CHECK(pkt_container->get_packet_at_index(0) == nullptr); + + CHECK_NOTHROW(pkt_container->drop_packet(0)); + CHECK(pkt_container->get_number_of_polled_packets() == 0); + CHECK(pkt_container->get_total_number_of_packets() == 1); + CHECK(pkt_container->get_packet_at_index(0) == nullptr); + } + } + + SECTION("poll_packets", "[]") { + + CHECK(pkt_container->get_number_of_polled_packets() == 0); + CHECK(pkt_container->get_total_number_of_packets() == 0); + + uint16_t nb_pkts_polled; + pkt_container->poll_packets(nb_pkts_polled); + CHECK(pkt_container->get_number_of_polled_packets() > 0); + CHECK(pkt_container->get_total_number_of_packets() == + pkt_container->get_number_of_polled_packets()); + CHECK(nb_pkts_polled == pkt_container->get_number_of_polled_packets()); + + CHECK_NOTHROW(pkt_container->get_packet_at_index(nb_pkts_polled - 1)); + PacketInfo* pkt_info = + pkt_container->get_packet_at_index(nb_pkts_polled - 1); + CHECK(pkt_info != nullptr); + CHECK(pkt_info->get_mbuf() != nullptr); + } + + SECTION("send_packets", "[]") { + + SECTION("do not drop") { + SECTION("send created packets") { + PacketInfo* pkt_info = pkt_container->get_empty_packet(); + CHECK(pkt_container->get_number_of_polled_packets() == 0); + CHECK(pkt_container->get_total_number_of_packets() == 1); + } + + SECTION("send polled packets") { + uint16_t nb_polled_pkts; + pkt_container->poll_packets(nb_polled_pkts); + + CHECK(nb_polled_pkts > 0); + } + + SECTION("send polled and created packets") { + uint16_t nb_polled_pkts; + pkt_container->poll_packets(nb_polled_pkts); + CHECK(nb_polled_pkts > 0); + + PacketInfo* pkt_info = pkt_container->get_empty_packet(); + CHECK(pkt_container->get_total_number_of_packets() > + pkt_container->get_number_of_polled_packets()); + } + + pkt_container->send_packets(); + CHECK(pkt_container->get_number_of_polled_packets() == 0); + CHECK(pkt_container->get_total_number_of_packets() == 0); + } + + SECTION("drop and send created packets") { + + const int PKTS_TO_POLL = 4; + int nb_pkts_to_drop = -1; + + for (int i = 0; i < PKTS_TO_POLL; ++i) { + pkt_container->get_empty_packet(); + } + + CHECK(pkt_container->get_total_number_of_packets() > + pkt_container->get_number_of_polled_packets()); + CHECK(pkt_container->get_total_number_of_packets() == PKTS_TO_POLL); + + SECTION("drop first packet") { + nb_pkts_to_drop = 1; + CHECK(pkt_container->get_nb_mbufs_in_mbuf_arr()[0] == + PKTS_TO_POLL); + CHECK(pkt_container->get_nb_pkts_dropped() == 0); + pkt_container->drop_packet(0); + CHECK(pkt_container->get_nb_pkts_dropped() == 1); + } + + SECTION("drop second packet") { + nb_pkts_to_drop = 1; + CHECK(pkt_container->get_nb_mbufs_in_mbuf_arr()[0] == + PKTS_TO_POLL); + CHECK(pkt_container->get_nb_pkts_dropped() == 0); + pkt_container->drop_packet(1); + CHECK(pkt_container->get_nb_pkts_dropped() == 1); + } + + SECTION("drop second and third packet") { + nb_pkts_to_drop = 2; + CHECK(pkt_container->get_nb_mbufs_in_mbuf_arr()[0] == + PKTS_TO_POLL); + CHECK(pkt_container->get_nb_pkts_dropped() == 0); + pkt_container->drop_packet(1); + pkt_container->drop_packet(2); + CHECK(pkt_container->get_nb_pkts_dropped() == 2); + } + + SECTION("drop last packet") { + nb_pkts_to_drop = 1; + CHECK(pkt_container->get_nb_mbufs_in_mbuf_arr()[0] == + PKTS_TO_POLL); + CHECK(pkt_container->get_nb_pkts_dropped() == 0); + pkt_container->drop_packet(PKTS_TO_POLL - 1); + CHECK(pkt_container->get_nb_pkts_dropped() == 1); + } + + pkt_container->reorder_mbuf_arrays(); + CHECK(pkt_container->get_nb_mbufs_in_mbuf_arr()[0] == + PKTS_TO_POLL - nb_pkts_to_drop); + + pkt_container->send_packets(); + CHECK(pkt_container->get_number_of_polled_packets() == 0); + CHECK(pkt_container->get_total_number_of_packets() == 0); + } + } + + // ===  D E L E T E O B J E C T S === // + delete pkt_container; + pkt_container = nullptr; +} diff --git a/test/PacketInfo_test.cpp b/test/PacketInfo_test.cpp new file mode 100644 index 0000000..53c16cd --- /dev/null +++ b/test/PacketInfo_test.cpp @@ -0,0 +1,132 @@ +#include "ConfigurationManagement/Configurator.hpp" +#include "Initializer.hpp" +#include "PacketDissection/PacketInfo.hpp" +#include "PacketDissection/PacketInfoCreator.hpp" +#include "PacketDissection/PacketInfoIpv4Icmp.hpp" +#include "PacketDissection/PacketInfoIpv4Tcp.hpp" +#include "PacketDissection/PacketInfoIpv4Udp.hpp" +#include +#include + +TEST_CASE("Creation","[]") +{ + + SECTION("PacketInfo","[]"){ + PacketInfo pkt_inf; + rte_mbuf* mbuf; + //REQUIRE_NOTHROW(pkt_inf.set_mbuf(mbuf)); + //REQUIRE_NOTHROW(nbuf = pkt_inf.get_mbuf()); + //CHECK(mbuf == nbuf); + CHECK(pkt_inf.get_type() == NONE); + } + + SECTION("Creation: IPv4ICMP", "[]") { + // PacketInfoIpv4Icmp* pkt_inf = + // static_cast(PacketInfoCreator::create_pkt_info(IPv4ICMP)); + PacketInfoIpv4Icmp pkt_inf; + CHECK(pkt_inf.get_type() == IPv4ICMP); + // pkt_inf->set_mbuf(mbuf); + // struct rte_ipv4_hdr* ip_hdr = rte_pktmbuf_mtod_offset(mbuf, struct + // rte_ipv4_hdr*, 0); REQUIRE_NOTHROW(pkt_inf->set_ip_hdr(ip_hdr)); + // struct rte_icmp_hdr* l4_header = rte_pktmbuf_mtod_offset(mbuf, struct + // rte_icmp_hdr*, 20); + // REQUIRE_NOTHROW(pkt_inf->set_icmp_hdr(l4_header)); uint32_t num; + // CHECK_NOTHROW(num= pkt_inf->get_dst_ip()); + // CHECK_NOTHROW(num= pkt_inf->get_src_ip()); + // CHECK_NOTHROW(num= pkt_inf->get_packet_size()); + // CHECK_NOTHROW(num= pkt_inf->get_payload_size()); + } + + SECTION("Creation: IPv4TCP", "[]") { + // PacketInfoIpv4Tcp* pkt_inf = + // static_cast(PacketInfoCreator::create_pkt_info(IPv4TCP)); + PacketInfoIpv4Tcp pkt_inf; + CHECK(pkt_inf.get_type() == IPv4TCP); + // pkt_inf->set_mbuf(mbuf); + // struct rte_ipv4_hdr* ip_hdr = rte_pktmbuf_mtod_offset(mbuf, struct + // rte_ipv4_hdr*, 0); REQUIRE_NOTHROW(pkt_inf->set_ip_hdr(ip_hdr)); + // struct rte_tcp_hdr* l4_header = rte_pktmbuf_mtod_offset(mbuf, struct + // rte_tcp_hdr*, 20); REQUIRE_NOTHROW(pkt_inf->set_tcp_hdr(l4_header)); + // uint32_t num; + // uint32_t num2; + // CHECK_NOTHROW(num= pkt_inf->get_dst_ip()); + // CHECK_NOTHROW(num= pkt_inf->get_src_ip()); + // CHECK_NOTHROW(num= pkt_inf->get_packet_size()); + // CHECK_NOTHROW(num= pkt_inf->get_payload_size()); + // CHECK_NOTHROW(num= pkt_inf->get_dst_port()); + // CHECK_NOTHROW(num= pkt_inf->get_src_port()); + // CHECK_NOTHROW(num= pkt_inf->get_flags()); + // CHECK_NOTHROW(num= pkt_inf->get_window_size()); + // CHECK_NOTHROW(pkt_inf->set_ack_num(num)); + // CHECK_NOTHROW(num2= pkt_inf->get_ack_num()); + // CHECK(num == num2); + // CHECK_NOTHROW(pkt_inf->set_seq_num(num)); + // CHECK_NOTHROW(num = pkt_inf->get_seq_num()); + // CHECK(num == num2); + } + + SECTION("Creation: IPv4UDP", "[]") { + // PacketInfoIpv4Udp* pkt_inf = + // static_cast(PacketInfoCreator::create_pkt_info(IPv4UDP)); + PacketInfoIpv4Udp pkt_inf; + CHECK(pkt_inf.get_type() == IPv4UDP); + // pkt_inf->set_mbuf(mbuf); + // struct rte_ipv4_hdr* ip_hdr = rte_pktmbuf_mtod_offset(mbuf, struct + // rte_ipv4_hdr*, 0); REQUIRE_NOTHROW(pkt_inf->set_ip_hdr(ip_hdr)); + // struct rte_udp_hdr* l4_header = rte_pktmbuf_mtod_offset(mbuf, struct + // rte_udp_hdr*, 20); REQUIRE_NOTHROW(pkt_inf->set_udp_hdr(l4_header)); + // uint32_t num; + // CHECK_NOTHROW(num= pkt_inf->get_dst_ip()); + // CHECK_NOTHROW(num= pkt_inf->get_src_ip()); + // CHECK_NOTHROW(num= pkt_inf->get_packet_size()); + // CHECK_NOTHROW(num= pkt_inf->get_payload_size()); + // CHECK_NOTHROW(num= pkt_inf->get_dst_port()); + // CHECK_NOTHROW(num= pkt_inf->get_src_port()); + } +} + +TEST_CASE("Transformation", "[]") { + + SECTION("keeping Type", "[]") { + PacketInfo* pkt_inf; + // pkt_inf = PacketInfoCreator::create_pkt_info(IPv4ICMP); + pkt_inf = new PacketInfoIpv4Icmp; + PacketInfoIpv4Icmp* pkt_inf_icmp; + pkt_inf_icmp = static_cast(pkt_inf); + CHECK(pkt_inf_icmp->get_type() == IPv4ICMP); + + // PacketInfoCreator::create_pkt_info(IPv4TCP) + pkt_inf = new PacketInfoIpv4Tcp; + PacketInfoIpv4Tcp* pkt_inf_tcp; + pkt_inf_tcp = static_cast(pkt_inf); + CHECK(pkt_inf_tcp->get_type() == IPv4TCP); + + // PacketInfoCreator::create_pkt_info(IPv4UDP) + pkt_inf = new PacketInfoIpv4Udp; + PacketInfoIpv4Udp* pkt_inf_udp; + pkt_inf_udp = static_cast(pkt_inf); + CHECK(pkt_inf_udp->get_type() == IPv4UDP); + + // PacketInfoCreator::create_pkt_info(NONE) + pkt_inf = new PacketInfo; + CHECK(pkt_inf->get_type() == NONE); + + PacketInfo* pkt_inf_arr[5]; + pkt_inf_arr[0] = pkt_inf_icmp; + pkt_inf_arr[1] = pkt_inf_tcp; + pkt_inf_arr[2] = pkt_inf_udp; + pkt_inf_arr[3] = pkt_inf; + CHECK(pkt_inf_arr[0]->get_type() == IPv4ICMP); + CHECK(pkt_inf_arr[1]->get_type() == IPv4TCP); + CHECK(pkt_inf_arr[2]->get_type() == IPv4UDP); + CHECK(pkt_inf_arr[3]->get_type() == NONE); + + // clean up + delete pkt_inf; + delete pkt_inf_icmp; + delete pkt_inf_tcp; + delete pkt_inf_udp; + delete pkt_inf_arr; + } +} + diff --git a/test/RandomNumberGenerator_test.cpp b/test/RandomNumberGenerator_test.cpp new file mode 100644 index 0000000..a04b947 --- /dev/null +++ b/test/RandomNumberGenerator_test.cpp @@ -0,0 +1,456 @@ +#include "RandomNumberGenerator.hpp" +#include +#include +#include // is used for testing the time in the 3rd test case + +TEST_CASE("random_number_generator_basic", "[]") { + + // This test was written to check basic functions like whether different + // numbers are generated. + SECTION("check_whether_different_16", "[]") { + // creates a new RNG object + RandomNumberGenerator* xor_shift = new RandomNumberGenerator(); + + // creates two pseudo random 16 bit numbers + u_int16_t test_1 = xor_shift->gen_rdm_16_bit(); + u_int16_t test_2 = xor_shift->gen_rdm_16_bit(); + + // printes these numbers out + std::cout << "1st generated 16 bit int: " << test_1 << std::endl; + std::cout << "2nd generated 16 bit int: " << test_2 << std::endl; + + // checks whether these numbers are different + // test1 == test2 wouldn't means that the test isn't random. + // This section just exists to see whether the algorithm basically works + // and generates numbers. + CHECK(test_1 != test_2); + } + + // The same test like above but for the 32 bit algorithm: + SECTION("CheckWhetherDifferent32", "[]") { + RandomNumberGenerator xor_shift; + u_int32_t test_1 = xor_shift.gen_rdm_32_bit(); + u_int32_t test_2 = xor_shift.gen_rdm_32_bit(); + std::cout << "1st generated 32 bit int: " << test_1 << std::endl; + std::cout << "2nd generated 32 bit int: " << test_2 << std::endl; + CHECK(test_1 != test_2); + } + + // The same test like above but for the 64 bit algorithm: + SECTION("CheckWhetherDifferent64", "[]") { + RandomNumberGenerator xor_shift; + u_int64_t test_1 = xor_shift.gen_rdm_64_bit(); + u_int64_t test_2 = xor_shift.gen_rdm_64_bit(); + std::cout << "1st generated 64 bit int: " << test_1 << std::endl; + std::cout << "2nd generated 64 bit int: " << test_2 << std::endl; + CHECK(test_1 != test_2); + // empty line for better layout in testlog + std::cout << std::endl; + } + + // This test checks the type of the return value. + // This particular section is for 16 bit + SECTION("CheckSize16", "[]") { + // Creates a RNG and generates a number like above + RandomNumberGenerator xor_shift; + u_int16_t test_value = xor_shift.gen_rdm_16_bit(); + std::cout << "values that are generated for checking the size: " + << std::endl; + std::cout << "generated value: " << test_value << std::endl; + // checks wheter the size of the return value is 16 bit or 2 byte + CHECK(sizeof(test_value) == 2); + } + + // The same for 32 bit + SECTION("CheckSize32", "[]") { + RandomNumberGenerator xor_shift; + u_int32_t test_value = xor_shift.gen_rdm_32_bit(); + std::cout << "generated value (32 bit): " << test_value << std::endl; + // checks wheter the size of the return value is 32 bit or 4 byte + CHECK(sizeof(test_value) == 4); + } + + // The same for 64 bit + SECTION("CheckSize64", "[]") { + RandomNumberGenerator xor_shift; + u_int64_t test_value = xor_shift.gen_rdm_64_bit(); + std::cout << "generated value (64 bit): " << test_value << std::endl; + // checks wheter the size of the return value is 64 bit or 8 byte + CHECK(sizeof(test_value) == 8); + std::cout << std::endl; + } + + // Checks whether different numbers are generated when using different RNGs + SECTION( + "Check whether different when using different RNG objects for 16 bit", + "[]") { + // creating two objects + RandomNumberGenerator xor_shift_1; + RandomNumberGenerator xor_shift_2; + // generating two values of 16 bit + std::cout << "16 bit seed 1: " << xor_shift_1._seed_x16 << std::endl; + std::cout << "16 bit seed 2: " << xor_shift_2._seed_x16 << std::endl; + u_int16_t test_1_16_bit = xor_shift_1.gen_rdm_16_bit(); + u_int16_t test_2_16_bit = xor_shift_2.gen_rdm_16_bit(); + CHECK(test_1_16_bit != test_2_16_bit); + } + + // the same for 32 bit again: + SECTION( + "Check whether different when using different RNG objects for 32 bit", + "[]") { + RandomNumberGenerator xor_shift_1; + RandomNumberGenerator xor_shift_2; + std::cout << "32 bit seed 1: " << xor_shift_1._seed_x32 << std::endl; + std::cout << "32 bit seed 2: " << xor_shift_2._seed_x32 << std::endl; + u_int32_t test_1_32_bit = xor_shift_1.gen_rdm_32_bit(); + u_int32_t test_2_32_bit = xor_shift_2.gen_rdm_32_bit(); + CHECK(test_1_32_bit != test_2_32_bit); + } + + // the same for 64 bit again: + SECTION( + "Check whether different when using different RNG objects for 64 bit", + "[]") { + RandomNumberGenerator xor_shift_1; + RandomNumberGenerator xor_shift_2; + std::cout << "64 bit seed 1: " << xor_shift_1._seed_x64 << std::endl; + std::cout << "64 bit seed 2: " << xor_shift_2._seed_x64 << std::endl; + u_int64_t test_1_64_bit = xor_shift_1.gen_rdm_64_bit(); + u_int64_t test_2_64_bit = xor_shift_2.gen_rdm_64_bit(); + CHECK(test_1_64_bit != test_2_64_bit); + std::cout << std::endl; + } + + // This test checks whether two RNGs generate the same number after the seed + // is set to the same number + SECTION("Check whether the same numbers are generated with the same seed " + "for 16 bit", + "[]") { + RandomNumberGenerator xor_shift_1; + RandomNumberGenerator xor_shift_2; + // set the seed to the same value in both RNGs + xor_shift_1._seed_x16 = 30000; + xor_shift_2._seed_x16 = 30000; + std::cout << "16 bit seed for RNG 1: " << xor_shift_1._seed_x16 + << std::endl; + std::cout << "16 bit seed for RNG 2: " << xor_shift_2._seed_x16 + << std::endl; + u_int16_t test_1_16_bit = xor_shift_1.gen_rdm_16_bit(); + u_int16_t test_2_16_bit = xor_shift_2.gen_rdm_16_bit(); + std::cout << "number generated from RNG 1: " << xor_shift_1._seed_x16 + << std::endl; + std::cout << "number generated from RNG 2: " << xor_shift_2._seed_x16 + << std::endl; + // check whether the results are the same too + CHECK(test_1_16_bit == test_2_16_bit); + std::cout << std::endl; + } + + // the same test for 32 bit + SECTION("Check whether the same numbers are generated with the same seed " + "for 32 bit", + "[]") { + RandomNumberGenerator xor_shift_1; + RandomNumberGenerator xor_shift_2; + // set the seed to the same value in both RNGs + xor_shift_1._seed_x32 = 30000000; + xor_shift_2._seed_x32 = 30000000; + std::cout << "32 bit seed for RNG 1: " << xor_shift_1._seed_x32 + << std::endl; + std::cout << "32 bit seed for RNG 2: " << xor_shift_2._seed_x32 + << std::endl; + u_int32_t test_1_32_bit = xor_shift_1.gen_rdm_32_bit(); + u_int32_t test_2_32_bit = xor_shift_2.gen_rdm_32_bit(); + std::cout << "number generated from RNG 1: " << xor_shift_1._seed_x32 + << std::endl; + std::cout << "number generated from RNG 2: " << xor_shift_2._seed_x32 + << std::endl; + // check whether the results are the same too + CHECK(test_1_32_bit == test_2_32_bit); + std::cout << std::endl; + } + + // the same test for 64 bit + SECTION("Check whether the same numbers are generated with the same seed " + "for 64 bit", + "[]") { + RandomNumberGenerator xor_shift_1; + RandomNumberGenerator xor_shift_2; + // set the seed to the same value in both RNGs + xor_shift_1._seed_x64 = 30000000000; + xor_shift_2._seed_x64 = 30000000000; + std::cout << "64 bit seed for RNG 1: " << xor_shift_1._seed_x64 + << std::endl; + std::cout << "64 bit seed for RNG 2: " << xor_shift_2._seed_x64 + << std::endl; + u_int64_t test_1_64_bit = xor_shift_1.gen_rdm_64_bit(); + u_int64_t test_2_64_bit = xor_shift_2.gen_rdm_64_bit(); + std::cout << "number generated from RNG 1: " << xor_shift_1._seed_x64 + << std::endl; + std::cout << "number generated from RNG 2: " << xor_shift_2._seed_x64 + << std::endl; + // check whether the results are the same too + CHECK(test_1_64_bit == test_2_64_bit); + std::cout << std::endl; + } + + SECTION("Check whether generated numbers are really in the interval", + "[]") { + RandomNumberGenerator xor_shift; + u_int16_t test_value; + int lower_limit = 1024; + int upper_limit = 49151; + bool no_number_has_been_outside_the_interval = true; + // inside the for loop an if statement checks for 1,000,000 generated + // numbers whether they are really in the interval + for (int i = 0; i < 10000000; i++) { + test_value = + xor_shift.gen_rdm_16_bit_in_interval(lower_limit, upper_limit); + if (test_value < lower_limit || test_value > upper_limit) { + no_number_has_been_outside_the_interval = false; + } + } + std::cout << "No generated number has been outside the interval? (1 " + "means true) --> " + << no_number_has_been_outside_the_interval << std::endl; + std::cout << std::endl; + CHECK(no_number_has_been_outside_the_interval == true); + } +} + +TEST_CASE("RandomNumberGeneratorStatistics", "[]") { + + // The result of the chi square test shows how uniform the generated numbers + // are distributed + // A big chi square means that the actual frequencies vary widely from the + // theoretical frequencies. + SECTION("ChiSquare16", "[]") { + RandomNumberGenerator xor_shift; + // 65536 - 1 = 2 ^ 16 different numbers can be generated + int r = 65536 - 1; + // 1,000,000 numbers are generated + int n = 1000000; + u_int16_t t; + // this array counts how often each number from 0 to r is returned as a + // result + int f[r] = {}; + for (int i = 0; i < r; i++) { + f[i] = 0; + } + for (int i = 1; i < n; i++) { + t = xor_shift.gen_rdm_16_bit_in_interval(1024, 49151); + f[t]++; + } + double chisquare = 0.0; + for (int i = 0; i < r; i++) { + // chi square is calculated + chisquare = chisquare + ((f[i] - n / r) * (f[i] - n / r) / (n / r)); + } + std::cout << "+++ chi square test for gen_rdm_16_bit_in_interval() +++" + << std::endl; + std::cout << "chi square is: " << chisquare << std::endl; + double k = sqrt(chisquare / (n + chisquare)); + std::cout << "k is: " << k << std::endl; + + // k is in [0; k_max] with k_max ≈ 1 + // Calculating k_norm wouldn't make sense. + // 0 means that every number is generated equally frequent + // 1 means not random at all + + // A bad result could be improved by returning _seed_x16 instead of + // _seed_x16 % 48128 + 1024 (valid port number) in + // RandomNumberGenerator.cpp. + + CHECK(k < 1.0); + + std::cout << std::endl; + } + + SECTION("ChiSquare16", "[]") { + RandomNumberGenerator xor_shift; + // 65526 - 1 = 2 ^ 16 different numbers can be generated + int r = 65536 - 1; + // 1,000,000 numbers are generated + int n = 1000000; + u_int16_t t; + // this array counts how often each number from 0 to r is returned as a + // result + int f[r] = {}; + for (int i = 0; i < r; i++) { + f[i] = 0; + } + for (int i = 1; i < n; i++) { + t = xor_shift.gen_rdm_16_bit(); + f[t]++; + } + double chisquare = 0.0; + for (int i = 0; i < r; i++) { + // chi square is calculated + chisquare = chisquare + ((f[i] - n / r) * (f[i] - n / r) / (n / r)); + } + std::cout << "+++ chi square test for gen_rdm_16_bit() +++" + << std::endl; + std::cout << "chi square is: " << chisquare << std::endl; + double k = sqrt(chisquare / (n + chisquare)); + std::cout << "k is: " << k << std::endl; + + CHECK(k < 1.0); + + std::cout << std::endl; + } + + // the following test fails due to an segmentation violation signal + // 32 bit seems to be to big + + /*SECTION("ChiSquare32", "[]") { + RandomNumberGenerator xor_shift; + u_int32_t r = 4294967296 - 1; + u_int64_t n = 10000000000; + u_int32_t t; + int f[r] = {}; + for (u_int64_t i = 0; i < r; i++) { + f[i] = 0; + } + for (u_int64_t i = 1; i < n; i++) { + t = xor_shift.gen_rdm_32_bit(); + f[t]++; + } + double chisquare = 0.0; + for (int i = 0; i < r; i++) { + chisquare = chisquare + ((f[i] - n / r) * (f[i] - n / r) / (n / r)); + } + std::cout << "chi square is: " << chisquare << std::endl; + double k = sqrt(chisquare / (n + chisquare)); + std::cout << "k is: " << k << std::endl; + // k is in [0; k_max] with k_max ≈ 1 + // 0 means independence + // 1 means not random at all + CHECK(k < 1.0); + }*/ +} + +TEST_CASE("RandomNumberGeneratorTime", "[]") { + + // The following section is calculating the time for generating n + // 16 bit numbers with a single RNG object + SECTION("TestTime16", "[]") { + // the following two lines initialize and start the timer + double time1 = 0.0, tstart; + tstart = clock(); + // creating a RNG object + RandomNumberGenerator xor_shift; + // amount of numbers generated + // can be changed if neccessary, but it you will get a segmentation + // violation error if it's to big + long n = 10000000; + // variable to store generated number + uint16_t test_value; + // generating those numbers + for (long i = 0; i < n; i++) { + test_value = xor_shift.gen_rdm_16_bit(); + } + // stops the timer and calculates the difference between start and end + time1 += clock() - tstart; + // prints out the time + std::cout << "time needed to generate " << n + << " 16 bit numbers: " << time1 / CLOCKS_PER_SEC << " s" + << std::endl; + CHECK(time1 / CLOCKS_PER_SEC < 10.0); + } + + // This test calculates the time needed to generate a certain amount of 16 + // bit ints with rand() allowowing a comparison with xorShift + SECTION("TestTime16Rand", "[]") { + double time1 = 0.0, tstart; + tstart = clock(); + long n = 10000000; + uint16_t test_value; + for (long i = 0; i < n; i++) { + test_value = rand(); + } + time1 += clock() - tstart; + std::cout << "time needed to generate " << n + << " 16 bit numbers with rand(): " << time1 / CLOCKS_PER_SEC + << " s" << std::endl; + CHECK(time1 / CLOCKS_PER_SEC < 10.0); + } + + // the same test for 32 bit numbers + SECTION("TestTime32", "[]") { + double time1 = 0.0, tstart; + tstart = clock(); + RandomNumberGenerator xor_shift; + long n = 10000000; + uint32_t test_value; + for (long i = 0; i < n; i++) { + test_value = xor_shift.gen_rdm_32_bit(); + } + time1 += clock() - tstart; + std::cout << "time needed to generate " << n + << " 32 bit numbers: " << time1 / CLOCKS_PER_SEC << " s" + << std::endl; + CHECK(time1 / CLOCKS_PER_SEC < 1.0); + } + + // true 32 bit numbers with shifting and rand() for comparison to the + // section above + SECTION("TestTime32Rand", "[]") { + double time1 = 0.0, tstart; + tstart = clock(); + long n = 10000000; + uint32_t test_value; + for (long i = 0; i < n; i++) { + test_value = (uint16_t)rand(); + test_value |= (uint16_t)rand() << 16; + } + time1 += clock() - tstart; + std::cout << "time needed to generate " << n + << " 32 bit numbers with rand() and shifting: " + << time1 / CLOCKS_PER_SEC << " s" << std::endl; + CHECK(time1 / CLOCKS_PER_SEC < 1.0); + } + + // the same test for 64 bit numbers + SECTION("TestTime64", "[]") { + double time1 = 0.0, tstart; + tstart = clock(); + RandomNumberGenerator xor_shift; + long n = 10000000; + uint64_t test_value; + for (long i = 0; i < n; i++) { + test_value = xor_shift.gen_rdm_64_bit(); + } + time1 += clock() - tstart; + std::cout << "time needed to generate " << n + << " 64 bit numbers: " << time1 / CLOCKS_PER_SEC << " s" + << std::endl; + CHECK(time1 / CLOCKS_PER_SEC < 1.0); + } + + // true 64 bit numbers with shifting and rand() for comparison to the + // section above + SECTION("TestTime64Rand", "[]") { + double time1 = 0.0, tstart; + tstart = clock(); + long n = 10000000; + uint64_t test_value = 0; + for (long i = 0; i < n; i++) { + // the following lines have been copied from + // Treatment::create_cookie_secret() + u_int64_t value1 = (uint16_t)rand(); + value1 = (value1 << 48); + test_value |= value1; + u_int64_t value2 = (uint16_t)rand(); + value2 = (value2 << 32); + test_value |= value2; + u_int64_t value3 = (uint16_t)rand(); + test_value |= value3; + } + time1 += clock() - tstart; + std::cout << "time needed to generate " << n + << " 64 bit numbers with rand() and shifting: " + << time1 / CLOCKS_PER_SEC << " s" << std::endl; + CHECK(time1 / CLOCKS_PER_SEC < 1.0); + } +} \ No newline at end of file diff --git a/test/Treatment_test.cpp b/test/Treatment_test.cpp new file mode 100644 index 0000000..6727a34 --- /dev/null +++ b/test/Treatment_test.cpp @@ -0,0 +1,1301 @@ +#define BOOST_LOG_DYN_LINK 1 + +#include +#include +#include +#include +#include +#include +#include +#include "Treatment/Treatment.hpp" + +class Treatment_friend { + + Treatment* treatment = new Treatment(); + + public: + static void s_increment_timestamp() { Treatment::s_increment_timestamp(); } + + void treat_packets_to_inside() { treatment->treat_packets_to_inside(); } + void treat_packets_to_outside() { treatment->treat_packets_to_outside(); } + + u_int32_t calc_cookie_hash(u_int8_t _s_timestamp, u_int32_t _extip, + u_int32_t _intip, u_int16_t _extport, + u_int16_t _intport) { + return treatment->calc_cookie_hash(_s_timestamp, _extip, _intip, + _extport, _intport); + } + + bool check_syn_cookie(u_int32_t cookie_value, const Data& d) { + return treatment->check_syn_cookie(cookie_value, d); + } + + // Getter + + u_int8_t get_s_timestamp() { return treatment->_s_timestamp; } + + u_int64_t get_cookie_secret() { return treatment->_cookie_secret; } + + PacketContainer* get_packet_to_inside() { + return treatment->_packet_to_inside; + } + + PacketContainer* get_packet_to_outside() { + return treatment->_packet_to_outside; + } + + google::dense_hash_map get_densemap() { + return treatment->_densemap; + } + + // Setter + + void set_s_timestamp(u_int8_t value) { treatment->_s_timestamp = value; } +}; + +TEST_CASE("Hashfunction", "[]") { + SECTION("XXH3: Not 0", "[]") { + u_int32_t extip = 12345; + u_int32_t intip = 98765; + u_int16_t extport = 123; + u_int16_t intport = 987; + XXH64_hash_t hash = XXH3_64bits_withSeed( + &extip, sizeof(extip), + XXH3_64bits_withSeed( + &intip, sizeof(intip), + XXH3_64bits_withSeed( + &extport, sizeof(extport), + XXH3_64bits_withSeed(&intport, sizeof(intport), 0)))); + REQUIRE(hash != 0); + } + + SECTION("XXH3: Backwards-not-Equal", "[]") { + u_int32_t extip = 12345; + u_int32_t intip = 98765; + u_int16_t extport = 123; + u_int16_t intport = 987; + XXH64_hash_t forhash = XXH3_64bits_withSeed( + &extip, sizeof(extip), + XXH3_64bits_withSeed( + &intip, sizeof(intip), + XXH3_64bits_withSeed( + &extport, sizeof(extport), + XXH3_64bits_withSeed(&intport, sizeof(intport), 0)))); + XXH64_hash_t backhash = XXH3_64bits_withSeed( + &intip, sizeof(intip), + XXH3_64bits_withSeed( + &extip, sizeof(extip), + XXH3_64bits_withSeed( + &intport, sizeof(intport), + XXH3_64bits_withSeed(&extport, sizeof(extport), 0)))); + REQUIRE(forhash != backhash); + } + + SECTION("XXH3: Same data results in same hash values", "[]") { + u_int32_t extip = 12345; + u_int32_t intip = 98765; + u_int16_t extport = 80; + u_int16_t intport = 21; + XXH64_hash_t hash1 = XXH3_64bits_withSeed( + &extip, sizeof(extip), + XXH3_64bits_withSeed( + &intip, sizeof(intip), + XXH3_64bits_withSeed( + &extport, sizeof(extport), + XXH3_64bits_withSeed(&intport, sizeof(intport), 0)))); + XXH64_hash_t hash2 = XXH3_64bits_withSeed( + &extip, sizeof(extip), + XXH3_64bits_withSeed( + &intip, sizeof(intip), + XXH3_64bits_withSeed( + &extport, sizeof(extport), + XXH3_64bits_withSeed(&intport, sizeof(intport), 0)))); + REQUIRE(hash1 == hash2); + } + + SECTION("XXH3: MAX U_INT_32_T in one ip value") { + u_int32_t extip = 4294967296 - 1; + u_int32_t intip = 98765; + u_int16_t extport = 80; + u_int16_t intport = 21; + XXH64_hash_t hash = XXH3_64bits_withSeed( + &extip, sizeof(extip), + XXH3_64bits_withSeed( + &intip, sizeof(intip), + XXH3_64bits_withSeed( + &extport, sizeof(extport), + XXH3_64bits_withSeed(&intport, sizeof(intport), 0)))); + REQUIRE(hash != 0); + } + + SECTION("XXH3: MAX U_INT_16_T in one port value") { + u_int32_t extip = 12345; + u_int32_t intip = 98765; + u_int16_t extport = 65536 - 1; + u_int16_t intport = 21; + XXH64_hash_t hash = XXH3_64bits_withSeed( + &extip, sizeof(extip), + XXH3_64bits_withSeed( + &intip, sizeof(intip), + XXH3_64bits_withSeed( + &extport, sizeof(extport), + XXH3_64bits_withSeed(&intport, sizeof(intport), 0)))); + REQUIRE(hash != 0); + } + + SECTION("XXH3: MAX values") { + u_int32_t extip = 4294967296 - 1; + u_int32_t intip = 4294967296 - 1; + u_int16_t extport = 65536 - 1; + u_int16_t intport = 65536 - 1; + XXH64_hash_t hash = XXH3_64bits_withSeed( + &extip, sizeof(extip), + XXH3_64bits_withSeed( + &intip, sizeof(intip), + XXH3_64bits_withSeed( + &extport, sizeof(extport), + XXH3_64bits_withSeed(&intport, sizeof(intport), 0)))); + REQUIRE(hash != 0); + } + + SECTION("XXH3: Try wrap around") { + u_int32_t extip = 4294967296 + 1; + u_int32_t intip = 4294967296 + 1; + u_int16_t extport = 65536 + 1; + u_int16_t intport = 65536 + 1; + XXH64_hash_t hash = XXH3_64bits_withSeed( + &extip, sizeof(extip), + XXH3_64bits_withSeed( + &intip, sizeof(intip), + XXH3_64bits_withSeed( + &extport, sizeof(extport), + XXH3_64bits_withSeed(&intport, sizeof(intport), 0)))); + REQUIRE(hash != 0); + } + + SECTION("XXH3: Check time for hashing") { + u_int32_t extip = 4294967296 + 1; + u_int32_t intip = 4294967296 + 1; + u_int16_t extport = 65536 + 1; + u_int16_t intport = 65536 + 1; + double time1 = 0.0, tstart; + tstart = clock(); // start + XXH64_hash_t hash = XXH3_64bits_withSeed( + &extip, sizeof(extip), + XXH3_64bits_withSeed( + &intip, sizeof(intip), + XXH3_64bits_withSeed( + &extport, sizeof(extport), + XXH3_64bits_withSeed(&intport, sizeof(intport), 0)))); + time1 += clock() - tstart; // end + time1 = time1 / CLOCKS_PER_SEC; // rescale to seconds + REQUIRE(time1 < 0.00001); + } + + SECTION("calc_cookie_hash() returns 32 bit integer", "[]") { + Treatment_friend treat; + for (int i = 0; i < 1000; i++) { + u_int32_t extip = (u_int32_t)rand(); + u_int32_t intip = (u_int32_t)rand(); + + u_int16_t extport = (u_int16_t)rand(); + u_int16_t intport = (u_int16_t)rand(); + + u_int32_t testValue = + treat.calc_cookie_hash(0, extip, intip, extport, intport); + + CHECK(testValue != 0); + CHECK(sizeof(testValue) == 4); + // BOOST_LOG_TRIVIAL(info)< densemap; + + // Dense_hash_map requires you call set_empty_key() immediately after + // constructing the hash_map, and before calling any other + // dense_hash_map method + Data empty; + empty._extip = 0; + empty._intip = 0; + empty._extport = 0; + empty._intport = 0; + densemap.set_empty_key(empty); + + Data d; + d._extip = 12345; + d._intip = 12334; + d._extport = 123; + d._intport = 1234; + + Info i(3, true, true, true, true, nullptr); + densemap[d] = i; + + REQUIRE(densemap.empty() == false); + } + + SECTION("Densemap:unchanged key after insertion", "[]") { + google::dense_hash_map + densemap; // Data, Info and MyHashFunction defined in Treatment.h + + // Dense_hash_map requires to call set_empty_key() immediately after + // constructing the hash_map, and before calling any other + // dense_hash_map method + Data empty; + empty._extip = 0; + empty._intip = 0; + empty._extport = 0; + empty._intport = 0; + densemap.set_empty_key(empty); + + Data d; + d._extip = 12345; + d._intip = 12334; + d._extport = 123; + d._intport = 1234; + + Info i(3, true, true, true, true, nullptr); + densemap[d] = i; + auto id = densemap.find(d); // const_iterator find(const key_type& k) + // const: Finds an element whose key is k + + CHECK(id->first._extip == d._extip); + CHECK(id->first._intip == d._intip); + CHECK(id->first._extport == d._extport); + CHECK(id->first._intport == d._intport); + CHECK(id->second._offset == 3); + CHECK(id->second._finseen_to_inside == true); + CHECK(id->second._finseen_to_outside == true); + CHECK(id->second._ack_to_inside_expected == true); + CHECK(id->second._ack_to_outside_expected == true); + } + + SECTION("Densemap: Erase all elements", "[]") { + google::dense_hash_map densemap; + + // Dense_hash_map requires to call set_empty_key() immediately after + // constructing the hash_map, and before calling any other + // dense_hash_map method + Data empty; + empty._extip = 0; + empty._intip = 0; + empty._extport = 0; + empty._intport = 0; + densemap.set_empty_key(empty); + + Data d1; + d1._extip = 12345; + d1._intip = 12334; + d1._extport = 123; + d1._intport = 1234; + + Info i1(3, true, true, true, true, nullptr); + densemap[d1] = i1; + + Data d2; + d2._extip = 98765; + d2._intip = 95678; + d2._extport = 80; + d2._intport = 81; + + Info i2(3, false, false, true, false, nullptr); + densemap[d2] = i2; + + CHECK(densemap.size() == 2); + + densemap.clear(); // ereases all of the elements + + CHECK(densemap.empty() == true); // bool empty() const: true if the dense_map's size is 0 + } + + SECTION("Densemap: Erase one element whose key is known", "[]") { + google::dense_hash_map densemap; + + // Dense_hash_map requires to call set_empty_key() immediately after + // constructing the hash_map, and before calling any other + // dense_hash_map method + Data empty; + empty._extip = 0; + empty._intip = 0; + empty._extport = 0; + empty._intport = 0; + densemap.set_empty_key(empty); + + // has to be defined at the very beginning of the programm to be able to + // erase elements later + Data deleted; + deleted._extip = 0; + deleted._intip = 0; + deleted._extport = 1; + deleted._intport = 1; + densemap.set_deleted_key(deleted); + + Data d1; + d1._extip = 12345; + d1._intip = 12334; + d1._extport = 123; + d1._intport = 1234; + + Info i1(3, true, true, true, true, nullptr); + densemap[d1] = + i1; // calculates index over d, store d as first and i as second + + Data d2; + d2._extip = 98765; + d2._intip = 95678; + d2._extport = 80; + d2._intport = 81; + + Info i2(3, true, false, false, true, nullptr); + densemap[d2] = i2; + + CHECK(densemap.size() == 2); + densemap.erase(d1); // d is my key + CHECK(densemap.size() == 1); + densemap.erase(d2); + CHECK(densemap.size() == 0); + } + + /* + This test fails like it should + SECTION("Densemap: deleted_key is not different drom the key-value used for + set_empty_key()"){ google::dense_hash_map + densemap; + + Data empty; // Dense_hash_map requires you call set_empty_kex() + immediately after constructing the hash_map, and before calling any other + dense_hash_map method empty._extip = 0; empty._intip = 0; empty._extport = + 0; empty._intport = 0; densemap.set_empty_key(empty); + + Data deleted; // Dense_hash_map requires you call set_empty_kex() + immediately after constructing the hash_map, and before calling any other + dense_hash_map method deleted._extip = 0; deleted._intip = 0; + deleted._extport = 0; + deleted._intport = 0; + densemap.set_deleted_key(deleted); } //has to be defined at + the very beginning of the programm to be able to erase elements later }*/ + + SECTION("Densemap: working with a lot of different data", "[]") { + google::dense_hash_map densemap; + + // Dense_hash_map requires to call set_empty_key() immediately after + // constructing the hash_map, and before calling any other + // dense_hash_map method + Data empty; + empty._extip = 0; + empty._intip = 0; + empty._extport = 0; + empty._intport = 0; + densemap.set_empty_key(empty); + + // has to be defined at the very beginning of the programm to be able to + // erase elements later + Data deleted; + deleted._extip = 0; + deleted._intip = 0; + deleted._extport = 1; + deleted._intport = 1; + densemap.set_deleted_key(deleted); + + for (int j = 0; j < 1000000; j++) { + Data d; + d._extip = rand(); + d._intip = rand(); + d._extport = rand(); + d._intport = rand(); + + Info i(3, false, true, false, true, nullptr); + densemap[d] = i; + } + + CHECK(densemap.size() == 1000000); + + Data d; + d._extip = rand(); + d._intip = rand(); + d._extport = rand(); + d._intport = rand(); + + Info i(3, false, false, true, true, nullptr); + densemap[d] = i; + + CHECK(densemap.size() == 1000001); + + densemap.erase(d); + + CHECK(densemap.size() == 1000000); + + densemap.clear(); + + CHECK(densemap.empty() == true); + } + + SECTION("Densemap: working with the same data", "[]") { + google::dense_hash_map densemap; + + // Dense_hash_map requires to call set_empty_key() immediately after + // constructing the hash_map, and before calling any other + // dense_hash_map method + Data empty; + empty._extip = 0; + empty._intip = 0; + empty._extport = 0; + empty._intport = 0; + densemap.set_empty_key(empty); + + // has to be defined at the very beginning of the programm to be able to + // erase elements later + Data deleted; + deleted._extip = 0; + deleted._intip = 0; + deleted._extport = 1; + deleted._intport = 1; + densemap.set_deleted_key(deleted); + + Data d; + d._extip = 12345; + d._intip = 54321; + d._extport = 12; + d._intport = 123; + + Info i1(3, true, true, true, true, nullptr); + densemap[d] = i1; + auto id1 = densemap.find(d); + + CHECK(densemap.size() == 1); + CHECK(id1->first._extip == d._extip); + CHECK(id1->first._intip == d._intip); + CHECK(id1->first._extport == d._extport); + CHECK(id1->first._intport == d._intport); + CHECK(id1->second._offset == 3); + CHECK(id1->second._finseen_to_inside == true); + CHECK(id1->second._finseen_to_outside == true); + CHECK(id1->second._ack_to_inside_expected == true); + CHECK(id1->second._ack_to_outside_expected == true); + + Info i2(3, true, true, true, true, nullptr); + densemap[d] = i2; + + CHECK(densemap.size() == 1); + + auto id2 = densemap.find(d); + + CHECK(id2->first._extip == d._extip); + CHECK(id2->first._intip == d._intip); + CHECK(id2->first._extport == d._extport); + CHECK(id2->first._intport == d._intport); + CHECK(id2->second._offset == 3); + CHECK(id2->second._finseen_to_inside == true); + CHECK(id2->second._finseen_to_outside == true); + CHECK(id2->second._ack_to_inside_expected == true); + CHECK(id2->second._ack_to_outside_expected == true); + } + + SECTION("Densemap: Using insert instead of []", "[]") { + google::dense_hash_map _densemap; + + // Dense_hash_map requires to call set_empty_key() immediately after + // constructing the hash_map, and before calling any other + // dense_hash_map method + Data empty; + empty._extip = 0; + empty._intip = 0; + empty._extport = 0; + empty._intport = 0; + _densemap.set_empty_key(empty); + + // has to be defined at the very beginning of the programm to be able to + // erase elements later + Data deleted; + deleted._intip = 0; + deleted._extport = 1; + deleted._intport = 1; + _densemap.set_deleted_key(deleted); + + Data d(12345, 53210, 12, 1234); + + Info i(3, true, true, true, true, nullptr); + _densemap.insert(std::pair(d, i)); + + CHECK(_densemap.empty() == false); + } + + SECTION( + "Densemap: Comparing if values after insertion are the same as before", + "[]") { + + google::dense_hash_map densemap; + + // Dense_hash_map requires to call set_empty_key() immediately after + // constructing the hash_map, and before calling any other + // dense_hash_map method + Data empty; + empty._extip = 0; + empty._intip = 0; + empty._extport = 0; + empty._intport = 0; + densemap.set_empty_key(empty); + + // has to be defined at the very beginning of the programm to be able to + // erase elements later + Data deleted; + deleted._intip = 0; + deleted._extport = 1; + deleted._intport = 1; + densemap.set_deleted_key(deleted); + + Data d; + d._extip = 12345; + d._intip = 54321; + d._extport = 12; + d._intport = 123; + + Info i(3, true, true, true, true, nullptr); + densemap.insert(std::pair(d, i)); + auto id = densemap.find(d); + + CHECK(id->first._extip == d._extip); + CHECK(id->first._intip == d._intip); + CHECK(id->first._extport == d._extport); + CHECK(id->first._intport == d._intport); + CHECK(id->second._offset == i._offset); + CHECK(id->second._finseen_to_inside == i._finseen_to_inside); + } +} + +TEST_CASE("Creating a random number for cookie_secret()", "[]") { + SECTION("Algorithm: Create random 64bit value", "[]") { + + for (int i = 0; i < 10000; i++) { + u_int64_t random64BitNumber = 0; + + u_int64_t value1 = (uint16_t)rand(); + value1 = value1 << 48; + random64BitNumber |= value1; + + u_int64_t value2 = (uint16_t)rand(); + value2 = value2 << 32; + random64BitNumber |= value2; + + u_int64_t value3 = rand(); + random64BitNumber |= value3; + + // BOOST_LOG_TRIVIAL(info) << random64BitNumber; + CHECK(sizeof(random64BitNumber) == 8); // in byte: 8 Byte = 64 bit + } + } + + SECTION("Rand: check size", "[]") { + + Treatment_friend treat; + for (int i = 0; i < 10000; i++) { + u_int64_t r = Rand::get_random_64bit_value(); + // BOOST_LOG_TRIVIAL(info) << r; + CHECK(sizeof(r) == 8); + } + } + + SECTION("Rand: 1000 values are different", "[]") { + + Treatment_friend treat; + int length = 1000; + u_int64_t arr[length]; + + for (int i = 0; i < length - 1; i++) { + arr[i] = Rand::get_random_64bit_value(); + } + + for (int i = 0; i < length - 1; i++) { + for (int j = 0; j < i; j++) { + CHECK(arr[i] != arr[j]); + } + } + } +} + +TEST_CASE("check_syn_cookie()", "[]") { + SECTION("Extract the last 8 bit of an u_int32_t") { + uint32_t v1 = 4294967295; + uint32_t v2 = v1 & 0xFF; + CHECK(v2 == 0b11111111); + + uint32_t v3 = 22500; + uint32_t v4 = v3 & 0xFF; + CHECK(v4 == 0b11100100); + + uint32_t v5 = 2820803657; + uint32_t v6 = v5 & 0xFF; + CHECK(v6 == 0b01001001); + } + + SECTION("check_syn_cookie(): diff == 0 (diff = _s_timestamp - " + "cookie_timestamp = 0-0 = 0)(without using the PacketDissection)", + "[]") { + // Create a Treatment object + Treatment_friend treat; + + u_int32_t extip = 12345; + u_int32_t intip = 98765; + u_int16_t extport = 123; + u_int16_t intport = 124; + + // Create a cookie value + u_int32_t cookie_value = + treat.calc_cookie_hash(0, extip, intip, extport, intport); + cookie_value = (cookie_value & 0xFFFFFF00); + cookie_value |= (u_int8_t)0; + + // create an Data object + Data d; + d._extip = extip; + d._intip = intip; + d._extport = extport; + d._intport = intport; + + REQUIRE(treat.check_syn_cookie(cookie_value, d)); + } + + SECTION("check_syn_cookie(): diff == 0, but false values in cookie_value " + "(without using the PacketDissection)", + "[]") { + // Create a Treatment object + Treatment_friend treat; + + u_int32_t extip = 12345; + u_int32_t intip = 98765; + u_int16_t extport = 123; + u_int16_t intport = 124; + + // Create a cookie value + u_int32_t cookie_value = treat.calc_cookie_hash( + 0, extip + 6, intip - 10, extport + 1, intport); + cookie_value = (cookie_value & 0xFFFFFF00); + cookie_value |= (u_int8_t)0; + + // create an Data object + Data d; + d._extip = extip; + d._intip = intip; + d._extport = extport; + d._intport = intport; + + REQUIRE(treat.check_syn_cookie(cookie_value, d) == false); + } + + SECTION("check_syn_cookie(): diff == 0 (diff = _s_timestamp - " + "cookie_timestamp = 3-3 = 0)(without using the PacketDissection)", + "[]") { + // Create a Treatment object + Treatment_friend treat; + + // increment _s_timestamp up to 3 + treat.s_increment_timestamp(); + treat.s_increment_timestamp(); + treat.s_increment_timestamp(); + CHECK(treat.get_s_timestamp() == 3); + + u_int32_t extip = 12345; + u_int32_t intip = 98765; + u_int16_t extport = 123; + u_int16_t intport = 124; + + // Create a cookie value with timestamp 3 + u_int32_t cookie_value = + treat.calc_cookie_hash(3, extip, intip, extport, intport); + cookie_value = (cookie_value & 0xFFFFFF00); + cookie_value |= (u_int8_t)3; + + // create a Data object + Data d; + d._extip = extip; + d._intip = intip; + d._extport = extport; + d._intport = intport; + + CHECK(treat.check_syn_cookie(cookie_value, d)); + } + + SECTION("check_syn_cookie(): diff == 1 (diff = _s_timestamp - " + "cookie_timestamp = 3- 2)(without using the PacketDissection)", + "[]") { + // Create a Treatment object + Treatment_friend treat; + + // increment _s_timestamp up to 3 + treat.s_increment_timestamp(); + treat.s_increment_timestamp(); + treat.s_increment_timestamp(); + CHECK(treat.get_s_timestamp() == 3); + + u_int32_t extip = 12345; + u_int32_t intip = 98765; + u_int16_t extport = 123; + u_int16_t intport = 124; + + // Create a cookie value with timestamp 2 + u_int32_t cookie_value = + treat.calc_cookie_hash(2, extip, intip, extport, intport); + cookie_value = (cookie_value & 0xFFFFFF00); + cookie_value |= (u_int8_t)2; + + // create a Data object + Data d; + d._extip = extip; + d._intip = intip; + d._extport = extport; + d._intport = intport; + + CHECK(treat.check_syn_cookie(cookie_value, d)); + } + + SECTION( + "check_syn_cookie(): diff == 1 (without using the PacketDissection)", + "[]") { + // Create a Treatment object + Treatment_friend treat; + + // increment _s_timestamp with _s_timestamp 1 + treat.s_increment_timestamp(); + CHECK(treat.get_s_timestamp() == 1); + + u_int32_t extip = 12345; + u_int32_t intip = 98765; + u_int16_t extport = 123; + u_int16_t intport = 124; + + // Create a cookie value with timestamp 0 + u_int32_t cookie_value = + treat.calc_cookie_hash(0, extip, intip, extport, intport); + cookie_value = (cookie_value & 0xFFFFFF00); + cookie_value |= (u_int8_t)0; + + // create a Data object + Data d; + d._extip = extip; + d._intip = intip; + d._extport = extport; + d._intport = intport; + + CHECK(treat.check_syn_cookie(cookie_value, d)); + } + + SECTION("check_syn_cookie(): diff > 1 (diff = _s_timestamp - " + "cookie_timestamp = 2- 0)(without using the PacketDissection)", + "[]") { + // Create a Treatment object + Treatment_friend treat; + + // increment _s_timestamp up to 32 + treat.s_increment_timestamp(); + treat.s_increment_timestamp(); + CHECK(treat.get_s_timestamp() == 2); + + u_int32_t extip = 12345; + u_int32_t intip = 98765; + u_int16_t extport = 123; + u_int16_t intport = 124; + + // Create a cookie value with timestamp 0 + u_int32_t cookie_value = + treat.calc_cookie_hash(0, extip, intip, extport, intport); + cookie_value = (cookie_value & 0xFFFFFF00); + cookie_value |= (u_int8_t)0; + + // create a Data object + Data d; + d._extip = extip; + d._intip = intip; + d._extport = extport; + d._intport = intport; + + CHECK(treat.check_syn_cookie(cookie_value, d) == false); + } + + SECTION("check_syn_cookie(): diff == 1 with random numbers (without using " + "the PacketDissection)", + "[]") { + // Create a Treatment object + Treatment_friend treat; + u_int8_t ran_num = rand(); + // increment _s_timestamp with _s_timestamp 6 + for (int i = 0; i < ran_num; i++) { + treat.s_increment_timestamp(); + } + + CHECK(treat.get_s_timestamp() == ran_num); + + u_int32_t extip = rand(); + u_int32_t intip = rand(); + u_int16_t extport = rand(); + u_int16_t intport = rand(); + + // Create a cookie value with timestamp 5 + u_int32_t cookie_value = treat.calc_cookie_hash( + (ran_num - 1), extip, intip, extport, intport); + cookie_value = cookie_value & 0xFFFFFF00; + cookie_value |= (u_int8_t)(ran_num - 1); + + // create a Data object + Data d; + d._extip = extip; + d._intip = intip; + d._extport = extport; + d._intport = intport; + + CHECK(treat.check_syn_cookie(cookie_value, d)); + } + + SECTION("check_syn_cookie(): diff > 1 (diff = _s_timestamp - " + "cookie_timestamp = 64- 7)(without using the PacketDissection)", + "[]") { + // Create a Treatment object + Treatment_friend treat; + + // increment _s_timestamp up to 64 + for (int i = 0; i < 64; i++) { + treat.s_increment_timestamp(); + } + CHECK(treat.get_s_timestamp() == 64); + + u_int32_t extip = 12345; + u_int32_t intip = 98765; + u_int16_t extport = 123; + u_int16_t intport = 124; + + // Create a cookie value with timestamp 7 + u_int32_t cookie_value = + treat.calc_cookie_hash(7, extip, intip, extport, intport); + cookie_value = (cookie_value & 0xFFFFFF00); + cookie_value |= (u_int8_t)7; + + // create a Data object + Data d; + d._extip = extip; + d._intip = intip; + d._extport = extport; + d._intport = intport; + + CHECK(treat.check_syn_cookie(cookie_value, d) == false); + } + + SECTION("check_syn_cookie(): diff < 0 (diff = _timestamp - " + "cookie_timestamp = 0- 7)(without using the PacketDissection)", + "[]") { + // Create a Treatment object + Treatment_friend treat; + + u_int32_t extip = 12345; + u_int32_t intip = 98765; + u_int16_t extport = 123; + u_int16_t intport = 124; + + // Create a cookie value with timestamp 7 + u_int32_t cookie_value = + treat.calc_cookie_hash(7, extip, intip, extport, intport); + cookie_value = (cookie_value & 0xFFFFFF00); + cookie_value |= (u_int8_t)7; + + // create a Data object + Data d; + d._extip = extip; + d._intip = intip; + d._extport = extport; + d._intport = intport; + + CHECK(treat.check_syn_cookie(cookie_value, d) == false); + } +} + +TEST_CASE("Boost", "[]") { + // BOOST_LOG_TRIVIAL(info) << "Dies ist eine Info Message"; + // BOOST_LOG_TRIVIAL(warning) << "Dies ist eine Warn-Nachricht"; +} + +TEST_CASE("UINTTEST", "[]") { + u_int32_t yyy = 0x00000000; + u_int32_t xxx = 0xFFFFFFFF; + + u_int32_t diff = yyy - xxx; + REQUIRE(diff == 1); +} + +TEST_CASE("Struct: Data", "[]") { + + SECTION("Default Constructor", "[]") { + Data dat; + + // attributes have to be 0 + CHECK(dat._extip == 0); + CHECK(dat._intip == 0); + CHECK(dat._extport == 0); + CHECK(dat._intport == 0); + } + + SECTION("Data empty using member initializer lists", "[]") { + Data empty(0, 0, 0, 0); + + CHECK(empty._extip == 0); + CHECK(empty._intip == 0); + CHECK(empty._extport == 0); + CHECK(empty._intport == 0); + } + + SECTION("Data empty without using member initializer lists", "[]") { + Data empty; + + empty._extip = 0; + empty._intip = 0; + empty._extport = 0; + empty._intport = 0; + + CHECK(empty._extip == 0); + CHECK(empty._intip == 0); + CHECK(empty._extport == 0); + CHECK(empty._intport == 0); + } + + SECTION("Data with random values using member initializer lists", "[]") { + for (int i = 0; i < 1000; i++) { + u_int32_t a = (u_int32_t)rand(); + u_int32_t b = (u_int32_t)rand(); + u_int16_t c = (u_int16_t)rand(); + u_int16_t d = (u_int16_t)rand(); + + Data dat(a, b, c, d); + + CHECK(dat._extip == a); + CHECK(dat._intip == b); + CHECK(dat._extport == c); + CHECK(dat._intport == d); + } + } + + SECTION("Data with random values without using member initializer lists", + "[]") { + Data dat; + + for (int i = 0; i < 1000; i++) { + u_int32_t a = (u_int32_t)rand(); + u_int32_t b = (u_int32_t)rand(); + u_int16_t c = (u_int16_t)rand(); + u_int16_t d = (u_int16_t)rand(); + + dat._extip = a; + dat._intip = b; + dat._extport = c; + dat._intport = d; + + CHECK(dat._extip == a); + CHECK(dat._intip == b); + CHECK(dat._extport == c); + CHECK(dat._intport == d); + } + } +} + +TEST_CASE("Struct: Info", "[]") { + SECTION("Default Constructor", "[]") { + Info inf; + + CHECK(inf._offset == 0); + CHECK(inf._finseen_to_inside == false); + CHECK(inf._finseen_to_outside == false); + CHECK(inf._ack_to_inside_expected == false); + CHECK(inf._ack_to_outside_expected == false); + } + + SECTION("Info with random values using member initializer lists", "[]") { + for (int i = 0; i < 1000; i++) { + int off = (int)rand(); + // random true or false + bool fins1 = (rand() > (RAND_MAX / 2)); + bool fins2 = (rand() > (RAND_MAX / 2)); + bool fins3 = (rand() > (RAND_MAX / 2)); + bool fins4 = (rand() > (RAND_MAX / 2)); + + Info inf(off, fins1, fins2, fins3, fins4, nullptr); + + CHECK(inf._offset == off); + CHECK(inf._finseen_to_inside == fins1); + CHECK(inf._finseen_to_outside == fins2); + CHECK(inf._ack_to_inside_expected == fins3); + CHECK(inf._ack_to_outside_expected == fins4); + } + } + + SECTION("Info with random values without using member initializer lists", + "[]") { + for (int i = 0; i < 1000; i++) { + int off = (int)rand(); + // random true or false + bool fins1 = (rand() > (RAND_MAX / 2)); + bool fins2 = (rand() > (RAND_MAX / 2)); + bool fins3 = (rand() > (RAND_MAX / 2)); + bool fins4 = (rand() > (RAND_MAX / 2)); + + + Info inf; + + inf._offset = off; + inf._finseen_to_inside = fins1; + inf._finseen_to_outside = fins2; + inf._ack_to_inside_expected = fins3; + inf._ack_to_outside_expected = fins4; + CHECK(inf._offset == off); + CHECK(inf._finseen_to_inside == fins1); + CHECK(inf._finseen_to_outside == fins2); + CHECK(inf._ack_to_inside_expected == fins3); + CHECK(inf._ack_to_outside_expected == fins4); + + + } + } +} + +TEST_CASE("s_increment_timestamp", "[]") { + SECTION("Increment _timestamp up to 255 (size of u_int8_t)", "[]") { + Treatment_friend treat; + for (u_int8_t i = 0; i < 255; i++) { // 255 = 2^8 -1 + CHECK(treat.get_s_timestamp() == i); + treat.s_increment_timestamp(); + } + CHECK(treat.get_s_timestamp() == 255); + } + SECTION("Increment _s_timestamp up to 1000 (>255>size if u_int8_t)", "[]") { + Treatment_friend treat; + + u_int8_t count = 0; + + for (int i = 0; i < 1000; i++) { + CHECK(treat.get_s_timestamp() == count); + treat.s_increment_timestamp(); + count++; // everytimes when count would reache 256, it will start + // with 0 since the size of u_int8_t is 255 + } + } + + SECTION("Change the value of _s_timestamp manually, increment _s_timestamp " + "should still work after this change") { + Treatment_friend treat; + + CHECK(treat.get_s_timestamp() == 0); + + // Change the value of _s_timestamp to 45 (higher value than before) + treat.set_s_timestamp(45); + CHECK(treat.get_s_timestamp() == 45); + + treat.s_increment_timestamp(); + CHECK(treat.get_s_timestamp() == 46); + + // Change the value of _s_timestamp to 45 (lower value than before) + treat.set_s_timestamp(22); + CHECK(treat.get_s_timestamp() == 22); + + treat.s_increment_timestamp(); + CHECK(treat.get_s_timestamp() == 23); + } +} +TEST_CASE("Benchmark", "[]") { + typedef std::unordered_map unordered; + unordered unord; + google::dense_hash_map densemap; + clock_t tu; + // clock_t tr; + clock_t td; + Data empty; + empty._extip = 0; + empty._extport = 0; + empty._intip = 0; + empty._intport = 0; + densemap.set_empty_key(empty); + Info flix(0, true, true, true, true, nullptr); + + // ------------------------------------------------------------------------------------------------------- + + //----------------------------------------------------- + long runs = 1; + clock_t uclock[runs] = {}; + clock_t dclock[runs] = {}; + long runner = 600000; + Data arr[runner] = {}; + + for (long r = 0; r < runs; ++r) { + + for (long i = 0; i < runner; ++i) { + arr[i]._extip = rand(); + arr[i]._intip = rand(); + arr[i]._extport = rand(); + arr[i]._intport = rand(); + } + + auto startu = std::chrono::high_resolution_clock::now(); + tu = clock(); + for (long i = 0; i < runner; ++i) { + unord.emplace(arr[i], flix); + } + + for (long i = 0; i < runner; ++i) { + unord.find(arr[i - 1 % runner]); + unord.find(arr[i]); + unord.find(arr[i + 1 % runner]); + unord.find(arr[i + 50 % runner]); + } + tu = clock() - tu; + auto finishu = std::chrono::high_resolution_clock::now(); + + auto startd = std::chrono::high_resolution_clock::now(); + td = clock(); + for (long i = 0; i < runner; ++i) { + densemap.insert(std::pair( + arr[i], flix)); // insert rather than densemap[arr[i]] + } + for (long i = 0; i < runner; ++i) { + densemap.find(arr[i - 1 % runner]); + densemap.find(arr[i]); + densemap.find(arr[i + 1 % runner]); + densemap.find(arr[i + 50 % runner]); + } + td = clock() - td; + auto finishd = std::chrono::high_resolution_clock::now(); + + std::chrono::duration elapsedu = finishu - startu; + std::chrono::duration elapsedd = finishd - startd; + dclock[r] = td; + uclock[r] = tu; + BOOST_LOG_TRIVIAL(info) + << "Elapsed time of unordered: " << elapsedu.count(); + BOOST_LOG_TRIVIAL(info) + << "Elapsed time of dense: " << elapsedd.count(); + } + int sumd = 0; + int sumu = 0; + for (long x = 0; x < runs; ++x) { + sumd = sumd + dclock[x]; + sumu = sumu + uclock[x]; + } + BOOST_LOG_TRIVIAL(info) + << "This is the average clock count of densemap of " << runs + << " rounds, of each " << runner << " elements inserted, and " + << 4 * runner << " elements searched : " << sumd / runs; + BOOST_LOG_TRIVIAL(info) + << "This is the average clock count of unordered_map of " << runs + << " rounds, of each " << runner << " elements inserted, and " + << 4 * runner << " elements searched : " << sumu / runs; +} diff --git a/test/dpdk_dummy_test.cpp b/test/dpdk_dummy_test.cpp new file mode 100644 index 0000000..29c66c1 --- /dev/null +++ b/test/dpdk_dummy_test.cpp @@ -0,0 +1,14 @@ +#include +#include +#include + +#include +#include + +TEST_CASE("rte_mbuf", "[]") { + struct rte_mbuf* mbuf; + struct rte_mempool* mempool = nullptr; + + mbuf = rte_pktmbuf_alloc(mempool); + CHECK(mbuf != nullptr); +} \ No newline at end of file diff --git a/test/meson.build b/test/meson.build index a82341b..727a425 100644 --- a/test/meson.build +++ b/test/meson.build @@ -1,15 +1,18 @@ - -# ..each entry will be a test executable -# ..the structure of the test directory should be equivalent -# ..to the structure in source/ or include/ +# each entry will be a test executable. +# the structure of the test directory should be equivalent +# to the structure in source/ or include/ # Syntax: # 'Name of the Test (e.g. class name)' : 'Path/to/source/file' +# Please keep all alphabetically sorted test_sources_dict = { - #'PacketInfo' : 'test/PacketDissection/PacketInfo_test.cpp', - 'PacketContainer' : 'test/PacketDissection/PacketContainer_test.cpp', - 'Configurator' : 'test/ConfigurationManagement/Configurator_test.cpp', - 'libdpdk_dummy' : 'test/libdpdk_dummy/libdpdk_dummy_test.cpp', - 'Treatment' : 'test/Treatment/Treatment_test.cpp', - 'RandomNumberGenerator' : 'test/RandomNumberGenerator/RandomNumberGenerator_test.cpp', + #'Attacker' : 'test/Attacker_test.cpp', + 'Configurator' : 'test/Configurator_test.cpp', + #'Initializer' : 'test/Initializer_test.cpp', + #'Inspection' : 'test/Inspection_test.cpp', + 'DPDK_dummy' : 'test/dpdk_dummy_test.cpp', + 'PacketContainer' : 'test/PacketContainer_test.cpp', + #'PacketInfo' : 'test/PacketInfo_test.cpp', + 'RandomNumberGenerator' : 'test/RandomNumberGenerator_test.cpp', + #'Treatment' : 'test/Treatment_test.cpp' } \ No newline at end of file