diff --git a/src/fast_library.cpp b/src/fast_library.cpp index c099b3e6..ccb4c24b 100644 --- a/src/fast_library.cpp +++ b/src/fast_library.cpp @@ -1109,7 +1109,7 @@ std::string get_printable_attack_name(attack_type_t attack) { } } -std::string serialize_network_load_to_text(map_element& network_speed_meter, bool average) { +std::string serialize_network_load_to_text(map_element_t& network_speed_meter, bool average) { std::stringstream buffer; std::string prefix = "Network"; @@ -1127,7 +1127,7 @@ std::string serialize_network_load_to_text(map_element& network_speed_meter, boo return buffer.str(); } -json_object* serialize_network_load_to_json(map_element& network_speed_meter) { +json_object* serialize_network_load_to_json(map_element_t& network_speed_meter) { json_object* jobj = json_object_new_object(); json_object_object_add(jobj, "incoming traffic", json_object_new_int(network_speed_meter.in_bytes)); diff --git a/src/fast_library.h b/src/fast_library.h index 9098671b..09af5403 100644 --- a/src/fast_library.h +++ b/src/fast_library.h @@ -111,9 +111,9 @@ bool manage_interface_promisc_mode(std::string interface_name, bool switch_on); std::string serialize_attack_description(attack_details& current_attack); attack_type_t detect_attack_type(attack_details& current_attack); std::string get_printable_attack_name(attack_type_t attack); -std::string serialize_network_load_to_text(map_element& network_speed_meter, bool average); +std::string serialize_network_load_to_text(map_element_t& network_speed_meter, bool average); json_object* serialize_attack_description_to_json(attack_details& current_attack); -json_object* serialize_network_load_to_json(map_element& network_speed_meter); +json_object* serialize_network_load_to_json(map_element_t& network_speed_meter); std::string serialize_statistic_counters_about_attack(attack_details& current_attack); std::string dns_lookup(std::string domain_name); diff --git a/src/fastnetmon.cpp b/src/fastnetmon.cpp index fda4f13b..607f7801 100644 --- a/src/fastnetmon.cpp +++ b/src/fastnetmon.cpp @@ -324,9 +324,14 @@ active_flow_spec_announces_t active_flow_spec_announces; // We count total number of incoming/outgoing/internal and other traffic type packets/bytes // And initilize by 0 all fields -total_counter_element total_counters[4]; -total_counter_element total_speed_counters[4]; -total_counter_element total_speed_average_counters[4]; +total_counter_element_t total_counters[4]; +total_counter_element_t total_speed_counters[4]; +total_counter_element_t total_speed_average_counters[4]; + +// IPv6 versions of total counters +total_counter_element_t total_counters_ipv6[4]; +total_counter_element_t total_speed_counters_ipv6[4]; +total_counter_element_t total_speed_average_counters_ipv6[4]; // Total amount of non parsed packets uint64_t total_unparsed_packets = 0; @@ -415,7 +420,7 @@ bool process_outgoing_traffic = true; void init_current_instance_of_ndpi(); #endif -void execute_ip_ban(uint32_t client_ip, map_element average_speed_element, std::string flow_attack_details, subnet_t customer_subnet); +void execute_ip_ban(uint32_t client_ip, map_element_t average_speed_element, std::string flow_attack_details, subnet_t customer_subnet); std::string get_attack_description_in_json(uint32_t client_ip, attack_details& current_attack); logging_configuration_t read_logging_settings(configuration_map_t configuration_map); std::string get_amplification_attack_type(amplification_attack_type_t attack_type); @@ -430,7 +435,7 @@ void exabgp_prefix_ban_manage(std::string action, std::string exabgp_next_hop, std::string exabgp_community); std::string print_subnet_load(); -bool we_should_ban_this_ip(map_element* current_average_speed_element, ban_settings_t current_ban_settings); +bool we_should_ban_this_ip(map_element_t* current_average_speed_element, ban_settings_t current_ban_settings); unsigned int get_max_used_protocol(uint64_t tcp, uint64_t udp, uint64_t icmp); void print_attack_details_to_file(std::string details, std::string client_ip_as_string, attack_details current_attack); std::string print_ban_thresholds(ban_settings_t current_ban_settings); @@ -1085,7 +1090,7 @@ void subnet_vectors_allocator(prefix_t* prefix, void* data) { subnet_t current_subnet = std::make_pair(subnet_as_integer, bitlen); - map_element zero_map_element; + map_element_t zero_map_element; memset(&zero_map_element, 0, sizeof(zero_map_element)); // Initilize our counters with fill constructor @@ -1111,7 +1116,7 @@ void subnet_vectors_allocator(prefix_t* prefix, void* data) { } void zeroify_all_counters() { - map_element zero_map_element; + map_element_t zero_map_element; memset(&zero_map_element, 0, sizeof(zero_map_element)); for (map_of_vector_counters::iterator itr = SubnetVectorMap.begin(); itr != SubnetVectorMap.end(); ++itr) { @@ -1279,7 +1284,7 @@ bool load_our_networks_list() { << total_number_of_hosts_in_our_networks; // 3 - speed counter, average speed counter and data counter - uint64_t memory_requirements = 3 * sizeof(map_element) * total_number_of_hosts_in_our_networks / 1024 / 1024; + uint64_t memory_requirements = 3 * sizeof(map_element_t) * total_number_of_hosts_in_our_networks / 1024 / 1024; logger << log4cpp::Priority::INFO << "We need " << memory_requirements << " MB of memory for storing counters for your networks"; diff --git a/src/fastnetmon_logic.cpp b/src/fastnetmon_logic.cpp index 2af47377..00bcea03 100644 --- a/src/fastnetmon_logic.cpp +++ b/src/fastnetmon_logic.cpp @@ -74,9 +74,12 @@ extern bool enable_netflow_collection; extern bool enable_pcap_collection; extern uint64_t incoming_total_flows_speed; extern uint64_t outgoing_total_flows_speed; -extern total_counter_element total_counters[4]; -extern total_counter_element total_speed_counters[4]; -extern total_counter_element total_speed_average_counters[4]; +extern total_counter_element_t total_counters[4]; +extern total_counter_element_t total_speed_counters[4]; +extern total_counter_element_t total_speed_average_counters[4]; +extern total_counter_element_t total_counters_ipv6[4]; +extern total_counter_element_t total_speed_counters_ipv6[4]; +extern total_counter_element_t total_speed_average_counters_ipv6[4]; extern host_group_ban_settings_map_t host_group_ban_settings_map; extern bool exabgp_announce_whole_subnet; extern subnet_to_host_group_map_t subnet_to_host_groups; @@ -164,7 +167,7 @@ unsigned int get_max_used_protocol(uint64_t tcp, uint64_t udp, uint64_t icmp) { return 0; } -unsigned int detect_attack_protocol(map_element& speed_element, direction_t attack_direction) { +unsigned int detect_attack_protocol(map_element_t& speed_element, direction_t attack_direction) { if (attack_direction == INCOMING) { return get_max_used_protocol(speed_element.tcp_in_packets, speed_element.udp_in_packets, speed_element.icmp_in_packets); @@ -176,8 +179,8 @@ unsigned int detect_attack_protocol(map_element& speed_element, direction_t atta } // We calculate speed from packet counters here -void build_speed_counters_from_packet_counters(map_element& new_speed_element, - map_element* vector_itr, +void build_speed_counters_from_packet_counters(map_element_t& new_speed_element, + map_element_t* vector_itr, double speed_calc_period) { // calculate_speed(new_speed_element speed_element, vector_itr* ); new_speed_element.in_packets = uint64_t((double)vector_itr->in_packets / speed_calc_period); @@ -229,8 +232,8 @@ void build_speed_counters_from_packet_counters(map_element& new_speed_element, new_speed_element.icmp_out_bytes = uint64_t((double)vector_itr->icmp_out_bytes / speed_calc_period); } -void build_average_speed_counters_from_speed_counters(map_element* current_average_speed_element, - map_element& new_speed_element, +void build_average_speed_counters_from_speed_counters(map_element_t* current_average_speed_element, + map_element_t& new_speed_element, double exp_value, double exp_power) { @@ -432,7 +435,7 @@ std::string print_subnet_load() { for (std::vector::iterator itr = vector_for_sort.begin(); itr != vector_for_sort.end(); ++itr) { - map_element* speed = &itr->second; + map_element_t* speed = &itr->second; std::string subnet_as_string = convert_subnet_to_string(itr->first); buffer << std::setw(18) << std::left << subnet_as_string; @@ -703,7 +706,7 @@ bool exceed_mbps_speed(uint64_t in_counter, uint64_t out_counter, unsigned int t } // Return true when we should ban this IP -bool we_should_ban_this_ip(map_element* average_speed_element, ban_settings_t current_ban_settings) { +bool we_should_ban_this_ip(map_element_t* average_speed_element, ban_settings_t current_ban_settings) { // we detect overspeed by packets if (current_ban_settings.enable_ban_for_pps && @@ -934,7 +937,7 @@ void cleanup_ban_list() { continue; } - map_element* average_speed_element = &itr_average_speed->second[shift_in_vector]; + map_element_t* average_speed_element = &itr_average_speed->second[shift_in_vector]; // We get ban settings from host subnet std::string host_group_name; @@ -1041,8 +1044,8 @@ std::string get_attack_description(uint32_t client_ip, attack_details& current_a if (enable_subnet_counters) { // Got subnet tracking structure // TODO: we suppose case "no key exists" is not possible - map_element network_speed_meter = PerSubnetSpeedMap[current_attack.customer_network]; - map_element average_network_speed_meter = PerSubnetAverageSpeedMap[current_attack.customer_network]; + map_element_t network_speed_meter = PerSubnetSpeedMap[current_attack.customer_network]; + map_element_t average_network_speed_meter = PerSubnetAverageSpeedMap[current_attack.customer_network]; attack_description << "Network: " << convert_subnet_to_string(current_attack.customer_network) << "\n"; @@ -1063,8 +1066,8 @@ std::string get_attack_description_in_json(uint32_t client_ip, attack_details& c json_object_object_add(jobj, "attack_details", serialize_attack_description_to_json(current_attack)); if (enable_subnet_counters) { - map_element network_speed_meter = PerSubnetSpeedMap[current_attack.customer_network]; - map_element average_network_speed_meter = PerSubnetAverageSpeedMap[current_attack.customer_network]; + map_element_t network_speed_meter = PerSubnetSpeedMap[current_attack.customer_network]; + map_element_t average_network_speed_meter = PerSubnetAverageSpeedMap[current_attack.customer_network]; json_object_object_add(jobj, "network_load", serialize_network_load_to_json(network_speed_meter)); json_object_object_add(jobj, "network_average_load", @@ -1687,7 +1690,7 @@ redisContext* redis_init_connection() { #endif -void execute_ip_ban(uint32_t client_ip, map_element average_speed_element, std::string flow_attack_details, subnet_t customer_subnet) { +void execute_ip_ban(uint32_t client_ip, map_element_t average_speed_element, std::string flow_attack_details, subnet_t customer_subnet) { struct attack_details current_attack; uint64_t pps = 0; @@ -2206,7 +2209,7 @@ void recalculate_speed() { speed_calc_period = time_difference; } - map_element zero_map_element; + map_element_t zero_map_element; memset(&zero_map_element, 0, sizeof(zero_map_element)); uint64_t incoming_total_flows = 0; @@ -2239,7 +2242,7 @@ void recalculate_speed() { double exp_power_subnet = -speed_calc_period / average_calculation_amount_for_subnets; double exp_value_subnet = exp(exp_power_subnet); - map_element* current_average_speed_element = &PerSubnetAverageSpeedMap[current_subnet]; + map_element_t* current_average_speed_element = &PerSubnetAverageSpeedMap[current_subnet]; current_average_speed_element->in_bytes = uint64_t( new_speed_element.in_bytes + exp_value_subnet * ((double)current_average_speed_element->in_bytes - @@ -2273,7 +2276,7 @@ void recalculate_speed() { int current_index = vector_itr - itr->second.begin(); // New element - map_element new_speed_element; + map_element_t new_speed_element; // convert to host order for math operations uint32_t subnet_ip = ntohl(itr->first.first); @@ -2316,7 +2319,7 @@ void recalculate_speed() { double exp_power = -speed_calc_period / average_calculation_amount; double exp_value = exp(exp_power); - map_element* current_average_speed_element = &SubnetVectorMapSpeedAverage[itr->first][current_index]; + map_element_t* current_average_speed_element = &SubnetVectorMapSpeedAverage[itr->first][current_index]; // Calculate average speed from per-second speed build_average_speed_counters_from_speed_counters(current_average_speed_element, @@ -2395,6 +2398,27 @@ void recalculate_speed() { total_counters[index].packets = 0; } + // Do same for IPv6 + for (unsigned int index = 0; index < 4; index++) { + total_speed_counters_ipv6[index].bytes = uint64_t((double)total_counters_ipv6[index].bytes / (double)speed_calc_period); + total_speed_counters_ipv6[index].packets = + uint64_t((double)total_counters_ipv6[index].packets / (double)speed_calc_period); + + double exp_power = -speed_calc_period / average_calculation_amount; + double exp_value = exp(exp_power); + + total_speed_average_counters_ipv6[index].bytes = uint64_t( + total_speed_counters_ipv6[index].bytes + exp_value * ((double)total_speed_average_counters_ipv6[index].bytes - + (double)total_speed_counters_ipv6[index].bytes)); + + total_speed_average_counters_ipv6[index].packets = uint64_t( + total_speed_counters_ipv6[index].packets + exp_value * ((double)total_speed_average_counters_ipv6[index].packets - + (double)total_speed_counters_ipv6[index].packets)); + + // nullify data counters after speed calculation + total_counters_ipv6[index].zeroify(); + } + // Set time of previous startup time(&last_call_of_traffic_recalculation); @@ -2422,7 +2446,7 @@ std::string draw_table(direction_t data_direction, bool do_redis_update, sort_ty current_speed_map = &SubnetVectorMapSpeed; } - map_element zero_map_element; + map_element_t zero_map_element; memset(&zero_map_element, 0, sizeof(zero_map_element)); unsigned int count_of_zero_speed_packets = 0; @@ -2440,7 +2464,7 @@ std::string draw_table(direction_t data_direction, bool do_redis_update, sort_ty uint32_t client_ip = htonl(client_ip_in_host_bytes_order); // Do not add zero speed packets to sort list - if (memcmp((void*)&zero_map_element, &*vector_itr, sizeof(map_element)) != 0) { + if (memcmp((void*)&zero_map_element, &*vector_itr, sizeof(map_element_t)) != 0) { vector_for_sort.push_back(std::make_pair(client_ip, *vector_itr)); } else { count_of_zero_speed_packets++; @@ -2489,7 +2513,7 @@ std::string draw_table(direction_t data_direction, bool do_redis_update, sort_ty uint64_t flows_average = 0; // Here we could have average or instantaneous speed - map_element* current_speed_element = &ii->second; + map_element_t* current_speed_element = &ii->second; // Create polymorphic pps, byte and flow counters if (data_direction == INCOMING) { @@ -2533,7 +2557,7 @@ std::string draw_table(direction_t data_direction, bool do_redis_update, sort_ty uint64_t flows = 0; // Here we could have average or instantaneous speed - map_element* current_speed_element = &ii->second; + map_element_t* current_speed_element = &ii->second; // Create polymorphic pps, byte and flow counters if (data_direction == INCOMING) { @@ -2642,12 +2666,19 @@ void process_packet(simple_packet_t& current_packet) { logger << log4cpp::Priority::INFO << "Dump: " << print_simple_packet(current_packet); } + uint64_t sampled_number_of_packets = current_packet.number_of_packets * current_packet.sample_ratio; + uint64_t sampled_number_of_bytes = current_packet.length * current_packet.sample_ratio; + if (current_packet.ip_protocol_version == 6) { subnet_ipv6_cidr_mask_t ipv6_cidr_subnet; current_packet.packet_direction = get_packet_direction_ipv6(lookup_tree_ipv6, current_packet.src_ipv6, current_packet.dst_ipv6, ipv6_cidr_subnet); + __sync_fetch_and_add(&total_counters_ipv6[current_packet.packet_direction].packets, sampled_number_of_packets); + __sync_fetch_and_add(&total_counters_ipv6[current_packet.packet_direction].bytes, sampled_number_of_bytes); + + #ifdef USE_NEW_ATOMIC_BUILTINS __atomic_add_fetch(&total_ipv6_packets, 1, __ATOMIC_RELAXED); #else @@ -2734,9 +2765,6 @@ void process_packet(simple_packet_t& current_packet) { - Another combinations of this three options */ - uint64_t sampled_number_of_packets = current_packet.number_of_packets * current_packet.sample_ratio; - uint64_t sampled_number_of_bytes = current_packet.length * current_packet.sample_ratio; - #ifdef USE_NEW_ATOMIC_BUILTINS __atomic_add_fetch(&total_counters[packet_direction].packets, sampled_number_of_packets, __ATOMIC_RELAXED); __atomic_add_fetch(&total_counters[packet_direction].bytes, sampled_number_of_bytes, __ATOMIC_RELAXED); @@ -2790,7 +2818,7 @@ void process_packet(simple_packet_t& current_packet) { return; } - map_element* current_element = &itr->second[shift_in_vector]; + map_element_t* current_element = &itr->second[shift_in_vector]; // Main packet/bytes counter #ifdef USE_NEW_ATOMIC_BUILTINS @@ -2961,7 +2989,7 @@ void process_packet(simple_packet_t& current_packet) { return; } - map_element* current_element = &itr->second[shift_in_vector]; + map_element_t* current_element = &itr->second[shift_in_vector]; // Main packet/bytes counter #ifdef USE_NEW_ATOMIC_BUILTINS diff --git a/src/fastnetmon_logic.hpp b/src/fastnetmon_logic.hpp index 6b734559..51e8b673 100644 --- a/src/fastnetmon_logic.hpp +++ b/src/fastnetmon_logic.hpp @@ -11,12 +11,12 @@ typedef std::map active_flow_spec_announces_t; -void build_speed_counters_from_packet_counters(map_element& new_speed_element, - map_element* vector_itr, +void build_speed_counters_from_packet_counters(map_element_t& new_speed_element, + map_element_t* vector_itr, double speed_calc_period) ; -void build_average_speed_counters_from_speed_counters(map_element* current_average_speed_element, - map_element& new_speed_element, +void build_average_speed_counters_from_speed_counters(map_element_t* current_average_speed_element, + map_element_t& new_speed_element, double exp_value, double exp_power); @@ -24,7 +24,7 @@ std::string get_amplification_attack_type(amplification_attack_type_t attack_typ std::string generate_flow_spec_for_amplification_attack(amplification_attack_type_t amplification_attack_type, std::string destination_ip); -bool we_should_ban_this_ip(map_element* average_speed_element, ban_settings_t current_ban_settings); +bool we_should_ban_this_ip(map_element_t* average_speed_element, ban_settings_t current_ban_settings); bool exceed_mbps_speed(uint64_t in_counter, uint64_t out_counter, unsigned int threshold_mbps); bool exceed_flow_speed(uint64_t in_counter, uint64_t out_counter, unsigned int threshold); @@ -86,7 +86,7 @@ void store_data_in_redis(std::string key_name, std::string attack_details); redisContext* redis_init_connection(); #endif -void execute_ip_ban(uint32_t client_ip, map_element average_speed_element, std::string flow_attack_details, subnet_t customer_subnet); +void execute_ip_ban(uint32_t client_ip, map_element_t average_speed_element, std::string flow_attack_details, subnet_t customer_subnet); void call_ban_handlers(uint32_t client_ip, attack_details& current_attack, std::string flow_attack_details); #ifdef MONGO diff --git a/src/fastnetmon_types.h b/src/fastnetmon_types.h index 282043fa..8b5e8760 100644 --- a/src/fastnetmon_types.h +++ b/src/fastnetmon_types.h @@ -14,6 +14,8 @@ #include "fastnetmon_simple_packet.h" +#include "map_element.hpp" + typedef std::map configuration_map_t; typedef std::map graphite_data_t; @@ -108,63 +110,21 @@ enum amplification_attack_type_t { AMPLIFICATION_ATTACK_CHARGEN = 6, }; -typedef struct { +class total_counter_element_t { + public: uint64_t bytes; uint64_t packets; uint64_t flows; -} total_counter_element; - -// main data structure for storing traffic and speed data for all our IPs -class map_element { - public: - map_element() - : in_bytes(0), out_bytes(0), in_packets(0), out_packets(0), tcp_in_packets(0), tcp_out_packets(0), - tcp_in_bytes(0), tcp_out_bytes(0), tcp_syn_in_packets(0), tcp_syn_out_packets(0), - tcp_syn_in_bytes(0), tcp_syn_out_bytes(0), udp_in_packets(0), udp_out_packets(0), - udp_in_bytes(0), udp_out_bytes(0), in_flows(0), out_flows(0), fragmented_in_packets(0), - fragmented_out_packets(0), fragmented_in_bytes(0), fragmented_out_bytes(0), - icmp_in_packets(0), icmp_out_packets(0), icmp_in_bytes(0), icmp_out_bytes(0) { - } - uint64_t in_bytes; - uint64_t out_bytes; - uint64_t in_packets; - uint64_t out_packets; - - // Fragmented traffic is so recently used for attacks - uint64_t fragmented_in_packets; - uint64_t fragmented_out_packets; - uint64_t fragmented_in_bytes; - uint64_t fragmented_out_bytes; - - // Additional data for correct attack protocol detection - uint64_t tcp_in_packets; - uint64_t tcp_out_packets; - uint64_t tcp_in_bytes; - uint64_t tcp_out_bytes; - - // Additional details about one of most popular atatck type - uint64_t tcp_syn_in_packets; - uint64_t tcp_syn_out_packets; - uint64_t tcp_syn_in_bytes; - uint64_t tcp_syn_out_bytes; - - uint64_t udp_in_packets; - uint64_t udp_out_packets; - uint64_t udp_in_bytes; - uint64_t udp_out_bytes; - - uint64_t icmp_in_packets; - uint64_t icmp_out_packets; - uint64_t icmp_in_bytes; - uint64_t icmp_out_bytes; - - uint64_t in_flows; - uint64_t out_flows; + void zeroify() { + bytes = 0; + packets = 0; + flows = 0; + } }; // structure with attack details -class attack_details : public map_element { +class attack_details : public map_element_t { public: attack_details() : attack_protocol(0), attack_power(0), max_attack_power(0), average_in_bytes(0), @@ -228,8 +188,8 @@ class conntrack_main_struct { contrack_map_type out_other; }; -typedef std::map map_for_counters; -typedef std::vector vector_of_counters; +typedef std::map map_for_counters; +typedef std::vector vector_of_counters; typedef std::map map_of_vector_counters; @@ -237,7 +197,7 @@ typedef std::map map_of_vector_counters; typedef std::vector vector_of_flow_counters; typedef std::map map_of_vector_counters_for_flow; -typedef map_element subnet_counter_t; +typedef map_element_t subnet_counter_t; typedef std::pair pair_of_map_for_subnet_counters_elements_t; typedef std::map map_for_subnet_counters; @@ -296,6 +256,6 @@ class ban_settings_t { typedef std::map host_group_ban_settings_map_t; // data structure for storing data in Vector -typedef std::pair pair_of_map_elements; +typedef std::pair pair_of_map_elements; #endif diff --git a/src/map_element.hpp b/src/map_element.hpp new file mode 100644 index 00000000..90e15179 --- /dev/null +++ b/src/map_element.hpp @@ -0,0 +1,93 @@ +#include +#include + +// main data structure for storing traffic and speed data for all our IPs +class map_element_t { + public: + map_element_t() + : in_bytes(0), out_bytes(0), in_packets(0), out_packets(0), tcp_in_packets(0), tcp_out_packets(0), + tcp_in_bytes(0), tcp_out_bytes(0), tcp_syn_in_packets(0), tcp_syn_out_packets(0), + tcp_syn_in_bytes(0), tcp_syn_out_bytes(0), udp_in_packets(0), udp_out_packets(0), + udp_in_bytes(0), udp_out_bytes(0), in_flows(0), out_flows(0), fragmented_in_packets(0), + fragmented_out_packets(0), fragmented_in_bytes(0), fragmented_out_bytes(0), + icmp_in_packets(0), icmp_out_packets(0), icmp_in_bytes(0), icmp_out_bytes(0) { + } + uint64_t in_bytes; + uint64_t out_bytes; + uint64_t in_packets; + uint64_t out_packets; + + // Fragmented traffic is so recently used for attacks + uint64_t fragmented_in_packets; + uint64_t fragmented_out_packets; + uint64_t fragmented_in_bytes; + uint64_t fragmented_out_bytes; + + // Additional data for correct attack protocol detection + uint64_t tcp_in_packets; + uint64_t tcp_out_packets; + uint64_t tcp_in_bytes; + uint64_t tcp_out_bytes; + + // Additional details about one of most popular atatck type + uint64_t tcp_syn_in_packets; + uint64_t tcp_syn_out_packets; + uint64_t tcp_syn_in_bytes; + uint64_t tcp_syn_out_bytes; + + uint64_t udp_in_packets; + uint64_t udp_out_packets; + uint64_t udp_in_bytes; + uint64_t udp_out_bytes; + + uint64_t icmp_in_packets; + uint64_t icmp_out_packets; + uint64_t icmp_in_bytes; + uint64_t icmp_out_bytes; + + uint64_t in_flows; + uint64_t out_flows; + + // Is total counters fields are zero? We are not handling per protocol counters here because we assume they should + // be counted twice + // Once: in total counter (in_bytes) and secondly in per protocol counter (for example: udp_in_bytes) + bool is_zero() const { + return in_bytes == 0 && out_bytes == 0 && in_packets == 0 && out_packets == 0 && in_flows == 0 && out_flows == 0; + } + + // Fill all counters by zeros + void zeroify() { + in_bytes = 0; + out_bytes = 0; + in_packets = 0; + out_packets = 0; + + fragmented_in_packets = 0; + fragmented_out_packets = 0; + fragmented_in_bytes = 0; + fragmented_out_bytes = 0; + + tcp_in_packets = 0; + tcp_out_packets = 0; + tcp_in_bytes = 0; + tcp_out_bytes = 0; + + tcp_syn_in_packets = 0; + tcp_syn_out_packets = 0; + tcp_syn_in_bytes = 0; + tcp_syn_out_bytes = 0; + + udp_in_packets = 0; + udp_out_packets = 0; + udp_in_bytes = 0; + udp_out_bytes = 0; + + icmp_in_packets = 0; + icmp_out_packets = 0; + icmp_in_bytes = 0; + icmp_out_bytes = 0; + + in_flows = 0; + out_flows = 0; + } +};