#!/usr/bin/perl
my $pid = fork();
if($pid!=0){
   exit 0;
}
use strict;

$SIG{TERM} = sub {exit 0;}; # I know it's dirty

my $html="/set/this/to/your/output.html"; #File that will be create for show stats
my $refreshRate="60"; #in Seconds
my $InetDev="ppp0";  #our Inet Device
my $LocalDev="eth0"; #our Local net Device

#Programms
my $TC="/sbin/tc";
my $IFCONFIG="/sbin/ifconfig";
my $GREP="/bin/grep";
my $CUT="/bin/cut";

if(!-f $TC){print "$TC not exist!\nexit now!\n";exit 1;}
if(!-f $IFCONFIG){print "$IFCONFIG not exist!\nexit now!\n";exit 1;}
if(!-f $GREP){print "$GREP not exist!\nexit now!\n";exit 1;}
if(!-f $CUT){print "$CUT not exist!\nexit now!\n";exit 1;}

my $cmd="$TC -s -d class show dev $InetDev";

#mldonkey must be runnig on the same machine
#my $MLinternIP=`$IFCONFIG $LocalDev |$GREP inet| $CUT -d : -f 2| $CUT -d\\  -f1`;

#$MLinternIP=~ s/\n//g;
my $html_head="
   <head>
      <title>QoS Status</title>
      <meta http-equiv=\"refresh\" content=\"$refreshRate;\">
      <link href=\"h.css\" rel=\"stylesheet\" type=\"text/css\">
   <head/>
   <body>
";


#Table Head
my @order=("name","sendrate","sent","pkts","dropped","overlimits","parent","leaf","rate","ceil","prio","quantum");

while (1){
   my %classes;
   open(PIPE, $cmd."|") or die "Fehler in Pipe: $!\n";#
      my $lastclass;
      while(my $input = <PIPE>){
         if($input=~ /^class/){
            my @tmp=split(/ /,$input);
            $lastclass=$tmp[2];
         }
         $classes{$lastclass}.=$input;
      }
   
   close(PIPE) or die "Fehler in Pipe: $!,$?\n";
   
   open(STATS,">$html")or die "Error open File $html : $!\n";#
      print STATS $html_head;
      print STATS "<p><table width='90%'class='cs'><tr>";
      for(my $i=0;$i<=$#order;$i++){
         print STATS "<td class='srh'>".uc($order[$i])."</td>";
      }      
      print STATS "</tr>\n";
      foreach my $key (sort { $a cmp  $b} keys %classes){   
         $classes{$key}=MakeParam($classes{$key});
         my %row=%{$classes{$key}};
         print STATS "<tr>\n";
         for(my $i=0;$i<=$#order;$i++){            
               print STATS "<td class='sr'>$row{$order[$i]}</td>";            
         }
         print STATS "</tr>";
      }
   close(STATS) or die "Error close File $html : $!\n";#
   sleep $refreshRate;
}

sub MakeParam{
   my $class=shift;
   my @Lines=split(/\n/,$class);
   my %parm;
   for(my $i=0;$i<=$#Lines;$i++){
      $Lines[$i]=~ s/^ | $//;
      $Lines[$i]=~ s/  / /g;
      my @tmp=split(/ /,$Lines[$i]);
      if(lc($Lines[$i])=~ /^class/){
         if(lc($tmp[3]) eq "root"){
#  0   1   2   3     4      5      6   7      8      9            
#class htb 1:1 root rate 120Kbit ceil 120Kbit burst 1752b/8 mpu 0b cburst 1752b/8 mpu 0b level 7
            $parm{"parent"}="ROOT CLASS";
            $parm{$tmp[0]}=$tmp[1];
            $parm{"name"}=$tmp[2];
            for(my $z=4;$z<=8;$z+=2){
               $parm{lc($tmp[$z])}=$tmp[$z+1];
            }
         }else{
#   0   1   2      3    4     5     6     7     8      9    10   11   12     13   14     15     16
#class htb 1:42 parent 1:41 leaf 42: prio 0 quantum 2560 rate 20Kbit ceil 105Kbit burst 1624b/8 mpu 0b cburst 1733b/8 mpu 0b level 0
            $parm{$tmp[3]}=$tmp[4];
            $parm{$tmp[0]}=$tmp[1];
            $parm{"name"}=$tmp[2];
            for(my $z=5;$z<=15;$z+=2){
               $parm{lc($tmp[$z])}=$tmp[$z+1];
            }
         }         
      }elsif(lc($Lines[$i])=~ /^sent/){
         #Sent 13202905 bytes 200362 pkts (dropped 0, overlimits 0)
         $parm{lc($tmp[0])}=sprintf("%2.2f",($tmp[1]/1024/1024))." MB";
         $parm{lc($tmp[4])}=$tmp[3];
         $tmp[5]=~ s/^\(//;
         $tmp[6]=~ s/,$//;
         $parm{lc($tmp[5])}=$tmp[6];
         $tmp[8]=~ s/\)$//;
         $parm{lc($tmp[7])}=$tmp[8];
      }elsif(lc($Lines[$i])=~ /^rate/){
         #rate 349bps 5pps
         if($tmp[1]=~ /bps$/){
            $parm{"sendrate"}=sprintf("%2.2f",($tmp[1]/1024))." KB/s" ;
         }else{
            $parm{"sendrate"}=$tmp[1];
         }
      }
   }
   return \%parm;
} 
