[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