2014-07-28 Ramon Novoa <rnovoa@artica.es>
* conf/pandora_server.conf.new, lib/PandoraFMS/Config.pm: Added configuration tokens to disable the translation of enterprise strings and variable bindings (SNMP console). * lib/PandoraFMS/SNMPServer.pm: Added thread support to the SNMP console. * lib/PandoraFMS/DB.pm: Fixed a warning. git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@10359 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
parent
a271695ba8
commit
d91a102537
|
@ -1,3 +1,13 @@
|
|||
2014-07-28 Ramon Novoa <rnovoa@artica.es>
|
||||
|
||||
* conf/pandora_server.conf.new,
|
||||
lib/PandoraFMS/Config.pm: Added configuration tokens to disable the
|
||||
translation of enterprise strings and variable bindings (SNMP console).
|
||||
|
||||
* lib/PandoraFMS/SNMPServer.pm: Added thread support to the SNMP console.
|
||||
|
||||
* lib/PandoraFMS/DB.pm: Fixed a warning.
|
||||
|
||||
2014-07-25 Miguel de Dios <miguel.dedios@artica.es>
|
||||
|
||||
* lib/PandoraFMS/GIS.pm, lib/PandoraFMS/DB.pm,
|
||||
|
|
|
@ -86,6 +86,18 @@ master 1
|
|||
|
||||
snmpconsole 0
|
||||
|
||||
# snmpconsole_threads: number of SNMP console threads for processing SNMP traps.
|
||||
|
||||
snmpconsole_threads 1
|
||||
|
||||
# Attempt to translate variable bindings when processing SNMP traps. 1 enabled, 0 disabled. 0 by default. (ENTERPRISE ONLY).
|
||||
|
||||
translate_variable_bindings 0
|
||||
|
||||
# Attempt to translate enterprise strings when processing SNMP traps. 1 enabled, 0 disabled. 1 by default. (ENTERPRISE ONLY).
|
||||
|
||||
translate_enterprise_strings 0
|
||||
|
||||
# snmptrapd will ignore authenticationFailure traps if set to 1.
|
||||
|
||||
snmp_ignore_authfailure 1
|
||||
|
|
|
@ -248,6 +248,9 @@ sub pandora_load_config {
|
|||
$pa_config->{"snmp_pdu_address"} = 0; # 5.0
|
||||
$pa_config->{"snmp_storm_protection"} = 0; # 5.0
|
||||
$pa_config->{"snmp_storm_timeout"} = 600; # 5.0
|
||||
$pa_config->{"snmpconsole_threads"} = 1; # 5.1
|
||||
$pa_config->{"translate_variable_bindings"} = 0; # 5.1
|
||||
$pa_config->{"translate_enterprise_strings"} = 1; # 5.1
|
||||
|
||||
# Internal MTA for alerts, each server need its own config.
|
||||
$pa_config->{"mta_address"} = '127.0.0.1'; # Introduced on 2.0
|
||||
|
@ -465,6 +468,15 @@ sub pandora_load_config {
|
|||
elsif ($parametro =~ m/^snmp_storm_timeout\s+(\d+)/i) {
|
||||
$pa_config->{'snmp_storm_timeout'}= clean_blank($1);
|
||||
}
|
||||
elsif ($parametro =~ m/^snmpconsole_threads\s+(\d+)/i) {
|
||||
$pa_config->{'snmpconsole_threads'}= clean_blank($1);
|
||||
}
|
||||
elsif ($parametro =~ m/^translate_variable_bindings\s+([0-1])/i) {
|
||||
$pa_config->{'translate_variable_bindings'}= clean_blank($1);
|
||||
}
|
||||
elsif ($parametro =~ m/^translate_enterprise_strings\s+([0-1])/i) {
|
||||
$pa_config->{'translate_enterprise_strings'}= clean_blank($1);
|
||||
}
|
||||
elsif ($parametro =~ m/^dbengine\s(.*)/i) {
|
||||
$pa_config->{'dbengine'}= clean_blank($1);
|
||||
}
|
||||
|
|
|
@ -884,9 +884,8 @@ sub get_alert_template_name ($$) {
|
|||
sub db_concat ($$) {
|
||||
my ($element1, $element2) = @_;
|
||||
|
||||
return " concat(" . $element1 . ", ' '," . $element2 . ") " if ($RDBMS eq 'mysql');
|
||||
|
||||
return " " . $element1 . " || ' ' || " . $element2 . " " if ($RDBMS eq 'oracle' or $RDBMS eq 'postgresql');
|
||||
return " concat(" . $element1 . ", ' '," . $element2 . ") ";
|
||||
}
|
||||
|
||||
########################################################################
|
||||
|
|
|
@ -25,6 +25,7 @@ use threads::shared;
|
|||
use Thread::Semaphore;
|
||||
|
||||
use Time::Local;
|
||||
use Time::HiRes qw(usleep);
|
||||
use XML::Simple;
|
||||
|
||||
# Default lib dir for RPM and DEB packages
|
||||
|
@ -33,21 +34,27 @@ use lib '/usr/lib/perl5';
|
|||
use PandoraFMS::Tools;
|
||||
use PandoraFMS::DB;
|
||||
use PandoraFMS::Core;
|
||||
use PandoraFMS::Server;
|
||||
use PandoraFMS::ProducerConsumerServer;
|
||||
|
||||
# Inherits from PandoraFMS::Server
|
||||
our @ISA = qw(PandoraFMS::Server);
|
||||
# Inherits from PandoraFMS::ProducerConsumerServer
|
||||
our @ISA = qw(PandoraFMS::ProducerConsumerServer);
|
||||
|
||||
# Tells the server to keep running
|
||||
my $RUN :shared;
|
||||
# Global variables
|
||||
my @TaskQueue :shared;
|
||||
my %PendingTasks :shared;
|
||||
my $Sem :shared;
|
||||
my $TaskSem :shared;
|
||||
|
||||
# Trap statistics by agent
|
||||
my %AGENTS = ();
|
||||
|
||||
# Index file management
|
||||
my ($IDX_FILE, $LAST_LINE, $LAST_SIZE) = ();
|
||||
|
||||
########################################################################################
|
||||
# SNMP Server class constructor.
|
||||
########################################################################################
|
||||
sub new ($$;$) {
|
||||
sub new ($$$) {
|
||||
my ($class, $config, $dbh) = @_;
|
||||
|
||||
return undef unless $config->{'snmpconsole'} == 1;
|
||||
|
@ -57,15 +64,46 @@ sub new ($$;$) {
|
|||
return undef;
|
||||
}
|
||||
|
||||
# Wait for the SNMP log file to be available
|
||||
my $log_file = $config->{'snmp_logfile'};
|
||||
sleep ($config->{'server_threshold'}) if (! -e $log_file);
|
||||
if (!open (SNMPLOGFILE, $log_file)) {
|
||||
logger ($config, ' [E] Could not open the SNMP log file ' . $config->{'snmp_logfile'} . ".", 1);
|
||||
print_message ($config, ' [E] Could not open the SNMP log file ' . $config->{'snmp_logfile'} . ".", 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Process index file, if available
|
||||
($IDX_FILE, $LAST_LINE, $LAST_SIZE) = ($log_file . '.index', 0, 0);
|
||||
if (-e $IDX_FILE) {
|
||||
open (INDEXFILE, $IDX_FILE) or return;
|
||||
my $idx_data = <INDEXFILE>;
|
||||
close INDEXFILE;
|
||||
($LAST_LINE, $LAST_SIZE) = split(/\s+/, $idx_data);
|
||||
}
|
||||
my $log_size = (stat ($log_file))[7];
|
||||
|
||||
# New SNMP log file found
|
||||
if ($log_size < $LAST_SIZE) {
|
||||
unlink ($IDX_FILE);
|
||||
($LAST_LINE, $LAST_SIZE) = (0, 0);
|
||||
}
|
||||
|
||||
# Skip already processed lines
|
||||
readline SNMPLOGFILE for (1..$LAST_LINE);
|
||||
|
||||
# Initialize semaphores and queues
|
||||
@TaskQueue = ();
|
||||
%PendingTasks = ();
|
||||
$Sem = Thread::Semaphore->new;
|
||||
$TaskSem = Thread::Semaphore->new (0);
|
||||
|
||||
# Call the constructor of the parent class
|
||||
my $self = $class->SUPER::new($config, 2, $dbh);
|
||||
my $self = $class->SUPER::new($config, 2, \&PandoraFMS::SNMPServer::data_producer, \&PandoraFMS::SNMPServer::data_consumer, $dbh);
|
||||
|
||||
# Save the path of snmptrapd
|
||||
$self->{'snmp_trapd'} = $config->{'snmp_trapd'};
|
||||
|
||||
# Run!
|
||||
$RUN = 1;
|
||||
|
||||
bless $self, $class;
|
||||
return $self;
|
||||
}
|
||||
|
@ -77,242 +115,219 @@ sub run ($) {
|
|||
my $self = shift;
|
||||
my $pa_config = $self->getConfig ();
|
||||
|
||||
print_message ($pa_config, " [*] Starting Pandora FMS SNMP Console.", 1);
|
||||
$self->SUPER::run (\&PandoraFMS::SNMPServer::pandora_snmptrapd);
|
||||
print_message ($pa_config, " [*] Starting Pandora FMS SNMP Console.", 2);
|
||||
|
||||
# Set the initial date for storm protection.
|
||||
$pa_config->{"__storm_ref__"} = time();
|
||||
|
||||
# This is the only server that reads from disk instead of from the DB. No need for a higher server threshold.
|
||||
$pa_config->{'server_threshold'} = 1;
|
||||
|
||||
$self->setNumThreads ($pa_config->{'snmpconsole_threads'});
|
||||
$self->SUPER::run (\@TaskQueue, \%PendingTasks, $Sem, $TaskSem);
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Data producer.
|
||||
###############################################################################
|
||||
sub data_producer ($) {
|
||||
my $self = shift;
|
||||
my ($pa_config, $dbh) = ($self->getConfig (), $self->getDBH ());
|
||||
|
||||
my @tasks;
|
||||
|
||||
# Slave server
|
||||
if ($pa_config->{'pandora_master'} == 0 && get_db_value ($dbh, 'SELECT name FROM tserver WHERE name = ANY(SELECT name FROM tserver WHERE status = 0)') == undef) {
|
||||
return @tasks;
|
||||
}
|
||||
|
||||
# Reset storm protection counters
|
||||
my $curr_time = time ();
|
||||
if ($pa_config->{"__storm_ref__"} + $pa_config->{"snmp_storm_timeout"} < $curr_time) {
|
||||
$pa_config->{"__storm_ref__"} = $curr_time;
|
||||
%AGENTS = ();
|
||||
}
|
||||
|
||||
while (my $line = <SNMPLOGFILE>) {
|
||||
$LAST_LINE++;
|
||||
$LAST_SIZE = (stat ($pa_config->{'snmp_logfile'}))[7];
|
||||
chomp ($line);
|
||||
|
||||
# Update index file
|
||||
open INDEXFILE, '>' . $IDX_FILE;
|
||||
print INDEXFILE $LAST_LINE . ' ' . $LAST_SIZE;
|
||||
close INDEXFILE;
|
||||
|
||||
# Skip lines other than SNMP Trap logs
|
||||
next unless ($line =~ m/^SNMPv[12]\[\*\*\]/);
|
||||
|
||||
# Storm protection.
|
||||
my ($ver, $date, $time, $source, $null) = split(/\[\*\*\]/, $line, 5);
|
||||
next unless defined ($source);
|
||||
if (! defined ($AGENTS{$source})) {
|
||||
$AGENTS{$source}{'count'} = 1;
|
||||
$AGENTS{$source}{'event'} = 0;
|
||||
} else {
|
||||
$AGENTS{$source}{'count'} += 1;
|
||||
}
|
||||
if ($pa_config->{'snmp_storm_protection'} > 0 && $AGENTS{$source}{'count'} > $pa_config->{'snmp_storm_protection'}) {
|
||||
if ($AGENTS{$source}{'event'} == 0) {
|
||||
pandora_event ($pa_config, "Too many traps coming from $source. Silenced for " . int ($pa_config->{"snmp_storm_timeout"} / 60) . " minutes.", 0, 0, 4, 0, 0, 'system', 0, $dbh);
|
||||
}
|
||||
$AGENTS{$source}{'event'} = 1;
|
||||
next;
|
||||
}
|
||||
|
||||
push (@tasks, $line);
|
||||
}
|
||||
|
||||
return @tasks;
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Data consumer.
|
||||
###############################################################################
|
||||
sub data_consumer ($$) {
|
||||
my ($self, $task) = @_;
|
||||
|
||||
pandora_snmptrapd ($self->getConfig (), $task, $self->getServerID (), $self->getDBH ());
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
# Process SNMP log file.
|
||||
##########################################################################
|
||||
sub pandora_snmptrapd {
|
||||
my $self = shift;
|
||||
my $pa_config = $self->getConfig ();
|
||||
my ($pa_config, $line, $server_id, $dbh) = @_;
|
||||
|
||||
my $dbh;
|
||||
eval {
|
||||
# Connect to the DB
|
||||
$dbh = db_connect ($pa_config->{'dbengine'}, $pa_config->{'dbname'}, $pa_config->{'dbhost'},
|
||||
$pa_config->{'dbport'}, $pa_config->{'dbuser'}, $pa_config->{'dbpass'});
|
||||
$self->setDBH ($dbh);
|
||||
(my $trap_ver, $line) = split(/\[\*\*\]/, $line, 2);
|
||||
|
||||
# Wait for the SNMP log file to be available
|
||||
my $log_file = $pa_config->{'snmp_logfile'};
|
||||
sleep ($pa_config->{'server_threshold'}) while (! -e $log_file);
|
||||
open (SNMPLOGFILE, $log_file) or return;
|
||||
# Process SNMP filter
|
||||
next if (matches_filter ($dbh, $pa_config, $line) == 1);
|
||||
|
||||
# Process index file, if available
|
||||
my ($idx_file, $last_line, $last_size) = ($log_file . '.index', 0, 0);
|
||||
if (-e $idx_file) {
|
||||
open (INDEXFILE, $idx_file) or return;
|
||||
my $idx_data = <INDEXFILE>;
|
||||
close INDEXFILE;
|
||||
($last_line, $last_size) = split(/\s+/, $idx_data);
|
||||
logger($pa_config, "Reading trap '$line'", 10);
|
||||
my ($date, $time, $source, $oid, $type, $type_desc, $value, $data) = ('', '', '', '', '', '', '', '');
|
||||
|
||||
if ($trap_ver eq "SNMPv1") {
|
||||
($date, $time, $source, $oid, $type, $type_desc, $value, $data) = split(/\[\*\*\]/, $line, 8);
|
||||
|
||||
$value = limpia_cadena ($value);
|
||||
|
||||
# Try to save as much information as possible if the trap could not be parsed
|
||||
$oid = $type_desc if ($oid eq '' || $oid eq '.');
|
||||
|
||||
} elsif ($trap_ver eq "SNMPv2") {
|
||||
($date, $time, $source, $data) = split(/\[\*\*\]/, $line, 4);
|
||||
my @data = split(/\t/, $data);
|
||||
|
||||
shift @data; # Drop unused 1st data.
|
||||
$oid = shift @data;
|
||||
|
||||
if (!defined($oid)) {
|
||||
logger($pa_config, "[W] snmpTrapOID not found (Illegal SNMPv2 trap?)", 1);
|
||||
next;
|
||||
}
|
||||
|
||||
my $log_size = (stat ($log_file))[7];
|
||||
|
||||
# New SNMP log file found
|
||||
if ($log_size < $last_size) {
|
||||
unlink ($idx_file);
|
||||
($last_line, $last_size) = (0, 0);
|
||||
}
|
||||
|
||||
# Skip already processed lines
|
||||
readline SNMPLOGFILE for (1..$last_line);
|
||||
|
||||
# Main loop
|
||||
my $storm_ref = time ();
|
||||
while ($RUN == 1) {
|
||||
|
||||
# Reset storm protection counters
|
||||
my $curr_time = time ();
|
||||
if ($storm_ref + $pa_config->{"snmp_storm_timeout"} < $curr_time) {
|
||||
$storm_ref = $curr_time;
|
||||
%AGENTS = ();
|
||||
}
|
||||
|
||||
while (my $line = <SNMPLOGFILE>) {
|
||||
$last_line++;
|
||||
$last_size = (stat ($log_file))[7];
|
||||
chomp ($line);
|
||||
|
||||
# Update index file
|
||||
open INDEXFILE, '>' . $idx_file;
|
||||
print INDEXFILE $last_line . ' ' . $last_size;
|
||||
close INDEXFILE;
|
||||
|
||||
# Skip lines other than SNMP Trap logs
|
||||
next unless ($line =~ m/^SNMPv[12]\[\*\*\]/);
|
||||
|
||||
(my $trap_ver, $line) = split(/\[\*\*\]/, $line, 2);
|
||||
|
||||
# Process SNMP filter
|
||||
next if (matches_filter ($dbh, $pa_config, $line) == 1);
|
||||
|
||||
logger($pa_config, "Reading trap '$line'", 10);
|
||||
my ($date, $time, $source, $oid, $type, $type_desc, $value, $data) = ('', '', '', '', '', '', '', '');
|
||||
|
||||
if ($trap_ver eq "SNMPv1") {
|
||||
($date, $time, $source, $oid, $type, $type_desc, $value, $data) = split(/\[\*\*\]/, $line, 8);
|
||||
|
||||
$value = limpia_cadena ($value);
|
||||
|
||||
# Try to save as much information as possible if the trap could not be parsed
|
||||
$oid = $type_desc if ($oid eq '' || $oid eq '.');
|
||||
|
||||
} elsif ($trap_ver eq "SNMPv2") {
|
||||
($date, $time, $source, $data) = split(/\[\*\*\]/, $line, 4);
|
||||
my @data = split(/\t/, $data);
|
||||
|
||||
shift @data; # Drop unused 1st data.
|
||||
$oid = shift @data;
|
||||
|
||||
if (!defined($oid)) {
|
||||
logger($pa_config, "[W] snmpTrapOID not found (Illegal SNMPv2 trap?)", 1);
|
||||
next;
|
||||
}
|
||||
$oid =~ s/.* = OID: //;
|
||||
$data = join("\t", @data);
|
||||
}
|
||||
|
||||
if ($trap_ver eq "SNMPv2" || $pa_config->{'snmp_pdu_address'} eq '1' ) {
|
||||
# extract IP address from %b part:
|
||||
# * destination part (->[dest_ip]:dest_port) appears in Net-SNMP > 5.3
|
||||
# * protocol name (TCP: or UDP:) and bracketted IP addr w/ port number appear in
|
||||
# Net-SNMP > 5.1 (Net-SNMP 5.1 has IP addr only).
|
||||
# * port number is signed (often negative) in Net-SNMP 5.2
|
||||
$source =~ s/(?:(?:TCP|UDP):\s*)?\[?([^] ]+)\]?(?::-?\d+)?(?:\s*->.*)?$/$1/;
|
||||
}
|
||||
|
||||
my $timestamp = $date . ' ' . $time;
|
||||
my ($custom_oid, $custom_type, $custom_value) = ('', '', '');
|
||||
|
||||
# custom_type, custom_value is not used since 4.0 version, all custom data goes on custom_oid
|
||||
$custom_oid = $data;
|
||||
|
||||
# Storm protection
|
||||
if (! defined ($AGENTS{$source})) {
|
||||
$AGENTS{$source}{'count'} = 1;
|
||||
$AGENTS{$source}{'event'} = 0;
|
||||
} else {
|
||||
$AGENTS{$source}{'count'} += 1;
|
||||
}
|
||||
if ($pa_config->{'snmp_storm_protection'} > 0 && $AGENTS{$source}{'count'} > $pa_config->{'snmp_storm_protection'}) {
|
||||
if ($AGENTS{$source}{'event'} == 0) {
|
||||
pandora_event ($pa_config, "Too many traps coming from $source. Silenced for " . int ($pa_config->{"snmp_storm_timeout"} / 60) . " minutes.", 0, 0, 4, 0, 0, 'system', 0, $dbh);
|
||||
}
|
||||
$AGENTS{$source}{'event'} = 1;
|
||||
next;
|
||||
}
|
||||
|
||||
#Trap forwarding
|
||||
if ($pa_config->{'snmp_forward_trap'}==1) {
|
||||
my $trap_data_string = "";
|
||||
|
||||
#We loop through all the custom data of the received trap, creating the $trap_data_string string to forward the trap properly
|
||||
while ($data =~ /([\.\d]+)\s=\s([^:]+):\s([\S ]+)/g) {
|
||||
my ($trap_data, $trap_type, $trap_value) = ($1, $2, $3);
|
||||
if ($trap_type eq "INTEGER") {
|
||||
#FIX for translated traps from IF-MIB.txt MIB
|
||||
$trap_value =~ s/\D//g;
|
||||
$trap_data_string = $trap_data_string . "$trap_data i $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "UNSIGNED"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data u $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "COUNTER32"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data c $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "STRING"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data s $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "HEX STRING"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data x $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "DECIMAL STRING"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data d $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "NULLOBJ"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data n $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "OBJID"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data o $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "TIMETICKS"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data t $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "IPADDRESS"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data a $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "BITS"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data b $trap_value ";
|
||||
}
|
||||
}
|
||||
|
||||
#We distinguish between the three different kinds of SNMP forwarding
|
||||
if ($pa_config->{'snmp_forward_version'} eq '3') {
|
||||
system("snmptrap -v $pa_config->{'snmp_forward_version'} -n \"\" -a $pa_config->{'snmp_forward_authProtocol'} -A $pa_config->{'snmp_forward_authPassword'} -x $pa_config->{'snmp_forward_privProtocol'} -X $pa_config->{'snmp_forward_privPassword'} -l $pa_config->{'snmp_forward_secLevel'} -u $pa_config->{'snmp_forward_secName'} -e $pa_config->{'snmp_forward_engineid'} $pa_config->{'snmp_forward_ip'} '' $oid $trap_data_string");
|
||||
}
|
||||
elsif ($pa_config->{'snmp_forward_version'} eq '2' || $pa_config->{'snmp_forward_version'} eq '2c') {
|
||||
system("snmptrap -v 2c -n \"\" -c $pa_config->{'snmp_forward_community'} $pa_config->{'snmp_forward_ip'} '' $oid $trap_data_string");
|
||||
}
|
||||
elsif ($pa_config->{'snmp_forward_version'} eq '1') {
|
||||
#Because of tne SNMP v1 protocol, we must perform additional steps for creating the trap
|
||||
my $value_sending = "";
|
||||
my $type_sending = "";
|
||||
|
||||
if ($value eq ''){
|
||||
$value_sending = "\"\"";
|
||||
}
|
||||
else {
|
||||
$value_sending = $value;
|
||||
$value_sending =~ s/[\$#@~!&*()\[\];.,:?^ `\\\/]+//g;
|
||||
}
|
||||
if ($type eq ''){
|
||||
$type_sending = "\"\"";
|
||||
}
|
||||
else{
|
||||
$type_sending = $type;
|
||||
}
|
||||
|
||||
system("snmptrap -v 1 -c $pa_config->{'snmp_forward_community'} $pa_config->{'snmp_forward_ip'} $oid \"\" $type_sending $value_sending \"\" $trap_data_string");
|
||||
}
|
||||
}
|
||||
|
||||
# Insert the trap into the DB
|
||||
if (! defined(enterprise_hook ('snmp_insert_trap', [$pa_config, $source, $oid, $type, $value, $custom_oid, $custom_value, $custom_type, $timestamp, $self->getServerID (), $dbh]))) {
|
||||
my $trap_id = db_insert ($dbh, 'id_trap', 'INSERT INTO ttrap (timestamp, source, oid, type, value, oid_custom, value_custom, type_custom) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
$timestamp, $source, $oid, $type, $value, $custom_oid, $custom_value, $custom_type);
|
||||
logger ($pa_config, "Received SNMP Trap from $source", 4);
|
||||
|
||||
# Evaluate alerts for this trap
|
||||
pandora_evaluate_snmp_alerts ($pa_config, $trap_id, $source, $oid, $type, $oid, $value, $custom_oid, $dbh);
|
||||
}
|
||||
}
|
||||
|
||||
sleep ($pa_config->{'server_threshold'});
|
||||
}
|
||||
};
|
||||
|
||||
if ($@) {
|
||||
$self->setErrStr ($@);
|
||||
$oid =~ s/.* = OID: //;
|
||||
$data = join("\t", @data);
|
||||
}
|
||||
|
||||
db_disconnect ($dbh);
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
# Stop the server, killing snmptrapd before.
|
||||
########################################################################################
|
||||
sub stop () {
|
||||
my $self = shift;
|
||||
|
||||
if ($self->{'snmp_trapd'} ne 'manual') {
|
||||
system ("kill -9 `cat /var/run/pandora_snmptrapd.pid 2>$DEVNULL`");
|
||||
unlink ('/var/run/pandora_snmptrapd.pid');
|
||||
if ($trap_ver eq "SNMPv2" || $pa_config->{'snmp_pdu_address'} eq '1' ) {
|
||||
# extract IP address from %b part:
|
||||
# * destination part (->[dest_ip]:dest_port) appears in Net-SNMP > 5.3
|
||||
# * protocol name (TCP: or UDP:) and bracketted IP addr w/ port number appear in
|
||||
# Net-SNMP > 5.1 (Net-SNMP 5.1 has IP addr only).
|
||||
# * port number is signed (often negative) in Net-SNMP 5.2
|
||||
$source =~ s/(?:(?:TCP|UDP):\s*)?\[?([^] ]+)\]?(?::-?\d+)?(?:\s*->.*)?$/$1/;
|
||||
}
|
||||
|
||||
my $timestamp = $date . ' ' . $time;
|
||||
my ($custom_oid, $custom_type, $custom_value) = ('', '', '');
|
||||
|
||||
# custom_type, custom_value is not used since 4.0 version, all custom data goes on custom_oid
|
||||
$custom_oid = $data;
|
||||
|
||||
#Trap forwarding
|
||||
if ($pa_config->{'snmp_forward_trap'}==1) {
|
||||
my $trap_data_string = "";
|
||||
|
||||
#We loop through all the custom data of the received trap, creating the $trap_data_string string to forward the trap properly
|
||||
while ($data =~ /([\.\d]+)\s=\s([^:]+):\s([\S ]+)/g) {
|
||||
my ($trap_data, $trap_type, $trap_value) = ($1, $2, $3);
|
||||
if ($trap_type eq "INTEGER") {
|
||||
#FIX for translated traps from IF-MIB.txt MIB
|
||||
$trap_value =~ s/\D//g;
|
||||
$trap_data_string = $trap_data_string . "$trap_data i $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "UNSIGNED"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data u $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "COUNTER32"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data c $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "STRING"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data s $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "HEX STRING"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data x $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "DECIMAL STRING"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data d $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "NULLOBJ"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data n $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "OBJID"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data o $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "TIMETICKS"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data t $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "IPADDRESS"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data a $trap_value ";
|
||||
}
|
||||
elsif ($trap_type eq "BITS"){
|
||||
$trap_data_string = $trap_data_string . "$trap_data b $trap_value ";
|
||||
}
|
||||
}
|
||||
|
||||
#We distinguish between the three different kinds of SNMP forwarding
|
||||
if ($pa_config->{'snmp_forward_version'} eq '3') {
|
||||
system("snmptrap -v $pa_config->{'snmp_forward_version'} -n \"\" -a $pa_config->{'snmp_forward_authProtocol'} -A $pa_config->{'snmp_forward_authPassword'} -x $pa_config->{'snmp_forward_privProtocol'} -X $pa_config->{'snmp_forward_privPassword'} -l $pa_config->{'snmp_forward_secLevel'} -u $pa_config->{'snmp_forward_secName'} -e $pa_config->{'snmp_forward_engineid'} $pa_config->{'snmp_forward_ip'} '' $oid $trap_data_string");
|
||||
}
|
||||
elsif ($pa_config->{'snmp_forward_version'} eq '2' || $pa_config->{'snmp_forward_version'} eq '2c') {
|
||||
system("snmptrap -v 2c -n \"\" -c $pa_config->{'snmp_forward_community'} $pa_config->{'snmp_forward_ip'} '' $oid $trap_data_string");
|
||||
}
|
||||
elsif ($pa_config->{'snmp_forward_version'} eq '1') {
|
||||
#Because of tne SNMP v1 protocol, we must perform additional steps for creating the trap
|
||||
my $value_sending = "";
|
||||
my $type_sending = "";
|
||||
|
||||
if ($value eq ''){
|
||||
$value_sending = "\"\"";
|
||||
}
|
||||
else {
|
||||
$value_sending = $value;
|
||||
$value_sending =~ s/[\$#@~!&*()\[\];.,:?^ `\\\/]+//g;
|
||||
}
|
||||
if ($type eq ''){
|
||||
$type_sending = "\"\"";
|
||||
}
|
||||
else{
|
||||
$type_sending = $type;
|
||||
}
|
||||
|
||||
system("snmptrap -v 1 -c $pa_config->{'snmp_forward_community'} $pa_config->{'snmp_forward_ip'} $oid \"\" $type_sending $value_sending \"\" $trap_data_string");
|
||||
}
|
||||
}
|
||||
|
||||
# Insert the trap into the DB
|
||||
if (! defined(enterprise_hook ('snmp_insert_trap', [$pa_config, $source, $oid, $type, $value, $custom_oid, $custom_value, $custom_type, $timestamp, $server_id, $dbh]))) {
|
||||
my $trap_id = db_insert ($dbh, 'id_trap', 'INSERT INTO ttrap (timestamp, source, oid, type, value, oid_custom, value_custom, type_custom) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
$timestamp, $source, $oid, $type, $value, $custom_oid, $custom_value, $custom_type);
|
||||
logger ($pa_config, "Received SNMP Trap from $source", 4);
|
||||
|
||||
# Evaluate alerts for this trap
|
||||
pandora_evaluate_snmp_alerts ($pa_config, $trap_id, $source, $oid, $type, $oid, $value, $custom_oid, $dbh);
|
||||
}
|
||||
|
||||
$self->SUPER::stop ();
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
|
@ -328,14 +343,14 @@ sub matches_filter ($$$) {
|
|||
my $eval_result;
|
||||
|
||||
# eval protects against server down (by invalid regular expressions)
|
||||
$eval_result = eval {
|
||||
$eval_result = eval {
|
||||
$string =~ m/$regexp/i ;
|
||||
};
|
||||
|
||||
if ($eval_result) {
|
||||
logger($pa_config, "Trap '$string' matches filter '$regexp'. Discarding...", 10);
|
||||
return 1;
|
||||
}
|
||||
if ($eval_result) {
|
||||
logger($pa_config, "Trap '$string' matches filter '$regexp'. Discarding...", 10);
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -393,7 +408,7 @@ sub start_snmptrapd ($) {
|
|||
print_message ($config, " [E] Could not start snmptrapd.", 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -403,7 +418,10 @@ sub start_snmptrapd ($) {
|
|||
sub DESTROY {
|
||||
my $self = shift;
|
||||
|
||||
$RUN = 0;
|
||||
if ($self->{'snmp_trapd'} ne 'manual') {
|
||||
system ("kill -9 `cat /var/run/pandora_snmptrapd.pid 2>$DEVNULL`");
|
||||
unlink ('/var/run/pandora_snmptrapd.pid');
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
Loading…
Reference in New Issue