[Cascavel-pm] Roteador
Alex E. J. Falcão
alfspsp em hotmail.com
Quarta Maio 12 14:00:31 CDT 2004
Vivan,
tenho um script que uso bastante para telnet em roteadores cisco. Acho que pode te ajudar. Não sou um expert em Perl, e sou novo na lista... Gostaria de redeber comentários sobre as funções. Utilizei o expect para verificar as respostas, mas estou implementando coisa melhor.
#!/usr/bin/perl
#
# Versao : 1.0
# Arquivo: telnet.pl
#
# O formato para uso deste script e:
# telnet.pl <Listagem_dos_hosts> <Arquivo_de_Comandos> [Arquivo_Log]
# <> - Obrigatorio
# [] - Opcional
#
# o arquivo de host deve ser no seguinte formato:
# IP | HOSTNAME | plataforma(7500, 2500 etc)
#
# os comandos devem estar um em cada linha, incluindo config terminal, end e tudo mais
#
#
if ( $ARGV[0] eq "" ) {
print <<ECHO;
O formato para uso deste script e:
telnet.pl <Listagem_dos_hosts> <Arquivo_de_Comandos> [opcoes]
<> - Obrigatorio
[] - Opcional
As opcoes disponiveis sao:
-log:<nome do arquivo> -> gera um unico arquivo de log, conforme especificado no nome do arquivo.
-logrouter:<diretorio> -> gera um arquivo de log para cada roteador, no formato <plataforma>_hostname.log
no diretorio especificado. Se nao for especificado nenhum, sera gerado no
diretorio corrente.
o arquivo de host deve ser no seguinte formato:
IP | HOSTNAME | plataforma(7500, 2500 etc)
os comandos devem estar um em cada linha, incluindo config terminal, end e tudo mais
ECHO
exit(0);
}
use Net::Ping;
use Term::ReadKey;
# Lendo e processando os argumentos de execucao.
#
$HOSTS=$ARGV[0];
$CMDFILE=$ARGV[1];
for ($m=2;$m<10;$m++) {
$n=$m-1;
last if ($ARGV[$m] eq "");
$OPCAO=$OPCAO.$ARGV[$m];
}
$n--;
# Somente duas opcoes podem ser executadas simultaneamente.
#
if ($n > 2) {
print <<ECHO;
Erro! Muitas opcoes foram especificadas. Especifique no maximo duas opcoes.
ECHO
print "$n\n";
exit(1);
}
# Trantando os argumentos.
#
if ($OPCAO =~ "-log:") {
$LOG="1";
($cum,$DIR) = split (/\:/,$OPCAO,2);
}
if ($OPCAO =~ "-logrouter") {
$LOGROUTER="1";
($cum,$LOGDIR) = split (/\:/,$OPCAO,2);
}
print "$LOG - $DIR\n";
print "$LOGROUTER - $LOGDIR\n";
#exit(0);
# A primeira operacao a ser realizada e solicitar o USERNAME e
# o PASSWORD para acessar os equipamentos da rede.
print "Enter your username: ";
ReadMode 'normal';
$username = ReadLine(0);
chomp $username;
print "Enter your password: ";
ReadMode 'noecho';
$password = ReadLine 0;
chomp $password;
print "\nEnable secret: ";
$enable = ReadLine 0;
chomp $enable;
ReadMode 'normal';
# Lendo o arquivo de hosts especificado pela variavel $HOSTS.
$m=0;
open (F,"$HOSTS") || die "Cade o arquivo $HOSTS ?";
while (<F>) {
s/\s+$//g; #remove "branco" no final da linha por nada
s/\s/ /g; #substitui "branco" por espaco
s/\n//; #substitui <ENTER> por nada
s/\s//g; #remove espacos entre os caracteres
next if /^\s*\!/; #ignora linhas de comentarios
next if /^\s*$/; #ignora linhas vazias
$TARGET[$m] = $_;
$m++;
}
close (F);
print "O arquivo de alvos \"$HOSTS\" contem $m host(s).\n";
# Lendo o arquivo de comandos especificado pela variavel $CMDFILE.
$n=0;
open (F,"$CMDFILE") || die "Cade o arquivo $CMDFILE ?";
while (<F>) {
s/\s+$//g; #remove "branco" no final da linha por nada
s/\s/ /g; #substitui "branco" por espaco
s/\n//; #substitui <ENTER> por nada
next if /^\s*\!/; #ignora linhas de comentarios
next if /^\s*$/; #ignora linhas vazias
$COMANDOS[$n] = $_;
$n++;
}
close (F);
print "O arquivo de comandos \"$CMDFILE\" contem $n linhas de instrucoes(s).\n\n";
# Inicializando variaveis que necessitam de um valor inicial
$TOTALCOMMMANDS=$m*$n;
$TOTALERROS=0;
$TOTALTIMEOUTS=0;
# Gerando o cabecalho do log, se especificado.
if ($LOG) {
open (LOG,">>$DIR");
# Obtem data e hora do inicio da execucao.
($mon,$mday,$year,$hour,$min) = (localtime())[4,3,5,2,1];
$year=$year+1900;
$mon++;
print LOG "\n\n################################################################################\n\n"
."O arquivo de alvos \"$HOSTS\" contem $m host(s).\n"
."O arquivo de comandos \"$CMDFILE\" contem $n linhas de instrucoes(s).\n"
."Iniciando execucao em $mday/$mon/$year - $hour:$min\n\n";
close (LOG);
}
# Executando o TELNET aos hosts especificados no arquivo de alvos e executando os comandos
# contidos no arquivo de comandos.
foreach (@TARGET) {
&EXECUTA($_);
}
# Gerando o rodape do log, se especificado.
if ($LOG) {
open (LOG,">>$DIR");
print LOG "\n\n################################################################################\n\n"
." SUMARIO DA EXECUCAO\n\n"
."Numero total de hosts: $m\n"
."Nomero de hosts que nao responderam: $TOTALTIMEOUTS\n\n"
."Numero de comandos executados: $TOTALCOMMMANDS\n"
."Numero de erros durante execucao: $TOTALERROS\n\n"
."Listagem de hosts que nao responderam:\n"
."$HOSTSTIMEOUT\n\n"
."Listagem de erros ocorridos em cada host\n";
for $HOST (sort keys (%LOGERROS)) {
print LOG "- Ocorreram $QTDERROS{$HOST} em $HOST:\n\n"
."$LOGERROS{$HOST}\n\n";
}
print LOG "\n\n################################################################################\n\n";
close (LOG);
}
# Sub-rotina de execucao condicional do TELNET a um host. Checa se o host esta respondendo a
# ICMP ECHO (ping).
sub EXECUTA {
($IP,$HOSTNAME,$PLATAFORM) = split (/\|/,$_[0],3);
# Obtem data e hora da execucao para cada host.
($mon,$mday,$year,$hour,$min) = (localtime())[4,3,5,2,1];
$year=$year+1900;
$mon++;
# Gera o log da operacao, se especificado.
if ($LOG) {
open (LOG,">>$DIR");
print LOG "\n\nLote de comandos: $CMDFILE\nHost: $HOSTNAME ($IP)\nData: $mday/$mon/$year - $hour:$min\n\n";
close (LOG);
}
# Primeiro testa se a porta 23 esta aberta no dispositivo, enviando um pacote de 32 Bytes com 2 segundos
# de timeout.
$p = Net::Ping->new("tcp",10,32);
$p->{port_num} = getservbyname("telnet", "tcp");
if ( $p->ping($IP, 2) ) {
print "Executando os comandos em $HOSTNAME ($IP)\n";;
&TELNET;
}
else {
print "O host $IP nao esta respondendo.\n";
$TOTALTIMEOUTS++;
$HOSTSTIMEOUT=$HOSTSTIMEOUT."- $HOSTNAME ($IP) : $mday/$mon/$year - $hour:$min\n";
# Gera o log da operacao, se especificado.
if ($LOG) {
open (LOG,">>$DIR");
print LOG "O Host nao responde.\n";
close (LOG);
}
}
$p->close();
}
# Sub-rotina para execucao do TELNET a um host, utilizando EXPECT.
sub TELNET {
open (F,">/tmp/telnet-router");
print F "#!/usr/bin/expect -f\n"
."spawn telnet $IP\n"
."expect \"Username: \"\n"
."send \"$username\\r\"\n"
."expect \"Password: \"\n"
."send \"$password\\r\"\n"
."expect \"*>\"\n"
."send \"enable\\r\"\n"
."expect \"Password: \"\n"
."send \"$enable\\r\"\n"
."expect \"*#\"\n"
."send \"term len 0\\r\"\n"
."expect \"*#\"\n";
foreach (@COMANDOS) {
if ( $_ eq "<CR>" ) {
print F "send \"\\r\\r\"\n"
."expect \"$HOSTNAME#\"\n";
}
else {
print F "send \"$_\\r\"\n"
."expect \"$HOSTNAME#\"\n";
}
}
print F "send \"exit\\r\"\n";
close (F);
system("chmod 777 /tmp/telnet-router");
$cum=`/tmp/telnet-router > /tmp/lastlog`;
# Alimentando o log unico.
#
if ($LOG) {
system ("cat /tmp/lastlog >> $DIR");
}
# Analisando os logs dos comandos executados no host em execucao.
open (LOGTEMP,"/tmp/lastlog");
$o=0;
while (<LOGTEMP>) {
$DADOS[$o] = $_;
if ( ($_ =~ "% Invalid input detected at") ) {
$LOGERROS{$HOSTNAME} = $LOGERROS{$HOSTNAME}.$DADOS[$o-2];
$QTDERROS{$HOSTNAME}++;
$TOTALERROS++;
}
$TOTALLINHAS++;
$o++;
}
close (F);
# Gerando o LOG individual de cada roteador.
#
if ($LOGROUTER) {
$FILE="";
$FILE=$LOGDIR."/" if !($LOGDIR eq "");
$FILE=$FILE.$PLATAFORM."_".$HOSTNAME.".log";
system("cp /tmp/lastlog $FILE");
}
unlink ("/tmp/telnet-router");
unlink ("/tmp/lastlog");
}
-------------- Próxima Parte ----------
Um anexo em HTML foi limpo...
URL: http://mail.pm.org/pipermail/cascavel-pm/attachments/20040512/22531554/attachment.htm
Mais detalhes sobre a lista de discussão Cascavel-pm