Added option sflow_read_packet_length_from_ip_header to use packet length from header instead of sFlow field. Closes #893

This commit is contained in:
Pavel Odintsov 2020-12-13 13:40:39 +00:00
parent 7b091457a1
commit ebee5b2a08
3 changed files with 27 additions and 16 deletions

@ -161,6 +161,10 @@ sflow_port = 6343
# sflow_port = 6343,6344
sflow_host = 0.0.0.0
# Some vendors may lie about full packet length in sFlow packet. To avoid this issue we can switch to using IP packet length from parsed header
sflow_read_packet_length_from_ip_header = off
###
### Actions when attack detected
###

@ -33,6 +33,10 @@ extern std::map<std::string, std::string> configuration_map;
// Number of raw packets received without any errors
uint64_t raw_udp_packets_received = 0;
// We have an option to use IP length from the packet header because some vendors may lie about it: https://github.com/pavel-odintsov/fastnetmon/issues/893
bool sflow_read_packet_length_from_ip_header = false;
// Number of failed receives
uint64_t udp_receive_errors = 0;
@ -112,12 +116,12 @@ void start_sflow_collection(process_packet_pointer func_ptr) {
for (auto port_string: sflow_ports_for_listen) {
unsigned int sflow_port = convert_string_to_integer(port_string);
if (sflow_port == 0) {
logger << log4cpp::Priority::ERROR << plugin_log_prefix << "Cannot parse port: " << port_string;
if (sflow_port == 0) {
logger << log4cpp::Priority::ERROR << plugin_log_prefix << "Cannot parse port: " << port_string;
continue;
}
}
sflow_ports.push_back(sflow_port);
sflow_ports.push_back(sflow_port);
}
if (sflow_ports.size() == 0) {
@ -139,6 +143,11 @@ void start_sflow_collection(process_packet_pointer func_ptr) {
sflow_host = configuration_map["sflow_host"];
}
if (configuration_map.count("sflow_read_packet_length_from_ip_header") != 0) {
sflow_read_packet_length_from_ip_header =
configuration_map["sflow_read_packet_length_from_ip_header"] == "on";
}
for (auto sflow_port: sflow_ports) {
sflow_collector_threads.add_thread(
new boost::thread(start_sflow_collector, sflow_host, sflow_port));
@ -297,21 +306,19 @@ bool process_sflow_flow_sample(uint8_t* data_pointer,
uint8_t* header_payload_pointer = payload_ptr + sizeof(sflow_raw_protocol_header_t);
bool use_packet_length_from_wire = true;
// We could enable this new parser for testing purposes
auto result = parse_raw_packet_to_simple_packet_full_ng(header_payload_pointer,
// We could enable this new parser for testing purposes
auto result = parse_raw_packet_to_simple_packet_full_ng(header_payload_pointer,
sflow_raw_protocol_header.frame_length_before_sampling,
sflow_raw_protocol_header.header_size, packet,
use_packet_length_from_wire);
sflow_read_packet_length_from_ip_header);
if (result != network_data_stuctures::parser_code_t::success) {
sflow_parse_error_nested_header++;
if (result != network_data_stuctures::parser_code_t::success) {
sflow_parse_error_nested_header++;
logger << log4cpp::Priority::DEBUG << plugin_log_prefix
<< "Cannot parse nested packet using ng parser: " << parser_code_to_string(result);
logger << log4cpp::Priority::DEBUG << plugin_log_prefix
<< "Cannot parse nested packet using ng parser: " << parser_code_to_string(result);
return false;
return false;
}
// Pass pointer to raw header to FastNetMon processing functions

@ -85,9 +85,9 @@ parser_code_t parse_raw_packet_to_simple_packet_full_ng(uint8_t* pointer,
packet.protocol = protocol;
if (use_packet_length_from_wire) {
packet.length = length_before_sampling;
} else {
packet.length = ipv4_header->total_length;
} else {
packet.length = length_before_sampling;
}
// Ignore all IP options and shift pointer to L3 payload