Sophie

Sophie

distrib > Fedora > 13 > i386 > media > os > by-pkgid > 3d5150bad1cfbac98406a6ada6605c44 > files > 45

argus-clients-2.0.6.fixes.1-19.fc12.i686.rpm

#! /usr/bin/perl 
# 
#  Argus Client Software.  Tools to read, analyze and manage Argus data.
#  Copyright (c) 2000-2003 QoSient, LLC
#  All rights reserved.
# 
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
# 
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
# 
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
# 
# ragraph-histogram.pl
#  
#
use lib qw( /usr/local/rrdtool-1.0.40/lib/perl ../lib/perl );
use RRDs;
use POSIX;
use strict;


my $tmpfile = tmpnam();
my $RRD     = $tmpfile.".rrd";
my $GIF     = "ragraph.gif";
my @arglist = ();

my $title = "";
my $fill = 1;
my $stack = 1;
my $split = 1;
my $log = 0;
my $rigid = 0;
my $upper = 0;
my $lower = 0;
my $height = 275;
my $width = 800;
my $xaxisstr;

my $timeindex = -1;
my $saddrindex = -1;
my $daddrindex = -1;
my $dportindex = -1;
my $protoindex = -1;
my $probeindex = -1;
my $transindex = -1;
my $avgdurindex = -1;
my $ddurindex = -1;
my $dstimeindex = -1;
my $dltimeindex = -1;
my $srcpktindex = -1;
my $dstpktindex = -1;
my $srcbyteindex = -1;
my $dstbyteindex = -1;
my $srclossindex = -1;
my $dstlossindex = -1;
my $srcjitterindex = -1;
my $dstjitterindex = -1;
  
my $srcdataindex = -1;
my $dstdataindex = -1;

my $minval  = 'U';
my $maxval  = 'U';
 
my @opts = ();
my @columns = ();
my @power = ();
   
my @objects = ();
my @objectlist = ();
my $objectindex = -1;
my $histo = 0;
my $objects;

my $num = 0;

my ($START, $FRAC, $END, $STEP, $COLUMNS, $PROTOS, $PROBES, $RUNS, $ERROR);
my @line_args;

ARG: while (my $arg = shift(@ARGV)) {
   for ($arg) {
      s/^-log//    && do { $log++; next ARG; };
      s/^-fill//   && do { $fill = 0; next ARG; };
      s/^-stack//  && do { $stack = 0; next ARG; };
      s/^-split//  && do { $split = 0; next ARG; };
      s/^-rigid//  && do { $rigid++; next ARG; };
      s/^-height// && do { $height = shift (@ARGV); next ARG; };
      s/^-width//  && do { $width = shift (@ARGV); next ARG; };
      s/^-upper//  && do { $upper = shift (@ARGV); next ARG; };
      s/^-lower//  && do { $lower = shift (@ARGV); next ARG; };
      s/^-title//  && do { $title = shift (@ARGV); next ARG; };
      s/^-w//      && do { $GIF = shift (@ARGV); next ARG; };
      s/^-N//      && do { $num = shift (@ARGV); next ARG; };
      /^-H/        && do { $histo++; };
      s/\(/\\\(/     && do { ; };
      s/\)/\\\)/     && do { ; };
   }
   $arglist[@arglist + 0] = $arg;
}

RagraphProcessArgusData ();
RagraphReadInitialValues ($tmpfile);
RagraphGenerateRRDParameters ($tmpfile);
RagraphGenerateRRD ();
RagraphGenerateGIF ();
RagraphCleanUp ();

exit;


sub RagraphCleanUp {
   `rm $tmpfile $RRD`
}

sub RagraphReadInitialValues {
   my $file = shift;
   my ($i, $k, $v);

   open(SESAME, $file);

   for (1 .. 7) {
      if (my $data = <SESAME>) {
         if ( ($k, $v) = $data =~ m/(\w+)=(.*)/ ) {
            for ($k) {
               /StartTime/ and do {(($START, $FRAC) = $v =~ m/(\d*)\.(.*)/) ;};
               /StopTime/  and do {(($END, $FRAC) = $v =~ m/(\d*)\.(.*)/) ;};
               /BinSize/   and do {(($STEP, $FRAC) = $v =~ m/(\d*)\.(.*)/) ;};
               /Columns/   and do { $COLUMNS = $v;};
               /Bins/      and do {$RUNS = $v;};
               /Protos/    and do {$PROTOS = $v;};
               /Probes/    and do {$PROBES = $v;};
            }
         }
      }
   }
   close(SESAME);
}

sub RagraphProcessArgusData {
   my @args = "";
   if ($histo) {
      @args = ("rahistogram -p6 -G -s ", @arglist, "> $tmpfile");
   } else {
      @args = ("rahistogram -p6 -G -s lasttime ", @arglist, "> $tmpfile");
   }
   
   my $input = `@args`;
}

my @dataobjects = ();
my @typeobjects = ();
my $objwidth = 0;

sub RagraphGenerateRRDParameters {
   my $file = shift;
   my $x;
   @columns = split(/,/, $COLUMNS);

   for ($x = 0; $x < (@columns + 0); $x++) {
      for ($columns[$x]) {
         /Time/		and do {$timeindex = $x; };

         /Host/	        and do {push @typeobjects, $x; $saddrindex = $x; $objwidth = 15; };
         /SrcAddr/	and do {push @typeobjects, $x; $saddrindex = $x; $objwidth = 15; };
         /InAddr/	and do {push @typeobjects, $x; $saddrindex = $x; $objwidth = 15; };
         /OutAddr/	and do {push @typeobjects, $x; $daddrindex = $x; $objwidth = 15; };
         /DstAddr/	and do {push @typeobjects, $x; $daddrindex = $x; $objwidth = 15; };
         /Type/		and do {push @typeobjects, $x; $protoindex = $x; $objwidth = 6; };
         /ProbeId/	and do {push @typeobjects, $x; $probeindex = $x; $objwidth = 15; };
         /Dport/	and do {push @typeobjects, $x; $dportindex = $x; $objwidth = 12; };

         /SrcPkt/	and do {push @dataobjects, $x; $srcpktindex = $x; };
         /InPkt/	and do {push @dataobjects, $x; $srcpktindex = $x; };
         /DstPkt/	and do {push @dataobjects, $x; $dstpktindex = $x; };
         /OutPkt/	and do {push @dataobjects, $x; $dstpktindex = $x; };
         /InAppBytes/	and do {push @dataobjects, $x; $srcbyteindex = $x; };
         /SAppBytes/	and do {push @dataobjects, $x; $srcbyteindex = $x; };
         /SrcBytes/	and do {push @dataobjects, $x; $srcbyteindex = $x; };
         /InBytes/	and do {push @dataobjects, $x; $srcbyteindex = $x; };
         /OutAppBytes/	and do {push @dataobjects, $x; $dstbyteindex = $x; };
         /DAppBytes/	and do {push @dataobjects, $x; $dstbyteindex = $x; };
         /DstBytes/	and do {push @dataobjects, $x; $dstbyteindex = $x; };
         /OutBytes/	and do {push @dataobjects, $x; $dstbyteindex = $x; };
         /pSrc_Loss/	and do {push @dataobjects, $x; $srclossindex = $x; };
         /pDst_Loss/	and do {push @dataobjects, $x; $dstlossindex = $x; };
         /Src_Loss/	and do {push @dataobjects, $x; $srclossindex = $x; };
         /Dst_Loss/	and do {push @dataobjects, $x; $dstlossindex = $x; };
         /SrcJitter/	and do {push @dataobjects, $x; $srcbyteindex = $x; };
         /DstJitter/	and do {push @dataobjects, $x; $dstbyteindex = $x; };
         /Trans/	and do {push @dataobjects, $x; $transindex = $x; };
         /AvgDur/	and do {push @dataobjects, $x; $avgdurindex = $x; };
         /dDur/		and do {push @dataobjects, $x; $ddurindex = $x; };
         /dsTime/	and do {push @dataobjects, $x; $dstimeindex = $x; };
         /dlTime/	and do {push @dataobjects, $x; $dltimeindex = $x; };
      }
   }

   if (($srcpktindex >= 0) || ($srcpktindex >= 0)) {
      if ($srcpktindex >= 0) {
         $srcdataindex = $srcpktindex;
      }
      if ($dstpktindex >= 0) {
         $dstdataindex = $dstpktindex;
      }
   
   } else {
      if (($srcbyteindex >= 0) || ($srcbyteindex >= 0)) {
         if ($srcbyteindex >= 0) {
           $srcdataindex = $srcbyteindex;
         }
         if ($dstbyteindex >= 0) {
            $dstdataindex = $dstbyteindex;
         }
   
      } else {
   
         if (($srcjitterindex >= 0) || ($dstjitterindex >= 0)) {
            if ($srcjitterindex >= 0) {
               $srcdataindex = $srcjitterindex;
            }
            if ($dstjitterindex >= 0) {
               $dstdataindex = $dstjitterindex;
            }
         } else {
            if (($srclossindex >= 0) || ($dstlossindex >= 0)) {
               if ($srclossindex >= 0) {
                  $srcdataindex = $srclossindex;
               }
               if ($dstlossindex >= 0) {
                  $dstdataindex = $dstlossindex;
               }
            }
         }
      }

      if ($avgdurindex >= 0) {
         $srcdataindex = -1;
         $dstdataindex = $avgdurindex;
         $minval = 0.000001;
      }
      if ($ddurindex >= 0) {
         $srcdataindex = -1;
         $dstdataindex = $ddurindex;
      }
      if ($transindex >= 0) {
         $srcdataindex = -1;
         $dstdataindex = $transindex;
      }
      if ($dstimeindex >= 0) {
         $srcdataindex = -1;
         $dstdataindex = $dstimeindex;
      }
      if ($dltimeindex >= 0) {
         $srcdataindex = -1;
         $dstdataindex = $dltimeindex;
      }
   }

   my $ind     = 4;
   my $cnt     = 1;
   my $lineind = 0;
   my $xaxislabel;

   @opts = ("--start", $START, "--step", $STEP);

   if (@typeobjects + 0) {
      my %objectlist = ();

      open(SESAME, $file);
      for (1 .. 7) {
         my $data = <SESAME>;
      }

      while (my $data = <SESAME>) {
         my @items = split(/,/, $data);

         for (my $i = 0; $i < (@typeobjects + 0); $i++) {
            chomp $items[$typeobjects[$i]];

            $objectlist{$items[$typeobjects[$i]]}[0]++;

            for (my $x = 0; $x < (@dataobjects + 0); $x++) {
               chomp $items[$dataobjects[$x]];
               $objectlist{$items[$typeobjects[$i]]}[1] += $items[$dataobjects[$x]];
            }
         }
      }
   
      for my $objs (sort { $objectlist{$b}[0] <=> $objectlist{$a}[0] } keys %objectlist) {
         if (!($objs eq "0.0.0.0")) {
            push @objects, $objs;
         }
      }
   
      if ($num > 0) {
         splice @objects, $num;
      }

      seek(SESAME, 0, 0);
      for (1 .. 7) { 
         my $data = <SESAME>;
      }
   
      if ($protoindex >= 0) {
         if ($daddrindex >= 0) {
            push @objects, "mcast";
         }
      }

      my $ncnt = 0;
      my $ocnt = 0;
   
      for (my $i = 0; $i < (@objects + 0); $i++) {
         for (my $x = 0; $x < (@dataobjects + 0); $x++) {
            for ($columns[$dataobjects[$x]]) {
               /Host|Src|In|SApp/             and do {
                  $opts[$ind++]          = "DS:objectIn$ncnt:GAUGE:$STEP:U:$maxval";
                  $line_args[$lineind++] = "DEF:alphaIn$ncnt=$RRD:objectIn$ncnt:AVERAGE";
                  $line_args[$lineind++] = "CDEF:ralphaIn$ncnt=alphaIn$ncnt,$STEP,/";
                  $ncnt++;
               };

               /Dst|Out|DApp|Trans|Dur|Time/  and do {
                  $opts[$ind++]          = "DS:objectOut$ocnt:GAUGE:$STEP:$minval:U";
                  $line_args[$lineind++] = "DEF:alphaOut$ocnt=$RRD:objectOut$ocnt:AVERAGE";
                  $line_args[$lineind++] = "CDEF:ralphaOut$ocnt=alphaOut$ocnt,$STEP,/";
                  $ocnt++;
               };
            }
         }
      }

   } else {
      my $ncnt = 0;
      my $ocnt = 0;

      shift @columns;
      push @objects, @columns;
      @columns = split(/,/, $COLUMNS);

      for (my $i = 0; $i < (@objects + 0); $i++) {
         for ($objects[$i]) {
            /Host|Src|In|SApp/             and do {
               $opts[$ind++]          = "DS:objectIn$ncnt:GAUGE:$STEP:U:$maxval";
               $line_args[$lineind++] = "DEF:alphaIn$ncnt=$RRD:objectIn$ncnt:AVERAGE";
               $line_args[$lineind++] = "CDEF:ralphaIn$ncnt=alphaIn$ncnt,$STEP,/";
               $ncnt++;
            };

            /Dst|Out|DApp|Trans|Dur|Time/  and do {
               $opts[$ind++]          = "DS:objectOut$ocnt:GAUGE:$STEP:$minval:U";
               $line_args[$lineind++] = "DEF:alphaOut$ocnt=$RRD:objectOut$ocnt:AVERAGE";
               $line_args[$lineind++] = "CDEF:ralphaOut$ocnt=alphaOut$ocnt,$STEP,/";
               $ocnt++;
            };
         }
      }
   }

   my %inColors;
   my %outColors;
   my @incolors  = ("#900000", "#008000", "#002275", "#ead00e", "#de2d1a", "#800080", "#008080", "#808080", "#808000");
   my @outcolors = ("#f00000", "#00e000", "#0000f0", "#ffff66", "#f68d00", "#e000e0", "#00e0e0", "#e0e0e0", "#e0e000");
    
   if ($protoindex >= 0) {
      %inColors  = (
         tcp   => "#a00000", udp   => "#008000", icmp  => "#000080", igmp  => "#008080",
         ospf  => "#800080", pim   => "#808080", mcast => "#808000", ip    => "#707070"
      );
    
      %outColors = (
         tcp   => "#f00000", udp   => "#00f000", icmp  => "#0000e0", igmp  => "#00e0e0",
         ospf  => "#e000e0", pim   => "#e0e0e0", mcast => "#e0e000", ip    => "#b0b0b0"
      );
    
   } else {

      if (@typeobjects + 0) {
         for (my $i = 0; $i < (@objects + 0); $i++) {
            $inColors{$objects[$i]} = $incolors[$i];
            $outColors{$objects[$i]} = $outcolors[$i];
         }
      } else {
         $inColors{$objects[0]} = $incolors[0];
         $outColors{$objects[0]} = $outcolors[0];
      }
   }
   
   if ((@dataobjects + 0) == 0) {
      printf "usage: $0 metric (srcid | proto [daddr] | dport) [-title \"title\"] [ra-options]\n";
   }
   
   if (($srcdataindex < 0) || ($dstdataindex < 0)) {
      $split = 0;
   }
   
   my $col;
   my $date;
   
   if (($END - $START) > (60 * 60 * 24)) {
      $date  = strftime "%a %b %e %Y", localtime($START);
      $date .= " - ";
      $date .= strftime "%a %b %e %Y", localtime($END);
    
   } else {
      $date  = strftime "%a %b %e %Y", localtime($START);
   }
    
   $line_args[$lineind++] = "COMMENT:$date\\c";
   $line_args[$lineind++] = "COMMENT:\\s";
   
   if ($fill && $split) {
      $line_args[$lineind++] = "HRULE:0#ffffff";
   } else {
      $line_args[$lineind++] = "HRULE:0#888888";
   }
   
   my $style;
   my $method;
   
   if ($fill) {
      $style = "AREA";
   } else {
      $style = "LINE2";
   }
   
   if ($stack) {
      $method = "STACK";
   } else {
      $method = $style;
   }

   if (@typeobjects + 0) {
      my $ncnt = 0;
      my $ocnt = 0;
      my $object;

      for (my $i = 0; $i < (@objects + 0); $i++) {
         for (my $x = 0; $x < (@dataobjects + 0); $x++) {
            for ($columns[$dataobjects[$x]]) {
               /Dst|Out|DApp/  and do {
                  if (!($col = $outColors{$objects[$i]})) {
                     $col = "#707070";
                  }
                  $object = sprintf "%-4.4s%-*.*s\\J", "out ", $objwidth, $objwidth, $objects[$i];
                  if ($ocnt == 0) {
                     $line_args[$lineind++] = "$style:ralphaOut$ocnt$col:$object:";
                  } else {
                     $line_args[$lineind++] = "$method:ralphaOut$ocnt$col:$object:";
                  }
                  $ocnt++;
               };
 
               /Trans|Dur|Time/  and do {
                  if (!($col = $inColors{$objects[$i]})) {
                     $col = "#707070";
                  }
                  $object = sprintf "%-*.*s\\J", $objwidth, $objwidth, $objects[$i];
                  if ($ocnt == 0) {
                     $line_args[$lineind++] = "$style:ralphaOut$ocnt$col:$object:";
                  } else {
                     $line_args[$lineind++] = "$method:ralphaOut$ocnt$col:$object:";
                  }
                  $ocnt++;
               };
            }
         }
      }

      if ($ocnt > 0) {
         $line_args[$lineind++] = "COMMENT:\\s";
         $line_args[$lineind++] = "COMMENT:\\s";
         if ($ocnt > 7) {
            $line_args[$lineind++] = "COMMENT:\\s";
         }
      }

      for (my $i = 0; $i < (@objects + 0); $i++) {
         for (my $x = 0; $x < (@dataobjects + 0); $x++) {
            for ($columns[$dataobjects[$x]]) {
               /Host|Src|In|SApp/   and do {
                  if (!($col = $inColors{$objects[$i]})) {
                     $col = "#b0b0b0";
                  }
                  $object = sprintf "%-4.4s%-*.*s\\J", " in ", $objwidth, $objwidth, $objects[$i];
                  if ($ncnt == 0) {
                     $line_args[$lineind++] = "$style:ralphaIn$ncnt$col:$object:";
                  } else {
                     $line_args[$lineind++] = "$method:ralphaIn$ncnt$col:$object:";
                  }
                  $ncnt++;
               };
            }
         }
      }

   } else {
      my $ncnt = 0;
      my $ocnt = 0;
      for (my $x = 0; $x < (@objects + 0); $x++) {
         for (my $object = $objects[$x]) {
            /Host|Src|In|SApp/    and do {
               if (!($col = $incolors[$ncnt])) {
                  $col = "#707070";
               }
               if ($ncnt == 0) {
                  $line_args[$lineind++] = "$style:ralphaIn$ncnt$col:$object";
               } else {
                  $line_args[$lineind++] = "$method:ralphaIn$ncnt$col:$object";
               }
               $ncnt++;
            };
            /Dst|Out|DApp|Trans|Dur|Time/   and do {
               if (!($col = $outcolors[$ocnt])) {
                  $col = "#b0b0b0";
               }
               if ($ocnt == 0) {
                  $line_args[$lineind++] = "$style:ralphaOut$ocnt$col:$object";
               } else {
                  $line_args[$lineind++] = "$method:ralphaOut$ocnt$col:$object";
               }
               $ocnt++;
            };
         }
      }
   }
   
my $xaxislabels = 0;

   for (my $x = 0; $x < (@columns + 0); $x++) {
      for ($columns[$x]) {
         /Pkt/     and do {$power[$x] = 1.0 ;      $xaxislabels++; $xaxislabel = " pkts/sec" ;};
         /Bytes/   and do {$power[$x] = 1.0 * 8.0; $xaxislabels++; $xaxislabel = "bits/sec" ;};
         /Jitter/  and do {$power[$x] = $STEP;     $xaxislabels++; $xaxislabel = "Jitter (uSecs)" ;};
         /Loss/    and do {$power[$x] = 1.0 ;      $xaxislabels++; $xaxislabel = "Loss (pkts/sec)" ;};
         /Trans/   and do {$power[$x] = 1.0 ;      $xaxislabels++; $xaxislabel = "Concurrent Transactions" ;};
         /AvgDur/  and do {$power[$x] = $STEP ;    $xaxislabels++; $xaxislabel = "Average Transaction Time (secs)" ;};
         /dDur/    and do {$power[$x] = $STEP ;    $xaxislabels++; $xaxislabel = "Network Transit Time (secs)" ;};
         /dsTime/  and do {$power[$x] = $STEP ;    $xaxislabels++; $xaxislabel = "Delta StartTime (secs)" ;};
         /dlTime/  and do {$power[$x] = $STEP ;    $xaxislabels++; $xaxislabel = "Delta LastTime (secs)" ;};
      }
   }

   if ($xaxislabels > 1) {
      if (($ddurindex >= 0) && (($dstimeindex >= 0) || ($dltimeindex >= 0))) {
         $xaxislabel = "Delta Time (secs)" ;
      }
   }
   
   if ($split) {
      if ($objectindex >= 0) {
         $xaxisstr = "inbound(-).outbound(+) ";
      } else {
         $xaxisstr = "dest(-).src(+) ";
      }
   } else {
      $xaxisstr = "";
   }
    
   $xaxisstr .= $xaxislabel;
   $opts[$ind] = "RRA:AVERAGE:0.5:1:$RUNS"; 
}


sub RagraphGenerateRRD {
   my $data;

   open(SESAME, $tmpfile);
    
   for (1 .. 7) {
      $data = <SESAME>;
   }
   
   RRDs::create $RRD, @opts;
   
   $ERROR = RRDs::error;
   if ($ERROR) {
     die "$0: unable to create `$RRD': $ERROR\n";
   }
   
   my $last = RRDs::last $RRD;
   if ($ERROR = RRDs::error) {
     die "$0: unable to get last `$RRD': $ERROR\n";
   }
   
   @opts = ();

   my $startime = $START;
   my $lasttime = $START + $STEP;
   
   my %objectvals;
   my %bins;
   my @vals;
   
   for (my $i = 0; $i < (@objects + 0); $i++) {
      $objectvals{$objects[$i], 'in'} = 0;
      $objectvals{$objects[$i], 'out'} = 0;
   }

   while (my $data = <SESAME>) {
      @opts = split(/,/, $data);
   
      my $thistime = $opts[0];
      if ($bins{$thistime}++ == 0) {
      }

      if (@typeobjects + 0) {
         for (my $i = 0; $i < (@typeobjects + 0); $i++) {
            my $thisobject = $opts[$typeobjects[$i]];
            chomp $thisobject;
  
            if ($daddrindex >= 0) {
               my @addr = split(/./, $opts[2]);
               if (($addr[0] & 0xF0) == 0xE0) {
                  $thisobject = "mcast";
               }
            }

            for (my $x = 0; $x < (@dataobjects + 0); $x++) {
               my $dataindex = $dataobjects[$x];
               for ($columns[$dataindex]) {
                  /Host|Src|In|SApp/             and do {
                     $objectvals{$thistime, $thisobject, 'in'} += $opts[$dataindex] * $power[$dataindex];
                  };
 
                  /Dst|Out|DApp|Trans|Dur|Time/  and do {
                     $objectvals{$thistime, $thisobject,'out'} += $opts[$dataindex] * $power[$dataindex];
                  };
               }
            }
         }

      } else {
         my $label;
         for (my $i = 0; $i < (@objects + 0); $i++) {
            for ($objects[$i]) {
               /Host|Src|In|SApp/             and do { $label = 'in'; };
               /Dst|Out|DApp|Trans|Dur|Time/  and do { $label = 'out'; };
            }
            my $value = $opts[$i+1];
            my $power = $power[$i+1];

            $objectvals{$thistime, $objects[$i], $label} += $opts[$i + 1] * $power[$i + 1];
         }
      }
   }
   
   close(SESAME);

   for my $thisbin (sort keys %bins) {
      my $prime = $thisbin;
      my $nvalue = 0;
      my $ovalue = 0;

      for (my $i = 0; $i < (@objects + 0); $i++) {
         if (@typeobjects + 0) {
            for (my $x = 0; $x < (@dataobjects + 0); $x++) {
               my $dataindex = $dataobjects[$x];

               for ($columns[$dataindex]) {
                  /Host|Src|In|SApp/             and do {
                     if (!($nvalue = $objectvals{$thisbin, $objects[$i], 'in'})) {
                        $nvalue = 0;
                     }
                     if ($split) {
                        if ($nvalue == 0) {
                           $prime .= ":$nvalue";
                        } else {
                           $prime .= ":-$nvalue";
                        }
                     } else {
                        $prime .= ":$nvalue";
                     }
                  };
 
                  /Dst|Out|DApp|Trans|Dur|Time/  and do {
                     if (!($ovalue = $objectvals{$thisbin, $objects[$i], 'out'})) {
                        $ovalue = 0;
                     }
                     $prime .= ":$ovalue";
                  };
               }
            }

         } else {
            my $label;
            for ($objects[$i]) {
               /Host|Src|In|SApp/             and do { $label = 'in'; };
               /Dst|Out|DApp|Trans|Dur|Time/  and do { $label = 'out'; };
            }

            $nvalue = $objectvals{$thisbin, $objects[$i], $label};
            if ($split && ($label eq 'in')) {
               $prime .= ":-$nvalue";
            } else {
               $prime .= ":$nvalue";
            }
         }
      }

      RRDs::update $RRD, "$prime";

      if ($ERROR = RRDs::error) {
         die "$0: unable to update `$RRD': $ERROR\n";
      }
   }
}


sub RagraphGenerateGIF {
   my @rrd_gifs = ($RRD, $GIF);
   
   my @rrd_args = (
         "--base", "1000",
         "--vertical-label", $xaxisstr,
         "--start", $START,
         "--end", $END,
         "--interlace", "--imgformat","GIF",
   );
   
   if ($title) {
      push @rrd_args, ("--title", $title); 
   }
   
   if ($rigid) {
      @rrd_args[++$#rrd_args] = "--rigid";
   }
   if ($log) {
      @rrd_args[++$#rrd_args] = "--log";
   }
   if ($width) {
      @rrd_args[++$#rrd_args] = "--width";
      @rrd_args[++$#rrd_args] = $width;
   }
   if ($height) {
      @rrd_args[++$#rrd_args] = "--height";
      @rrd_args[++$#rrd_args] = $height;
   }
   if (!($rigid) && ($upper || $lower)) {
      @rrd_args[++$#rrd_args] = "--rigid";
   }
   if ($upper) {
      @rrd_args[++$#rrd_args] = "--upper-limit";
      @rrd_args[++$#rrd_args] = $upper;
   }
   if ($lower) {
      @rrd_args[++$#rrd_args] = "--lower-limit";
      @rrd_args[++$#rrd_args] = $lower;
   }
   
   push @rrd_args, @line_args;

   while (@rrd_gifs) {
     my $RRD = shift(@rrd_gifs);
     my $GIF = shift(@rrd_gifs);
   
     my ($graphret,$xs,$ys) = RRDs::graph $GIF, @rrd_args;
   
      if ($ERROR = RRDs::error) {
         print "ERROR: $ERROR\n";
      }
   }
}