Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

IP Accounting parser

by Viking (Beadle)
on Jan 11, 2001 at 14:49 UTC ( [id://51111]=sourcecode: print w/replies, xml ) Need Help??
Category: Networking Code
Author/Contact Info Bjorn <bjornn@ihug.co.nz>
Description: This parses a log file of ipchains IP accounting data and spits it out as a csv. I use this at work for statistical and billing purposes. It is still a work in progress (but it does work) so I'm interested in any comments. The log file is created from a shell script run from a cron, which you will find at the end of the code.
#!/usr/bin/perl

use strict;
use warnings;

my $logfile = $ARGV[0];

my $start_date;
my $end_date;
my %log_totals;


open (FILE< $logfile) or die "Could not open $logfile: $!\n";

for (<FILE>) {
        if (/^\d+/) {
                ($start_date) = m/^(\d+)/o unless ($start_date);
                ($end_date) = m/^(\d+)/o;
        } elsif (/^\s+\d+/o) {
                my ($bytes,$source,$destination,$ports) =
                m/
                        ^\s+\d+\s+(\d+)                 # pkts & bytes
                        .+                              # bla bla bla
                        \s+(\S+)                        # source
                        \s+(\S+)                        # destination
                        \s+(n\/a|\w+\s+->\s+\w+)$       # ports
                /ox;

                my ($src_port,$dest_port) = ('any','any');

                ($src_port,$dest_port) = $ports =~ m/(\w+)\s+->\s+(\w+
+)/o
                        unless ($ports eq 'n/a');
                &data2hash($bytes,$source,$src_port,$destination,$dest
+_port);
                # print "$bytes,$source,$src_port,$destination,$dest_p
+ort\n";
        }
}

my $start = localtime($start_date);
my $end = localtime($end_date);

print "From: $start\n";
print "To: $end\n";
print "Source Address,Source Port,Destination Address,Destination Port
+,Bytes\n";
for my $key (keys %log_totals) {
        print "$key,$log_totals{$key}\n";
}

sub data2hash {
        my ($bytes,$src_addr,$src_port,$dest_addr,$dest_port) = @_;

        if ($src_addr ne 'anywhere') { # we have a src address match
                if ($src_port ne 'any') { # we have a src port match
                        $log_totals{"$src_addr,$src_port,,"} += $bytes
+;
                } elsif ($dest_port ne 'any') { # we have a dest port 
+match
                        $log_totals{"$src_addr,,,$dest_port"} += $byte
+s;
                } else { # only src address match
                        $log_totals{"$src_addr,,,"} += $bytes;
                }
        } elsif ($dest_addr ne 'anywhere') { # we have a dest address 
+match
                if ($src_port ne 'any') { # we have a src port match
                        $log_totals{",$src_port,$dest_addr,"} += $byte
+s;
                } elsif ($dest_port ne 'any') { # we have a dest port 
+match
                        $log_totals{",,$dest_addr,$dest_port"} += $byt
+es;
                } else { # only dest address match
                        $log_totals{",,$dest_addr,"} += $bytes;
                }
        } else { # shouldn't get here
                print STDERR "eh?\n";
        }
}

close FILE;


#!/bin/bash
/bin/date +%s >>/var/log/ip-acc/ip-acc.log
/sbin/ipchains -L ip-acc -v -x >>/var/log/ip-acc/ip-acc.log
/sbin/ipchains -Z ip-acc
Replies are listed 'Best First'.
Re: IP Accounting parser
by turnstep (Parson) on Jan 12, 2001 at 02:52 UTC

    Erk! This code:

    open FILE, $logfile || die $!;
    does not act the way you want it to. Because the || has a higher precedence than the comma, what actually happens is this:
    open FILE, ($logfile || die $!);
    see perlop for the complete precedence list.

    If you really want to use the || then put parenthesis around things like so:

    open (FILE, $logfile) || die "Could not open $logfile: $!\n";

    Better yet, use the super-low-priority or, which allows you to acheive your original effect:

    open FILE, $logfile or die "Could not open $logfile: $!\n";

    Best of all, be correct and non-ambigous and use both:

    open (FILE< $logfile) or die "Could not open $logfile: $!\n";

      I always get || and or mixed up, I will attempt to burn the precedence list into my brain.

        It may help to think of or and and as 'lowercase', and thus 'lower precedence' as opposed to || and && which require the use of the shift key, and therefore are 'uppercase' and 'upper precedence'

        You could also just remember that nothing is lower in precedence than and and or

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://51111]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2024-04-24 00:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found