mirror of
https://github.com/pavel-odintsov/fastnetmon
synced 2024-11-23 17:32:59 +01:00
BGP Flow Spec RFC 5575 support have added
This commit is contained in:
parent
4d6a9f142c
commit
b13bc1e667
@ -36,6 +36,7 @@ Supported packet capture engines:
|
|||||||
You could look [comparison table](https://github.com/FastVPSEestiOu/fastnetmon/blob/master/docs/CAPTURE_BACKENDS.md) for all available packet capture engines.
|
You could look [comparison table](https://github.com/FastVPSEestiOu/fastnetmon/blob/master/docs/CAPTURE_BACKENDS.md) for all available packet capture engines.
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
- Complete [BGP Flow Spec support](docs/BGP_FLOW_SPEC.md), RFC 5575
|
||||||
- Can process incoming and outgoing traffic
|
- Can process incoming and outgoing traffic
|
||||||
- Can trigger block script if certain IP loads network with a large amount of packets/bytes/flows per second
|
- Can trigger block script if certain IP loads network with a large amount of packets/bytes/flows per second
|
||||||
- Thresholds could be configured in per subnet basis with hostgroups feature
|
- Thresholds could be configured in per subnet basis with hostgroups feature
|
||||||
|
@ -6,7 +6,7 @@ cd /usr/src/
|
|||||||
git clone git clone https://github.com/Exa-Networks/exabgp.git
|
git clone git clone https://github.com/Exa-Networks/exabgp.git
|
||||||
```
|
```
|
||||||
|
|
||||||
Thay are not compatible with ExaBGP 3.0
|
They are not compatible with ExaBGP 3.0
|
||||||
|
|
||||||
vim /root/announcer.py:
|
vim /root/announcer.py:
|
||||||
|
|
||||||
@ -52,3 +52,35 @@ Run it:
|
|||||||
cd /usr/src/exabgp
|
cd /usr/src/exabgp
|
||||||
env exabgp.api.file=/tmp/exabgp.cmd exabgp.daemon.user=root exabgp.daemon.daemonize=false exabgp.daemon.pid=/var/run/exabgp.pid exabgp.log.destination=/var/log/exabgp.log sbin/exabgp --debug /etc/exabgp_flowspec.conf
|
env exabgp.api.file=/tmp/exabgp.cmd exabgp.daemon.user=root exabgp.daemon.daemonize=false exabgp.daemon.pid=/var/run/exabgp.pid exabgp.log.destination=/var/log/exabgp.log sbin/exabgp --debug /etc/exabgp_flowspec.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Then, please install Git version of FastNetMon (stable version do not support this features yet):
|
||||||
|
```bash
|
||||||
|
wget https://raw.githubusercontent.com/FastVPSEestiOu/fastnetmon/master/src/fastnetmon_install.pl -Ofastnetmon_install.pl
|
||||||
|
sudo perl fastnetmon_install.pl --use-git-master
|
||||||
|
```
|
||||||
|
|
||||||
|
FastNetMon configuration /etc/fastnetmon.conf:
|
||||||
|
```bash
|
||||||
|
# This options are mandatory for Flow Spec attack detector
|
||||||
|
collect_attack_pcap_dumps = on
|
||||||
|
process_pcap_attack_dumps_with_dpi = on
|
||||||
|
|
||||||
|
exabgp = on
|
||||||
|
exabgp_command_pipe = /var/run/exabgp.cmd
|
||||||
|
exabgp_community = 65001:666
|
||||||
|
exabgp_next_hop = 10.0.3.114
|
||||||
|
|
||||||
|
exabgp_flow_spec_announces = on
|
||||||
|
|
||||||
|
# Please switch off unicast BGP announces with ExaBGP because they are not compatible with Flow Spec
|
||||||
|
exabgp_announce_whole_subnet = no
|
||||||
|
exabgp_announce_host = no
|
||||||
|
```
|
||||||
|
|
||||||
|
Be aware! We will announce rules with discard option!
|
||||||
|
|
||||||
|
Currently we support only most popular amplification attack types:
|
||||||
|
- DNS amplification (we drop all udp traffic originating from 53 port)
|
||||||
|
- NTP amplification (we drop all udp traffic originating from 123 port)
|
||||||
|
- SSDP amplification (we drop all udp traffic originating from 1900 port)
|
||||||
|
- SNMP amplification (we drop all udp traffic originating from 161 port)
|
||||||
|
@ -162,10 +162,11 @@ exabgp_announce_host = on
|
|||||||
# Announce origin subnet of IP address instead IP itself
|
# Announce origin subnet of IP address instead IP itself
|
||||||
exabgp_announce_whole_subnet = no
|
exabgp_announce_whole_subnet = no
|
||||||
|
|
||||||
# TODO: is not implemented yet!
|
|
||||||
# Announce Flow Spec rules when we could detect certain attack type
|
# Announce Flow Spec rules when we could detect certain attack type
|
||||||
# Please we aware! Flow Spec announce triggered when we collect some details about attack,
|
# Please we aware! Flow Spec announce triggered when we collect some details about attack,
|
||||||
# i.e. when we call attack_details script
|
# i.e. when we call attack_details script
|
||||||
|
# Please disable exabgp_announce_host and exabgp_announce_whole_subnet if you want this feature
|
||||||
|
# Please use ExaBGP v4 only (Git version), for more details: https://github.com/FastVPSEestiOu/fastnetmon/blob/master/docs/BGP_FLOW_SPEC.md
|
||||||
exabgp_flow_spec_announces = no
|
exabgp_flow_spec_announces = no
|
||||||
|
|
||||||
# Graphite monitoring
|
# Graphite monitoring
|
||||||
|
@ -236,6 +236,10 @@ unsigned int number_of_packets_for_pcap_attack_dump = 500;
|
|||||||
// log file
|
// log file
|
||||||
log4cpp::Category& logger = log4cpp::Category::getRoot();
|
log4cpp::Category& logger = log4cpp::Category::getRoot();
|
||||||
|
|
||||||
|
// We storae all active BGP Flow Spec announces here
|
||||||
|
typedef std::map<std::string, uint32_t> active_flow_spec_announces_t;
|
||||||
|
active_flow_spec_announces_t active_flow_spec_announces;
|
||||||
|
|
||||||
/* Configuration block ends */
|
/* Configuration block ends */
|
||||||
|
|
||||||
// We count total number of incoming/outgoing/internal and other traffic type packets/bytes
|
// We count total number of incoming/outgoing/internal and other traffic type packets/bytes
|
||||||
@ -332,6 +336,8 @@ void init_current_instance_of_ndpi();
|
|||||||
void block_all_traffic_with_82599_hardware_filtering(std::string client_ip_as_string);
|
void block_all_traffic_with_82599_hardware_filtering(std::string client_ip_as_string);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
std::string generate_flow_spec_for_amplification_attack(amplification_attack_type_t amplification_attack_type, std::string destination_ip);
|
||||||
|
bool exabgp_flow_spec_ban_manage(std::string action, std::string flow_spec_rule_as_text);
|
||||||
void call_attack_details_handlers(uint32_t client_ip, attack_details& current_attack, std::string attack_fingerprint);
|
void call_attack_details_handlers(uint32_t client_ip, attack_details& current_attack, std::string attack_fingerprint);
|
||||||
void call_ban_handlers(uint32_t client_ip, attack_details& current_attack, std::string flow_attack_details);
|
void call_ban_handlers(uint32_t client_ip, attack_details& current_attack, std::string flow_attack_details);
|
||||||
void call_unban_handlers(uint32_t client_ip, attack_details& current_attack);
|
void call_unban_handlers(uint32_t client_ip, attack_details& current_attack);
|
||||||
@ -2439,6 +2445,36 @@ void exabgp_prefix_ban_manage(std::string action, std::string prefix_as_string_w
|
|||||||
close(exabgp_pipe);
|
close(exabgp_pipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool exabgp_flow_spec_ban_manage(std::string action, std::string flow_spec_rule_as_text) {
|
||||||
|
std::string announce_action;
|
||||||
|
|
||||||
|
if (action == "ban") {
|
||||||
|
announce_action = "announce";
|
||||||
|
} else {
|
||||||
|
announce_action = "withdraw";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trailing \n is very important!
|
||||||
|
std::string bgp_message = announce_action + " " + flow_spec_rule_as_text + "\n";
|
||||||
|
|
||||||
|
int exabgp_pipe = open(exabgp_command_pipe.c_str(), O_WRONLY);
|
||||||
|
|
||||||
|
if (exabgp_pipe <= 0) {
|
||||||
|
logger << log4cpp::Priority::ERROR << "Can't open ExaBGP pipe for flow spec announce " << exabgp_command_pipe;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wrote_bytes = write(exabgp_pipe, bgp_message.c_str(), bgp_message.size());
|
||||||
|
|
||||||
|
if (wrote_bytes != bgp_message.size()) {
|
||||||
|
logger << log4cpp::Priority::ERROR << "Can't write message to ExaBGP pipe";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(exabgp_pipe);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void execute_ip_ban(uint32_t client_ip, map_element speed_element, map_element average_speed_element, std::string flow_attack_details, subnet_t customer_subnet) {
|
void execute_ip_ban(uint32_t client_ip, map_element speed_element, map_element average_speed_element, std::string flow_attack_details, subnet_t customer_subnet) {
|
||||||
struct attack_details current_attack;
|
struct attack_details current_attack;
|
||||||
uint64_t pps = 0;
|
uint64_t pps = 0;
|
||||||
@ -3043,7 +3079,8 @@ void send_attack_details(uint32_t client_ip, attack_details current_attack_detai
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_DPI
|
#ifdef ENABLE_DPI
|
||||||
void dpi_parse_packet(char* buffer, uint32_t len, std::stringstream& ss) {
|
// Parse raw binary stand-alone packet with nDPI
|
||||||
|
ndpi_protocol dpi_parse_packet(char* buffer, uint32_t len, struct ndpi_id_struct *src, struct ndpi_id_struct *dst, struct ndpi_flow_struct *flow, std::string parsed_packet_as_string) {
|
||||||
struct pfring_pkthdr packet_header;
|
struct pfring_pkthdr packet_header;
|
||||||
memset(&packet_header, 0, sizeof(packet_header));
|
memset(&packet_header, 0, sizeof(packet_header));
|
||||||
packet_header.len = len;
|
packet_header.len = len;
|
||||||
@ -3051,10 +3088,6 @@ void dpi_parse_packet(char* buffer, uint32_t len, std::stringstream& ss) {
|
|||||||
|
|
||||||
fastnetmon_parse_pkt((u_char*)buffer, &packet_header, 4, 1, 0);
|
fastnetmon_parse_pkt((u_char*)buffer, &packet_header, 4, 1, 0);
|
||||||
|
|
||||||
struct ndpi_id_struct *src = NULL;
|
|
||||||
struct ndpi_id_struct *dst = NULL;
|
|
||||||
struct ndpi_flow_struct *flow = NULL;
|
|
||||||
|
|
||||||
src = (struct ndpi_id_struct*)malloc(ndpi_size_id_struct);
|
src = (struct ndpi_id_struct*)malloc(ndpi_size_id_struct);
|
||||||
memset(src, 0, ndpi_size_id_struct);
|
memset(src, 0, ndpi_size_id_struct);
|
||||||
|
|
||||||
@ -3070,16 +3103,13 @@ void dpi_parse_packet(char* buffer, uint32_t len, std::stringstream& ss) {
|
|||||||
|
|
||||||
ndpi_protocol detected_protocol = ndpi_detection_process_packet(my_ndpi_struct, flow, iph, ipsize, current_tickt, src, dst);
|
ndpi_protocol detected_protocol = ndpi_detection_process_packet(my_ndpi_struct, flow, iph, ipsize, current_tickt, src, dst);
|
||||||
|
|
||||||
char* protocol_name = ndpi_get_proto_name(my_ndpi_struct, detected_protocol.protocol);
|
// So bad approach :(
|
||||||
char* master_protocol_name = ndpi_get_proto_name(my_ndpi_struct, detected_protocol.master_protocol);
|
|
||||||
|
|
||||||
char print_buffer[512];
|
char print_buffer[512];
|
||||||
fastnetmon_print_parsed_pkt(print_buffer, 512, (u_char*)buffer, &packet_header);
|
fastnetmon_print_parsed_pkt(print_buffer, 512, (u_char*)buffer, &packet_header);
|
||||||
ss << print_buffer << " protocol: " << protocol_name << " master_protocol: " << master_protocol_name << "\n";
|
|
||||||
|
|
||||||
ndpi_free_flow(flow);
|
parsed_packet_as_string = std::string(print_buffer);
|
||||||
free(dst);
|
|
||||||
free(src);
|
return detected_protocol;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -3101,7 +3131,7 @@ void init_current_instance_of_ndpi() {
|
|||||||
|
|
||||||
// Not so pretty copy and paste from pcap_reader()
|
// Not so pretty copy and paste from pcap_reader()
|
||||||
// TODO: rewrite to memory parser
|
// TODO: rewrite to memory parser
|
||||||
void produce_dpi_dump_for_pcap_dump(std::string pcap_file_path, std::stringstream& ss) {
|
void produce_dpi_dump_for_pcap_dump(std::string pcap_file_path, std::stringstream& ss, std::string client_ip_as_string) {
|
||||||
int filedesc = open(pcap_file_path.c_str(), O_RDONLY);
|
int filedesc = open(pcap_file_path.c_str(), O_RDONLY);
|
||||||
|
|
||||||
if (filedesc <= 0) {
|
if (filedesc <= 0) {
|
||||||
@ -3128,9 +3158,14 @@ void produce_dpi_dump_for_pcap_dump(std::string pcap_file_path, std::stringstrea
|
|||||||
// Buffer for packets
|
// Buffer for packets
|
||||||
char packet_buffer[pcap_header.snaplen];
|
char packet_buffer[pcap_header.snaplen];
|
||||||
|
|
||||||
unsigned int read_packets = 0;
|
unsigned int total_packets_number = 0;
|
||||||
|
|
||||||
|
uint64_t dns_amplification_packets = 0;
|
||||||
|
uint64_t ntp_amplification_packets = 0;
|
||||||
|
uint64_t ssdp_amplification_packets = 0;
|
||||||
|
uint64_t snmp_amplification_packets = 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
// printf("Start packet %d processing\n", read_packets);
|
|
||||||
struct fastnetmon_pcap_pkthdr pcap_packet_header;
|
struct fastnetmon_pcap_pkthdr pcap_packet_header;
|
||||||
ssize_t packet_header_readed_bytes =
|
ssize_t packet_header_readed_bytes =
|
||||||
read(filedesc, &pcap_packet_header, sizeof(struct fastnetmon_pcap_pkthdr));
|
read(filedesc, &pcap_packet_header, sizeof(struct fastnetmon_pcap_pkthdr));
|
||||||
@ -3152,7 +3187,91 @@ void produce_dpi_dump_for_pcap_dump(std::string pcap_file_path, std::stringstrea
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dpi_parse_packet(packet_buffer, pcap_packet_header.incl_len, ss);
|
struct ndpi_id_struct *src = NULL;
|
||||||
|
struct ndpi_id_struct *dst = NULL;
|
||||||
|
struct ndpi_flow_struct *flow = NULL;
|
||||||
|
|
||||||
|
src = (struct ndpi_id_struct*)malloc(ndpi_size_id_struct);
|
||||||
|
memset(src, 0, ndpi_size_id_struct);
|
||||||
|
|
||||||
|
dst = (struct ndpi_id_struct*)malloc(ndpi_size_id_struct);
|
||||||
|
memset(dst, 0, ndpi_size_id_struct);
|
||||||
|
|
||||||
|
flow = (struct ndpi_flow_struct *)malloc(ndpi_size_flow_struct);
|
||||||
|
memset(flow, 0, ndpi_size_flow_struct);
|
||||||
|
|
||||||
|
std::string parsed_packet_as_string;
|
||||||
|
|
||||||
|
ndpi_protocol detected_protocol = dpi_parse_packet(packet_buffer, pcap_packet_header.incl_len, src, dst, flow, parsed_packet_as_string);
|
||||||
|
|
||||||
|
char* protocol_name = ndpi_get_proto_name(my_ndpi_struct, detected_protocol.protocol);
|
||||||
|
char* master_protocol_name = ndpi_get_proto_name(my_ndpi_struct, detected_protocol.master_protocol);
|
||||||
|
|
||||||
|
if (detected_protocol.protocol == NDPI_PROTOCOL_DNS) {
|
||||||
|
// It's answer for ANY request with so much
|
||||||
|
if (flow->protos.dns.query_type == 255 && flow->protos.dns.num_queries < flow->protos.dns.num_answers) {
|
||||||
|
dns_amplification_packets++;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (detected_protocol.protocol == NDPI_PROTOCOL_NTP) {
|
||||||
|
// Detect packets with type MON_GETLIST_1
|
||||||
|
if (flow->protos.ntp.version == 2 && flow->protos.ntp.request_code == 42) {
|
||||||
|
ntp_amplification_packets++;
|
||||||
|
}
|
||||||
|
} else if (detected_protocol.protocol == NDPI_PROTOCOL_SSDP) {
|
||||||
|
// So, this protocol completely unexpected in WAN networks
|
||||||
|
ssdp_amplification_packets++;
|
||||||
|
} else if (detected_protocol.protocol == NDPI_PROTOCOL_SNMP) {
|
||||||
|
// TODO: we need detailed tests for SNMP!
|
||||||
|
snmp_amplification_packets++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ss << parsed_packet_as_string << " protocol: " << protocol_name << " master_protocol: " << master_protocol_name << "\n";
|
||||||
|
|
||||||
|
// Free up all memory
|
||||||
|
ndpi_free_flow(flow);
|
||||||
|
free(dst);
|
||||||
|
free(src);
|
||||||
|
|
||||||
|
total_packets_number++;
|
||||||
|
}
|
||||||
|
|
||||||
|
amplification_attack_type_t attack_type;
|
||||||
|
|
||||||
|
// Detect amplification attack type
|
||||||
|
if ( (double)dns_amplification_packets / (double)total_packets_number > 0.5) {
|
||||||
|
attack_type = AMPLIFICATION_ATTACK_DNS;
|
||||||
|
} else if ( (double)ntp_amplification_packets / (double)total_packets_number > 0.5) {
|
||||||
|
attack_type = AMPLIFICATION_ATTACK_NTP;
|
||||||
|
} else if ( (double)ssdp_amplification_packets / (double)total_packets_number > 0.5) {
|
||||||
|
attack_type = AMPLIFICATION_ATTACK_SSDP;
|
||||||
|
} else if ( (double)snmp_amplification_packets / (double)total_packets_number > 0.5) {
|
||||||
|
attack_type = AMPLIFICATION_ATTACK_SNMP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attack_type == AMPLIFICATION_ATTACK_UNKNOWN) {
|
||||||
|
logger << log4cpp::Priority::ERROR << "We can't detect attack type with DPI it's not so criticial, only for your information";
|
||||||
|
} else {
|
||||||
|
std::string flow_spec_rule_text = generate_flow_spec_for_amplification_attack(attack_type, client_ip_as_string);
|
||||||
|
|
||||||
|
logger << log4cpp::Priority::INFO << "We have generated BGP Flow Spec rule for this attack: " << flow_spec_rule_text;
|
||||||
|
|
||||||
|
if (exabgp_flow_spec_announces) {
|
||||||
|
active_flow_spec_announces_t::iterator itr = active_flow_spec_announces.find(flow_spec_rule_text);
|
||||||
|
|
||||||
|
if (itr == active_flow_spec_announces.end()) {
|
||||||
|
// We havent this flow spec rule active yet
|
||||||
|
|
||||||
|
logger << log4cpp::Priority::INFO << "We will publish flow spec announce about this attack";
|
||||||
|
bool exabgp_publish_result = exabgp_flow_spec_ban_manage("ban", flow_spec_rule_text);
|
||||||
|
|
||||||
|
if (exabgp_publish_result) {
|
||||||
|
active_flow_spec_announces[ flow_spec_rule_text ] = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We have already blocked this attack
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3193,7 +3312,7 @@ void call_attack_details_handlers(uint32_t client_ip, attack_details& current_at
|
|||||||
|
|
||||||
string_buffer_for_dpi_data << "\n\nDPI\n\n";
|
string_buffer_for_dpi_data << "\n\nDPI\n\n";
|
||||||
|
|
||||||
produce_dpi_dump_for_pcap_dump(attack_pcap_dump_path, string_buffer_for_dpi_data);
|
produce_dpi_dump_for_pcap_dump(attack_pcap_dump_path, string_buffer_for_dpi_data, client_ip_as_string);
|
||||||
|
|
||||||
attack_fingerprint = attack_fingerprint + string_buffer_for_dpi_data.str();
|
attack_fingerprint = attack_fingerprint + string_buffer_for_dpi_data.str();
|
||||||
}
|
}
|
||||||
@ -3588,3 +3707,32 @@ std::string get_printable_attack_name(attack_type_t attack) {
|
|||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string generate_flow_spec_for_amplification_attack(amplification_attack_type_t amplification_attack_type, std::string destination_ip) {
|
||||||
|
exabgp_flow_spec_rule_t exabgp_rule;
|
||||||
|
|
||||||
|
bgp_flow_spec_action_t my_action;
|
||||||
|
|
||||||
|
// We drop all traffic by default
|
||||||
|
my_action.set_type(FLOW_SPEC_ACTION_DISCARD);
|
||||||
|
|
||||||
|
// TODO: rewrite!
|
||||||
|
exabgp_rule.set_destination_subnet( convert_subnet_from_string_to_binary_with_cidr_format( destination_ip + "/32") );
|
||||||
|
|
||||||
|
// We use only UDP here
|
||||||
|
exabgp_rule.add_protocol(FLOW_SPEC_PROTOCOL_UDP);
|
||||||
|
|
||||||
|
if (amplification_attack_type == AMPLIFICATION_ATTACK_DNS) {
|
||||||
|
exabgp_rule.add_source_port(53);
|
||||||
|
} else if (amplification_attack_type == AMPLIFICATION_ATTACK_NTP) {
|
||||||
|
exabgp_rule.add_source_port(123);
|
||||||
|
} else if (amplification_attack_type == AMPLIFICATION_ATTACK_SSDP) {
|
||||||
|
exabgp_rule.add_source_port(1900);
|
||||||
|
} else if (amplification_attack_type == AMPLIFICATION_ATTACK_SNMP) {
|
||||||
|
exabgp_rule.add_source_port(161);
|
||||||
|
} else if (amplification_attack_type == AMPLIFICATION_ATTACK_CHARGEN) {
|
||||||
|
exabgp_rule.add_source_port(19);
|
||||||
|
}
|
||||||
|
|
||||||
|
return exabgp_rule.serialize_single_line_exabgp_v4_configuration();
|
||||||
|
}
|
||||||
|
@ -66,6 +66,16 @@ enum attack_type_t {
|
|||||||
ATTACK_IP_FRAGMENTATION_FLOOD = 5,
|
ATTACK_IP_FRAGMENTATION_FLOOD = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Amplification types
|
||||||
|
enum amplification_attack_type_t {
|
||||||
|
AMPLIFICATION_ATTACK_UNKNOWN = 1,
|
||||||
|
AMPLIFICATION_ATTACK_DNS = 2,
|
||||||
|
AMPLIFICATION_ATTACK_NTP = 3,
|
||||||
|
AMPLIFICATION_ATTACK_SSDP = 4,
|
||||||
|
AMPLIFICATION_ATTACK_SNMP = 5,
|
||||||
|
AMPLIFICATION_ATTACK_CHARGEN = 6,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint64_t bytes;
|
uint64_t bytes;
|
||||||
uint64_t packets;
|
uint64_t packets;
|
||||||
|
Loading…
Reference in New Issue
Block a user