1
0
mirror of https://github.com/pavel-odintsov/fastnetmon synced 2024-11-23 00:52:00 +01:00

Added decoding of the outer vlan tag in sflow packets. (#736)

* Added decoding of the outer vlan tag in sFlow packets for QnQ
This commit is contained in:
Dmitriy Limonov 2018-09-28 18:59:49 +03:00 committed by Pavel Odintsov
parent 64ef4bd012
commit f527101e62
6 changed files with 56 additions and 1 deletions

@ -1284,3 +1284,12 @@ bool store_data_to_stats_server(unsigned short int graphite_port, std::string gr
return false;
}
}
bool convert_hex_as_string_to_uint(std::string hex, uint32_t& value) {
std::stringstream ss;
ss << std::hex << hex;
ss >> value;
return ss.fail();
}

@ -53,6 +53,7 @@ std::string convert_int_to_string(int value);
std::string print_ipv6_address(struct in6_addr& ipv6_address);
std::string print_simple_packet(simple_packet packet);
std::string convert_timeval_to_date(struct timeval tv);
bool convert_hex_as_string_to_uint(std::string hex, uint32_t& value);
int extract_bit_value(uint8_t num, int bit);
int extract_bit_value(uint16_t num, int bit);

@ -165,6 +165,12 @@ sflow_host = 0.0.0.0
# This option is not default and you need build it additionally
# sflow_lua_hooks_path = /usr/src/fastnetmon/src/sflow_hooks.lua
# sFlow processing QinQ
sflow_qinq_process = off
# sFlow ethertype of outer tag in QinQ
sflow_qinq_ethertype = 0x8100
###
### Actions when attack detected
###

@ -123,6 +123,7 @@ typedef struct _SFSample {
uint8_t eth_dst[8];
/* vlan */
uint32_t in_outer_vlan;
uint32_t in_vlan;
uint32_t in_priority;
uint32_t internalPriority;

@ -41,6 +41,12 @@ bool sflow_lua_hooks_enabled = false;
std::string sflow_lua_hooks_path = "/usr/src/fastnetmon/src/sflow_hooks.lua";
#endif
// Ethertype of outer tag in QinQ
uint32_t sflow_qinq_ethertype = 0x8100;
// Disable QinQ processing by default
bool sflow_qinq_process = false;
// sFLOW v4 specification: http://www.sflow.org/rfc3176.txt
std::string plugin_name = "sflow";
@ -86,6 +92,24 @@ void start_sflow_collection(process_packet_pointer func_ptr) {
interface_for_binding = configuration_map["sflow_host"];
}
if (configuration_map.count("sflow_qinq_process") != 0) {
if (configuration_map["sflow_qinq_process"] == "on") {
sflow_qinq_process = true;
logger << log4cpp::Priority::INFO << plugin_log_prefix << "qinq processing enabled";
if (configuration_map.count("sflow_qinq_ethertype") != 0) {
if (convert_hex_as_string_to_uint(configuration_map["sflow_qinq_ethertype"], sflow_qinq_ethertype)) {
logger << log4cpp::Priority::WARN << plugin_log_prefix
<< "can't parse value in sflow_qinq_ethertype variable";
logger << log4cpp::Priority::INFO << plugin_log_prefix
<< "disable qinq processing";
sflow_qinq_process = false;
}
}
}
}
#ifdef ENABLE_LUA_HOOKS
if (configuration_map.count("sflow_lua_hooks_path") != 0) {
sflow_lua_hooks_path = configuration_map["sflow_lua_hooks_path"];
@ -535,8 +559,21 @@ void decode_link_layer(SFSample* sample) {
type_len = (ptr[0] << 8) + ptr[1];
ptr += 2;
if (sflow_qinq_process && type_len == sflow_qinq_ethertype && ((ptr[2] << 8) + ptr[3]) == 0x8100) {
/* Outer VLAN tag - next two bytes */
uint32_t vlanData = (ptr[0] << 8) + ptr[1];
uint32_t vlan = vlanData & 0x0fff;
uint32_t priority = vlanData >> 13;
ptr += 2;
sample->in_outer_vlan = vlan;
/* now get the type_len again (next two bytes) */
type_len = (ptr[0] << 8) + ptr[1];
ptr += 2;
}
if (type_len == 0x8100) {
/* VLAN - next two bytes */
/* Inner VLAN tag - next two bytes */
uint32_t vlanData = (ptr[0] << 8) + ptr[1];
uint32_t vlan = vlanData & 0x0fff;
uint32_t priority = vlanData >> 13;

@ -151,6 +151,7 @@ typedef struct _SFSample {
uint8_t eth_dst[8];
/* vlan */
uint32_t in_outer_vlan;
uint32_t in_vlan;
uint32_t in_priority;
uint32_t internalPriority;