[Cascavel-pm] Roteador

Alceu Rodrigues de Freitas Junior glasswalk3r em yahoo.com.br
Quarta Maio 12 22:06:52 CDT 2004


Bem vindo a lista Alex.

Sugiro que dê uma olhada nos módulos Getopt::Std e Getopt::Long para
processar as opções em linha de comando do seu script.

Aos monges paulistanos, quando teremos um novo encontro por esses
lados? O Alex também é de São Paulo e um bom bebedor de cerveja também.

[]'s


-- 
Alceu Rodrigues de Freitas Junior
--
glasswalk3r em yahoo.com.br
PGP public key at http://www.imortais.cjb.net/addgb.html
---------------------------------------------------------------
He who knows others is wise.
He who knows himself is enlightened.
                -- Lao Tsu



On Wed, 12 May 2004 16:00:31 -0300 "Alex E. J. Falcão"
<alfspsp em hotmail.com> wrote:

> 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");
> }



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