Jason from SYN/ACK Networks did a write up on his Perl script (rtrcommander) which helps when you need to modify a large number of routers quickly. I figured I’d post it here so I’ll never lose it, hopefully some of you guys will find it useful as well.

Check out his post for a good explanation. Here’s the script itself:

#!/usr/bin/perl
#
# This file is part of Mr. Audit.
#
# Mr. Audit 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 3 of the License, or
# (at your option) any later version.
#
# Mr. Audit 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 Foobar.  If not, see <http://www.gnu.org/licenses/>.
#
###################################################################################
#
# This script gets the configs for every device in the audit database. 
# The configs are used by other scripts for the automated audit.
#
# Mr. Audit was written by Jason Rowley - jrowley<at>convergedinnovations<dot>com
#
# This script is version 2.00
# Last updated September 17, 2009 @ 18:14 EST
#
###################################################################################
 
use Net::Telnet::Cisco;
use Getopt::Std;
use IO::Prompt;
use FileHandle;
 
### variables
#my $DEBUG	= "true";
my $DEBUG	= "false";
my $VERSION	= "2.0";
 
my $logfile	= "";
my $combined	= 0;
my $username	= "";
my $password	= "";
my $host	= "";
 
### arrays
my @routerlist	= ();
my @commandlist	= ();
 
###
### Begin main 
###
init();
getrtrs();
getcmds();
 
foreach (@routerlist)
{
	chomp($_);
	$host = $_;
	print "\nHOSTNAME: $host\n";
 
	openrtr();
	sendcmds();
	closertr();
}
 
exit;
 
 
###
### Initializes stuff
###
sub init
{
	usage() unless $ARGV[0];
 
	my $opt_string = 'hu:p:r:c:l:';
	getopts( "$opt_string", \%opt ) or &usage;
	usage() if $opt{h};
 
	if (!$opt{u})
	{
		$username = prompt("username: ");
		chomp($username);
	}
	else
	{
		$username = $opt{u};
	}
 
	if (!$opt{p})
	{
		### got username, prompt for password
		$password = prompt("password: ", -e => '*');
		chomp($password);
	}
	else
	{
		$password = $opt{p};
	}
 
	if (!$opt{r})
	{
		print "Missing router list\n";
		usage();
		exit;
	}
 
	if (!$opt{c})
	{
		print "Missing command file\n";
		usage();
		exit;
	}
 
	if ($opt{l})
	{
		$logfile = $opt{l};
		$combined = 1;
	}
}
 
###
### Displays help
###
sub usage
{
	print STDERR << "EOF";
 
New and Improved Router Commander $VERSION
 
	Usage: 
	$0 [-h] -u <username> [-p <password>] -r <rtrlist> -c <cmdlist> [-l <loglocation>]
 
	-h                : prints this message
	-u                : username
	-p                : password - if not specified, will be prompted
	-r                : file containing list of routers
	-c                : file containing commands to run
	-l                : file where we should log to; defaults to "ipaddress.log"
 
	Examples:
 
	rtrcmd -u username -p password -r routerlist -c commandlist
	rtrcmd -u username -r routerlist -c commandlist -l mycombinedlogfile.txt
EOF
	exit;
}
 
 
### 
### Get routers
###
sub getrtrs
{
	my $rf = $opt{r};
	open (RF, $rf);
	@routerlist = <RF>;
	close(RF);
}
 
 
###
### Get commands
###
sub getcmds
{
	my $cf = $opt{c};
	open (CF, $cf);
	@commandlist = <CF>;
	close(CF);
}
 
 
### 
### Send commands
### 
sub sendcmds
{
	foreach (@commandlist)
	{
		chomp($_);
		print "Sending: $_\n";
		my @temp = $::OPENRTR->cmd("$_");
 
		if ($combined == 1)
		{
			open LOGFILE, ">>$logfile" or die $!;
			print LOGFILE @temp;
			close LOGFILE;
		}
	}
}
 
 
sub openrtr
{
	if ($combined == 1)
	{
		if ($::OPENRTR = Net::Telnet::Cisco->new(Host => $host, Errmode => "return"))
		{
			if ($::OPENRTR->login($username, $password))
			{
				my @temp = $::OPENRTR->cmd("term len 0");
			}
			else
			{
				print "Invalid username or password while trying $host\n";
				$::OPENRTR->close;
				exit;
			}
		}
		else
		{
			print "Could not connect to $host\n";
			exit;
		}
	}
	else
	{
		if ($::OPENRTR = Net::Telnet::Cisco->new(Host => $host, Input_log => "$host.log", Errmode => "return"))
		{
			if ($::OPENRTR->login($username, $password))
			{
				my @temp = $::OPENRTR->cmd("term len 0");
			}
			else
			{
				print "Invalid username or password while trying $host\n";
				$::OPENRTR->close;
				exit;
			}
		}
		else
		{
			print "Could not connect to $host\n";
			exit;
		}
	}
}
 
sub closertr
{
	$::OPENRTR->close;
}

Colby

Colby Glass has been in IT since 2002. He is currently a Systems Engineer (presales) with a Cisco Gold partner and holds the CCNP R/S, CCNP DC, CCDP, CCIP, JNCIA-ER.

More Posts