Move common code to library

This commit is contained in:
Pavel Odintsov 2015-03-21 14:24:31 +03:00
parent a49b1b2d5d
commit c52a89e258
8 changed files with 422 additions and 385 deletions

View File

@ -1,6 +1,14 @@
#include <sys/types.h>
#include <stdint.h>
#include "fast_library.h"
#include <arpa/inet.h>
#include <stdlib.h> // atoi
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <netdb.h>
boost::regex regular_expression_cidr_pattern("^\\d+\\.\\d+\\.\\d+\\.\\d+\\/\\d+$");
// convert string to integer
int convert_string_to_integer(std::string line) {
@ -24,3 +32,367 @@ uint16_t fast_hton(uint16_t value) {
uint32_t fast_hton(uint32_t value) {
return htonl(value);
}
uint32_t convert_ip_as_string_to_uint(std::string ip) {
struct in_addr ip_addr;
inet_aton(ip.c_str(), &ip_addr);
// in network byte order
return ip_addr.s_addr;
}
std::string convert_ip_as_uint_to_string(uint32_t ip_as_integer) {
struct in_addr ip_addr;
ip_addr.s_addr = ip_as_integer;
return (std::string)inet_ntoa(ip_addr);
}
// convert integer to string
std::string convert_int_to_string(int value) {
std::stringstream out;
out << value;
return out.str();
}
void copy_networks_from_string_form_to_binary(std::vector<std::string> networks_list_as_string, std::vector<subnet>& our_networks ) {
for( std::vector<std::string>::iterator ii=networks_list_as_string.begin(); ii!=networks_list_as_string.end(); ++ii) {
std::vector<std::string> subnet_as_string;
split( subnet_as_string, *ii, boost::is_any_of("/"), boost::token_compress_on );
unsigned int cidr = convert_string_to_integer(subnet_as_string[1]);
uint32_t subnet_as_int = convert_ip_as_string_to_uint(subnet_as_string[0]);
uint32_t netmask_as_int = convert_cidr_to_binary_netmask(cidr);
subnet current_subnet = std::make_pair(subnet_as_int, netmask_as_int);
our_networks.push_back(current_subnet);
}
}
// extract 24 from 192.168.1.1/24
unsigned int get_cidr_mask_from_network_as_string(std::string network_cidr_format) {
std::vector<std::string> subnet_as_string;
split( subnet_as_string, network_cidr_format, boost::is_any_of("/"), boost::token_compress_on );
if (subnet_as_string.size() != 2) {
return 0;
}
return convert_string_to_integer(subnet_as_string[1]);
}
std::string print_time_t_in_fastnetmon_format(time_t current_time) {
struct tm* timeinfo;
char buffer[80];
timeinfo = localtime (&current_time);
strftime (buffer, sizeof(buffer), "%d_%m_%y_%H:%M:%S", timeinfo);
return std::string(buffer);
}
// extract 192.168.1.1 from 192.168.1.1/24
std::string get_net_address_from_network_as_string(std::string network_cidr_format) {
std::vector<std::string> subnet_as_string;
split( subnet_as_string, network_cidr_format, boost::is_any_of("/"), boost::token_compress_on );
if (subnet_as_string.size() != 2) {
return 0;
}
return subnet_as_string[0];
}
std::string get_printable_protocol_name(unsigned int protocol) {
std::string proto_name;
switch (protocol) {
case IPPROTO_TCP:
proto_name = "tcp";
break;
case IPPROTO_UDP:
proto_name = "udp";
break;
case IPPROTO_ICMP:
proto_name = "icmp";
break;
default:
proto_name = "unknown";
break;
}
return proto_name;
}
uint32_t convert_cidr_to_binary_netmask(unsigned int cidr) {
uint32_t binary_netmask = 0xFFFFFFFF;
binary_netmask = binary_netmask << ( 32 - cidr );
// htonl from host byte order to network
// ntohl from network byte order to host
// We need network byte order at output
return htonl(binary_netmask);
}
bool is_cidr_subnet(const char* subnet) {
boost::cmatch what;
if (regex_match(subnet, what, regular_expression_cidr_pattern)) {
return true;
} else {
return false;
}
}
// check file existence
bool file_exists(std::string path) {
FILE* check_file = fopen(path.c_str(), "r");
if (check_file) {
fclose(check_file);
return true;
} else {
return false;
}
}
bool folder_exists(std::string path) {
if (access(path.c_str(), 0) == 0) {
struct stat status;
stat(path.c_str(), &status);
if (status.st_mode & S_IFDIR) {
return true;
}
}
return false;
}
#define BIG_CONSTANT(x) (x##LLU)
/*
// calculate hash
unsigned int seed = 11;
uint64_t hash = MurmurHash64A(&current_packet, sizeof(current_packet), seed);
*/
// https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash2.cpp
// 64-bit hash for 64-bit platforms
uint64_t MurmurHash64A ( const void * key, int len, uint64_t seed ) {
const uint64_t m = BIG_CONSTANT(0xc6a4a7935bd1e995);
const int r = 47;
uint64_t h = seed ^ (len * m);
const uint64_t * data = (const uint64_t *)key;
const uint64_t * end = data + (len/8);
while(data != end) {
uint64_t k = *data++;
k *= m;
k ^= k >> r;
k *= m;
h ^= k;
h *= m;
}
const unsigned char * data2 = (const unsigned char*)data;
switch(len & 7) {
case 7: h ^= uint64_t(data2[6]) << 48;
case 6: h ^= uint64_t(data2[5]) << 40;
case 5: h ^= uint64_t(data2[4]) << 32;
case 4: h ^= uint64_t(data2[3]) << 24;
case 3: h ^= uint64_t(data2[2]) << 16;
case 2: h ^= uint64_t(data2[1]) << 8;
case 1: h ^= uint64_t(data2[0]);
h *= m;
};
h ^= h >> r;
h *= m;
h ^= h >> r;
return h;
}
// http://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html
int timeval_subtract (struct timeval * result, struct timeval * x, struct timeval * y) {
/* Perform the carry for the later subtraction by updating y. */
if (x->tv_usec < y->tv_usec) {
int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
y->tv_usec -= 1000000 * nsec;
y->tv_sec += nsec;
}
if (x->tv_usec - y->tv_usec > 1000000) {
int nsec = (x->tv_usec - y->tv_usec) / 1000000;
y->tv_usec += 1000000 * nsec;
y->tv_sec -= nsec;
}
/* Compute the time remaining to wait. tv_usec is certainly positive. */
result->tv_sec = x->tv_sec - y->tv_sec;
result->tv_usec = x->tv_usec - y->tv_usec;
/* Return 1 if result is negative. */
return x->tv_sec < y->tv_sec;
}
std::string print_tcp_flags(uint8_t flag_value) {
if (flag_value == 0) {
return "-";
}
// cod from pfring.h
// (tcp->fin * TH_FIN_MULTIPLIER) + (tcp->syn * TH_SYN_MULTIPLIER) +
// (tcp->rst * TH_RST_MULTIPLIER) + (tcp->psh * TH_PUSH_MULTIPLIER) +
// (tcp->ack * TH_ACK_MULTIPLIER) + (tcp->urg * TH_URG_MULTIPLIER);
/*
// Required for decoding tcp flags
#define TH_FIN_MULTIPLIER 0x01
#define TH_SYN_MULTIPLIER 0x02
#define TH_RST_MULTIPLIER 0x04
#define TH_PUSH_MULTIPLIER 0x08
#define TH_ACK_MULTIPLIER 0x10
#define TH_URG_MULTIPLIER 0x20
*/
std::vector<std::string> all_flags;
if (extract_bit_value(flag_value, 1)) {
all_flags.push_back("fin");
}
if (extract_bit_value(flag_value, 2)) {
all_flags.push_back("syn");
}
if (extract_bit_value(flag_value, 3)) {
all_flags.push_back("rst");
}
if (extract_bit_value(flag_value, 4)) {
all_flags.push_back("psh");
}
if (extract_bit_value(flag_value, 5)) {
all_flags.push_back("ack");
}
if (extract_bit_value(flag_value, 6)) {
all_flags.push_back("urg");
}
std::ostringstream flags_as_string;
if (all_flags.empty()) {
return "-";
}
// concatenate all vector elements with comma
std::copy(all_flags.begin(), all_flags.end() - 1, std::ostream_iterator<std::string>(flags_as_string, ","));
// add last element
flags_as_string << all_flags.back();
return flags_as_string.str();
}
// http://stackoverflow.com/questions/14528233/bit-masking-in-c-how-to-get-first-bit-of-a-byte
int extract_bit_value(uint8_t num, int bit) {
if (bit > 0 && bit <= 8) {
return ( (num >> (bit-1)) & 1 );
} else {
return 0;
}
}
std::string print_simple_packet(simple_packet packet) {
std::stringstream buffer;
buffer<<convert_timeval_to_date(packet.ts)<<" ";
buffer
<<convert_ip_as_uint_to_string(packet.src_ip)<<":"<<packet.source_port
<<" > "
<<convert_ip_as_uint_to_string(packet.dst_ip)<<":"<<packet.destination_port
<<" protocol: "<<get_printable_protocol_name(packet.protocol);
// Print flags only for TCP
if (packet.protocol == IPPROTO_TCP) {
buffer<<" flags: "<<print_tcp_flags(packet.flags);
}
buffer<<" ";
buffer<<"packets: " <<packet.number_of_packets <<" ";
buffer<<"size: " <<packet.length <<" bytes ";
buffer<<"sample ratio: "<<packet.sample_ratio <<" ";
buffer<<" \n";
return buffer.str();
}
std::string convert_timeval_to_date(struct timeval tv) {
time_t nowtime = tv.tv_sec;
struct tm *nowtm = localtime(&nowtime);
char tmbuf[64];
char buf[64];
strftime(tmbuf, sizeof(tmbuf), "%Y-%m-%d %H:%M:%S", nowtm);
snprintf(buf, sizeof(buf), "%s.%06ld", tmbuf, tv.tv_usec);
return std::string(buf);
}
uint64_t convert_speed_to_mbps(uint64_t speed_in_bps) {
return uint64_t((double)speed_in_bps / 1024 / 1024 * 8);
}
std::string get_protocol_name_by_number(unsigned int proto_number) {
struct protoent* proto_ent = getprotobynumber( proto_number );
std::string proto_name = proto_ent->p_name;
return proto_name;
}
// exec command in shell
std::vector<std::string> exec(std::string cmd) {
std::vector<std::string> output_list;
FILE* pipe = popen(cmd.c_str(), "r");
if (!pipe) return output_list;
char buffer[256];
while(!feof(pipe)) {
if(fgets(buffer, 256, pipe) != NULL) {
size_t newbuflen = strlen(buffer);
// remove newline at the end
if (buffer[newbuflen - 1] == '\n') {
buffer[newbuflen - 1] = '\0';
}
output_list.push_back(buffer);
}
}
pclose(pipe);
return output_list;
}

View File

@ -1,12 +1,48 @@
#ifndef _FAST_LIBRARY_H
#define _FAST_LIBRARY_H
#include "fastnetmon_types.h"
#include <stdint.h>
#include <sys/types.h>
#include <string>
#include <iostream>
#include <vector>
#include <utility>
#include <sstream>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/regex.hpp>
// Boost libs
#include <boost/algorithm/string.hpp>
std::string get_protocol_name_by_number(unsigned int proto_number);
uint64_t convert_speed_to_mbps(uint64_t speed_in_bps);
std::vector<std::string> exec(std::string cmd);
uint32_t convert_ip_as_string_to_uint(std::string ip);
std::string convert_ip_as_uint_to_string(uint32_t ip_as_integer);
std::string convert_int_to_string(int value);
std::string print_simple_packet(simple_packet packet);
std::string convert_timeval_to_date(struct timeval tv);
int extract_bit_value(uint8_t num, int bit);
std::string print_tcp_flags(uint8_t flag_value);
uint64_t MurmurHash64A ( const void * key, int len, uint64_t seed );
std::string print_tcp_flags(uint8_t flag_value);
int timeval_subtract (struct timeval * result, struct timeval * x, struct timeval * y);
bool folder_exists(std::string path);
bool is_cidr_subnet(const char* subnet);
bool file_exists(std::string path);
uint32_t convert_cidr_to_binary_netmask(unsigned int cidr);
std::string get_printable_protocol_name(unsigned int protocol);
std::string get_net_address_from_network_as_string(std::string network_cidr_format);
std::string print_time_t_in_fastnetmon_format(time_t current_time);
unsigned int get_cidr_mask_from_network_as_string(std::string network_cidr_format);
void copy_networks_from_string_form_to_binary(std::vector<std::string> networks_list_as_string, std::vector<subnet>& our_networks);
int convert_string_to_integer(std::string line);
// Byte order type safe converters
uint16_t fast_ntoh(uint16_t value);
uint32_t fast_ntoh(uint32_t value);
uint16_t fast_hton(uint16_t value);

View File

@ -8,7 +8,6 @@
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <math.h>
#include <sys/socket.h>
@ -21,10 +20,10 @@
#include <netinet/ip_icmp.h>
#include <netinet/if_ether.h>
#include <netinet/in.h>
#include <netdb.h>
#include "libpatricia/patricia.h"
#include "fastnetmon_types.h"
#include "fast_library.h"
// Plugins
#include "sflow_plugin/sflow_collector.h"
@ -79,8 +78,6 @@
std::string global_config_path = "/etc/fastnetmon.conf";
boost::regex regular_expression_cidr_pattern("^\\d+\\.\\d+\\.\\d+\\.\\d+\\/\\d+$");
time_t last_call_of_traffic_recalculation;
// Variable with all data from main screen
@ -200,8 +197,6 @@ uint64_t total_unparsed_packets = 0;
uint64_t incoming_total_flows_speed = 0;
uint64_t outgoing_total_flows_speed = 0;
typedef std::pair<uint32_t, uint32_t> subnet;
// main data structure for storing traffic and speed data for all our IPs
class map_element {
public:
@ -361,42 +356,25 @@ void block_all_traffic_with_82599_hardware_filtering(std::string client_ip_as_st
#endif
bool we_should_ban_this_ip(map_element* current_average_speed_element);
std::string get_net_address_from_network_as_string(std::string network_cidr_format);
unsigned int get_max_used_protocol(uint64_t tcp, uint64_t udp, uint64_t icmp);
std::string get_printable_protocol_name(unsigned int protocol);
void print_attack_details_to_file(std::string details, std::string client_ip_as_string, attack_details current_attack);
bool folder_exists(std::string path);
std::string print_time_t_in_fastnetmon_format(time_t current_time);
std::string print_ban_thresholds();
bool load_configuration_file();
std::string print_flow_tracking_for_ip(conntrack_main_struct& conntrack_element, std::string client_ip);
void convert_integer_to_conntrack_hash_struct(packed_session* packed_connection_data, packed_conntrack_hash* unpacked_data);
uint64_t convert_conntrack_hash_struct_to_integer(packed_conntrack_hash* struct_value);
int timeval_subtract (struct timeval * result, struct timeval * x, struct timeval * y);
bool is_cidr_subnet(const char* subnet);
uint64_t MurmurHash64A (const void * key, int len, uint64_t seed);
void cleanup_ban_list();
std::string print_tcp_flags(uint8_t flag_value);
int extract_bit_value(uint8_t num, int bit);
std::string get_attack_description(uint32_t client_ip, attack_details& current_attack);
uint64_t convert_speed_to_mbps(uint64_t speed_in_bps);
void send_attack_details(uint32_t client_ip, attack_details current_attack_details);
std::string convert_timeval_to_date(struct timeval tv);
void free_up_all_resources();
unsigned int get_cidr_mask_from_network_as_string(std::string network_cidr_format);
std::string print_ddos_attack_details();
void execute_ip_ban(uint32_t client_ip, map_element new_speed_element, map_element current_speed_element, std::string flow_attack_details);
direction get_packet_direction(uint32_t src_ip, uint32_t dst_ip, unsigned long& subnet);
void recalculate_speed();
std::string print_channel_speed(std::string traffic_type, direction packet_direction);
void process_packet(simple_packet& current_packet);
void copy_networks_from_string_form_to_binary(std::vector<std::string> networks_list_as_string, std::vector<subnet>& our_networks);
bool file_exists(std::string path);
void traffic_draw_programm();
void ulog_main_loop();
void signal_handler(int signal_number);
uint32_t convert_cidr_to_binary_netmask(unsigned int cidr);
/* Class for custom comparison fields by different fields */
class TrafficComparatorClass {
@ -454,54 +432,6 @@ std::string get_direction_name(direction direction_value) {
return direction_name;
}
uint32_t convert_ip_as_string_to_uint(std::string ip) {
struct in_addr ip_addr;
inet_aton(ip.c_str(), &ip_addr);
// in network byte order
return ip_addr.s_addr;
}
std::string convert_ip_as_uint_to_string(uint32_t ip_as_integer) {
struct in_addr ip_addr;
ip_addr.s_addr = ip_as_integer;
return (std::string)inet_ntoa(ip_addr);
}
// convert integer to string
std::string convert_int_to_string(int value) {
std::stringstream out;
out << value;
return out.str();
}
// exec command in shell
std::vector<std::string> exec(std::string cmd) {
std::vector<std::string> output_list;
FILE* pipe = popen(cmd.c_str(), "r");
if (!pipe) return output_list;
char buffer[256];
while(!feof(pipe)) {
if(fgets(buffer, 256, pipe) != NULL) {
size_t newbuflen = strlen(buffer);
// remove newline at the end
if (buffer[newbuflen - 1] == '\n') {
buffer[newbuflen - 1] = '\0';
}
output_list.push_back(buffer);
}
}
pclose(pipe);
return output_list;
}
// exec command and pass data to it stdin
bool exec_with_stdin_params(std::string cmd, std::string params) {
FILE* pipe = popen(cmd.c_str(), "w");
@ -672,17 +602,7 @@ std::string draw_table(map_for_counters& my_map_packets, direction data_directio
return output_buffer.str();
}
// check file existence
bool file_exists(std::string path) {
FILE* check_file = fopen(path.c_str(), "r");
if (check_file) {
fclose(check_file);
return true;
} else {
return false;
}
}
// TODO: move to lirbary
// read whole file to vector
std::vector<std::string> read_file_to_vector(std::string file_name) {
std::vector<std::string> data;
@ -1055,102 +975,6 @@ bool load_our_networks_list() {
return true;
}
// extract 24 from 192.168.1.1/24
unsigned int get_cidr_mask_from_network_as_string(std::string network_cidr_format) {
std::vector<std::string> subnet_as_string;
split( subnet_as_string, network_cidr_format, boost::is_any_of("/"), boost::token_compress_on );
if (subnet_as_string.size() != 2) {
return 0;
}
return convert_string_to_integer(subnet_as_string[1]);
}
// extract 192.168.1.1 from 192.168.1.1/24
std::string get_net_address_from_network_as_string(std::string network_cidr_format) {
std::vector<std::string> subnet_as_string;
split( subnet_as_string, network_cidr_format, boost::is_any_of("/"), boost::token_compress_on );
if (subnet_as_string.size() != 2) {
return 0;
}
return subnet_as_string[0];
}
void copy_networks_from_string_form_to_binary(std::vector<std::string> networks_list_as_string, std::vector<subnet>& our_networks ) {
for( std::vector<std::string>::iterator ii=networks_list_as_string.begin(); ii!=networks_list_as_string.end(); ++ii) {
std::vector<std::string> subnet_as_string;
split( subnet_as_string, *ii, boost::is_any_of("/"), boost::token_compress_on );
unsigned int cidr = convert_string_to_integer(subnet_as_string[1]);
uint32_t subnet_as_int = convert_ip_as_string_to_uint(subnet_as_string[0]);
uint32_t netmask_as_int = convert_cidr_to_binary_netmask(cidr);
subnet current_subnet = std::make_pair(subnet_as_int, netmask_as_int);
our_networks.push_back(current_subnet);
}
}
uint32_t convert_cidr_to_binary_netmask(unsigned int cidr) {
uint32_t binary_netmask = 0xFFFFFFFF;
binary_netmask = binary_netmask << ( 32 - cidr );
// htonl from host byte order to network
// ntohl from network byte order to host
// We need network byte order at output
return htonl(binary_netmask);
}
std::string get_printable_protocol_name(unsigned int protocol) {
std::string proto_name;
switch (protocol) {
case IPPROTO_TCP:
proto_name = "tcp";
break;
case IPPROTO_UDP:
proto_name = "udp";
break;
case IPPROTO_ICMP:
proto_name = "icmp";
break;
default:
proto_name = "unknown";
break;
}
return proto_name;
}
std::string print_simple_packet(simple_packet packet) {
std::stringstream buffer;
buffer<<convert_timeval_to_date(packet.ts)<<" ";
buffer
<<convert_ip_as_uint_to_string(packet.src_ip)<<":"<<packet.source_port
<<" > "
<<convert_ip_as_uint_to_string(packet.dst_ip)<<":"<<packet.destination_port
<<" protocol: "<<get_printable_protocol_name(packet.protocol);
// Print flags only for TCP
if (packet.protocol == IPPROTO_TCP) {
buffer<<" flags: "<<print_tcp_flags(packet.flags);
}
buffer<<" ";
buffer<<"packets: " <<packet.number_of_packets <<" ";
buffer<<"size: " <<packet.length <<" bytes ";
buffer<<"sample ratio: "<<packet.sample_ratio <<" ";
buffer<<" \n";
return buffer.str();
}
/* Process simple unified packet */
void process_packet(simple_packet& current_packet) {
// Packets dump is very useful for bug hunting
@ -1718,10 +1542,6 @@ std::string print_channel_speed(std::string traffic_type, direction packet_direc
return stream.str();
}
uint64_t convert_speed_to_mbps(uint64_t speed_in_bps) {
return uint64_t((double)speed_in_bps / 1024 / 1024 * 8);
}
void init_logging() {
log4cpp::PatternLayout* layout = new log4cpp::PatternLayout();
layout->setConversionPattern ("%d [%p] %m%n");
@ -1734,19 +1554,6 @@ void init_logging() {
logger.info("Logger initialized!");
}
bool folder_exists(std::string path) {
if (access(path.c_str(), 0) == 0) {
struct stat status;
stat(path.c_str(), &status);
if (status.st_mode & S_IFDIR) {
return true;
}
}
return false;
}
int main(int argc,char **argv) {
lookup_tree = New_Patricia(32);
whitelist_tree = New_Patricia(32);
@ -2244,17 +2051,6 @@ void cleanup_ban_list() {
}
}
std::string print_time_t_in_fastnetmon_format(time_t current_time) {
struct tm* timeinfo;
char buffer[80];
timeinfo = localtime (&current_time);
strftime (buffer, sizeof(buffer), "%d_%m_%y_%H:%M:%S", timeinfo);
return std::string(buffer);
}
std::string print_ddos_attack_details() {
std::stringstream output_buffer;
@ -2317,12 +2113,6 @@ std::string get_attack_description(uint32_t client_ip, attack_details& current_a
return attack_description.str();
}
std::string get_protocol_name_by_number(unsigned int proto_number) {
struct protoent* proto_ent = getprotobynumber( proto_number );
std::string proto_name = proto_ent->p_name;
return proto_name;
}
void send_attack_details(uint32_t client_ip, attack_details current_attack_details) {
std::string pps_as_string = convert_int_to_string(current_attack_details.attack_power);
std::string attack_direction = get_direction_name(current_attack_details.attack_direction);
@ -2370,177 +2160,6 @@ void send_attack_details(uint32_t client_ip, attack_details current_attack_detai
}
}
std::string convert_timeval_to_date(struct timeval tv) {
time_t nowtime = tv.tv_sec;
struct tm *nowtm = localtime(&nowtime);
char tmbuf[64];
char buf[64];
strftime(tmbuf, sizeof(tmbuf), "%Y-%m-%d %H:%M:%S", nowtm);
snprintf(buf, sizeof(buf), "%s.%06ld", tmbuf, tv.tv_usec);
return std::string(buf);
}
// http://stackoverflow.com/questions/14528233/bit-masking-in-c-how-to-get-first-bit-of-a-byte
int extract_bit_value(uint8_t num, int bit) {
if (bit > 0 && bit <= 8) {
return ( (num >> (bit-1)) & 1 );
} else {
return 0;
}
}
std::string print_tcp_flags(uint8_t flag_value) {
if (flag_value == 0) {
return "-";
}
// cod from pfring.h
// (tcp->fin * TH_FIN_MULTIPLIER) + (tcp->syn * TH_SYN_MULTIPLIER) +
// (tcp->rst * TH_RST_MULTIPLIER) + (tcp->psh * TH_PUSH_MULTIPLIER) +
// (tcp->ack * TH_ACK_MULTIPLIER) + (tcp->urg * TH_URG_MULTIPLIER);
/*
// Required for decoding tcp flags
#define TH_FIN_MULTIPLIER 0x01
#define TH_SYN_MULTIPLIER 0x02
#define TH_RST_MULTIPLIER 0x04
#define TH_PUSH_MULTIPLIER 0x08
#define TH_ACK_MULTIPLIER 0x10
#define TH_URG_MULTIPLIER 0x20
*/
std::vector<std::string> all_flags;
if (extract_bit_value(flag_value, 1)) {
all_flags.push_back("fin");
}
if (extract_bit_value(flag_value, 2)) {
all_flags.push_back("syn");
}
if (extract_bit_value(flag_value, 3)) {
all_flags.push_back("rst");
}
if (extract_bit_value(flag_value, 4)) {
all_flags.push_back("psh");
}
if (extract_bit_value(flag_value, 5)) {
all_flags.push_back("ack");
}
if (extract_bit_value(flag_value, 6)) {
all_flags.push_back("urg");
}
std::ostringstream flags_as_string;
if (all_flags.empty()) {
return "-";
}
// concatenate all vector elements with comma
std::copy(all_flags.begin(), all_flags.end() - 1, std::ostream_iterator<std::string>(flags_as_string, ","));
// add last element
flags_as_string << all_flags.back();
return flags_as_string.str();
}
#define BIG_CONSTANT(x) (x##LLU)
/*
// calculate hash
unsigned int seed = 11;
uint64_t hash = MurmurHash64A(&current_packet, sizeof(current_packet), seed);
*/
// https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash2.cpp
// 64-bit hash for 64-bit platforms
uint64_t MurmurHash64A ( const void * key, int len, uint64_t seed ) {
const uint64_t m = BIG_CONSTANT(0xc6a4a7935bd1e995);
const int r = 47;
uint64_t h = seed ^ (len * m);
const uint64_t * data = (const uint64_t *)key;
const uint64_t * end = data + (len/8);
while(data != end) {
uint64_t k = *data++;
k *= m;
k ^= k >> r;
k *= m;
h ^= k;
h *= m;
}
const unsigned char * data2 = (const unsigned char*)data;
switch(len & 7) {
case 7: h ^= uint64_t(data2[6]) << 48;
case 6: h ^= uint64_t(data2[5]) << 40;
case 5: h ^= uint64_t(data2[4]) << 32;
case 4: h ^= uint64_t(data2[3]) << 24;
case 3: h ^= uint64_t(data2[2]) << 16;
case 2: h ^= uint64_t(data2[1]) << 8;
case 1: h ^= uint64_t(data2[0]);
h *= m;
};
h ^= h >> r;
h *= m;
h ^= h >> r;
return h;
}
bool is_cidr_subnet(const char* subnet) {
boost::cmatch what;
if (regex_match(subnet, what, regular_expression_cidr_pattern)) {
return true;
} else {
return false;
}
}
// http://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html
int timeval_subtract (struct timeval * result, struct timeval * x, struct timeval * y) {
/* Perform the carry for the later subtraction by updating y. */
if (x->tv_usec < y->tv_usec) {
int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
y->tv_usec -= 1000000 * nsec;
y->tv_sec += nsec;
}
if (x->tv_usec - y->tv_usec > 1000000) {
int nsec = (x->tv_usec - y->tv_usec) / 1000000;
y->tv_usec += 1000000 * nsec;
y->tv_sec -= nsec;
}
/* Compute the time remaining to wait. tv_usec is certainly positive. */
result->tv_sec = x->tv_sec - y->tv_sec;
result->tv_usec = x->tv_usec - y->tv_usec;
/* Return 1 if result is negative. */
return x->tv_sec < y->tv_sec;
}
uint64_t convert_conntrack_hash_struct_to_integer(packed_conntrack_hash* struct_value) {
uint64_t unpacked_data = 0;
memcpy(&unpacked_data, struct_value, sizeof(uint64_t));

View File

@ -1,6 +1,9 @@
#ifndef _FASTNETMON_TYPES_H
#define _FASTNETMON_TYPES_H
#include <utility> // std::pair
#include <stdint.h> // uint32_t
// simplified packet struct for lightweight save into memory
class simple_packet {
public:
@ -20,8 +23,7 @@ public:
struct timeval ts;
};
typedef std::pair<uint32_t, uint32_t> subnet;
typedef void (*process_packet_pointer)(simple_packet&);
#include "fast_library.h"
#endif

View File

@ -13,6 +13,8 @@
#include <vector>
#include <map>
#include "../fast_library.h"
// log4cpp logging facility
#include "log4cpp/Category.hh"
#include "log4cpp/Appender.hh"

View File

@ -10,6 +10,8 @@
#include <boost/algorithm/string.hpp>
#include "../fast_library.h"
// For support uint32_t, uint16_t
#include <sys/types.h>

View File

@ -8,6 +8,8 @@
#include "log4cpp/PatternLayout.hh"
#include "log4cpp/Priority.hh"
#include "../fast_library.h"
// For support uint32_t, uint16_t
#include <sys/types.h>

View File

@ -7,6 +7,8 @@
// sflowtool-3.32
#include "sflow.h"
#include "../fast_library.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>