use strict; use warnings; use Data::Dumper; use Config::Tiny; use Path::Tiny 'path'; binmode STDOUT, ':encoding(cp437)'; use Control::CLI; my $ini = Config::Tiny->read( 'ciscodump.ini' ); my $dumpdir = path($ini->{_}{dir}); my $debugdir = $dumpdir->child('debug'); my $debug = $ini->{_}{debug}; $Data::Dumper::Useqq = 1; sub dbg { print @_ if $debug; @_; } dbg Dumper $ini; my @k = grep { $_ !~ /^(_|dump)$/ } keys %$ini; print Dumper \@k if $debug; my %dumpcommands = %{$ini->{dump}}; my $prompt = '(?m:^\W?(?!Device#)[\w\/\d.:-]+[>#])'; my %cs_opts; $cs_opts{Prompt} = $prompt; $cs_opts{Errmode} = 'return'; $cs_opts{Output_record_separator} = "\r"; for my $host (@k) { my $user = $ini->{$host}{user} // $ini->{_}{user}; my $pass = $ini->{$host}{pass} // $ini->{_}{pass}; my $enable = $ini->{$host}{enable} // $ini->{_}{enable}; my $info = $ini->{$host}{info} // $ini->{_}{info}; my $method = $ini->{$host}{use} // 'SSH'; print "$host\t- $info\n"; $debug = $ini->{_}{debug} // $ini->{$host}{debug}; $debugdir->mkpath if $debug; $cs_opts{Dump_Log} = $debugdir->child($host . '.log')->stringify if $debug; $cs_opts{Timeout} = $ini->{$host}{timeout} // 10; my $hostdir = $dumpdir->child($host); $hostdir->mkpath; my $cc = Control::CLI->new( %cs_opts, Use => $method ); my %login_opts = ( Username => $user, Password => $pass, ); if ($method =~ /^TELNET$/i) { if ($cc->connect(Host => $host)) { dbg "TELNET connection established\n"; if ($cc->login(%login_opts)) { dbg "logged in\n"; } else { warn 'login failed: ' . $cc->errmsg(); } } else { warn 'connection could not be established: ' . $cc->errmsg(); next; } } else { # SSH if ($cc->connect(Host => $host, %login_opts)) { dbg "SSH connection established\n"; } else { warn 'connection could not be established: ' . $cc->errmsg(); next; } } dbg Dumper $cc->read(Blocking => 1, Timeout => 5); dbg "enable>\n"; dbg Dumper $cc->cmd(command => 'enable', prompt => 'Password:'); # dbg "waiting>\n"; # my @wf = $cc->waitfor(Match => 'Password:'); # dbg Dumper \@wf; dbg "sending>\n"; dbg Dumper $cc->cmd($enable); dbg "after>\n"; my $out = $cc->cmd('term len 0'); dbg Dumper $out; dbg Dumper $cc->cmd('term page 0') if grep { /invalid/i } $out; for my $prefix (keys %dumpcommands) { my $cmd = $dumpcommands{$prefix}; dbg "command: '$cmd'\n"; my $out = $cc->cmd($cmd); dbg Dumper \$out; $hostdir->child($prefix . '.txt')->spew_raw($out); } $cc->disconnect; };