#!/usr/bin/perl
# $Id: tcmenu,v 1.20 2001/02/25 12:06:28 stes Exp $

$IPMENU=$ENV{'IPMENU'};
require "$IPMENU/ipmenu.lib";

$level=$ARGV[0];

$menu="$TMP/Menu.$$";
if (!open(MENU,">$menu")) {
  print "`message \"Problem writing to $menu\"`nop\n";exit 0;
}

if ($level == 0) {
  $title='Links';
}
if ($level == 1) {
  $dev=$ARGV[1];
  $title=$dev;
}
if ($level == 2) {
  $dev=$ARGV[1];
  ($handle,$type)=split(/:/,$ARGV[2]);
  $title=uc($type);
}
if ($level == 3) {
  $dev=$ARGV[1];
  ($handle,$type)=split(/:/,$ARGV[2]);
  $classid=$ARGV[3];
  $title='Classes';
}
if ($level == 4 || $level == 5) {
  $dev=$ARGV[1];
  ($handle,$type)=split(/:/,$ARGV[2]);
  $parentid=$ARGV[3];
  $classid=$ARGV[4];
  $title="$handle:$classid";
}
if ($level == 6) {
  $dev=$ARGV[1];
  ($handle,$type)=split(/:/,$ARGV[2]);
  $title=uc($type);
}

sub printaddqdisc
{
  my ($m) = @_;
  print $m "name=Add TBF\n";
  print $m "action=`$IPMENU/addtbf 'dev $dev root'`\n";
  print $m "itemmsg=Add token bucket filter\n";
  print $m "name=Add PFIFO\n";
  print $m "action=`$IPMENU/addfifo 'dev $dev root pfifo'`\n";
  print $m "itemmsg=Add 1-band packet fifo\n";
  print $m "name=Add BFIFO\n";
  print $m "action=`$IPMENU/addfifo 'dev $dev root bfifo'`\n";
  print $m "itemmsg=Add 1-band byte backlog fifo\n";
  print $m "name=Add PRIO\n";
  print $m "action=`$IPMENU/addprio 'dev $dev root prio'`\n";
  print $m "itemmsg=Add 3-band priority scheduler\n";
  print $m "name=Add SFQ\n";
  print $m "action=`$IPMENU/addsfq 'dev $dev root sfq'`\n";
  print $m "itemmsg=Add stochastic fairness queueing discipline\n";
  print $m "name=Add RED\n";
  print $m "action=`$IPMENU/addred 'dev $dev root red'`\n";
  print $m "itemmsg=Add random early detection queue\n";
  print $m "name=Add CBQ\n";
  print $m "action=`$IPMENU/addcbq 'dev $dev root cbq'`\n";
  print $m "itemmsg=Add class based queuing\n";
}

sub printaddqdisc2
{
  my ($m,$p) = @_;
  print $m "name=Add TBF\n";
  print $m "action=`$IPMENU/addtbf 'dev $dev parent $p'`\n";
  print $m "itemmsg=Add token bucket filter\n";
  print $m "name=Add PFIFO\n";
  print $m "action=`$IPMENU/addfifo 'dev $dev parent $p pfifo'`\n";
  print $m "itemmsg=Add 1-band packet fifo\n";
  print $m "name=Add BFIFO\n";
  print $m "action=`$IPMENU/addfifo 'dev $dev parent $p bfifo'`\n";
  print $m "itemmsg=Add 1-band byte backlog fifo\n";
  print $m "name=Add PRIO\n";
  print $m "action=`$IPMENU/addprio 'dev $dev parent $p prio'`\n";
  print $m "itemmsg=Add 3-band priority scheduler\n";
  print $m "name=Add SFQ\n";
  print $m "action=`$IPMENU/addsfq 'dev $dev parent $p sfq'`\n";
  print $m "itemmsg=Add stochastic fairness queueing discipline\n";
  print $m "name=Add RED\n";
  print $m "action=`$IPMENU/addred 'dev $dev parent $p red'`\n";
  print $m "itemmsg=Add random early detection queue\n";
  print $m "name=Add CBQ\n";
  print $m "action=`$IPMENU/addcbq 'dev $dev parent $p cbq'`\n";
  print $m "itemmsg=Add class based queuing\n";
}


print MENU "menu=$title\n";
print MENU "close=`rm -f $menu`nop\n";

if ($level == 0) {
  @links = iplinks();
  $num = 1;
  map {
   if (!/Any/) {
     print MENU "name=$num. $_\n";
     print MENU "action=`$IPMENU/tcmenu 1 $_`\n";
     $num++;
   }
  } @links;
}

if ($level == 1) {

  $qdisc=0;
  open(PIPE,"tc qdisc show dev $dev |");
  while (<PIPE>) {
    ($w,$type,$handle) = split(/ /);
    $qdisc++;
  }
  close(PIPE);
  
  if ($qdisc == 0) {
    print MENU "lifetime=shortterm\n";
    printaddqdisc(\*MENU);
  } else {
    $t=uc($type);
    print MENU "lifetime=shortterm\n";
    print MENU "name=$t\n";
    print MENU "action=`$IPMENU/tcmenu 2 $dev $handle$type`\n";
  }
}

if ($level == 2) {
  if ($type eq 'cbq') {
      print MENU "name=1. Classes\n";
      print MENU "action=`$IPMENU/tcmenu 3 $dev '$handle:cbq' 0`\n";
      print MENU "name=2. Edit\n";
      print MENU "action=`$IPMENU/editcbq $dev '$handle:'`\n";
      print MENU "name=3. Statistics\n";
      print MENU "action=run tc -s qdisc show dev $dev\n";
      print MENU "name=4. Delete\n";
      print MENU "action=`tc qdisc delete dev $dev root $type bandwidth 1Mbit avpkt 1000`nop\n";
  } else {
    print MENU "name=1. Edit\n";
    print MENU "action=`$IPMENU/edit$type $dev '$handle:'`\n";
    print MENU "name=2. Statistics\n";
    print MENU "action=run tc -s qdisc show dev $dev\n";
    print MENU "name=3. Delete\n";
    print MENU "action=`tc qdisc delete dev $dev root $type`nop\n";
  }
}

if ($level == 3) {

   print MENU "lifetime=shortterm\n";
   
   $i=1;
   open(PIPE,"tc -d class show dev $dev |"); 
   while (<PIPE>) {
    if (/class cbq $handle:([\d]+)/) {
     $myclassid=$1;
     if (/parent $handle:([\d]*)/) {
       $myparentid=$1;
     }
     if ($classid == $myparentid) {
       $rate='';if (/rate ([\d\w]+)/) { $rate=$1; }
       print MENU "name=$i. $handle:$myclassid - Rate $rate\n";
       print MENU "action=`$IPMENU/tcmenu 4 $dev '$handle:cbq' $classid $myclassid`\n";
       $i++;
     }
    }
   }
   close(PIPE);
   print MENU "name=$i. Class statistics\n";
   print MENU "action=run tc -s class show dev $dev\n";
   $i++;
   print MENU "name=$i. Add class\n";
   print MENU "action=`$IPMENU/addclass $dev $handle:$classid`\n";
}

if ($level == 4) {
   print MENU "name=1. Subclasses\n";
   print MENU "action=`$IPMENU/tcmenu 3 $dev '$handle:cbq' $classid`\n";
   print MENU "name=2. Queueing\n";
   print MENU "action=`$IPMENU/tcmenu 5 $dev '$handle:cbq' $parentid $classid`\n";
   print MENU "name=3. Edit\n";
   print MENU "action=`$IPMENU/editclass $dev $handle $classid $parentid`\n";
   print MENU "name=4. Delete\n";
   print MENU "action=`tc class delete dev $dev classid $handle:$classid`nop\n";
}

if ($level == 5) {

  $leaf='';
  open(PIPE,"tc class show dev $dev |");
  while (<PIPE>) {
    if (/cbq $handle:$classid/) {
      if (/leaf ([\w\d:]+)/) { $leaf=$1; }
    }
  }
  close(PIPE);

  if ($leaf eq '') {
    print MENU "lifetime=shortterm\n";
    printaddqdisc2(\*MENU,"$handle:$classid");
  } else {

    open(PIPE,"tc qdisc show dev $dev |");
    while (<PIPE>) {
      ($c,$t,$l) = split(/ /);
      if ($leaf eq $l) { $type = $t; }
    }
    close(PIPE);
  
    $t=uc($type);
    print MENU "lifetime=shortterm\n";
    print MENU "name=$t\n";
    print MENU "action=`$IPMENU/tcmenu 6 $dev $leaf$type`\n";
  }
}

if ($level == 6) {
  if ($type eq 'cbq') {
      print MENU "name=1. Classes\n";
      print MENU "action=`$IPMENU/tcmenu 3 $dev '$handle:cbq' 0`\n";
      print MENU "name=2. Edit\n";
      print MENU "action=`$IPMENU/editcbq $dev '$handle:'`\n";
      print MENU "name=3. Statistics\n";
      print MENU "action=run tc -s qdisc show dev $dev\n";
      print MENU "name=4. Delete\n";
      print MENU "action=`tc qdisc delete dev $dev root $type bandwidth 1Mbit avpkt 1000`nop\n";
  } else {
    print MENU "name=1. Edit\n";
    print MENU "action=`$IPMENU/edit$type $dev '$handle:'`\n";
    print MENU "name=2. Statistics\n";
    print MENU "action=run tc -s qdisc show dev $dev\n";
    print MENU "name=3. Delete\n";
    print MENU "action=`tc qdisc delete dev $dev root $type`nop\n";
  }
}

print MENU "name=Close\n";
print MENU "action=close\n";

close(MENU);
print "open $menu\n";

