#!/usr/bin/perl # uutraf.pl -- UUCP Traffic Analyzer # SCCS Status : @(#)@ uutraf 1.8 # Author : Johan Vromans # Created On : *** # Last Modified By: Johan Vromans # Last Modified On: Mon Aug 30 15:02:22 1993 # Update Count : 6 # Status : OK # Requires: : Perl V4 or later # Reads UUCP syslog, and generates a report from it. # # Created by Johan Vromans # Loosely based on an idea by Greg Hackney (hack@texbell.swbt.com) # Usage: uutraf [-taylor|-hdb|-bnu|-bsd] [syslog] # Logfile formats: # # BSD: # # jv mhres (2/23-5:18) (698818735) received 135 b 2 secs # root mhres (2/23-5:19) (698818742) sent 2365 b 3 secs, Pk: 38, Rxmt: 0 # # HDB: # # uunet!uucp M (12/10-09:04:22) (C,16390,1) [ttyXX] <- 2371 / 5.000 secs, \ # 474 bytes/sec # # Taylor: # # jv mhres (1992-02-24 20:49:04.06) sent 16234 bytes in 148.780 seconds \ # (109 bytes/sec) # jv mhres (1992-02-24 21:04:05.76) received 449 bytes in 6.550 seconds \ # (68 bytes/sec) $uucp_type = "gnu"; %hosts = (); # hosts seen %bytes_in = (); # of bytes received from host %bytes_out = (); # of bytes sent to host %secs_in = (); # of seconds connect for recving %secs_out = (); # of seconds connect for sending %files_in = (); # of input requests %files_out = (); # of output requests # read info, break the lines and tally if ( $ARGV[0] =~ /^-/ ) { ($uucp_type = substr (shift (@ARGV), 1)) =~ tr/A-Z/a-z/; } if ( $uucp_type eq "taylor" || $uucp_type eq "gnu" ) { @ARGV = ("/usr/local/spool/uucp/Stats") unless $#ARGV >= 0; $pat = "^[^ ]+ ([^ ]+) \\(([-0-9:\\/ .]+)\\) " . "(sent|received) (\\d+) bytes in (\\d+)\\.(\\d+) seconds"; $uucp_type = 0; $recv = "received"; } elsif ( $uucp_type eq "hdb" || $uucp_type eq "bnu" ) { @ARGV = ("/usr/spool/uucp/.Admin/xferstats") unless $#ARGV >= 0; $pat = "^([^!]+)![^(]+\\(([-0-9:\\/]+)\\).+([<>])-? " . "(\\d+) \\/ (\\d+)\\.(\\d+) secs"; $uucp_type = 1; $recv = "<"; } elsif ( $uucp_type eq "bsd" || $uucp_type eq "v7" ) { @ARGV = ("/usr/spool/uucp/SYSLOG") unless $#ARGV >= 0; $pat = "^[^ ]+ ([^ ]+) \\(([-0-9:\\/]+)\\) \\([^)]+\\) " . "(sent|received) (\\d+) b (\\d+) secs"; $uucp_type = 2; $recv = "received"; } else { die ("FATAL: Unknown UUCP type: $uucp_type\n"); } $garbage = 0; while ( <> ) { unless ( /$pat/o ) { print STDERR "$_"; next if /failed/; if ( $garbage++ > 10 ) { die ("FATAL: Too much garbage; wrong UUCP type?\n"); } next; } # gather timestamps $last_date = $2; $first_date = $last_date unless defined $first_date; # initialize new hosts unless ( defined $hosts{$1} ) { $hosts{$1} = $files_in{$1} = $files_out{$1} = $bytes_in{$1} = $bytes_out{$1} = $secs_in{$1} = $secs_out{$1} = 0; } # Taylor and HDB have milliseconds, BSD has not. $secs = ($uucp_type == 2) ? ($5 + ($5 == 0 ? 0.5 : 0)) : ($5 + $6/1000); # tally if ( $3 eq $recv ) { # recv $bytes_in{$1} += $4; $files_in{$1}++; $secs_in{$1} += $secs; } else { # xmit $bytes_out{$1} += $4; $files_out{$1}++; $secs_out{$1} += $secs; } $garbage = 0; } @hosts = keys (%hosts); die ("No info found, stopped\n") if $#hosts < 0; ################ report section ################ $thishost = &gethostname(); $thishost = (defined $thishost) ? "on node $thishost" : "report"; if ( $uucp_type eq 0 ) { # Taylor UUCP substr ($first_date, 16) = ""; substr ($last_date, 16) = ""; } format std_head = @||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| "UUCP traffic $thishost from $first_date to $last_date" Remote -----------K-Bytes----------- ----Hours---- --Avg CPS-- --Files-- Host Recv Sent Total Recv Sent Recv Sent Recv Sent . format std_out = @<<<<<<< @>>>>>>>> @>>>>>>>> @>>>>>>>> @>>>>> @>>>>> @>>>> @>>>> @>>> @>>> $Zhost, $Zi_bytes, $Zo_bytes, $Zt_bytes, $Zi_hrs, $Zo_hrs, $Zi_acps, $Zo_acps, $Zi_count, $Zo_count . $^ = "std_head"; $~ = "std_out"; &print_dashes (); reset "T"; # reset totals foreach $host (@hosts) { &print_line ($host, $bytes_in{$host}, $bytes_out{$host}, $secs_in{$host}, $secs_out{$host}, $files_in{$host}, $files_out{$host}); } &print_dashes (); &print_line ("Total", $Ti_bytes, $To_bytes, $Ti_secs, $To_secs, $Ti_count, $To_count); ################ that's it ################ sub print_line { reset "Z"; # reset print fields local ($Zhost, $Zi_bytes, $Zo_bytes, $Zi_secs, $Zo_secs, $Zi_count, $Zo_count) = @_; $Ti_bytes += $Zi_bytes; $To_bytes += $Zo_bytes; $Zt_bytes = $Zi_bytes + $Zo_bytes; $Tt_bytes += $Zt_bytes; $Zi_acps = ($Zi_secs > 0) ? sprintf ("%.0f", $Zi_bytes/$Zi_secs) : "0"; $Zo_acps = ($Zo_secs > 0) ? sprintf ("%.0f", $Zo_bytes/$Zo_secs) : "0"; $Zi_bytes = sprintf ("%.1f", $Zi_bytes/1000); $Zo_bytes = sprintf ("%.1f", $Zo_bytes/1000); $Zt_bytes = sprintf ("%.1f", $Zt_bytes/1000); $Zi_hrs = sprintf ("%.1f", $Zi_secs/3600); $Zo_hrs = sprintf ("%.1f", $Zo_secs/3600); $Ti_secs += $Zi_secs; $To_secs += $Zo_secs; $Ti_count += $Zi_count; $To_count += $Zo_count; write; } sub print_dashes { $Zhost = $Zi_bytes = $Zo_bytes = $Zt_bytes = $Zi_hrs = $Zo_hrs = $Zi_acps = $Zo_acps = $Zi_count = $Zo_count = "------------"; write; # easy, isn't it? } ################ missing ################ sub gethostname { $ENV{"SHELL"} = "/bin/sh"; $try = `hostname 2>/dev/null`; chop $try; return $+ if $try =~ /^[-.\w]+$/; $try = `uname -n 2>/dev/null`; chop $try; return $+ if $try =~ /^[-.\w]+$/; $try = `uuname -l 2>/dev/null`; chop $try; return $+ if $try =~ /^[-.\w]+$/; return undef; }