package My::parser::stats; use strict; use warnings; use DBI; sub new { my $class = shift; my $config = shift; my $self = {}; bless ($self, $class); $self->{'config'} = $config; my $short_time = $config->get_as_single_val('config','short') || die "Failed to get short value"; my $long_time = $config->get_as_single_val('config','long') || die "Failed to get long value"; $self->{'short'} = $short_time; $self->{'long'} = $long_time; return $self; } sub recent_hostile { my $self = shift; my $dbh = $self->{'config'}->db_connect(); my $sth = $dbh->prepare(" SELECT COUNT(1) FROM reject WHERE time > DATE_SUB(NOW(), INTERVAL 5 MINUTE)") || return { retval => 0, retmsg => 'Failed checking for rejects last 5 minutes: '.DBI::errstr }; $sth->execute() || return { retval => 0, retmsg => 'Failed execute on checking for rejects last 5 minutes: '.DBI::errstr }; my $rows = $sth->fetchrow_arrayref->[0]; return { retval => 1, rows => $rows, retmsg => $rows.' the last 5 minutes' }; } sub checker { my $self = shift; my $tocheck = shift; my $host = $tocheck->{'host'}; my $asn = $tocheck->{'asn'}; my $iso = $tocheck->{'iso'}; unless($self && $host) { return { retval => 0, retmsg => "Too few variables to run My::parser::stats->checker, got host($host), asn($asn), iso($iso)" }; } my $retval; my $rows; my $msg; my $return = { retval => 1 }; my @times = ($self->{'short'},$self->{'long'}); #### Mapping between checks and tables in db my %checks = ('reject' => 'reject','blocks' => 'reject_iptables','iso' => 'reject','asn' => 'reject', 'block_iso' => 'reject_iptables', 'block_asn' => 'reject_iptables'); #### Mapping between checks and column in db my %values = ('reject' => 'ip','blocks' => 'ip', 'iso' => 'iso', 'asn' => 'asn', 'block_iso' => 'iso', 'block_asn' => 'asn'); my %keys = ('reject' => $host, 'blocks' => $host, 'iso' => $iso, 'block_iso' => $iso, 'asn' => $asn, 'block_asn' => $asn); my $dbh = $self->{'config'}->db_connect(); foreach my $time(@times) { foreach my $c(keys %checks) { my $fromcheck = $self->check($keys{$c},$time,$values{$c},$checks{$c}); if($fromcheck->{'retval'}) { my $temp = $fromcheck->{'rows'}; $return->{$time}->{$c} = $temp; # } else { # $self->{'config'}->{'logger'}->log("Check failed: $fromcheck->{'retmsg'}"); } } } return $return; } sub check { my $self = shift; my $host = shift; my $allowed_time = shift; my $value = shift; my $table = shift; my $retval; my $rows; my $msg; my $dbh = $self->{'config'}->db_connect(); if($host && $allowed_time && $value && $table) { my $sth = $dbh->prepare(" SELECT COUNT(1) FROM $table WHERE $value = ? AND time > DATE_SUB(NOW(), INTERVAL ? MINUTE)") || return { retval => 0, retmsg => "Checking $host in $table for $value in the last $allowed_time minutes failed: ".DBI::errstr }; $sth->execute($host,$allowed_time) || return { retval => 0, retmsg => "Execute failed on $table, checking for $host in $allowed_time: ".DBI::errstr }; my $rows = $sth->fetchrow_arrayref->[0]; return { retval => 1, rows => $rows, retmsg => "$rows in $allowed_time minutes" }; } else { return { retval => 0, retmsg => "Check called with too few arguments, we got host: $host, allowed_time: $allowed_time, value: $value, table: $table" }; } } 1;