On 10/05/2010 11:14 AM, pf at alt-ctrl-del.org wrote:
> 
> Great!
> By saving one version with:
> if ($line =~ ' connect from .*\[([\d\.]+?)\]') {
> 
> And another with:
> if ($line =~ 'smtpd.*client=.*\[([\d\.]+?)\]') {
> 
> I can compare attempts vs success, from specific networks.
> 

Rather than use an array of programs, here's a program of arrays. It
will print the CIDR, followed by successes/attempts.


#!/usr/bin/perl
use strict;
use warnings;

use Net::CIDR::Lite;

if ($#ARGV < 1) {
  print("Usage: parse.pl <logfile> <cidrfile>\n");
  exit
}

my $logfile  = $ARGV[0];
my $cidrfile = $ARGV[1];

open(my $cidrh, '<', $cidrfile) or die "Can't open $cidrfile: $!";

# The list of CIDR objects.
my @cidrs  = ();

# A hash, of CIDR => (successes, attempts)
my %counts = ();

while (my $line = <$cidrh>) {
  # Add each line in the CIDR file to the hash, with default
  # counts of (0, 0).
  my $cidr = Net::CIDR::Lite->new;
  $cidr->add($line);
  push(@cidrs, $cidr);
  $counts{$cidr} = [0,0];
}

close($cidrh);
open(my $logh,  '<', $logfile) or die "Can't open $logfile: $!";

# Loop through the log file, looking for connections. When one is
# found, we go through the list of CIDRs to see if the IP address
# belongs to any. If it does, increase the attempt count for that
# CIDR.
while (my $line = <$logh>) {
  # The leading space rules out "DISconnect from..."
  if ($line =~ ' connect from .*\[([\d\.]+?)\]') {
    my $ip = $1;
    foreach my $cidr (@cidrs) {
      if ($cidr->find($ip)) {
        $counts{$cidr}->[1] += 1;
      }
    }
  }
  elsif ($line =~ 'smtpd.*client=.*\[([\d\.]+?)\]') {
    # Likewise for the successes, except we increase a different
    # variable.
    my $ip = $1;
    foreach my $cidr (@cidrs) {
      if ($cidr->find($ip)) {
        $counts{$cidr}->[0] += 1;
      }
    }
  }
}

close($cidrh);

# And finally, print the tally.
foreach my $cidr (@cidrs) {
  my @list = $cidr->list();
  my $attempts  = $counts{$cidr}->[1];
  my $successes = $counts{$cidr}->[0];
  print("@list: $successes/$attempts\n");
}

Reply via email to