Reading argus-1.8.1 output in Perl

Peter Van Epp vanepp at sfu.ca
Sun Jul 9 23:25:33 EDT 2000


	Yep, been there almost done that :-) One version that looks for echo
reply scans is in the contrib section of the ftp site. Below are two (not ready
for prime time nor public distribution) scripts I have been poking slowly at
for almost a year now. If you have time please feed corrections/improvements
back. The first one is intended to parse output lines from argus as a 
subroutine. In theory it will deal with counts or without but I normally use
it as in 

ra -r argus.log.gz -c -n | perlscript.pl

so it may or may not work without the counts. Sometime I hope to get it cleaned 
up and documented, but it hasn't happened so far :-).


parse_argus_log is used inside the perl script like this:

#!/usr/bin/perl

require "parse_argus_log.pl";
use Socket;

open(STDIN,$ARGV[0]) || die "Can't open $ARGV[0]: $!\n"
        if $ARGV[0];

$line = 0;
while (<STDIN>) {
        $line ++;
        if (($line % 10000) == 0) {
                print STDERR "Processing $line\n";
        }
        chop;
        &parse_argus_log("$_");
        $ips{"$dst_ip $dst_port"} += 1;
        $ips{"$src_ip $src_port"} += 1;
}

parse_argus_log.pl


sub main'parse_argus_log {

	# Parse an argus log file line in to the variable listed below to 
	# make it easy to scan log files from a perl script.
	
	local ($_) = @_;
	local ($rest, $t, $p, $a,$b,$c,$d,$e,$f,$g,$h);

	$date = ""; 
	$flag = "";
	$mid_flag = "";
	$end_flag = "";
	$type = "";
	$src_ip = "";
	$dst_ip = "";
	$src_pkt = "";
	$dst_pkt = "";
	$src_bytes = "";
	$dst_bytes = "";
	$src_net ="";
	$dst_net ="";
	$src_port = "";
	$dst_port = "";

	($date, $flag, $rest) = unpack("A18 A5 A200",$_);
	if ($start_time eq "") {
		$start_time = $date;
	}
	($type, $rest) = split(' ',$rest,2);
	if ($type eq "man") {
		$mid_flag = ' ';
	 	($src_ip, $dst_ip, $src_pkt, $dst_pkt, $src_bytes, 
		 $dst_bytes, $end_flag) = split(' ',$rest,7); 
	} elsif ($type eq "icmp") {
	 	($src_ip, $mid_flag, $dst_ip, $src_pkt, $dst_pkt, 
		 $end_flag) = split(' ',$rest,6); 
		if ($end_flag =~ /port/) {
			($t, $p, $dst_port, $rest) = split(' ',$end_flag);
		}
		($a,$b,$c,$d)= split(/\./,$src_ip);
		($e,$f,$g,$h)= split(/\./,$dst_ip);
	} else {
	 	($src_ip, $mid_flag, $dst_ip, $src_pkt, $dst_pkt, 
		 $src_bytes, $dst_bytes, $end_flag) = split(' ',$rest,8); 
		($a,$b,$c,$d,$src_port)= split(/\./,$src_ip);
		($e,$f,$g,$h,$dst_port)= split(/\./,$dst_ip);
	}
	$src_ip = "$a.$b.$c.$d";
	$src_net = "$a.$b.$c.";
	$dst_ip = "$e.$f.$g.$h";
	$dst_net = "$e.$f.$g.";
}

1;

	And an old (but still used) script that predates the parse subroutine
that sorts for traffic (very useful for finding napster/gnuella servers):


#!/usr/bin/perl

open(STDIN,$ARGV[0]) || die "Can't open $ARGV[0]: $!\n"
	if $ARGV[0];
$line = 0;
$start_time = "";
$end_time = "";
while (<STDIN>) {
	$line ++;
	if (($line % 10000) == 0) {
		print STDERR "Processing $line\n";
	}
	chop;
	$src_bytes = " ";
	$dest_bytes = " ";
	$source_net ="";
	$dest_net ="";
	$src_port = " ";
	$dst_port = " ";
	($date, $flag, $rest) = unpack("A18 A5 A200",$_);
	if ($start_time eq "") {
		$start_time = $date;
	}
	($type, $rest) = split(' ',$rest,2);
	if ($type eq "man") {
		$mid_flag = ' ';
	 	($source_ip, $dest_ip, $src_pkt, $dest_pkt, $src_bytes, 
		 $dest_bytes, $end_flag) = split(' ',$rest,7); 
	} elsif ($type eq "icmp") {
	 	($source_ip, $mid_flag, $dest_ip, $src_pkt, $dest_pkt, 
		 $end_flag) = split(' ',$rest,6); 
		if ($end_flag =~ /port/) {
			($t, $p, $dst_port, $rest) = split(' ',$end_flag);
		}
	} else {
	 	($source_ip, $mid_flag, $dest_ip, $src_pkt, $dest_pkt, 
		 $src_bytes, $dest_bytes, $end_flag) = split(' ',$rest,8); 
		($a,$b,$c,$d,$src_port)= split(/\./,$source_ip);
		$source_ip = "$a.$b.$c.$d";
		$source_net = "$a.$b.$c";
		($a,$b,$c,$d,$dst_port)= split(/\./,$dest_ip);
		$dest_ip = "$a.$b.$c.$d";
		$dest_net = "$a.$b.$c";
	}
	if ($source_net ne "") {
		$source_net{$source_net} += $src_bytes;
		$source_machine{$source_ip} += $src_bytes;
		$total_bytes += $src_bytes;
		$total_src_bytes += $src_bytes;
		$total_net{$source_net} += $src_bytes;
		$total_machine{$source_ip} += $src_bytes;
		$total_src_dst{"$source_ip $dest_ip"} += $src_bytes;
	}
	if ($dest_net ne "") {
		$dest_net{$dest_net} += $dest_bytes;
		$dest_machine{$dest_ip} += $dest_bytes;
		$total_bytes += $dest_bytes;
		$total_dest_bytes += $dest_bytes; 
		$total_net{$dest_net} += $dest_bytes;
		$total_machine{$dest_ip} += $dest_bytes;
		$total_src_dst{"$source_ip $dest_ip"} += $dest_bytes;
	}
        if (($source_ip eq "142.58.29.254") || ($dest_ip eq "142.58.29.254")) {
                $local_router_bytes += $src_bytes;
                $local_router_bytes += $dest_bytes;
                $local_router_src_bytes += $src_bytes;
                $local_router_dest_bytes += $dest_bytes;
                if ($type eq "ipnip") {
                        $mbone_bytes += $src_bytes;
                        $mbone_bytes += $dest_bytes;
                        $mbone_src_bytes += $src_bytes;
                        $mbone_dest_bytes += $dest_bytes;
                }
		if (($src_port eq "161") || ($dst_port eq "161")) {
			$snmp_bytes += $src_bytes;
			$snmp_bytes += $dest_bytes;
			$snmp_src_bytes += $src_bytes;
			$snmp_dest_bytes += $dest_bytes;
		}
        } else {
                $transit_bytes += $src_bytes;
                $transit_bytes += $dest_bytes;
                $transit_src_bytes += $src_bytes;
                $transit_dest_bytes += $dest_bytes;
        }
}
$end_time = $date;

foreach $net (keys %total_machine) {
	$count = $total_machine{$net};
	$c_count = &commas($count);
	$total_machine_count{$count} .= "$c_count $net\n";
}
%total_machine = "";

$total_bytes = &commas($total_bytes);
$total_src_bytes = &commas($total_src_bytes);
$total_dest_bytes = &commas($total_dest_bytes);

print "Start time $start_time to $end_time\n";
print "\n\ntotal byte count by machine\n\n$total_bytes all machines ";
print "src bytes: $total_src_bytes dest bytes: $total_dest_bytes\n";
$mbone_bytes = &commas($mbone_bytes); 
$mbone_src_bytes = &commas($mbone_src_bytes);
$mbone_dest_bytes = &commas($mbone_dest_bytes);
print "Mbone: total: $mbone_bytes src: $mbone_src_bytes dest: $mbone_dest_bytes\n";

$snmp_bytes = &commas($snmp_bytes);
$snmp_src_bytes = &commas($snmp_src_bytes);
$snmp_dest_bytes = &commas($snmp_dest_bytes);
print "SNMP: total: $snmp_bytes  src: $snmp_src_bytes dest: $snmp_dest_bytes\n";


$transit_bytes = &commas($transit_bytes);
$transit_src_bytes = &commas($transit_src_bytes);
$transit_dest_bytes = &commas($transit_dest_bytes);
print "Transit: total: $transit_bytes  src: $transit_src_bytes dest: $transit_dest_bytes\n\n";

foreach $count (sort numerically (keys %total_machine_count)) {
	print "$total_machine_count{$count}";
}
%total_machine_count = "";

foreach $net (keys %total_src_dst) {
	$count = $total_src_dst{$net};
	$c_count = &commas($count);
	$total_src_dst_count{$count} .= "$c_count $net\n";
}

print "\n\ntotal byte count by machine pair\n\n";

foreach $count (sort numerically (keys %total_src_dst_count)) {
	print "$total_src_dst_count{$count}";
}

foreach $net (keys %total_net) {
	$count = $total_net{$net};
	$c_count = &commas($count);
	$total_net_count{$count} .= "$c_count $net\n";
}

# print "\n\ntotal byte count by net\n\n";
# 
# foreach $count (sort numerically (keys %total_net_count)) {
# 	print "$total_net_count{$count}";
# }
# 
# foreach $net (keys %total_machine) {
# 	$count = $total_machine{$net};
# 	$c_count = &commas($count);
# 	$total_machine_count{$count} .= "$c_count $net\n";
# }
# 
# print "\n\ntotal byte count by machine\n\n";
# 
# foreach $count (sort numerically (keys %total_machine_count)) {
# 	print "$total_machine_count{$count}";
# }
# 
# foreach $net (keys %source_net) {
# 	$count = $source_net{$net};
# 	$c_count = &commas($count);
# 	$source_net_count{$count} .= "$c_count $net\n";
# }
# 
# print "\n\nSource byte count by net\n\n";
# 
# foreach $count (sort numerically (keys %source_net_count)) {
# 	print "$source_net_count{$count}";
# }
# 
# foreach $net (keys %dest_net) {
# 	$count = $dest_net{$net};
# 	$c_count = &commas($count);
# 	$dest_net_count{$count} .= "$c_count $net\n";
# }
# 
# print "\n\nDestination byte count by net\n\n";
# 
# foreach $count (sort numerically (keys %dest_net_count)) {
# 	print "$dest_net_count{$count}";
# }
# 
# foreach $machine (keys %source_machine) {
# 	$count = $source_machine{$machine};
# 	$c_count = &commas($count);
# 	$source_machine_count{$count} .= "$c_count $machine\n";
# }
# 
# print "\n\nSource byte count by machine\n\n";
# 
# foreach $count (sort numerically (keys %source_machine_count)) {
# 	print "$source_machine_count{$count}";
# }
# 
# foreach $net (keys %dest_machine) {
# 	$count = $dest_machine{$net};
# 	$c_count = &commas($count);
# 	$dest_machine_count{$count} .= "$c_count $net\n";
# }
# 
# print "\n\nDest byte count by machine\n\n";
# 
# foreach $count (sort numerically (keys %dest_machine_count)) {
# 	print "$dest_machine_count{$count}";
# }


sub numerically {$b <=> $a;}
sub commas {
        local($_) = @_;
        1 while s/(.*\d)(\d\d\d)/$1,$2/;
        $_;
}                             


Peter Van Epp / Operations and Technical Support 
Simon Fraser University, Burnaby, B.C. Canada


> 
> Hi all,
> 
> I have argus-1.8.1 in a nice and stable way, where it logs all traffic in
> detailed mode. I would like to write some scripts for extracting data from
> the program's output file. I know fullra is available as a sample program
> for C programmers, but does anyone have any Perl scripts for data extraction
> they can share?
> 
> Thanks,
> 
> -- Lenny
> 
> 



More information about the argus mailing list