#!/usr/bin/perl
######################################
#Haphazardly written by:
#Brian Guinan
#Date: 5/5/03
$Version = ".2";
use Expect;
use CGI;
$q = new CGI;
# $Expect::Debug=1
# $Expect::Exp_Internal=1;
# $Expect::Log_Stdout=0; # Turn off verbose client interaction
#############################
#Script requires a whitespace delimited config file in the following f
+ormat:
#RouterName CodeName Username UserPassword Ena
+blePassword
# with a new line for each router you wish to configure
#############################
###These settings reflect temporary addresses used during the config p
+rocess
############################
#$port = "ttyS0";
my $timeout = 5;
my $cmd = "show flash";
my @out;
my $router_name,$codename,$username,$user_password,$enable_password =
+"";
$tftp_server = "153.2.255.205";
$porta = "ttyS0";
$portb = "ttyS1";
$porta_IP = "153.2.254.70";
$portb_IP = "153.2.254.69";
$subnet_mask = "255.255.252.0";
$gateway_IP = "153.2.255.1";
$g_upload_path='/var/www/data';
$configfile = "config.txt";
$readfile = "$g_upload_path" . "/" . "$configfile";
$tmpfile = "/var/www/data/logfile" . "/" . "config.txt.lock";
my $flag = "-Done";
my $IP = $porta_IP;
my $static_commands = "no logging on;!;int faste0/0;ip address $IP $su
+bnet_mask;duplex auto;speed auto;no shut;!;exit;ip route 0.0.0.0 0.0.
+0.0 $gateway_IP;!;partition flash 2 16 16;!;";
##############################
####Dont change anything below this line.... else dont come to me!
##############################
if (! $q->param()) #send the form
{
#$ScriptLocation = $ENV{'SCRIPT_NAME'};
#$ServerName = $ENV{'SERVER_NAME'};
print "Content-type: text/html\n\n";
print "<title> Config </title>";
if (($ENV{'HTTP_HOST'} ne "") && ($ENV{'REQUEST_URI'} ne "")){
print "<form method=\"POST\" action=\"https://$ENV{'HT
+TP_HOST'}$ENV{'REQUEST_URI'}\">";
}
else {
print "<<form method=\"post\" action=\"https://$URI/cg
+i-bin/micro_config.cgi\">";
};
print <<FORM;
<p>
<h2><font size=7 color="#0000ff"><u>C</u></font>isco <font size=7 colo
+r="#0000ff"><u>I</u></font>nitial <font size=7 color="#0000ff"><u>C</
+u></font>onfig <font size=7 color="#0001ff"><u>U</u></font>tility
</h2>
Version: $Version
<p>
Select router to configure:<br>
<form>
<select name="router">
FORM
open (CONFIGFILE, "$readfile")|| die "Cant open configfile: $readfile!
+\n";
while (<CONFIGFILE>){
@data = split(/\s+/);
if ((@data[0] !~ m/.*$flag$/)&&($bool != 1)){
print "<option selected=\"@data[0]\">@data[0]\n";
$bool = 1;
} else {
print("<option value=\"@data[0]\">@data[0]\n");
}
};
close(CONFIGFILE);
print <<FORM;
</select><br>
Select the serial port to use<br>
<select name="port">
<option value="$porta;$porta_IP">com 1
<option value="$portb;$portb_IP">com 2
</select>
<p>
<input type="submit" value="Configure it!">
<input type="reset" value="Reset Form">
</form>
FORM
}
else #process the form data
{
print "Content-type: multipart/mixed;boundary=boundary\n\n";
$status = system("killall console");
sleep 2;
#uncommment this is you want the page to perpetually scroll down
#print <<SCRIPT;
#<script language="javascript"type="text/javascript">
#<!--
#var scrollMe = window.setInterval("window.scrollBy(0,1000);", 1000);
#-->
##</script>
#<pre>
#SCRIPT
print "<pre WRAP>\n\n...working....\n\n"; #give user some feedback t
+o blank screen
#get passed paramaters and make assignmants
$router_name = $q->param("router");
($router_name, $codename) = split(/;/,$router_name);
#$port = $q->param("port");
($port, $IP) = split(/;/,$q->param("port"));
#check running procesies
@array = `ps -ax | grep console`;
@split = split(/\s+/,@array[0]);
if (@split[5] eq $port){
#ENABLE IF PROCESS KEEPS STICKING
warning("Killing a previous console session");
$bla = `kill -9 @split[0]`;
sleep 2;
};
unless ($console = Expect->spawn("/usr/local/bin/console $port")){
warning("never got a console spawned");
die "never got a console spawned\n ".$console->exp_error()."\n
+";
} #did we spawn the client ok?
$console->log_file("/var/www/data/logfile/logfile.console.txt");
($router_name,$codename,$username,$user_password,$enable_password) = r
+ead_config($readfile,$router_name,$flag);
#still_booting();
login($username,$user_password);
#$enable_password = "password";
getroot($enable_password);
#clean();
static_conf("$static_commands");
sleep 5;
#check_network($gateway_IP);
check_network();
if (flash("1") ne $codename){
warning("Copying code to flash:1: from TFTP server");
copy_flash("$tftp_server","flash","$codename");
}else{
warning("Correct flash ($codename) already on first partition"
+);
};
if (flash("2") ne $codename){
warning("Copying code to flash:2: from flash:1:");
copy_flash("flash:1:","flash:2:","$codename");
}else{
warning("Correct flash ($codename) already on second partition
+");
};
copy_flash("$tftp_server","start","$router_name.TXT");
#clean();
#logout();
reload();
login($username,$user_password);
getroot($enable_password);
run_cmd("write mem",30,"[#>]");
logout();
};
sub warning{
my $warning = $_[0];
print "\n\<HTML\>\<font size=\"\5\" color=\"#FF0000\" face=\"T
+imes\"\>$warning\<\/font\>\<\/html\>\<pre WRAP\>\n";
};
sub still_booting{
foreach my $i (1..20){
my $out = run_cmd("\r",10,"sername|dialog|RETURN");
if ($out =~ m/sername|dialog|RETURN/){
return();
};
};
}
sub reload{
warning("Reloading router");
my $out = run_cmd("reload",5,":");
if ($out =~ m/Save/){
$out = run_cmd("no",5,"\]");
if ($out =~ m/reload/){
$out = run_cmd("\r",600,"sername|dialog|RETURN
+");
return();
};
}elsif($out =~ m/reload/){
$out = run_cmd("\r",600,"sername|dialog|RETURN");
return();
}else{
warning("ERROR: Couldent issue reload");
death();
};
return();
}
sub clean{
my $toclean = $_[0];
warning("Erasing flash and start");
my $out = run_cmd("erase $toclean",5,"\[confirm\]");
$out = run_cmd("\r",60,"[#>]");
if (($out !~ m/\[OK\]/)||($out !~ m/complete/)){
warning("ERROR: could not erase $toclean");
death();
};
# static_conf("no partition flash 2;");
# print "Router config erased. Rebooting router to complete\n";
# $out = run_cmd("reload",5,".*");
return();
};
sub check_network{
my $out, $icmp_dest;
if ($_[0] =~ m/\d+\.\d+\.\d+\.\d+/){
$icmp_dest = $_[0];
}else{
$icmp_dest = "";;
$out = run_cmd("show ip route",5,"[#>]");
my @parse = split(/S\*/,$out);
my $size = @parse;
my $counter = 1;
while ($counter < $size){
if (@parse[$counter] =~ m/0\.0\.0\.0\/0/){
my @sub_parse = split(/\s+/,@parse[$co
+unter]);
$counter = 2;
$size = @sub_parse;
while ($counter < $size){
if (@sub_parse[$counter] =~ m/
+\d+\.\d+\.\d+\.\d+/){
$icmp_dest = @sub_pars
+e[$counter];
$counter = 99;
};
$counter++;
};
}else{
warning("No default gateway to ping!")
+;
};
$counter++;
};
}
if ($icmp_dest ne ""){
$out = run_cmd("ping $icmp_dest",5,"[#>]");
}else{
warning("ERROR: No default gateway to ping!");
death();
};
if ($out !~ m/\!/){
warning("ERROR: Cant ping $icmp_dest");
warning("Check network cabeling and that host is alive
+");
}else{
warning("Default gateway pingable, network working!");
};
return();
};
sub read_config{
my $config_file = $_[0];
my $router_name = $_[1];
my $flag = $_[2];
my $codename,$username,$user_password,$enable_password = "";
open (CONFIGFILE, "$config_file")|| die "cant open configfile:
+ $config_file\n";
undef $_;
while (defined($_ = <CONFIGFILE>)){
if ($_ =~ m/$router_name($flag)*\s+/){
($router_name,$codename,$username,$user_passwo
+rd,$enable_password) = split(/\s+/);
$router_name =~ s/$flag//g;
close (CONFIGFILE);
return ($router_name,$codename,$username,$user
+_password,$enable_password);
};
};
close (CONFIGFILE);
death();
return();
};
sub logout{
warning("Logging out... have a nice day!");
my $out = run_cmd("exit",5,"RETURN");
return();
};
sub static_conf{
my @split_commands = split(/;/,$_[0]);
my $size = @split_commands;
my $counter = 0;
my $out = run_cmd("conf t",5,"#");
while ($counter < $size){
$out = run_cmd("@split_commands[$counter]",5,"[#>]");
if (@split_commands[$counter] =~ m/exit/){
sleep 3; #needed to let router digest
};
$counter++;
};
$out = run_cmd("end",5,"[#>]");
return();
};
sub flash{
my $partition = $_[0];
my $out = run_cmd("show flash",5,"[#>]");
my @split = split(/\s/,$out);
my $size = @split;
my $counter = 0;
my $partition_count = 0;
while ($counter < $size){
if ((@split[$counter] =~ m/partition/)&&(@split[$count
+er+1] =~ m/$partition/)){
$partition_count++;
}elsif((@split[$counter] =~ m/status/)&&($partition_co
+unt != 0)){
return(@split[$counter+9]);
}elsif(@split[$counter] =~ m/invalid\s+checksum/){
warning("ERROR: flash:$partition has an invala
+d checksum!");
warning("Press cancel or will app will format
+and reload flash in 10 seconds!");
sleep 10; #told you so!
clean("flash:$partition");
}elsif(@split[$counter] =~ m/No/){
warning("No files in flash:$partition:");
return();
};
$counter++;
};
warning("ERROR: Could not get codename on flash:$partition");
};
sub copy_flash{
my $source = $_[0];
my $destination = $_[1];
my $filename = $_[2];
my $out;
if ($source =~ m/\d+\.\d+\.\d+\.\d+/){
$out = run_cmd("copy tftp $destination",5,"\\?");
if ($out =~ m/Address/){
$out = run_cmd("$source",5,"\\?");
};
}else{
$out = run_cmd("copy $source $destination",5,"\\?");
};
if($out =~ m/Source/){
$out = run_cmd("$filename",5,"\\?");
if($out =~ m/estination/){
if($destination =~ m/start/){
$out = run_cmd("\r",60,"confirm|[#>]")
+;
}else{
$out = run_cmd("$filename",60,"confirm
+|[#>]");
};
if($out =~ m/Erase/){
$out = run_cmd("\r",300,"[#>\\?]");
if($out =~ m/Erasing/){
$out = run_cmd("\r",300,"[#>]"
+);
};
};
};
}elsif($out =~ m/Error/){
warning("ERROR: Error copying file. Please check that
+file ($filename) on $source exists");
}elsif($out =~ m/OK/){
$out =~ s/.*OK//g;
$out =~ s/\r?$//g;
warning("SNIPPED OUT: $out");
}else{
warning("ERROR: Something took a dump here");
};
if ($out =~ m/Error/){
warning("ERROR: Error copying file. Please check file
+($filename) on $source exists");
death();
};
if ($out =~ m/OK/){
warning("Flash copied from $source to $destination OK"
+);
# $out =~ s/.*OK//g;
# $out =~ s/.*\r?$//;
#BROKEN warning("Snipped Info: $out");
}else{
warning("Something FFU'd");
death();
};
return();
}
sub getroot{
my $enable = $_[0];
#returns:
# 0 if no
# 1 of yes
my $out = run_cmd("sho privilege",5,"[#>]");
if ($out !~ m/.*15.*/){
$out = run_cmd("enable",5,":");
if ($out =~ m/Password/){
$out = run_cmd("$enable",5,"[#:]");
if ($out =~ m/Password/){
warning("ERROR: Bad Enable Password");
die();
};
};
getroot();
}else{
return 1;
};
}
sub login{
my $username = $_[0];
my $password = $_[1];
foreach my $i (1..5){
my $out = run_cmd("\r",5,"no\]:|sername:|[#>]");
if ($out !~ m/[#>]/){
if ($out =~ m/sername/){
$out = run_cmd("$username",2,"[#>:]");
};
if($out =~ m/assword/){
$out = run_cmd("$password",2,"[#>:]");
};
if($out =~ m/dialog/){
warning("A Virgin!");
$out = run_cmd("no",3,"[#>:]");
if ($out =~ m/terminate/){
$out = run_cmd("yes",10,"[#>:]
+");
};
};
# if (@out[0] eq "1"){
# return (0);
# };
}elsif ($out =~ m/dialog/){
$out = run_cmd("no",20,".*");
}else{
return(0);
};
$i++;
};
# death();
};
sub prompt_cmd{
my $command = $_[0];
my $timeout = $_[1];
my $prompt = ".*" . $_[2];
print $console "\r";
my @out = $console->expect($timeout,'-re',$prompt);
if (@out[0] eq "1"){
print $console "$command\r";
@out = $console->expect($timeout,'-re',$prompt);
if (@out[0] eq "1"){
@out[3] =~ s/$command//g;
}else{
warning("ERROR: Got prompt... command hung?");
return;
};
}else{
warning("ERROR: Router never gave prompt");
return;
};
return @out[3];
}
sub run_cmd{
my $command = $_[0];
my $timeout = $_[1];
my $prompt = ".*" . $_[2];
$console->clear_accum();
print $console "$command\r";
my @out = $console->expect($timeout,'-re',$prompt);
# if (@out[0] ne "1"){
# print "ERROR: Didnt get specified prompt returned\n";
# return;
# };
my $output = @out[3] . @out[2] . @out[4];
return $output;
# return @out[3];
}
sub death{
warning("UNEXPECTED ERROR: FFU!");
# if no longer needed, do a soft_close to nicely shut down the
+ command - french style
$console->hard_close(undef);
exit 1;
}
|