Implemented logic to properly track internal traffic for incoming and outgoing directions

This commit is contained in:
Pavel Odintsov 2020-09-26 20:40:28 +01:00
parent 23efd99d27
commit 7abcdbf8ee
5 changed files with 120 additions and 27 deletions

@ -93,7 +93,7 @@ set(FASTNETMON_PROFILER OFF)
set(FASTNETMON_PROFILE_FLAGS "-g -pg")
# set(CMAKE_BUILD_TYPE DEBUG)
set(CMAKE_BUILD_TYPE DEBUG)
if (NOT CMAKE_BUILD_TYPE)
message(STATUS "Setting build type to Release as none was specified.")

@ -769,11 +769,18 @@ direction get_packet_direction_ipv6(patricia_tree_t* lookup_tree, struct in6_add
}
/* Get traffic type: check it belongs to our IPs */
/* It populates subnet and subnet_cidr_mask for incoming and outgoing traffic */
/* But for internal traffic it populates destination_subnet* and source_subnet* */
direction get_packet_direction(patricia_tree_t* lookup_tree,
uint32_t src_ip,
uint32_t dst_ip,
unsigned long& subnet,
unsigned int& subnet_cidr_mask) {
unsigned int& subnet_cidr_mask,
unsigned long& destination_subnet,
unsigned int& destination_subnet_cidr_mask,
unsigned long& source_subnet,
unsigned int& source_subnet_cidr_mask
) {
direction packet_direction;
bool our_ip_is_destination = false;
@ -786,8 +793,6 @@ direction get_packet_direction(patricia_tree_t* lookup_tree,
patricia_node_t* found_patrica_node = NULL;
prefix_for_check_adreess.add.sin.s_addr = dst_ip;
unsigned long destination_subnet = 0;
unsigned int destination_subnet_cidr_mask = 0;
found_patrica_node = patricia_search_best2(lookup_tree, &prefix_for_check_adreess, 1);
if (found_patrica_node) {
@ -799,8 +804,6 @@ direction get_packet_direction(patricia_tree_t* lookup_tree,
found_patrica_node = NULL;
prefix_for_check_adreess.add.sin.s_addr = src_ip;
unsigned long source_subnet = 0;
unsigned int source_subnet_cidr_mask = 0;
found_patrica_node = patricia_search_best2(lookup_tree, &prefix_for_check_adreess, 1);
if (found_patrica_node) {

@ -86,7 +86,11 @@ direction get_packet_direction(patricia_tree_t* lookup_tree,
uint32_t src_ip,
uint32_t dst_ip,
unsigned long& subnet,
unsigned int& subnet_cidr_mask);
unsigned int& subnet_cidr_mask,
unsigned long& destination_subnet,
unsigned int& destination_subnet_cidr_mask,
unsigned long& source_subnet,
unsigned int& source_subnet_cidr_mas);
direction get_packet_direction_ipv6(patricia_tree_t* lookup_tree, struct in6_addr src_ipv6, struct in6_addr dst_ipv6);

27
src/fast_platform.h Normal file

@ -0,0 +1,27 @@
#ifndef FAST_PLATFORM_H
#define FAST_PLATFORM_H
// This file automatically generated for your platform (Linux, FreeBSD and others) with cmake
/* Platform specific paths */
std::string fastnetmon_version = "1.1.8 master git-23efd99d277a4e3161c3e6c510ad010e6e436842";
std::string pid_path = "/var/run/fastnetmon.pid";
std::string global_config_path = "/etc/fastnetmon.conf";
std::string log_file_path = "/var/log/fastnetmon.log";
std::string attack_details_folder = "/var/log/fastnetmon_attacks";
// Default path to notify script
std::string notify_script_path = "/usr/local/bin/notify_about_attack.sh";
// Default path to file with networks for whitelising
std::string white_list_path = "/etc/networks_whitelist";
// Default path to file with all networks listing
std::string networks_list_path = "/etc/networks_list";
/* Platform specific paths end */
#endif

@ -1808,8 +1808,17 @@ void process_packet(simple_packet_t& current_packet) {
unsigned long subnet = 0;
unsigned int subnet_cidr_mask = 0;
// We use these variables to track subnets for internal traffic because we have two of them
unsigned long destination_subnet_host = 0;
unsigned int destination_subnet_cidr_mask = 0;
unsigned long source_subnet_host = 0;
unsigned int source_subnet_cidr_mask = 0;
direction packet_direction = get_packet_direction(lookup_tree_ipv4, current_packet.src_ip,
current_packet.dst_ip, subnet, subnet_cidr_mask);
current_packet.dst_ip, subnet, subnet_cidr_mask,
destination_subnet_host, destination_subnet_cidr_mask,
source_subnet_host, source_subnet_cidr_mask);
// It's useful in case when we can't find what packets do not processed correctly
if (DEBUG_DUMP_OTHER_PACKETS && packet_direction == OTHER) {
@ -1824,27 +1833,14 @@ void process_packet(simple_packet_t& current_packet) {
subnet_t current_subnet = std::make_pair(subnet, subnet_cidr_mask);
uint32_t subnet_in_host_byte_order = 0;
// We operate in host bytes order and need to convert subnet
if (subnet != 0) {
subnet_in_host_byte_order = ntohl(current_subnet.first);
}
// Try to find map key for this subnet
map_of_vector_counters::iterator itr;
// We will use them for INTERNAL traffic type
subnet_t source_subnet = std::make_pair(source_subnet_host, source_subnet_cidr_mask);
subnet_t destination_subnet = std::make_pair(destination_subnet_host, destination_subnet_cidr_mask);
// Iterator for subnet counter
subnet_counter_t* subnet_counter = NULL;
if (packet_direction == OUTGOING or packet_direction == INCOMING) {
// Find element in map of vectors
itr = SubnetVectorMap.find(current_subnet);
if (itr == SubnetVectorMap.end()) {
logger << log4cpp::Priority::ERROR << "Can't find vector address in subnet map";
return;
}
if (enable_subnet_counters) {
map_for_subnet_counters::iterator subnet_iterator;
@ -1891,8 +1887,39 @@ void process_packet(simple_packet_t& current_packet) {
__sync_fetch_and_add(&total_counters[packet_direction].bytes, sampled_number_of_bytes);
#endif
// Incerement main and per protocol packet counters
// Increment main and per protocol packet counters
// Below we will implement different logic according to packet direction
// We cannot use if / else if / else in this case because same conditions may trigger twice
// For internal traffic type we trigger incoming and outgoing processing paths in same time
if (packet_direction == OUTGOING or (process_internal_traffic_as_external && packet_direction == INTERNAL)) {
uint32_t subnet_in_host_byte_order = 0;
// Try to find map key for this subnet
map_of_vector_counters::iterator itr;
if (packet_direction == OUTGOING) {
// We operate in host bytes order and need to convert subnet
if (subnet != 0) {
subnet_in_host_byte_order = ntohl(current_subnet.first);
}
// Find element in map of vectors
itr = SubnetVectorMap.find(current_subnet);
}
// In this case we need to use another subnet
if (packet_direction == INTERNAL) {
subnet_in_host_byte_order = ntohl(source_subnet.first);
// Lookup another subnet in this case
itr = SubnetVectorMap.find(source_subnet);
}
if (itr == SubnetVectorMap.end()) {
logger << log4cpp::Priority::ERROR << "Can't find vector address in subnet map";
return;
}
int64_t shift_in_vector = (int64_t)ntohl(current_packet.src_ip) - (int64_t)subnet_in_host_byte_order;
if (shift_in_vector < 0 or shift_in_vector >= itr->second.size()) {
@ -2032,8 +2059,38 @@ void process_packet(simple_packet_t& current_packet) {
// no flow tracking for icmp
} else {
}
}
if (packet_direction == INCOMING or (process_internal_traffic_as_external && packet_direction == INTERNAL)) {
uint32_t subnet_in_host_byte_order = 0;
// Try to find map key for this subnet
map_of_vector_counters::iterator itr;
if (packet_direction == INCOMING) {
// We operate in host bytes order and need to convert subnet
if (subnet != 0) {
subnet_in_host_byte_order = ntohl(current_subnet.first);
}
// Find element in map of vectors
itr = SubnetVectorMap.find(current_subnet);
}
// In this case we need to use another subnet
if (packet_direction == INTERNAL) {
subnet_in_host_byte_order = ntohl(destination_subnet.first);
// Lookup destination subnet in this case
itr = SubnetVectorMap.find(destination_subnet);
}
if (itr == SubnetVectorMap.end()) {
logger << log4cpp::Priority::ERROR << "Can't find vector address in subnet map";
return;
}
} else if (packet_direction == INCOMING or (process_internal_traffic_as_external && packet_direction == INTERNAL)) {
int64_t shift_in_vector = (int64_t)ntohl(current_packet.dst_ip) - (int64_t)subnet_in_host_byte_order;
if (shift_in_vector < 0 or shift_in_vector >= itr->second.size()) {
@ -2173,7 +2230,9 @@ void process_packet(simple_packet_t& current_packet) {
// TBD
}
} else if (packet_direction == INTERNAL) {
}
if (packet_direction == INTERNAL) {
}
}