#!/usr/bin/perl
use Net::Telnet ();
################################
my $cisco_ip = '192.168.0.1';
my $cisco_pass = 'secret';
my $cisco_enable = 'my_enable';
my $cisco_if = 'fast 0/0';
my @posible_rates = (64,128,192,256,512,1024);
################################

$argnum=$#ARGV+1;
if($argnum<3)
{
	exit 0;
}
$ip = shift;
$mask = shift;
$shape = shift;

################################
# you have to make some sort of
# ip-to-acl_number mapping here
if($ip =~ /\d+\.\d+\.\d+\.(\d+)/)
{
  $acl = 2000 + $1;
}
else
{
  exit 0;
}
################################

$wildcard = eval{255-$1}."\.".eval{255-$2}."\.".eval{255-$3}."\.".eval{255-$4} if $mask =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/;
if ($wildcard eq '')
{
	exit 0;
}

$t = new Net::Telnet ();
$t->open(Host => $cisco_ip);

$t->waitfor('/Password.*$/');
$t->print($cisco_pass);
$line = $t->getline;
#print $line;
$t->print("enable");
$line = $t->getline;
#print $line;
$t->print($cisco_enable);
$line = $t->getline;
#print $line;
$t->print("conf t");
$line = $t->getline;
#print $line;
$line = $t->getline;
#print $line;

$t->print("int ".$sico_if);
$t->waitfor('/\(config-if\)\#$/');


foreach (@posible_rates)
{
print "no rate-limit output access-group $acl ".eval{$_*1000}." ".eval{$_*1000/8}." ".eval{$_*1000/8.}." conform-action transmit exceed-action drop\n";
	$t->print("no rate-limit output access-group $acl ".eval{$_*1000}." ".eval{$_*1000/8}." ".eval{$_*1000/8.}." conform-action transmit exceed-action drop");
	$t->waitfor('/\(config-if\)\#$/');
}

$t->print("exit");
$line = $t->getline;
#print $line;


$t->print("no ip access-list extended $acl");
$line = $t->getline;
#print $line;


if (match($shape, @posible_rates))
{
	$t->print("ip access-list extended ".$acl);
	$line = $t->getline;
	#print $line;

	$t->print("permit ip any ".$ip." ".$wildcard);
	$line = $t->getline;
	#print $line;

	$t->print("deny ip any any");
	$line = $t->getline;
	#print $line;

	$t->print("exit");
	$line = $t->getline;
	#print $line;

	$t->print("int ".$cisco_if);
	$t->waitfor('/\(config-if\)\#$/');

	$t->print("rate-limit output access-group ".$acl." ".eval{$shape*1000}." ".eval{$shape*1000/8}." ".eval{$shape*1000/8}." conform-action transmit exceed-action drop");
	$t->waitfor('/\(config-if\)\#$/');

	$t->print("exit");
	$line = $t->getline;
	#print $line;
}

$t->print("exit");
$line = $t->getline;
#print $line;

sub match {
  my ($element, @arr) = @_;
  foreach(@arr){
	if($_ == $element)
	{
		return 1;
	}
  }       
  return 0;
}
