// 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]); }
subnet_t convert_subnet_from_string_to_binary_with_cidr_format(std::string subnet_cidr) { std::vector<std::string> subnet_as_string; split(subnet_as_string, subnet_cidr, 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]); return std::make_pair(subnet_as_int, cidr); }
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); } }
void start_netflow_collection(process_packet_pointer func_ptr) { logger<< log4cpp::Priority::INFO<<"netflow plugin started"; netflow_process_func_ptr = func_ptr; // By default we listen on IPv4 std::string netflow_host = "0.0.0.0"; if (configuration_map.count("netflow_port") != 0) { netflow_port = convert_string_to_integer(configuration_map["netflow_port"]); } if (configuration_map.count("netflow_host") != 0) { netflow_host = configuration_map["netflow_host"]; } if (configuration_map.count("netflow_sampling_ratio") != 0) { sampling_rate = convert_string_to_integer(configuration_map["netflow_sampling_ratio"]); logger<< log4cpp::Priority::INFO<<"We use custom sampling ratio for netflow: "<<sampling_rate; } logger<< log4cpp::Priority::INFO<<"netflow plugin will listen on "<<netflow_host<<":"<<netflow_port<< " udp port"; unsigned int udp_buffer_size = 65536; char udp_buffer[udp_buffer_size]; struct addrinfo hints; memset(&hints, 0, sizeof hints); // Could be AF_INET6 or AF_INET hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; // This flag will generate wildcard IP address if we not specified certain IP address for binding hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; struct addrinfo *servinfo = NULL; const char* address_for_binding = NULL; if (!netflow_host.empty()) { address_for_binding = netflow_host.c_str(); } char port_as_string[16]; sprintf(port_as_string, "%d", netflow_port); int getaddrinfo_result = getaddrinfo(address_for_binding, port_as_string, &hints, &servinfo); if (getaddrinfo_result != 0) { logger<< log4cpp::Priority::ERROR<<"Netflow getaddrinfo function failed with code: "<<getaddrinfo_result<<" please check netflow_host"; exit(1); } int sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol); int bind_result = bind(sockfd, servinfo->ai_addr, servinfo->ai_addrlen); if (bind_result) { logger<< log4cpp::Priority::ERROR<<"Can't listen port: "<<netflow_port<<" on host "<<netflow_host<<" errno:"<<errno<< " error: "<<strerror(errno); return; } struct sockaddr_in6 peer; memset(&peer, 0, sizeof(peer)); for (;;) { // This approach provide ability to store both IPv4 and IPv6 client's addresses struct sockaddr_storage client_address; // It's MUST memset(&client_address, 0, sizeof(struct sockaddr_storage)); socklen_t address_len = sizeof(struct sockaddr_storage); int received_bytes = recvfrom(sockfd, udp_buffer, udp_buffer_size, 0, (struct sockaddr *)&client_address, &address_len); if (received_bytes > 0) { // Pass host and port as numbers without any conversion int getnameinfo_flags = NI_NUMERICSERV | NI_NUMERICHOST; char host[NI_MAXHOST]; char service[NI_MAXSERV]; int result = getnameinfo((struct sockaddr *) &client_address, address_len, host, NI_MAXHOST, service, NI_MAXSERV, getnameinfo_flags); // We sill store client's IP address as string for allowing IPv4 and IPv6 processing in same time std::string client_addres_in_string_format = std::string(host); // logger<< log4cpp::Priority::INFO<<"We receive packet from IP: "<<client_addres_in_string_format; // printf("We receive %d\n", received_bytes); process_netflow_packet((u_int8_t*)udp_buffer, received_bytes, client_addres_in_string_format); } else { logger<< log4cpp::Priority::ERROR<<"netflow data receive failed"; } } freeaddrinfo(servinfo); }
// #include <sys/prctl.h> void start_netflow_collection(process_packet_pointer func_ptr) { logger << log4cpp::Priority::INFO << "netflow plugin started"; #ifdef ENABLE_LUA_HOOKS if (lua_hooks_enabled) { netflow_lua_state = init_lua_jit(lua_hooks_path); if (netflow_lua_state == NULL) { lua_hooks_enabled = false; } } #endif // prctl(PR_SET_NAME,"fastnetmon_netflow", 0, 0, 0); netflow_process_func_ptr = func_ptr; // By default we listen on IPv4 std::string netflow_host = "0.0.0.0"; std::string netflow_ports = ""; if (configuration_map.count("netflow_port") != 0) { netflow_ports = configuration_map["netflow_port"]; } if (configuration_map.count("netflow_host") != 0) { netflow_host = configuration_map["netflow_host"]; } if (configuration_map.count("netflow_sampling_ratio") != 0) { sampling_rate = convert_string_to_integer(configuration_map["netflow_sampling_ratio"]); logger << log4cpp::Priority::INFO << "Using custom sampling ratio for netflow: " << sampling_rate; } if (configuration_map.count("netflow_divide_counters_on_interval_length") != 0) { netflow_divide_counters_on_interval_length = configuration_map["netflow_divide_counters_on_interval_length"] == "on" ? true : false; } #ifdef ENABLE_LUA_HOOKS if (configuration_map.count("netflow_lua_hooks_path") != 0) { lua_hooks_path = configuration_map["netflow_lua_hooks_path"]; lua_hooks_enabled = true; } #endif boost::thread_group netflow_collector_threads; std::vector<std::string> ports_for_listen; boost::split(ports_for_listen, netflow_ports, boost::is_any_of(","), boost::token_compress_on); logger << log4cpp::Priority::INFO << netflow_plugin_log_prefix << "We will listen on " << ports_for_listen.size() << " ports"; for (std::vector<std::string>::iterator port = ports_for_listen.begin(); port != ports_for_listen.end(); ++port) { unsigned int netflow_port = convert_string_to_integer(*port); if (netflow_port == 0) { netflow_port = 2055; } netflow_collector_threads.add_thread( new boost::thread(start_netflow_collector, netflow_host, convert_string_to_integer(*port) )); } netflow_collector_threads.join_all(); }
// #include <sys/prctl.h> void start_netflow_collection(process_packet_pointer func_ptr) { logger << log4cpp::Priority::INFO << "netflow plugin started"; #ifdef ENABLE_LUA_HOOKS init_lua_jit(); #endif // prctl(PR_SET_NAME,"fastnetmon_netflow", 0, 0, 0); netflow_process_func_ptr = func_ptr; // By default we listen on IPv4 std::string netflow_host = "0.0.0.0"; if (configuration_map.count("netflow_port") != 0) { netflow_port = convert_string_to_integer(configuration_map["netflow_port"]); } if (configuration_map.count("netflow_host") != 0) { netflow_host = configuration_map["netflow_host"]; } if (configuration_map.count("netflow_sampling_ratio") != 0) { sampling_rate = convert_string_to_integer(configuration_map["netflow_sampling_ratio"]); logger << log4cpp::Priority::INFO << "We use custom sampling ratio for netflow: " << sampling_rate; } if (configuration_map.count("netflow_divide_counters_on_interval_length") != 0) { netflow_divide_counters_on_interval_length = configuration_map["netflow_divide_counters_on_interval_length"] == "on" ? true : false; } #ifdef ENABLE_LUA_HOOKS if (configuration_map.count("netflow_lua_hooks_path") != 0) { lua_hooks_path = configuration_map["netflow_lua_hooks_path"]; } #endif logger << log4cpp::Priority::INFO << "netflow plugin will listen on " << netflow_host << ":" << netflow_port << " udp port"; unsigned int udp_buffer_size = 65536; char udp_buffer[udp_buffer_size]; struct addrinfo hints; memset(&hints, 0, sizeof hints); // Could be AF_INET6 or AF_INET hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; // This flag will generate wildcard IP address if we not specified certain IP address for // binding hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; struct addrinfo* servinfo = NULL; const char* address_for_binding = NULL; if (!netflow_host.empty()) { address_for_binding = netflow_host.c_str(); } char port_as_string[16]; sprintf(port_as_string, "%d", netflow_port); int getaddrinfo_result = getaddrinfo(address_for_binding, port_as_string, &hints, &servinfo); if (getaddrinfo_result != 0) { logger << log4cpp::Priority::ERROR << "Netflow getaddrinfo function failed with code: " << getaddrinfo_result << " please check netflow_host"; exit(1); } int sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol); int bind_result = bind(sockfd, servinfo->ai_addr, servinfo->ai_addrlen); if (bind_result) { logger << log4cpp::Priority::ERROR << "Can't listen port: " << netflow_port << " on host " << netflow_host << " errno:" << errno << " error: " << strerror(errno); return; } struct sockaddr_in6 peer; memset(&peer, 0, sizeof(peer)); /* We should specify timeout there for correct toolkit shutdown */ /* Because otherwise recvfrom will stay in blocked mode forever */ struct timeval tv; tv.tv_sec = 5; /* X Secs Timeout */ tv.tv_usec = 0; // Not init'ing this can cause strange errors setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)); while (true) { // This approach provide ability to store both IPv4 and IPv6 client's addresses struct sockaddr_storage client_address; // It's MUST memset(&client_address, 0, sizeof(struct sockaddr_storage)); socklen_t address_len = sizeof(struct sockaddr_storage); int received_bytes = recvfrom(sockfd, udp_buffer, udp_buffer_size, 0, (struct sockaddr*)&client_address, &address_len); if (received_bytes > 0) { // Pass host and port as numbers without any conversion int getnameinfo_flags = NI_NUMERICSERV | NI_NUMERICHOST; char host[NI_MAXHOST]; char service[NI_MAXSERV]; int result = getnameinfo((struct sockaddr*)&client_address, address_len, host, NI_MAXHOST, service, NI_MAXSERV, getnameinfo_flags); // We sill store client's IP address as string for allowing IPv4 and IPv6 processing in // same time std::string client_addres_in_string_format = std::string(host); // logger<< log4cpp::Priority::INFO<<"We receive packet from IP: // "<<client_addres_in_string_format; // printf("We receive %d\n", received_bytes); process_netflow_packet((u_int8_t*)udp_buffer, received_bytes, client_addres_in_string_format); } else { if (received_bytes == -1) { if (errno == EAGAIN) { // We got timeout, it's OK! } else { logger << log4cpp::Priority::ERROR << "netflow data receive failed"; } } } // Add interruption point for correct application shutdown boost::this_thread::interruption_point(); } freeaddrinfo(servinfo); }