[Cascavel-pm] Roteador

Alex E. J. Falcão alexjfalcao em hotmail.com
Quarta Maio 12 13:58:34 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 receber 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/1a79fa19/attachment.htm


Mais detalhes sobre a lista de discussão Cascavel-pm