Projects Personal Contact Rss
 


System Utilities / RadiusSplit

Source Text

#!/usr/bin/perl
#
# radiussplit - Split the Radius logs into per user logs.
#
# This program should be run as a 'pipe', e.g. in a script:
# tail -f /etc/raddb/detail | radiussplit


# Author:       Paul Gregg <pgregg@pgregg.com>
# Date:         10 July 1998
# Summary:      Radius,  User's activity,  Port usage, Log/Detail files.
# Version:      1.0
# Copyright:    1997,1998,1999,2000 Paul Gregg <pgregg@pgregg.com>
# Copy Policy:  Free to copy and distribute provided all headers are left
#               intact and no charge is made for this program.  I would
#               appreciate copies of any modifications to the script.
# URL:          http://www.pgregg.com/projects/
# FTP:          None yet (I'm lazy)
#
#
# Supported:    Livingston Radius V2.0+, V1.16
#               Merit Radius
#               Ascend Radius
#               Dale Reed's RadiusNT
#               Radiator Perl Radius Server


#require "ctime.pl";
#use POSIX;

#Unbuffered output
$| = 1;

# gzcat - 'cat for .gz / gzip files'
# If you don't have gzcat and do have gzip then use: ln gzip gzcat
$GZCAT = "/usr/local/bin/gzcat";

# zcat - 'cat for .Z / compressed files'
$ZCAT = "/usr/bin/zcat";

# Livingston Radius V1.16+, RadiusNT, Merit Radius, and some Ascend:
# e.g. Record stamp of type: Tue Jul  1 00:28:34 1997
$RECORD_DATE_FMT = "DAY MON MDAY HH:MM:SS YEAR";

# Ascend Radius:
# e.g. Record stamp of type: 23-07-1997 00:02:55
#$RECORD_DATE_FMT = "MDAY-MON-YEAR HH:MM:SS";

#### You should not have to modify anything below here


@weekdays = ( "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" );
%weekhash = ( "Sun", 0, "Mon", 1, "Tue", 2, "Wed", 3, "Thu", 4,
                "Fri", 5, "Sat", 6 );
@months = (     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" );
%monthshash = ( "Jan", 0, "Feb", 1, "Mar", 2, "Apr", 3, "May", 4, "Jun", 5,
                "Jul", 6, "Aug", 7, "Sep", 8, "Oct", 9, "Nov", 10, "Dec", 11);


#Extract all command line arguments
$args=1 if ( $#ARGV > 0 );
while ($args) {
  $flag = shift(@ARGV);
  if ($flag eq "--help") { &help; exit; }
  if (substr($flag, 0, 1) eq '-') {
    #if ($flag =~ /[tbharsH]/) {
    #  $arg{'s'} = TRUE if ($flag =~ /s/);
    #} else {
      $arg{substr($flag, 1, 1)} = shift(@ARGV);
    #}
  } else {
    die "Usage: $usage\n Error in $flag - not a valid flag.\n";
  }
  $args = 0 if (!$ARGV[0]);
}

$DEFOUT = "/var/adm/radacct/portmaster1/users";

if ( (!defined($arg{'o'})) ) {
  warn "No output directory specified - using $DEFOUT/YYYY/MM/\n";
  $arg{'o'} = "THISMONTH";
}

printf ( "Sending output to directory: %s\n", $arg{'o'} ) if ($DEBUG ge 1);

$/=""; # 'line' split on single blank lines


while ( $file_record = <STDIN> ) {
  $DIR = $arg{'o'};
  @record = ();
  @record = split(/\n/, $file_record);
  process_record(@record);

  if ( $AcctStatusType eq "Stop" && $UserName) {

    if ($DIR eq "THISMONTH") {
      my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
                        localtime($Timestamp);
      $year += 1900;
      $DIR = sprintf("%s/%4d/%02d", $DEFOUT, $year, $mon+1);
      if ( ! -d "$DIR" ) { makedirs($DIR); }
    }

    $line = join ("\n", @record) . "\n\n";
    print ".";
    if ( -f "$DIR/$UserName" ) {
      open(OUT, ">>$DIR/$UserName") || die "Can't open file $DIR/$UserName: $!\n";
    } else {
      open(OUT, ">$DIR/$UserName") || warn "Can't open file $DIR/$UserName: $!\n";
    }
    #for (@record) {
    #  print OUT "$_\n";
    #}
    ##print OUT @record;
    #print OUT "\n";
    print OUT $line;
    close(OUT);
  }
}

exit;

sub process_record {
  my @new_record = @_;

  $AcctSessionId = ""; $UserName = ""; $NASPort=""; $NASPortType="";
  $NASIPAddress = "";
  $AcctStatusType=""; $AcctSessionTime=""; $AcctInputOctets="";
  $AcctOutputOctets=""; $AcctTerminateCause=""; $ServiceType="";
  $FramedProtocol=""; $FramedIPAddress=""; $Timestamp=""; $AcctDelayTime="";
  $ConnectInfo=""; $REC=""; $VALUE="";
  foreach (@new_record) {  # Collect data
    s/^\s+//;  #Strip leading spaces.
    print " -> $_" if ($DEBUG ge 3);
    chomp;
    ($REC, $VALUE) = split(" = ", $_, 2);
    next if ( ! $VALUE ); # line isn't a REC = VALUE type.
    $REC =~ s/-//g;  # Strip the '-'s from the REC name.


    ${$REC} = $VALUE; # Store this REC = VALUE
    print ":$REC: - :$VALUE:\n" if ($DEBUG ge 2);

    return if ($REC eq "AcctStatusType" && $VALUE eq "Start");
  }

  # Check for a valid Timestamp - if none, generate one from record stamp
  if ($Timestamp == "") {
    my $recdate = $record[0];
    chomp $recdate;
    $recdate =~ s/ +/ /g;
    $recdate =~ s/:/ /g;
    my @recdates = split(/ /, $recdate);
    my $stdfmt = $RECORD_DATE_FMT;
    $stdfmt =~ s/:/ /g;
    my @stds = split(/ /, $stdfmt);
    while ($foo = shift (@stds)) {
      $val = shift(@recdates);
      $$foo = $val;
    }
    #print "$DAY, $MON, $MDAY, $HH, $MM, $SS, $YEAR\n";
    $Timestamp = calendar_time( $DAY, $MON, $MDAY, $HH, $MM, $SS, $YEAR );
    #print "TIMESTAMP = $Timestamp\n";
  }

  # Remove "" marks from $AcctSessionId, $UserName and $ConnectInfo
  $UserName =~ s/\"//g;
  $AcctSessionId =~ s/\"//g;
  $ConnectInfo =~ s/\"//g;

  # And correct the Timestamp backwards if there was an accounting delay
  $Timestamp -= $AcctDelayTime;
  $AcctDelayTime = 0;

  # Generate a Unique ID from AcctSessionId, UserName, NASPort and NASIPAddress
  $UniqueId = "$UserName/$AcctSessionId/$NASPort/$NASIPAddress";

}

sub calendar_time {
  my $day = shift;
  my $month = shift;
  my $mday = shift;
  my $hour = shift;
  my $min = shift;
  my $sec = shift;
  my $year = shift;
  $year -= 1900 if ($year >= 1900);
  #printf "$sec:$min:$hour $mday, $month=$monthshash{$month}, $year, $day=$weekhash{$day}\n";
  #my $cal = mktime($sec, $min, $hour,  $mday, $monthshash{$month}, $year,
  #              $weekhash{$day}, 0, 0);
  return $cal;
}


sub makedirs {
  # Ensure the directory exists
  my $dir = shift;
  return if ( -d $dir );
  print "  Making directory $dir\n";
  if ( ! mkdir($dir,0755) ) { # Failed, lets recurse upwards to fix
    my $lastslashpos = rindex ($dir, "/"); # Find the last / in the dir
    my $dirup = substr( $dir, 0, $lastslashpos );
    makedirs($dirup);
    mkdir($dir,0755)
  }
}



All content © Paul Gregg, 1994 - 2024
Page last updated: 15 July 2008 23:06:07.
This site https://pgregg.com has been online since 5th October 2000
Previous websites live at various URLs since 1994