Jeff ,
Thanks for all your help! This is what I have now (below and this time the
whole thing): I think I have included all that you talked about plus
others:
The sub scanlog does write the information to the files but it does not
return anything back to the main program and I also get the error:
Use of uninitialized value in split at ./test.pl line 9.
Also, is there a better way of counting the number of times each IP address
gets blocked with category PO? Each time I get to the blocklimit it writes
to the file but I really just want the max number of blocks over the limit.
It will write the same IP each time it gets over the blocklimit though.
------------------------------------------------------------------------------
#!/usr/bin/perl -w
require Mail::Send;
$|=1; # no buffering
use constant IP_LIST_FILE => "/etc/squid/iplist.txt";
use constant SUSPEND_FILE => "/etc/squid/SuspendIpList.txt";
use constant LOG_FILE => "/opt/n2h2/logs/filter_log";
my $sysop = "[EMAIL PROTECTED]";
my $flag = "PO";
my $hour = (split, localtime)[2];
my $blocklimit = 5;
my $matches = 0;
my $matched = 0;
{
($matched,$ip,$hour,$time,$category,$url) =
&Scanlog($flag,$hour,$blocklimit,$matches,);
if($matched > $blocklimit){
$msg = new Mail::Send Subject=>'SuspendIpList', To=>"$sysop";
$fh = $msg->open;
print $fh "Someone has tried to access $matches banned sites
today\n";
print $fh "Their IP address ($ip) has been added to
/etc/squid/SuspendIpList.txt\n";
print $fh "To unblock them, remove their entry from the file and
run squid -k reconfigure\n";
print $fh "$matches, $ip, $hour, $time, $category, $url\n";
$fh->close; # complete the message and send it
$matched = 0;
}
else{
open my $output2, ">", SUSPEND_FILE or die "Can't write
@{[SUSPEND_FILE]}: $!";
print $output2 "10.0.0.252/32\n";
close $output2;
}
}
sub Scanlog {
my ($flag,$hour,$blocklimit,$matches,)[EMAIL PROTECTED];
open my $slog, "-|", "tail -n 25000 @{[LOG_FILE]}" or die "Unable
to open $log:$!\n";
open my $output, ">", IP_LIST_FILE or die "Can't write
@{[IP_LIST_FILE]}: $!";
open my $output2, ">", SUSPEND_FILE or die "Can't write
@{[SUSPEND_FILE]}: $!";
while (my $line = <$slog>){ # assigns each line in turn to $line
#use an array slice to select the fields we want
my ($time, $ip, $url, $category) = (split " ", $line)[1,4,7,10];
my ($hr) = split /:/, $time;
if($flag eq $category and $hr eq $hour){
$matches += 1 ;
}
if($matches > $blocklimit){
print $output "$matches, $ip, $hour, $time, $category,
$url\n";
print $output2 "$ip/32\n";
$matched = $matches;
$matches = 0;
}
}
close $output;
close $output2;
return($matched,$ip,$hour,$time,$category,$url);
}
------------------------------------------------------------------
Ryan Lamberton
----- Original Message -----
From: "Jeff 'japhy' Pinyan" <[EMAIL PROTECTED]>
To: "FamiLink Admin" <[EMAIL PROTECTED]>
Cc: <beginners@perl.org>
Sent: Wednesday, September 28, 2005 12:24 PM
Subject: Re: a little help...
On Sep 28, FamiLink Admin said:
I am trying to read a log file and get a list of how many times an IP
address get blocked each hour by category PO. An example line in the log
with a block is:
-------------
[2005-09-28 10:05:03 -7:00] 127.0.0.1 71.32.59.249 216.163.137.3 -
http://www.playboy.com/ blocked 0 PO
-------------
What I have kinda works but I am not sure if it is the best practice. This
is the first time programming in perl and this is what I have so far:
Your indentation leaves much to be desired, so I've "fixed" it.
sub Scanlog {
local($ipb) = @_;
No reason to use 'local'; stick with 'my' here. But... what is $ipb? You
don't use it anywhere!
open my $slog, "-|", "tail -n 50000 $log" or die "Unable to open
$log:$!\n";
open (OUTPUT,">/etc/squid/iplist.txt");
open (OUTPUT2,">/etc/squid/SuspendIpList.txt");
You should also die if neither of those could be opened:
open(OUTPUT, ">...") or die "can't create /etc/squid/iplist.txt: $!";
while (<$slog>){ # assigns each line in turn to $_
# use an array slice to select the fields we want
@data = (split ,$_)[1,4,10,5,7];
$hr = (split /:/ ,$data[0])[0];
$ip = "$data[1]";
Those three variables should all be declared with 'my'. Your line
assigning to @data has a typo that hasn't effected you, but it might
eventually.
my @data = (split)[1,4,10,5,7]; # why out of order?
my $hr = (split /:/, $data[0])[0];
my $ip = $data[1]; # no need to quote $data[1] here
if ($flag eq $data[2]) {
Where is $flag coming from?
if ($hr eq $hour) {
Where is $hour coming from?
Those two if statements can be combined into one, since you don't do
anything if they aren't both true.
if ($flag eq $data[2] and $hr eq $hour) {
foreach (/$data[2]/) {
$matches += 1 ;
}
I have a feeling this could lead to false positives. How do you know that
'PO' (or whatever else $data[2] might hold) won't appear in the URL, for
instance? Perhaps this should just be
$matches++;
But where is $matches coming from?!
if ($matches > $blocklimit) {
Where does $blocklimit come from?!
$ip1 = "$data[1]/32";
Declare that with 'my'.
print OUTPUT "$matches,", "$hour, ","$ip1, ", "@data","\n";
You could just write that as
print OUTPUT "$matches, $hour, $data[1]/32 @data\n";
print OUTPUT2 "$ip1\n";
$matched = $matches;
$matches = 0;
Where did $matched come from?
}
}
}
}
close (OUTPUT);
close (OUTPUT2);
}
You should not use any variables in a function that you did not pass to it
or create IN it.
--
Jeff "japhy" Pinyan % How can we ever be the sold short or
RPI Acacia Brother #734 % the cheated, we who for every service
http://www.perlmonks.org/ % have long ago been overpaid?
http://princeton.pm.org/ % -- Meister Eckhart
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>