Discussion:
[rancid] Understand some regex used in rancid
Lance Vermilion
2008-11-13 00:36:50 UTC
Permalink
I don't understand what this is meaning. i have searched around but
still can't figure out what the # sign is used for in perl regex like
it is being used here.

while (/#\s*($cmds_regexp)\s*$/) {


If I can figure this out then I will have the IPS module working for
rancid using the default clogin/rancid with only minor tweaks.
Max Palatnik
2008-11-13 04:05:13 UTC
Permalink
The # sign is probably the # in Switch# or Hostname#, so this command
searches for the following:

#(0 or more whitespace), the variable $cmds_regexp, then 0 or more
whitespace at the end of a line.

Hope this helps
Max
Post by Lance Vermilion
I don't understand what this is meaning. i have searched around but
still can't figure out what the # sign is used for in perl regex like
it is being used here.
while (/#\s*($cmds_regexp)\s*$/) {
If I can figure this out then I will have the IPS module working for
rancid using the default clogin/rancid with only minor tweaks.
_______________________________________________
Rancid-discuss mailing list
http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
john heasley
2008-11-13 06:53:10 UTC
Permalink
Post by Lance Vermilion
I don't understand what this is meaning. i have searched around but
still can't figure out what the # sign is used for in perl regex like
it is being used here.
while (/#\s*($cmds_regexp)\s*$/) {
the # is a #, the end of the enabled user's prompt.
Post by Lance Vermilion
If I can figure this out then I will have the IPS module working for
rancid using the default clogin/rancid with only minor tweaks.
_______________________________________________
Rancid-discuss mailing list
http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
Lance Vermilion
2008-11-13 21:11:19 UTC
Permalink
Thx Max and John.

As for making rancid work with IPS modules I have found that the post
from Jeremy M. Guthrie
"http://www.shrubbery.net/pipermail/rancid-discuss/2007-May/002209.html"
does very well and doesn't require making a lot of changes to rancid
to handle the errors that happen if you run too many commands that are
invalid commands. I also eliminated the need for his ipslogin. I
simply just had perl set the TERM to vt100 before it ran clogin and
then set the TERM back to network after it was finished running
clogin. I also fixed some typo's he had where it was the work "at"
instead of "@". I fixed what should be skipped for the ShowVersion as
it had some extra stuff that can change.

Here is a copy of what I put on my webpage. http://www.gheek.net/?p=78

In order to get rancid to collect the config from an IPS module you
will need to make sure you have the correct login creds in the rancid
users ".cloginrc", add the type of ips to "rancid-fe" and you also
need to create the "ipsrancid" script.

Changes required for "rancid-fe"
'ips' => 'ipsrancid',

Create the "ipsrancid" script as "<rancid_home>/bin/ipsrancid". Make
sure you "chmod 755 <rancid_home>/bin/ipsrancid" and "chown
<rancid_user>:<rancid_user> <rancid_home>/bin/ipsrancid".
#! /usr/bin/perl
##
## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
## without fee for non-commerical purposes provided that this license
## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
## It is provided solely "as is". The author(s) disclaim(s) all
## responsibility and liability with respect to this software's usage
## or its effect upon hardware, computer systems, other software, or
## anything else.
##
## Except where noted otherwise, rancid was written by and is maintained by
## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
# hacked version of Hank's rancid - this one tries to deal with Hitachi's.
#
# Modified again by Lance Vermilion (11/13/08)
# Modified from htrancid by Jeremy M. Guthrie
# Created on 5/4/2007
#
# This is meant to try handle Cisco's IPS V5.X line and on
#
# RANCID - Really Awesome New Cisco confIg Differ
#
# usage: ipsrancid [-d] [-l] [-f filename | $host]
use Getopt::Std;
getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
$timeo = 90; # clogin timeout in seconds
my(@commandtable, %commands, @commands);# command lists
my(%filter_pwds); # password filtering mode

# This routine is used to print out the router configuration
sub ProcessHistory {

($new_hist_tag,$new_command,$command_string, @string) = (@_);
if ((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
&& defined %history) {
print eval "$command \%history";
undef %history;
}
if (($new_hist_tag) && ($new_command) && ($command_string)) {
if ($history{$command_string}) {
$history{$command_string} = "$history{$command_string}@string";
} else {
$history{$command_string} = "@string";
}
} elsif (($new_hist_tag) && ($new_command)) {
$history{++$#history} = "@string";
} else {
print "@string";
}
$hist_tag = $new_hist_tag;
$command = $new_command;
1;
}

sub numerically { $a <=> $b; }

# This is a sort routine that will sort numerically on the
# keys of a hash as if it were a normal array.
sub keynsort {
local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
$sorted_lines[$i] = $lines{$key};
$i++;
}
@sorted_lines;
}

# This is a sort routine that will sort on the
# keys of a hash as if it were a normal array.
sub keysort {
local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
$sorted_lines[$i] = $lines{$key};
$i++;
}
@sorted_lines;
}

# This is a sort routine that will sort on the
# values of a hash as if it were a normal array.
sub valsort{
local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
$sorted_lines[$i] = $key;
$i++;
}
@sorted_lines;
}

# This is a numerical sort routine (ascending).
sub numsort {
local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a <=> $b} keys %lines) {
$sorted_lines[$i] = $lines{$num};
$i++;
}
@sorted_lines;
}

# This is a sort routine that will sort on the
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
$sorted_lines[$i] = $lines{$addr};
$i++;
}
@sorted_lines;
}

# These two routines will sort based upon IP addresses
sub ipaddrval {
my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#);
$a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
}

# This routine parses "show config"
sub ShowConfig {
print STDERR " In ShowConfig: $_" if ($debug);

$firstexit=0;

while (<INPUT>) {
tr/\015//d;
tr/\020//d;

#strip out the stupid spinning running-config progress thingy
s/Generating current config: \.*[\|\/\-\\]//gi;
$skipprocess=0;

#sometimes an 'exit' appears at the top of the config, we
don't want them
if ( (/^exit/) && ( ! $firstexit ) ) {
$firstexit=1;
$skipprocess=1;
}

#remove spaces left over from lame spinning progress thingy
if ( /^\s+! ――――――――――/ ) {
s/^\s+!/!/g
}

if (/^(read-only-community) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(read-write-community) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(trap-community-name) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(ntp-keys \d+ md5-key) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(password) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}

last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowConfig Data: $_" if ($debug);
ProcessHistory("","","","$_");
}
}
}
$clean_run=1;
print STDERR " Exiting ShowConfig: $_" if ($debug);
return(0);
}

# This routine parses single command's that return no required info
sub ShowVersion {
print STDERR " In ShowVersion: $_" if ($debug);
ProcessHistory("","","","!\n!IPS Show Version Start\n");

while (<INPUT>) {
tr/\015//d;

$skipprocess=0;

if ( /^Sensor up-time/ ) { $skipprocess=1; }
if ( ( /using.*bytes of available/i ) ) { $skipprocess=1; }

last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowVersion Data: $_" if ($debug);
ProcessHistory("","","","! $_");
}
}
}
ProcessHistory("","","","!\n!IPS Show Version End\n");
print STDERR " Exiting ShowVersion: $_" if ($debug);
return(0)
}

# This routine parses single command's that return no required info
sub ShowUsersAll {
print STDERR " In ShowUsersAll: $_" if ($debug);
ProcessHistory("","","","!\n!IPS User Database Start\n");

while (<INPUT>) {
tr/\015//d;

$skipprocess=0;

s/^ CLI ID //g;
s/^ //g;
s/^\* +[0-9]+ +//g;

last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowUsersAll Data: $_" if ($debug);
ProcessHistory("","","","!$_");
}
}
}
ProcessHistory("","","","!\n!IPS User Database End\n!\n!\n");
print STDERR " Exiting ShowUsersAll: $_" if ($debug);
return(0)
}

# dummy function
sub DoNothing {print STDOUT;}

# Main
@commandtable = (
{'show version' => 'ShowVersion'},
{'show users all' => 'ShowUsersAll'},
{'show configuration' => 'ShowConfig'}
);
# Use an array to preserve the order of the commands and a hash for mapping
# commands to the subroutine and track commands that have been completed.
@commands = map(keys(%$_), @commandtable);
%commands = map(%$_, @commandtable);

$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);

open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
if ($debug) { $| = 1; }

# The IPS doesn't like the TERM of network so we must change it
if ( $ENV{TERM} eq 'network' ) {
$ENV{TERM} = 'vt100′;
}
if ($file) {
print STDERR "opening file $host\n" if ($debug);
print STDOUT "opening file $host\n" if ($log);
open(INPUT,"<$host") || die "open failed for $host: $!\n";
} else {
print STDERR "executing clogin -t $timeo -c\"$cisco_cmds\"
$host\n" if ($debug);
print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\"
$host\n" if ($log);
if (defined($ENV{NOPIPE})) {
system "clogin -t $timeo -c \"$cisco_cmds\" $host </dev/null >
$host.raw 2>&1" || die "clogin failed for $host: $!\n";
open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n";
} else {
open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host
</dev/null |") || die "clogin failed for $host: $!\n";
}
}
# Change the TERM back to network
if ( $ENV{TERM} eq 'vt100′ ) {
$ENV{TERM} = 'network';
}

# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
$filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
$filter_pwds = 1;
}

ProcessHistory("","","","!RANCID-CONTENT-TYPE: ipsrancid\n!\n");
TOP: while(<INPUT>) {
tr/\015//d;

#strip out the stupid spinning running-config progress thingy
s/Generating current config: \.*[\|\/\-\\]//gi;

if (/^.*logout$/) {
$clean_run=1;
last;
}
if (/^Error:/) {
print STDOUT ("$host clogin error: $_");
print STDERR ("$host clogin error: $_") if ($debug);
$clean_run=0;
last;
}
while (/($cmds_regexp)/) {
$cmd = $1;
if (!defined($prompt)) {
$prompt = ($_ =~ /^([^#]+#)/)[0];
$prompt =~ s/([][}{)(\\])/\\$1/g;
print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
}
print STDERR ("IPS COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
print STDERR "$host: found unexpected command - \"$cmd\"\n";
$clean_run = 0;
last TOP;
}
$rval = &{$commands{$cmd}};
delete($commands{$cmd});
if ($rval == -1) {
$clean_run = 0;
last TOP;
}
}
}
print STDOUT "Done $logincmd: $_\n" if ($log);
# Flush History
ProcessHistory("","","","");
# Cleanup
close(INPUT);
close(OUTPUT);

if (defined($ENV{NOPIPE})) {
unlink("$host.raw") if (! $debug);
}

# check for completeness
if (scalar(%commands) || !$clean_run ) {
if (scalar(%commands)) {
printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands)));
printf(STDERR "$host: missed cmd(s): %s\n", join(',',
keys(%commands))) if ($debug);
}
if (!$clean_run ) {
print STDOUT "$host: End of run not found\n";
print STDERR "$host: End of run not found\n" if ($debug);
system("/usr/bin/tail -1 $host.new");
}
unlink "$host.new" if (! $debug);
}
Post by john heasley
Post by Lance Vermilion
I don't understand what this is meaning. i have searched around but
still can't figure out what the # sign is used for in perl regex like
it is being used here.
while (/#\s*($cmds_regexp)\s*$/) {
the # is a #, the end of the enabled user's prompt.
Post by Lance Vermilion
If I can figure this out then I will have the IPS module working for
rancid using the default clogin/rancid with only minor tweaks.
_______________________________________________
Rancid-discuss mailing list
http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
Gregory W Zill
2008-11-14 14:18:24 UTC
Permalink
Lance Vermilion
2008-11-14 15:32:13 UTC
Permalink
Gregory,

You need to set autoenable for that device inside your ".cloginrc".
The IP puts you in privilege 15 when you login. I am guessing you do
not have that specified so rancid is trying to enable.
I get what appears to be a second user inputted somehow. Have you seen this?
How might I fix? This is a 4215 IPS.
$ clogin test_cisco_ips6
test_cisco_ips6
spawn ssh -c 3des -x -l cisco test_cisco_ips6
Last login: Fri Nov 14 09:07:54 2008 from 10.1.1.107
cisco
test_cisco_ips6# cisco
^
% Invalid input detected at '^' marker
BTW, the ipsrancid is great -- thank you
Thx Max and John.
As for making rancid work with IPS modules I have found that the post
from Jeremy M. Guthrie
"http://www.shrubbery.net/pipermail/rancid-discuss/2007-May/002209.html"
does very well and doesn't require making a lot of changes to rancid
to handle the errors that happen if you run too many commands that are
invalid commands. I also eliminated the need for his ipslogin. I
simply just had perl set the TERM to vt100 before it ran clogin and
then set the TERM back to network after it was finished running
clogin. I also fixed some typo's he had where it was the work "at"
it had some extra stuff that can change.
Here is a copy of what I put on my webpage. http://www.gheek.net/?p=78
In order to get rancid to collect the config from an IPS module you
will need to make sure you have the correct login creds in the rancid
users ".cloginrc", add the type of ips to "rancid-fe" and you also
need to create the "ipsrancid" script.
Changes required for "rancid-fe"
'ips' => 'ipsrancid',
Create the "ipsrancid" script as "<rancid_home>/bin/ipsrancid". Make
sure you "chmod 755 <rancid_home>/bin/ipsrancid" and "chown
<rancid_user>:<rancid_user> <rancid_home>/bin/ipsrancid".
#! /usr/bin/perl
##
## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
## without fee for non-commerical purposes provided that this license
## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
## It is provided solely "as is". The author(s) disclaim(s) all
## responsibility and liability with respect to this software's usage
## or its effect upon hardware, computer systems, other software, or
## anything else.
##
## Except where noted otherwise, rancid was written by and is maintained by
## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
# hacked version of Hank's rancid - this one tries to deal with Hitachi's.
#
# Modified again by Lance Vermilion (11/13/08)
# Modified from htrancid by Jeremy M. Guthrie
# Created on 5/4/2007
#
# This is meant to try handle Cisco's IPS V5.X line and on
#
# RANCID - Really Awesome New Cisco confIg Differ
#
# usage: ipsrancid [-d] [-l] [-f filename | $host]
use Getopt::Std;
getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
$timeo = 90; # clogin timeout in seconds
my(%filter_pwds); # password filtering mode
# This routine is used to print out the router configuration
sub ProcessHistory {
if ((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
&& defined %history) {
print eval "$command \%history";
undef %history;
}
if (($new_hist_tag) && ($new_command) && ($command_string)) {
if ($history{$command_string}) {
} else {
}
} elsif (($new_hist_tag) && ($new_command)) {
} else {
}
$hist_tag = $new_hist_tag;
$command = $new_command;
1;
}
sub numerically { $a <=> $b; }
# This is a sort routine that will sort numerically on the
# keys of a hash as if it were a normal array.
sub keynsort {
local($i) = 0;
foreach $key (sort numerically keys(%lines)) {
$sorted_lines[$i] = $lines{$key};
$i++;
}
@sorted_lines;
}
# This is a sort routine that will sort on the
# keys of a hash as if it were a normal array.
sub keysort {
local($i) = 0;
foreach $key (sort keys(%lines)) {
$sorted_lines[$i] = $lines{$key};
$i++;
}
@sorted_lines;
}
# This is a sort routine that will sort on the
# values of a hash as if it were a normal array.
sub valsort{
local($i) = 0;
foreach $key (sort values %lines) {
$sorted_lines[$i] = $key;
$i++;
}
@sorted_lines;
}
# This is a numerical sort routine (ascending).
sub numsort {
local($i) = 0;
foreach $num (sort {$a <=> $b} keys %lines) {
$sorted_lines[$i] = $lines{$num};
$i++;
}
@sorted_lines;
}
# This is a sort routine that will sort on the
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
local($i) = 0;
foreach $addr (sort sortbyipaddr keys %lines) {
$sorted_lines[$i] = $lines{$addr};
$i++;
}
@sorted_lines;
}
# These two routines will sort based upon IP addresses
sub ipaddrval {
$a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
}
# This routine parses "show config"
sub ShowConfig {
print STDERR " In ShowConfig: $_" if ($debug);
$firstexit=0;
while (<INPUT>) {
tr/\015//d;
tr/\020//d;
#strip out the stupid spinning running-config progress thingy
s/Generating current config: \.*[\|\/\-\\]//gi;
$skipprocess=0;
#sometimes an 'exit' appears at the top of the config, we
don't want them
if ( (/^exit/) && ( ! $firstexit ) ) {
$firstexit=1;
$skipprocess=1;
}
#remove spaces left over from lame spinning progress thingy
if ( /^\s+! ――――――――――/ ) {
s/^\s+!/!/g
}
if (/^(read-only-community) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(read-write-community) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(trap-community-name) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(ntp-keys \d+ md5-key) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(password) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowConfig Data: $_" if ($debug);
ProcessHistory("","","","$_");
}
}
}
$clean_run=1;
print STDERR " Exiting ShowConfig: $_" if ($debug);
return(0);
}
# This routine parses single command's that return no required info
sub ShowVersion {
print STDERR " In ShowVersion: $_" if ($debug);
ProcessHistory("","","","!\n!IPS Show Version Start\n");
while (<INPUT>) {
tr/\015//d;
$skipprocess=0;
if ( /^Sensor up-time/ ) { $skipprocess=1; }
if ( ( /using.*bytes of available/i ) ) { $skipprocess=1; }
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowVersion Data: $_" if ($debug);
ProcessHistory("","","","! $_");
}
}
}
ProcessHistory("","","","!\n!IPS Show Version End\n");
print STDERR " Exiting ShowVersion: $_" if ($debug);
return(0)
}
# This routine parses single command's that return no required info
sub ShowUsersAll {
print STDERR " In ShowUsersAll: $_" if ($debug);
ProcessHistory("","","","!\n!IPS User Database Start\n");
while (<INPUT>) {
tr/\015//d;
$skipprocess=0;
s/^ CLI ID //g;
s/^ //g;
s/^\* +[0-9]+ +//g;
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowUsersAll Data: $_" if ($debug);
ProcessHistory("","","","!$_");
}
}
}
ProcessHistory("","","","!\n!IPS User Database End\n!\n!\n");
print STDERR " Exiting ShowUsersAll: $_" if ($debug);
return(0)
}
# dummy function
sub DoNothing {print STDOUT;}
# Main
@commandtable = (
{'show version' => 'ShowVersion'},
{'show users all' => 'ShowUsersAll'},
{'show configuration' => 'ShowConfig'}
);
# Use an array to preserve the order of the commands and a hash for mapping
# commands to the subroutine and track commands that have been completed.
@commands = map(keys(%$_), @commandtable);
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
if ($debug) { $| = 1; }
# The IPS doesn't like the TERM of network so we must change it
if ( $ENV{TERM} eq 'network' ) {
$ENV{TERM} = 'vt100′;
}
if ($file) {
print STDERR "opening file $host\n" if ($debug);
print STDOUT "opening file $host\n" if ($log);
open(INPUT,"<$host") || die "open failed for $host: $!\n";
} else {
print STDERR "executing clogin -t $timeo -c\"$cisco_cmds\"
$host\n" if ($debug);
print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\"
$host\n" if ($log);
if (defined($ENV{NOPIPE})) {
system "clogin -t $timeo -c \"$cisco_cmds\" $host </dev/null >
$host.raw 2>&1" || die "clogin failed for $host: $!\n";
open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n";
} else {
open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host
</dev/null |") || die "clogin failed for $host: $!\n";
}
}
# Change the TERM back to network
if ( $ENV{TERM} eq 'vt100′ ) {
$ENV{TERM} = 'network';
}
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
$filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
$filter_pwds = 1;
}
ProcessHistory("","","","!RANCID-CONTENT-TYPE: ipsrancid\n!\n");
TOP: while(<INPUT>) {
tr/\015//d;
#strip out the stupid spinning running-config progress thingy
s/Generating current config: \.*[\|\/\-\\]//gi;
if (/^.*logout$/) {
$clean_run=1;
last;
}
if (/^Error:/) {
print STDOUT ("$host clogin error: $_");
print STDERR ("$host clogin error: $_") if ($debug);
$clean_run=0;
last;
}
while (/($cmds_regexp)/) {
$cmd = $1;
if (!defined($prompt)) {
$prompt = ($_ =~ /^([^#]+#)/)[0];
$prompt =~ s/([][}{)(\\])/\\$1/g;
print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
}
print STDERR ("IPS COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
print STDERR "$host: found unexpected command - \"$cmd\"\n";
$clean_run = 0;
last TOP;
}
$rval = &{$commands{$cmd}};
delete($commands{$cmd});
if ($rval == -1) {
$clean_run = 0;
last TOP;
}
}
}
print STDOUT "Done $logincmd: $_\n" if ($log);
# Flush History
ProcessHistory("","","","");
# Cleanup
close(INPUT);
close(OUTPUT);
if (defined($ENV{NOPIPE})) {
unlink("$host.raw") if (! $debug);
}
# check for completeness
if (scalar(%commands) || !$clean_run ) {
if (scalar(%commands)) {
printf(STDOUT "$host: missed cmd(s): %s\n", join(',',
keys(%commands)));
printf(STDERR "$host: missed cmd(s): %s\n", join(',',
keys(%commands))) if ($debug);
}
if (!$clean_run ) {
print STDOUT "$host: End of run not found\n";
print STDERR "$host: End of run not found\n" if ($debug);
system("/usr/bin/tail -1 $host.new");
}
unlink "$host.new" if (! $debug);
}
I don't understand what this is meaning. i have searched around but
still can't figure out what the # sign is used for in perl regex like
it is being used here.
while (/#\s*($cmds_regexp)\s*$/) {
the # is a #, the end of the enabled user's prompt.
If I can figure this out then I will have the IPS module working for
rancid using the default clogin/rancid with only minor tweaks.
_______________________________________________
Rancid-discuss mailing list
http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
_______________________________________________
Rancid-discuss mailing list
http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
--
Gregory W Zill, MBA, CISSP
Information Security Engineer
Phone: 402-361-3066
Making Security Manageable
________________________________
ActiveGuard(R) and SecurCompass(R) are recognized excellence award winners by SC
Magazine and InfoSecurity Products Guide.
Confidentiality Notice: The content of this communication, along with any
attachments, is covered by federal and state law governing electronic
communications and may contain confidential and legally privileged
information. If the reader of this message is not the intended recipient,
you are hereby notified that any dissemination, distribution, use or copying
of the information contained herein is strictly prohibited. If you have
received this communication in error, please immediately contact us by
Copyright 2000-2008, Solutionary, Inc. All rights reserved. ActiveGuard,
SecurCompass, Solutionary and the Solutionary logo are registered marks of
Solutionary, Inc. SecurComply is a service mark of Solutionary, Inc.
Gregory W Zill
2008-11-14 15:44:00 UTC
Permalink
Lance Vermilion
2008-11-14 18:37:23 UTC
Permalink
Are you running the IPS on a 6500 or on a ASA?
Lance,
I originally had "autoenable...0" and from there I went to "noenable" --
upon your suggestion I just tried "autoenable...1" all have just about the
same result. However, the "autoenable...1" with clogin does allow me to
interact with the IPS, whereas the other settings freeze once logged in and
I end up timing out back to the rancid host.
Gregory,
You need to set autoenable for that device inside your ".cloginrc".
The IP puts you in privilege 15 when you login. I am guessing you do
not have that specified so rancid is trying to enable.
I get what appears to be a second user inputted somehow. Have you seen this?
How might I fix? This is a 4215 IPS.
$ clogin test_cisco_ips6
test_cisco_ips6
spawn ssh -c 3des -x -l cisco test_cisco_ips6
Last login: Fri Nov 14 09:07:54 2008 from 10.1.1.107
cisco
test_cisco_ips6# cisco
^
% Invalid input detected at '^' marker
BTW, the ipsrancid is great -- thank you
Thx Max and John.
As for making rancid work with IPS modules I have found that the post
from Jeremy M. Guthrie
"http://www.shrubbery.net/pipermail/rancid-discuss/2007-May/002209.html"
does very well and doesn't require making a lot of changes to rancid
to handle the errors that happen if you run too many commands that are
invalid commands. I also eliminated the need for his ipslogin. I
simply just had perl set the TERM to vt100 before it ran clogin and
then set the TERM back to network after it was finished running
clogin. I also fixed some typo's he had where it was the work "at"
it had some extra stuff that can change.
Here is a copy of what I put on my webpage. http://www.gheek.net/?p=78
In order to get rancid to collect the config from an IPS module you
will need to make sure you have the correct login creds in the rancid
users ".cloginrc", add the type of ips to "rancid-fe" and you also
need to create the "ipsrancid" script.
Changes required for "rancid-fe"
'ips' => 'ipsrancid',
Create the "ipsrancid" script as "<rancid_home>/bin/ipsrancid". Make
sure you "chmod 755 <rancid_home>/bin/ipsrancid" and "chown
<rancid_user>:<rancid_user> <rancid_home>/bin/ipsrancid".
#! /usr/bin/perl
##
## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
## without fee for non-commerical purposes provided that this license
## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
## It is provided solely "as is". The author(s) disclaim(s) all
## responsibility and liability with respect to this software's usage
## or its effect upon hardware, computer systems, other software, or
## anything else.
##
## Except where noted otherwise, rancid was written by and is maintained by
## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
# hacked version of Hank's rancid - this one tries to deal with Hitachi's.
#
# Modified again by Lance Vermilion (11/13/08)
# Modified from htrancid by Jeremy M. Guthrie
# Created on 5/4/2007
#
# This is meant to try handle Cisco's IPS V5.X line and on
#
# RANCID - Really Awesome New Cisco confIg Differ
#
# usage: ipsrancid [-d] [-l] [-f filename | $host]
use Getopt::Std;
getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
$timeo = 90; # clogin timeout in seconds
my(%filter_pwds); # password filtering mode
# This routine is used to print out the router configuration
sub ProcessHistory {
if ((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
&& defined %history) {
print eval "$command \%history";
undef %history;
}
if (($new_hist_tag) && ($new_command) && ($command_string)) {
if ($history{$command_string}) {
} else {
}
} elsif (($new_hist_tag) && ($new_command)) {
} else {
}
$hist_tag = $new_hist_tag;
$command = $new_command;
1;
}
sub numerically { $a <=> $b; }
# This is a sort routine that will sort numerically on the
# keys of a hash as if it were a normal array.
sub keynsort {
local($i) = 0;
foreach $key (sort numerically keys(%lines)) {
$sorted_lines[$i] = $lines{$key};
$i++;
}
@sorted_lines;
}
# This is a sort routine that will sort on the
# keys of a hash as if it were a normal array.
sub keysort {
local($i) = 0;
foreach $key (sort keys(%lines)) {
$sorted_lines[$i] = $lines{$key};
$i++;
}
@sorted_lines;
}
# This is a sort routine that will sort on the
# values of a hash as if it were a normal array.
sub valsort{
local($i) = 0;
foreach $key (sort values %lines) {
$sorted_lines[$i] = $key;
$i++;
}
@sorted_lines;
}
# This is a numerical sort routine (ascending).
sub numsort {
local($i) = 0;
foreach $num (sort {$a <=> $b} keys %lines) {
$sorted_lines[$i] = $lines{$num};
$i++;
}
@sorted_lines;
}
# This is a sort routine that will sort on the
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
local($i) = 0;
foreach $addr (sort sortbyipaddr keys %lines) {
$sorted_lines[$i] = $lines{$addr};
$i++;
}
@sorted_lines;
}
# These two routines will sort based upon IP addresses
sub ipaddrval {
$a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
}
# This routine parses "show config"
sub ShowConfig {
print STDERR " In ShowConfig: $_" if ($debug);
$firstexit=0;
while (<INPUT>) {
tr/\015//d;
tr/\020//d;
#strip out the stupid spinning running-config progress thingy
s/Generating current config: \.*[\|\/\-\\]//gi;
$skipprocess=0;
#sometimes an 'exit' appears at the top of the config, we
don't want them
if ( (/^exit/) && ( ! $firstexit ) ) {
$firstexit=1;
$skipprocess=1;
}
#remove spaces left over from lame spinning progress thingy
if ( /^\s+! ――――――――――/ ) {
s/^\s+!/!/g
}
if (/^(read-only-community) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(read-write-community) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(trap-community-name) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(ntp-keys \d+ md5-key) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(password) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowConfig Data: $_" if ($debug);
ProcessHistory("","","","$_");
}
}
}
$clean_run=1;
print STDERR " Exiting ShowConfig: $_" if ($debug);
return(0);
}
# This routine parses single command's that return no required info
sub ShowVersion {
print STDERR " In ShowVersion: $_" if ($debug);
ProcessHistory("","","","!\n!IPS Show Version Start\n");
while (<INPUT>) {
tr/\015//d;
$skipprocess=0;
if ( /^Sensor up-time/ ) { $skipprocess=1; }
if ( ( /using.*bytes of available/i ) ) { $skipprocess=1; }
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowVersion Data: $_" if ($debug);
ProcessHistory("","","","! $_");
}
}
}
ProcessHistory("","","","!\n!IPS Show Version End\n");
print STDERR " Exiting ShowVersion: $_" if ($debug);
return(0)
}
# This routine parses single command's that return no required info
sub ShowUsersAll {
print STDERR " In ShowUsersAll: $_" if ($debug);
ProcessHistory("","","","!\n!IPS User Database Start\n");
while (<INPUT>) {
tr/\015//d;
$skipprocess=0;
s/^ CLI ID //g;
s/^ //g;
s/^\* +[0-9]+ +//g;
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowUsersAll Data: $_" if ($debug);
ProcessHistory("","","","!$_");
}
}
}
ProcessHistory("","","","!\n!IPS User Database End\n!\n!\n");
print STDERR " Exiting ShowUsersAll: $_" if ($debug);
return(0)
}
# dummy function
sub DoNothing {print STDOUT;}
# Main
@commandtable = (
{'show version' => 'ShowVersion'},
{'show users all' => 'ShowUsersAll'},
{'show configuration' => 'ShowConfig'}
);
# Use an array to preserve the order of the commands and a hash for mapping
# commands to the subroutine and track commands that have been completed.
@commands = map(keys(%$_), @commandtable);
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
if ($debug) { $| = 1; }
# The IPS doesn't like the TERM of network so we must change it
if ( $ENV{TERM} eq 'network' ) {
$ENV{TERM} = 'vt100′;
}
if ($file) {
print STDERR "opening file $host\n" if ($debug);
print STDOUT "opening file $host\n" if ($log);
open(INPUT,"<$host") || die "open failed for $host: $!\n";
} else {
print STDERR "executing clogin -t $timeo -c\"$cisco_cmds\"
$host\n" if ($debug);
print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\"
$host\n" if ($log);
if (defined($ENV{NOPIPE})) {
system "clogin -t $timeo -c \"$cisco_cmds\" $host </dev/null >
$host.raw 2>&1" || die "clogin failed for $host: $!\n";
open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n";
} else {
open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host
</dev/null |") || die "clogin failed for $host: $!\n";
}
}
# Change the TERM back to network
if ( $ENV{TERM} eq 'vt100′ ) {
$ENV{TERM} = 'network';
}
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
$filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
$filter_pwds = 1;
}
ProcessHistory("","","","!RANCID-CONTENT-TYPE: ipsrancid\n!\n");
TOP: while(<INPUT>) {
tr/\015//d;
#strip out the stupid spinning running-config progress thingy
s/Generating current config: \.*[\|\/\-\\]//gi;
if (/^.*logout$/) {
$clean_run=1;
last;
}
if (/^Error:/) {
print STDOUT ("$host clogin error: $_");
print STDERR ("$host clogin error: $_") if ($debug);
$clean_run=0;
last;
}
while (/($cmds_regexp)/) {
$cmd = $1;
if (!defined($prompt)) {
$prompt = ($_ =~ /^([^#]+#)/)[0];
$prompt =~ s/([][}{)(\\])/\\$1/g;
print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
}
print STDERR ("IPS COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
print STDERR "$host: found unexpected command - \"$cmd\"\n";
$clean_run = 0;
last TOP;
}
$rval = &{$commands{$cmd}};
delete($commands{$cmd});
if ($rval == -1) {
$clean_run = 0;
last TOP;
}
}
}
print STDOUT "Done $logincmd: $_\n" if ($log);
# Flush History
ProcessHistory("","","","");
# Cleanup
close(INPUT);
close(OUTPUT);
if (defined($ENV{NOPIPE})) {
unlink("$host.raw") if (! $debug);
}
# check for completeness
if (scalar(%commands) || !$clean_run ) {
if (scalar(%commands)) {
printf(STDOUT "$host: missed cmd(s): %s\n", join(',',
keys(%commands)));
printf(STDERR "$host: missed cmd(s): %s\n", join(',',
keys(%commands))) if ($debug);
}
if (!$clean_run ) {
print STDOUT "$host: End of run not found\n";
print STDERR "$host: End of run not found\n" if ($debug);
system("/usr/bin/tail -1 $host.new");
}
unlink "$host.new" if (! $debug);
}
I don't understand what this is meaning. i have searched around but
still can't figure out what the # sign is used for in perl regex like
it is being used here.
while (/#\s*($cmds_regexp)\s*$/) {
the # is a #, the end of the enabled user's prompt.
If I can figure this out then I will have the IPS module working for
rancid using the default clogin/rancid with only minor tweaks.
_______________________________________________
Rancid-discuss mailing list
http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
_______________________________________________
Rancid-discuss mailing list
http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
--
Gregory W Zill, MBA, CISSP
Information Security Engineer
Phone: 402-361-3066
Making Security Manageable
________________________________
ActiveGuard(R) and SecurCompass(R) are recognized excellence award winners by SC
Magazine and InfoSecurity Products Guide.
Confidentiality Notice: The content of this communication, along with any
attachments, is covered by federal and state law governing electronic
communications and may contain confidential and legally privileged
information. If the reader of this message is not the intended recipient,
you are hereby notified that any dissemination, distribution, use or copying
of the information contained herein is strictly prohibited. If you have
received this communication in error, please immediately contact us by
Copyright 2000-2008, Solutionary, Inc. All rights reserved. ActiveGuard,
SecurCompass, Solutionary and the Solutionary logo are registered marks of
Solutionary, Inc. SecurComply is a service mark of Solutionary, Inc.
--
Gregory W Zill, MBA, CISSP
Information Security Engineer
Phone: 402-361-3066
Making Security Manageable
________________________________
ActiveGuard(R) and SecurCompass(R) are recognized excellence award winners by SC
Magazine and InfoSecurity Products Guide.
Confidentiality Notice: The content of this communication, along with any
attachments, is covered by federal and state law governing electronic
communications and may contain confidential and legally privileged
information. If the reader of this message is not the intended recipient,
you are hereby notified that any dissemination, distribution, use or copying
of the information contained herein is strictly prohibited. If you have
received this communication in error, please immediately contact us by
Copyright 2000-2008, Solutionary, Inc. All rights reserved. ActiveGuard,
SecurCompass, Solutionary and the Solutionary logo are registered marks of
Solutionary, Inc. SecurComply is a service mark of Solutionary, Inc.
Lance Vermilion
2008-11-14 19:49:24 UTC
Permalink
it looks like you have some windows inserted control characters. I
would run a perl -c ipsrancid to see if it is all ok.

I think what your issue is.

getopts('dfl').....something like this line. Those should be single
ticks (1 key left of enter on a US keyboard).
This is a Cisco 4215 chassis IPS.
I have checked the logs and noticed another item since I may be getting a
little further along with "autoenable...1"
=====================================
Getting missed routers: round 4.
Unrecognized character \xE2 at /home/mdrancid/bin/ipsrancid line 32.
-------- Original Message --------
Are you running the IPS on a 6500 or on a ASA?
Lance,
I originally had "autoenable...0" and from there I went to "noenable" --
upon your suggestion I just tried "autoenable...1" all have just about the
same result. However, the "autoenable...1" with clogin does allow me to
interact with the IPS, whereas the other settings freeze once logged in and
I end up timing out back to the rancid host.
Gregory,
You need to set autoenable for that device inside your ".cloginrc".
The IP puts you in privilege 15 when you login. I am guessing you do
not have that specified so rancid is trying to enable.
I get what appears to be a second user inputted somehow. Have you seen this?
How might I fix? This is a 4215 IPS.
$ clogin test_cisco_ips6
test_cisco_ips6
spawn ssh -c 3des -x -l cisco test_cisco_ips6
Last login: Fri Nov 14 09:07:54 2008 from 10.1.1.107
cisco
test_cisco_ips6# cisco
^
% Invalid input detected at '^' marker
BTW, the ipsrancid is great -- thank you
Thx Max and John.
As for making rancid work with IPS modules I have found that the post
from Jeremy M. Guthrie
"http://www.shrubbery.net/pipermail/rancid-discuss/2007-May/002209.html"
does very well and doesn't require making a lot of changes to rancid
to handle the errors that happen if you run too many commands that are
invalid commands. I also eliminated the need for his ipslogin. I
simply just had perl set the TERM to vt100 before it ran clogin and
then set the TERM back to network after it was finished running
clogin. I also fixed some typo's he had where it was the work "at"
it had some extra stuff that can change.
Here is a copy of what I put on my webpage. http://www.gheek.net/?p=78
In order to get rancid to collect the config from an IPS module you
will need to make sure you have the correct login creds in the rancid
users ".cloginrc", add the type of ips to "rancid-fe" and you also
need to create the "ipsrancid" script.
Changes required for "rancid-fe"
'ips' => 'ipsrancid',
Create the "ipsrancid" script as "<rancid_home>/bin/ipsrancid". Make
sure you "chmod 755 <rancid_home>/bin/ipsrancid" and "chown
<rancid_user>:<rancid_user> <rancid_home>/bin/ipsrancid".
#! /usr/bin/perl
##
## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
## without fee for non-commerical purposes provided that this license
## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
## It is provided solely "as is". The author(s) disclaim(s) all
## responsibility and liability with respect to this software's usage
## or its effect upon hardware, computer systems, other software, or
## anything else.
##
## Except where noted otherwise, rancid was written by and is maintained by
## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
# hacked version of Hank's rancid - this one tries to deal with Hitachi's.
#
# Modified again by Lance Vermilion (11/13/08)
# Modified from htrancid by Jeremy M. Guthrie
# Created on 5/4/2007
#
# This is meant to try handle Cisco's IPS V5.X line and on
#
# RANCID - Really Awesome New Cisco confIg Differ
#
# usage: ipsrancid [-d] [-l] [-f filename | $host]
use Getopt::Std;
getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
$timeo = 90; # clogin timeout in seconds
my(%filter_pwds); # password filtering mode
# This routine is used to print out the router configuration
sub ProcessHistory {
if ((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
&& defined %history) {
print eval "$command \%history";
undef %history;
}
if (($new_hist_tag) && ($new_command) && ($command_string)) {
if ($history{$command_string}) {
} else {
}
} elsif (($new_hist_tag) && ($new_command)) {
} else {
}
$hist_tag = $new_hist_tag;
$command = $new_command;
1;
}
sub numerically { $a <=> $b; }
# This is a sort routine that will sort numerically on the
# keys of a hash as if it were a normal array.
sub keynsort {
local($i) = 0;
foreach $key (sort numerically keys(%lines)) {
$sorted_lines[$i] = $lines{$key};
$i++;
}
@sorted_lines;
}
# This is a sort routine that will sort on the
# keys of a hash as if it were a normal array.
sub keysort {
local($i) = 0;
foreach $key (sort keys(%lines)) {
$sorted_lines[$i] = $lines{$key};
$i++;
}
@sorted_lines;
}
# This is a sort routine that will sort on the
# values of a hash as if it were a normal array.
sub valsort{
local($i) = 0;
foreach $key (sort values %lines) {
$sorted_lines[$i] = $key;
$i++;
}
@sorted_lines;
}
# This is a numerical sort routine (ascending).
sub numsort {
local($i) = 0;
foreach $num (sort {$a <=> $b} keys %lines) {
$sorted_lines[$i] = $lines{$num};
$i++;
}
@sorted_lines;
}
# This is a sort routine that will sort on the
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
local($i) = 0;
foreach $addr (sort sortbyipaddr keys %lines) {
$sorted_lines[$i] = $lines{$addr};
$i++;
}
@sorted_lines;
}
# These two routines will sort based upon IP addresses
sub ipaddrval {
$a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
}
# This routine parses "show config"
sub ShowConfig {
print STDERR " In ShowConfig: $_" if ($debug);
$firstexit=0;
while (<INPUT>) {
tr/\015//d;
tr/\020//d;
#strip out the stupid spinning running-config progress thingy
s/Generating current config: \.*[\|\/\-\\]//gi;
$skipprocess=0;
#sometimes an 'exit' appears at the top of the config, we
don't want them
if ( (/^exit/) && ( ! $firstexit ) ) {
$firstexit=1;
$skipprocess=1;
}
#remove spaces left over from lame spinning progress thingy
if ( /^\s+! ――――――――――/ ) {
s/^\s+!/!/g
}
if (/^(read-only-community) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(read-write-community) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(trap-community-name) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(ntp-keys \d+ md5-key) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(password) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowConfig Data: $_" if ($debug);
ProcessHistory("","","","$_");
}
}
}
$clean_run=1;
print STDERR " Exiting ShowConfig: $_" if ($debug);
return(0);
}
# This routine parses single command's that return no required info
sub ShowVersion {
print STDERR " In ShowVersion: $_" if ($debug);
ProcessHistory("","","","!\n!IPS Show Version Start\n");
while (<INPUT>) {
tr/\015//d;
$skipprocess=0;
if ( /^Sensor up-time/ ) { $skipprocess=1; }
if ( ( /using.*bytes of available/i ) ) { $skipprocess=1; }
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowVersion Data: $_" if ($debug);
ProcessHistory("","","","! $_");
}
}
}
ProcessHistory("","","","!\n!IPS Show Version End\n");
print STDERR " Exiting ShowVersion: $_" if ($debug);
return(0)
}
# This routine parses single command's that return no required info
sub ShowUsersAll {
print STDERR " In ShowUsersAll: $_" if ($debug);
ProcessHistory("","","","!\n!IPS User Database Start\n");
while (<INPUT>) {
tr/\015//d;
$skipprocess=0;
s/^ CLI ID //g;
s/^ //g;
s/^\* +[0-9]+ +//g;
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowUsersAll Data: $_" if ($debug);
ProcessHistory("","","","!$_");
}
}
}
ProcessHistory("","","","!\n!IPS User Database End\n!\n!\n");
print STDERR " Exiting ShowUsersAll: $_" if ($debug);
return(0)
}
# dummy function
sub DoNothing {print STDOUT;}
# Main
@commandtable = (
{'show version' => 'ShowVersion'},
{'show users all' => 'ShowUsersAll'},
{'show configuration' => 'ShowConfig'}
);
# Use an array to preserve the order of the commands and a hash for mapping
# commands to the subroutine and track commands that have been completed.
@commands = map(keys(%$_), @commandtable);
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
if ($debug) { $| = 1; }
# The IPS doesn't like the TERM of network so we must change it
if ( $ENV{TERM} eq 'network' ) {
$ENV{TERM} = 'vt100′;
}
if ($file) {
print STDERR "opening file $host\n" if ($debug);
print STDOUT "opening file $host\n" if ($log);
open(INPUT,"<$host") || die "open failed for $host: $!\n";
} else {
print STDERR "executing clogin -t $timeo -c\"$cisco_cmds\"
$host\n" if ($debug);
print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\"
$host\n" if ($log);
if (defined($ENV{NOPIPE})) {
system "clogin -t $timeo -c \"$cisco_cmds\" $host </dev/null >
$host.raw 2>&1" || die "clogin failed for $host: $!\n";
open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n";
} else {
open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host
</dev/null |") || die "clogin failed for $host: $!\n";
}
}
# Change the TERM back to network
if ( $ENV{TERM} eq 'vt100′ ) {
$ENV{TERM} = 'network';
}
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
$filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
$filter_pwds = 1;
}
ProcessHistory("","","","!RANCID-CONTENT-TYPE: ipsrancid\n!\n");
TOP: while(<INPUT>) {
tr/\015//d;
#strip out the stupid spinning running-config progress thingy
s/Generating current config: \.*[\|\/\-\\]//gi;
if (/^.*logout$/) {
$clean_run=1;
last;
}
if (/^Error:/) {
print STDOUT ("$host clogin error: $_");
print STDERR ("$host clogin error: $_") if ($debug);
$clean_run=0;
last;
}
while (/($cmds_regexp)/) {
$cmd = $1;
if (!defined($prompt)) {
$prompt = ($_ =~ /^([^#]+#)/)[0];
$prompt =~ s/([][}{)(\\])/\\$1/g;
print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
}
print STDERR ("IPS COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
print STDERR "$host: found unexpected command - \"$cmd\"\n";
$clean_run = 0;
last TOP;
}
$rval = &{$commands{$cmd}};
delete($commands{$cmd});
if ($rval == -1) {
$clean_run = 0;
last TOP;
}
}
}
print STDOUT "Done $logincmd: $_\n" if ($log);
# Flush History
ProcessHistory("","","","");
# Cleanup
close(INPUT);
close(OUTPUT);
if (defined($ENV{NOPIPE})) {
unlink("$host.raw") if (! $debug);
}
# check for completeness
if (scalar(%commands) || !$clean_run ) {
if (scalar(%commands)) {
printf(STDOUT "$host: missed cmd(s): %s\n", join(',',
keys(%commands)));
printf(STDERR "$host: missed cmd(s): %s\n", join(',',
keys(%commands))) if ($debug);
}
if (!$clean_run ) {
print STDOUT "$host: End of run not found\n";
print STDERR "$host: End of run not found\n" if ($debug);
system("/usr/bin/tail -1 $host.new");
}
unlink "$host.new" if (! $debug);
}
I don't understand what this is meaning. i have searched around but
still can't figure out what the # sign is used for in perl regex like
it is being used here.
while (/#\s*($cmds_regexp)\s*$/) {
the # is a #, the end of the enabled user's prompt.
If I can figure this out then I will have the IPS module working for
rancid using the default clogin/rancid with only minor tweaks.
_______________________________________________
Rancid-discuss mailing list
http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
_______________________________________________
Rancid-discuss mailing list
http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
--
Gregory W Zill, MBA, CISSP
Information Security Engineer
Phone: 402-361-3066
Making Security Manageable
________________________________
ActiveGuard(R) and SecurCompass(R) are recognized excellence award winners by SC
Magazine and InfoSecurity Products Guide.
Confidentiality Notice: The content of this communication, along with any
attachments, is covered by federal and state law governing electronic
communications and may contain confidential and legally privileged
information. If the reader of this message is not the intended recipient,
you are hereby notified that any dissemination, distribution, use or copying
of the information contained herein is strictly prohibited. If you have
received this communication in error, please immediately contact us by
Copyright 2000-2008, Solutionary, Inc. All rights reserved. ActiveGuard,
SecurCompass, Solutionary and the Solutionary logo are registered marks of
Solutionary, Inc. SecurComply is a service mark of Solutionary, Inc.
--
Gregory W Zill, MBA, CISSP
Information Security Engineer
Phone: 402-361-3066
Making Security Manageable
________________________________
ActiveGuard(R) and SecurCompass(R) are recognized excellence award winners by SC
Magazine and InfoSecurity Products Guide.
Confidentiality Notice: The content of this communication, along with any
attachments, is covered by federal and state law governing electronic
communications and may contain confidential and legally privileged
information. If the reader of this message is not the intended recipient,
you are hereby notified that any dissemination, distribution, use or copying
of the information contained herein is strictly prohibited. If you have
received this communication in error, please immediately contact us by
Copyright 2000-2008, Solutionary, Inc. All rights reserved. ActiveGuard,
SecurCompass, Solutionary and the Solutionary logo are registered marks of
Solutionary, Inc. SecurComply is a service mark of Solutionary, Inc.
_______________________________________________
Rancid-discuss mailing list
http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
--
----------------------------
Gregory W Zill, MBA, CISSP
Managed Device Team
Solutionary, Inc.
"Making security manageable"
----------------------------
Managed Devices
2008-11-14 18:44:40 UTC
Permalink
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-2022-JP"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
This is a Cisco 4215 chassis IPS.<br>
<br>
I have checked the logs and noticed another item since I may be getting
a little further along with "autoenable...1"<br>
<br>
<blockquote>=====================================<br>
Getting missed routers: round 4.<br>
Unrecognized character \xE2 at /home/mdrancid/bin/ipsrancid line 32.<br>
</blockquote>
<br>
-------- Original Message --------<br>
<blockquote
cite="mid:***@mail.gmail.com"
type="cite">
<pre wrap="">Are you running the IPS on a 6500 or on a ASA?

2008/11/14 Gregory W Zill <a class="moz-txt-link-rfc2396E" href="mailto:***@solutionary.com">&lt;***@solutionary.com&gt;</a>:
</pre>
<blockquote type="cite">
<pre wrap="">Lance,
I originally had "autoenable...0" and from there I went to "noenable" --
upon your suggestion I just tried "autoenable...1" all have just about the
same result. However, the "autoenable...1" with clogin does allow me to
interact with the IPS, whereas the other settings freeze once logged in and
I end up timing out back to the rancid host.

Gregory,

You need to set autoenable for that device inside your ".cloginrc".
The IP puts you in privilege 15 when you login. I am guessing you do
not have that specified so rancid is trying to enable.

2008/11/14 Gregory W Zill <a class="moz-txt-link-rfc2396E" href="mailto:***@solutionary.com">&lt;***@solutionary.com&gt;</a>:


I get what appears to be a second user inputted somehow. Have you seen this?
How might I fix? This is a 4215 IPS.

$ clogin test_cisco_ips6
test_cisco_ips6
spawn ssh -c 3des -x -l cisco test_cisco_ips6

Password:
Last login: Fri Nov 14 09:07:54 2008 from 10.1.1.107

cisco
test_cisco_ips6# cisco
^
% Invalid input detected at '^' marker


BTW, the ipsrancid is great -- thank you

Thx Max and John.

As for making rancid work with IPS modules I have found that the post
from Jeremy M. Guthrie
<a class="moz-txt-link-rfc2396E" href="http://www.shrubbery.net/pipermail/rancid-discuss/2007-May/002209.html">"http://www.shrubbery.net/pipermail/rancid-discuss/2007-May/002209.html"</a>
does very well and doesn't require making a lot of changes to rancid
to handle the errors that happen if you run too many commands that are
invalid commands. I also eliminated the need for his ipslogin. I
simply just had perl set the TERM to vt100 before it ran clogin and
then set the TERM back to network after it was finished running
clogin. I also fixed some typo's he had where it was the work "at"
instead of "@". I fixed what should be skipped for the ShowVersion as
it had some extra stuff that can change.

Here is a copy of what I put on my webpage. <a class="moz-txt-link-freetext" href="http://www.gheek.net/?p=78">http://www.gheek.net/?p=78</a>

In order to get rancid to collect the config from an IPS module you
will need to make sure you have the correct login creds in the rancid
users ".cloginrc", add the type of ips to "rancid-fe" and you also
need to create the "ipsrancid" script.

Changes required for "rancid-fe"
'ips' =&gt; 'ipsrancid',

Create the "ipsrancid" script as "&lt;rancid_home&gt;/bin/ipsrancid". Make
sure you "chmod 755 &lt;rancid_home&gt;/bin/ipsrancid" and "chown
&lt;rancid_user&gt;:&lt;rancid_user&gt; &lt;rancid_home&gt;/bin/ipsrancid".
#! /usr/bin/perl
##
## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
## without fee for non-commerical purposes provided that this license
## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
## It is provided solely "as is". The author(s) disclaim(s) all
## responsibility and liability with respect to this software's usage
## or its effect upon hardware, computer systems, other software, or
## anything else.
##
## Except where noted otherwise, rancid was written by and is maintained by
## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin
Schutz.
##
#
# hacked version of Hank's rancid - this one tries to deal with Hitachi's.
#
# Modified again by Lance Vermilion (11/13/08)
# Modified from htrancid by Jeremy M. Guthrie
# Created on 5/4/2007
#
# This is meant to try handle Cisco's IPS V5.X line and on
#
# RANCID - Really Awesome New Cisco confIg Differ
#
# usage: ipsrancid [-d] [-l] [-f filename | $host]
use Getopt::Std;
getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
$timeo = 90; # clogin timeout in seconds
my(@commandtable, %commands, @commands);# command lists
my(%filter_pwds); # password filtering mode

# This routine is used to print out the router configuration
sub ProcessHistory {

($new_hist_tag,$new_command,$command_string, @string) = (@_);
if ((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
&amp;&amp; defined %history) {
print eval "$command \%history";
undef %history;
}
if (($new_hist_tag) &amp;&amp; ($new_command) &amp;&amp; ($command_string)) {
if ($history{$command_string}) {
$history{$command_string} = "$history{$command_string}@string";
} else {
$history{$command_string} = "@string";
}
} elsif (($new_hist_tag) &amp;&amp; ($new_command)) {
$history{++$#history} = "@string";
} else {
print "@string";
}
$hist_tag = $new_hist_tag;
$command = $new_command;
1;
}

sub numerically { $a &lt;=&gt; $b; }

# This is a sort routine that will sort numerically on the
# keys of a hash as if it were a normal array.
sub keynsort {
local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
$sorted_lines[$i] = $lines{$key};
$i++;
}
@sorted_lines;
}

# This is a sort routine that will sort on the
# keys of a hash as if it were a normal array.
sub keysort {
local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
$sorted_lines[$i] = $lines{$key};
$i++;
}
@sorted_lines;
}

# This is a sort routine that will sort on the
# values of a hash as if it were a normal array.
sub valsort{
local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
$sorted_lines[$i] = $key;
$i++;
}
@sorted_lines;
}

# This is a numerical sort routine (ascending).
sub numsort {
local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a &lt;=&gt; $b} keys %lines) {
$sorted_lines[$i] = $lines{$num};
$i++;
}
@sorted_lines;
}

# This is a sort routine that will sort on the
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
$sorted_lines[$i] = $lines{$addr};
$i++;
}
@sorted_lines;
}

# These two routines will sort based upon IP addresses
sub ipaddrval {
my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#);
$a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&amp;ipaddrval($a) &lt;=&gt; &amp;ipaddrval($b);
}

# This routine parses "show config"
sub ShowConfig {
print STDERR " In ShowConfig: $_" if ($debug);

$firstexit=0;

while (&lt;INPUT&gt;) {
tr/\015//d;
tr/\020//d;

#strip out the stupid spinning running-config progress thingy
s/Generating current config: \.*[\|\/\-\\]//gi;
$skipprocess=0;

#sometimes an 'exit' appears at the top of the config, we
don't want them
if ( (/^exit/) &amp;&amp; ( ! $firstexit ) ) {
$firstexit=1;
$skipprocess=1;
}

#remove spaces left over from lame spinning progress thingy
if ( /^\s+! ――――――――――/ ) {
s/^\s+!/!/g
}

if (/^(read-only-community) / &amp;&amp; $filter_pwds &gt;= 1) {
ProcessHistory("","","","!$1 &lt;removed&gt;\n"); next;
}
if (/^(read-write-community) / &amp;&amp; $filter_pwds &gt;= 1) {
ProcessHistory("","","","!$1 &lt;removed&gt;\n"); next;
}
if (/^(trap-community-name) / &amp;&amp; $filter_pwds &gt;= 1) {
ProcessHistory("","","","!$1 &lt;removed&gt;\n"); next;
}
if (/^(ntp-keys \d+ md5-key) / &amp;&amp; $filter_pwds &gt;= 1) {
ProcessHistory("","","","!$1 &lt;removed&gt;\n"); next;
}
if (/^(password) / &amp;&amp; $filter_pwds &gt;= 1) {
ProcessHistory("","","","!$1 &lt;removed&gt;\n"); next;
}

last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowConfig Data: $_" if
($debug);
ProcessHistory("","","","$_");
}
}
}
$clean_run=1;
print STDERR " Exiting ShowConfig: $_" if ($debug);
return(0);
}

# This routine parses single command's that return no required info
sub ShowVersion {
print STDERR " In ShowVersion: $_" if ($debug);
ProcessHistory("","","","!\n!IPS Show Version Start\n");

while (&lt;INPUT&gt;) {
tr/\015//d;

$skipprocess=0;

if ( /^Sensor up-time/ ) { $skipprocess=1; }
if ( ( /using.*bytes of available/i ) ) { $skipprocess=1; }

last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowVersion Data: $_" if
($debug);
ProcessHistory("","","","! $_");
}
}
}
ProcessHistory("","","","!\n!IPS Show Version End\n");
print STDERR " Exiting ShowVersion: $_" if ($debug);
return(0)
}

# This routine parses single command's that return no required info
sub ShowUsersAll {
print STDERR " In ShowUsersAll: $_" if ($debug);
ProcessHistory("","","","!\n!IPS User Database Start\n");

while (&lt;INPUT&gt;) {
tr/\015//d;

$skipprocess=0;

s/^ CLI ID //g;
s/^ //g;
s/^\* +[0-9]+ +//g;

last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowUsersAll Data: $_" if
($debug);
ProcessHistory("","","","!$_");
}
}
}
ProcessHistory("","","","!\n!IPS User Database End\n!\n!\n");
print STDERR " Exiting ShowUsersAll: $_" if ($debug);
return(0)
}

# dummy function
sub DoNothing {print STDOUT;}

# Main
@commandtable = (
{'show version' =&gt; 'ShowVersion'},
{'show users all' =&gt; 'ShowUsersAll'},
{'show configuration' =&gt; 'ShowConfig'}
);
# Use an array to preserve the order of the commands and a hash for mapping
# commands to the subroutine and track commands that have been completed.
@commands = map(keys(%$_), @commandtable);
%commands = map(%$_, @commandtable);

$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);

open(OUTPUT,"&gt;$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
if ($debug) { $| = 1; }

# The IPS doesn't like the TERM of network so we must change it
if ( $ENV{TERM} eq 'network' ) {
$ENV{TERM} = 'vt100′;
}
if ($file) {
print STDERR "opening file $host\n" if ($debug);
print STDOUT "opening file $host\n" if ($log);
open(INPUT,"&lt;$host") || die "open failed for $host: $!\n";
} else {
print STDERR "executing clogin -t $timeo -c\"$cisco_cmds\"
$host\n" if ($debug);
print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\"
$host\n" if ($log);
if (defined($ENV{NOPIPE})) {
system "clogin -t $timeo -c \"$cisco_cmds\" $host &lt;/dev/null &gt;
$host.raw 2&gt;&amp;1" || die "clogin failed for $host: $!\n";
open(INPUT, "&lt; $host.raw") || die "clogin failed for $host: $!\n";
} else {
open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host
&lt;/dev/null |") || die "clogin failed for $host: $!\n";
}
}
# Change the TERM back to network
if ( $ENV{TERM} eq 'vt100′ ) {
$ENV{TERM} = 'network';
}

# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
$filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
$filter_pwds = 1;
}

ProcessHistory("","","","!RANCID-CONTENT-TYPE: ipsrancid\n!\n");
TOP: while(&lt;INPUT&gt;) {
tr/\015//d;

#strip out the stupid spinning running-config progress thingy
s/Generating current config: \.*[\|\/\-\\]//gi;

if (/^.*logout$/) {
$clean_run=1;
last;
}
if (/^Error:/) {
print STDOUT ("$host clogin error: $_");
print STDERR ("$host clogin error: $_") if ($debug);
$clean_run=0;
last;
}
while (/($cmds_regexp)/) {
$cmd = $1;
if (!defined($prompt)) {
$prompt = ($_ =~ /^([^#]+#)/)[0];
$prompt =~ s/([][}{)(\\])/\\$1/g;
print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
}
print STDERR ("IPS COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
print STDERR "$host: found unexpected command - \"$cmd\"\n";
$clean_run = 0;
last TOP;
}
$rval = &amp;{$commands{$cmd}};
delete($commands{$cmd});
if ($rval == -1) {
$clean_run = 0;
last TOP;
}
}
}
print STDOUT "Done $logincmd: $_\n" if ($log);
# Flush History
ProcessHistory("","","","");
# Cleanup
close(INPUT);
close(OUTPUT);

if (defined($ENV{NOPIPE})) {
unlink("$host.raw") if (! $debug);
}

# check for completeness
if (scalar(%commands) || !$clean_run ) {
if (scalar(%commands)) {
printf(STDOUT "$host: missed cmd(s): %s\n", join(',',
keys(%commands)));
printf(STDERR "$host: missed cmd(s): %s\n", join(',',
keys(%commands))) if ($debug);
}
if (!$clean_run ) {
print STDOUT "$host: End of run not found\n";
print STDERR "$host: End of run not found\n" if ($debug);
system("/usr/bin/tail -1 $host.new");
}
unlink "$host.new" if (! $debug);
}

On Wed, Nov 12, 2008 at 11:53 PM, john heasley <a class="moz-txt-link-rfc2396E" href="mailto:***@shrubbery.net">&lt;***@shrubbery.net&gt;</a> wrote:


Wed, Nov 12, 2008 at 05:36:50PM -0700, Lance Vermilion:


I don't understand what this is meaning. i have searched around but
still can't figure out what the # sign is used for in perl regex like
it is being used here.

while (/#\s*($cmds_regexp)\s*$/) {


the # is a #, the end of the enabled user's prompt.



If I can figure this out then I will have the IPS module working for
rancid using the default clogin/rancid with only minor tweaks.
_______________________________________________
Rancid-discuss mailing list
<a class="moz-txt-link-abbreviated" href="mailto:Rancid-***@shrubbery.net">Rancid-***@shrubbery.net</a>
<a class="moz-txt-link-freetext" href="http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss">http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss</a>


_______________________________________________
Rancid-discuss mailing list
<a class="moz-txt-link-abbreviated" href="mailto:Rancid-***@shrubbery.net">Rancid-***@shrubbery.net</a>
<a class="moz-txt-link-freetext" href="http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss">http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss</a>


--

Gregory W Zill, MBA, CISSP
Information Security Engineer
Phone: 402-361-3066
Email: <a class="moz-txt-link-abbreviated" href="mailto:***@solutionary.com">***@solutionary.com</a>
Making Security Manageable
________________________________
ActiveGuard(R) and SecurCompass(R) are recognized excellence award winners
by SC
Magazine and InfoSecurity Products Guide.

Confidentiality Notice: The content of this communication, along with any
attachments, is covered by federal and state law governing electronic
communications and may contain confidential and legally privileged
information. If the reader of this message is not the intended recipient,
you are hereby notified that any dissemination, distribution, use or copying
of the information contained herein is strictly prohibited. If you have
received this communication in error, please immediately contact us by
telephone at 402.361.3000 or e-mail <a class="moz-txt-link-abbreviated" href="mailto:***@solutionary.com">***@solutionary.com</a>. Thank you.

Copyright 2000-2008, Solutionary, Inc. All rights reserved. ActiveGuard,
SecurCompass, Solutionary and the Solutionary logo are registered marks of
Solutionary, Inc. SecurComply is a service mark of Solutionary, Inc.


--

Gregory W Zill, MBA, CISSP
Information Security Engineer
Phone: 402-361-3066
Email: <a class="moz-txt-link-abbreviated" href="mailto:***@solutionary.com">***@solutionary.com</a>
Making Security Manageable
________________________________
ActiveGuard(R) and SecurCompass(R) are recognized excellence award winners by SC
Magazine and InfoSecurity Products Guide.

Confidentiality Notice: The content of this communication, along with any
attachments, is covered by federal and state law governing electronic
communications and may contain confidential and legally privileged
information. If the reader of this message is not the intended recipient,
you are hereby notified that any dissemination, distribution, use or copying
of the information contained herein is strictly prohibited. If you have
received this communication in error, please immediately contact us by
telephone at 402.361.3000 or e-mail <a class="moz-txt-link-abbreviated" href="mailto:***@solutionary.com">***@solutionary.com</a>. Thank you.

Copyright 2000-2008, Solutionary, Inc. All rights reserved. ActiveGuard,
SecurCompass, Solutionary and the Solutionary logo are registered marks of
Solutionary, Inc. SecurComply is a service mark of Solutionary, Inc.
</pre>
</blockquote>
<pre wrap=""><!---->_______________________________________________
Rancid-discuss mailing list
<a class="moz-txt-link-abbreviated" href="mailto:Rancid-***@shrubbery.net">Rancid-***@shrubbery.net</a>
<a class="moz-txt-link-freetext" href="http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss">http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss</a>
</pre>
</blockquote>
<br>
<br>
<pre class="moz-signature" cols="72">--

----------------------------
Gregory W Zill, MBA, CISSP
Managed Device Team
Solutionary, Inc.
"Making security manageable"
----------------------------
</pre>
</body>
</html>

Sam Munzani
2008-11-14 17:07:51 UTC
Permalink
John,
Can we get a new beta revision out with this included? I think somebody
had made Cisco MDS9000 switches work after the last beta.

Thanks,
sam
Post by Lance Vermilion
Thx Max and John.
As for making rancid work with IPS modules I have found that the post
from Jeremy M. Guthrie
"http://www.shrubbery.net/pipermail/rancid-discuss/2007-May/002209.html"
does very well and doesn't require making a lot of changes to rancid
to handle the errors that happen if you run too many commands that are
invalid commands. I also eliminated the need for his ipslogin. I
simply just had perl set the TERM to vt100 before it ran clogin and
then set the TERM back to network after it was finished running
clogin. I also fixed some typo's he had where it was the work "at"
it had some extra stuff that can change.
Here is a copy of what I put on my webpage. http://www.gheek.net/?p=78
In order to get rancid to collect the config from an IPS module you
will need to make sure you have the correct login creds in the rancid
users ".cloginrc", add the type of ips to "rancid-fe" and you also
need to create the "ipsrancid" script.
Changes required for "rancid-fe"
'ips' => 'ipsrancid',
Create the "ipsrancid" script as "<rancid_home>/bin/ipsrancid". Make
sure you "chmod 755 <rancid_home>/bin/ipsrancid" and "chown
<rancid_user>:<rancid_user> <rancid_home>/bin/ipsrancid".
#! /usr/bin/perl
##
## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
## without fee for non-commerical purposes provided that this license
## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
## It is provided solely "as is". The author(s) disclaim(s) all
## responsibility and liability with respect to this software's usage
## or its effect upon hardware, computer systems, other software, or
## anything else.
##
## Except where noted otherwise, rancid was written by and is maintained by
## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
# hacked version of Hank's rancid - this one tries to deal with Hitachi's.
#
# Modified again by Lance Vermilion (11/13/08)
# Modified from htrancid by Jeremy M. Guthrie
# Created on 5/4/2007
#
# This is meant to try handle Cisco's IPS V5.X line and on
#
# RANCID - Really Awesome New Cisco confIg Differ
#
# usage: ipsrancid [-d] [-l] [-f filename | $host]
use Getopt::Std;
getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
$timeo = 90; # clogin timeout in seconds
my(%filter_pwds); # password filtering mode
# This routine is used to print out the router configuration
sub ProcessHistory {
if ((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
&& defined %history) {
print eval "$command \%history";
undef %history;
}
if (($new_hist_tag) && ($new_command) && ($command_string)) {
if ($history{$command_string}) {
} else {
}
} elsif (($new_hist_tag) && ($new_command)) {
} else {
}
$hist_tag = $new_hist_tag;
$command = $new_command;
1;
}
sub numerically { $a <=> $b; }
# This is a sort routine that will sort numerically on the
# keys of a hash as if it were a normal array.
sub keynsort {
local($i) = 0;
foreach $key (sort numerically keys(%lines)) {
$sorted_lines[$i] = $lines{$key};
$i++;
}
@sorted_lines;
}
# This is a sort routine that will sort on the
# keys of a hash as if it were a normal array.
sub keysort {
local($i) = 0;
foreach $key (sort keys(%lines)) {
$sorted_lines[$i] = $lines{$key};
$i++;
}
@sorted_lines;
}
# This is a sort routine that will sort on the
# values of a hash as if it were a normal array.
sub valsort{
local($i) = 0;
foreach $key (sort values %lines) {
$sorted_lines[$i] = $key;
$i++;
}
@sorted_lines;
}
# This is a numerical sort routine (ascending).
sub numsort {
local($i) = 0;
foreach $num (sort {$a <=> $b} keys %lines) {
$sorted_lines[$i] = $lines{$num};
$i++;
}
@sorted_lines;
}
# This is a sort routine that will sort on the
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
local($i) = 0;
foreach $addr (sort sortbyipaddr keys %lines) {
$sorted_lines[$i] = $lines{$addr};
$i++;
}
@sorted_lines;
}
# These two routines will sort based upon IP addresses
sub ipaddrval {
$a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) <=> &ipaddrval($b);
}
# This routine parses "show config"
sub ShowConfig {
print STDERR " In ShowConfig: $_" if ($debug);
$firstexit=0;
while (<INPUT>) {
tr/\015//d;
tr/\020//d;
#strip out the stupid spinning running-config progress thingy
s/Generating current config: \.*[\|\/\-\\]//gi;
$skipprocess=0;
#sometimes an 'exit' appears at the top of the config, we
don't want them
if ( (/^exit/) && ( ! $firstexit ) ) {
$firstexit=1;
$skipprocess=1;
}
#remove spaces left over from lame spinning progress thingy
if ( /^\s+! ――――――――――/ ) {
s/^\s+!/!/g
}
if (/^(read-only-community) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(read-write-community) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(trap-community-name) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(ntp-keys \d+ md5-key) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
if (/^(password) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 <removed>\n"); next;
}
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowConfig Data: $_" if ($debug);
ProcessHistory("","","","$_");
}
}
}
$clean_run=1;
print STDERR " Exiting ShowConfig: $_" if ($debug);
return(0);
}
# This routine parses single command's that return no required info
sub ShowVersion {
print STDERR " In ShowVersion: $_" if ($debug);
ProcessHistory("","","","!\n!IPS Show Version Start\n");
while (<INPUT>) {
tr/\015//d;
$skipprocess=0;
if ( /^Sensor up-time/ ) { $skipprocess=1; }
if ( ( /using.*bytes of available/i ) ) { $skipprocess=1; }
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowVersion Data: $_" if ($debug);
ProcessHistory("","","","! $_");
}
}
}
ProcessHistory("","","","!\n!IPS Show Version End\n");
print STDERR " Exiting ShowVersion: $_" if ($debug);
return(0)
}
# This routine parses single command's that return no required info
sub ShowUsersAll {
print STDERR " In ShowUsersAll: $_" if ($debug);
ProcessHistory("","","","!\n!IPS User Database Start\n");
while (<INPUT>) {
tr/\015//d;
$skipprocess=0;
s/^ CLI ID //g;
s/^ //g;
s/^\* +[0-9]+ +//g;
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowUsersAll Data: $_" if ($debug);
ProcessHistory("","","","!$_");
}
}
}
ProcessHistory("","","","!\n!IPS User Database End\n!\n!\n");
print STDERR " Exiting ShowUsersAll: $_" if ($debug);
return(0)
}
# dummy function
sub DoNothing {print STDOUT;}
# Main
@commandtable = (
{'show version' => 'ShowVersion'},
{'show users all' => 'ShowUsersAll'},
{'show configuration' => 'ShowConfig'}
);
# Use an array to preserve the order of the commands and a hash for mapping
# commands to the subroutine and track commands that have been completed.
@commands = map(keys(%$_), @commandtable);
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
if ($debug) { $| = 1; }
# The IPS doesn't like the TERM of network so we must change it
if ( $ENV{TERM} eq 'network' ) {
$ENV{TERM} = 'vt100′;
}
if ($file) {
print STDERR "opening file $host\n" if ($debug);
print STDOUT "opening file $host\n" if ($log);
open(INPUT,"<$host") || die "open failed for $host: $!\n";
} else {
print STDERR "executing clogin -t $timeo -c\"$cisco_cmds\"
$host\n" if ($debug);
print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\"
$host\n" if ($log);
if (defined($ENV{NOPIPE})) {
system "clogin -t $timeo -c \"$cisco_cmds\" $host </dev/null >
$host.raw 2>&1" || die "clogin failed for $host: $!\n";
open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n";
} else {
open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host
</dev/null |") || die "clogin failed for $host: $!\n";
}
}
# Change the TERM back to network
if ( $ENV{TERM} eq 'vt100′ ) {
$ENV{TERM} = 'network';
}
# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
$filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
$filter_pwds = 1;
}
ProcessHistory("","","","!RANCID-CONTENT-TYPE: ipsrancid\n!\n");
TOP: while(<INPUT>) {
tr/\015//d;
#strip out the stupid spinning running-config progress thingy
s/Generating current config: \.*[\|\/\-\\]//gi;
if (/^.*logout$/) {
$clean_run=1;
last;
}
if (/^Error:/) {
print STDOUT ("$host clogin error: $_");
print STDERR ("$host clogin error: $_") if ($debug);
$clean_run=0;
last;
}
while (/($cmds_regexp)/) {
$cmd = $1;
if (!defined($prompt)) {
$prompt = ($_ =~ /^([^#]+#)/)[0];
$prompt =~ s/([][}{)(\\])/\\$1/g;
print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
}
print STDERR ("IPS COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
print STDERR "$host: found unexpected command - \"$cmd\"\n";
$clean_run = 0;
last TOP;
}
$rval = &{$commands{$cmd}};
delete($commands{$cmd});
if ($rval == -1) {
$clean_run = 0;
last TOP;
}
}
}
print STDOUT "Done $logincmd: $_\n" if ($log);
# Flush History
ProcessHistory("","","","");
# Cleanup
close(INPUT);
close(OUTPUT);
if (defined($ENV{NOPIPE})) {
unlink("$host.raw") if (! $debug);
}
# check for completeness
if (scalar(%commands) || !$clean_run ) {
if (scalar(%commands)) {
printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands)));
printf(STDERR "$host: missed cmd(s): %s\n", join(',',
keys(%commands))) if ($debug);
}
if (!$clean_run ) {
print STDOUT "$host: End of run not found\n";
print STDERR "$host: End of run not found\n" if ($debug);
system("/usr/bin/tail -1 $host.new");
}
unlink "$host.new" if (! $debug);
}
Post by john heasley
Post by Lance Vermilion
I don't understand what this is meaning. i have searched around but
still can't figure out what the # sign is used for in perl regex like
it is being used here.
while (/#\s*($cmds_regexp)\s*$/) {
the # is a #, the end of the enabled user's prompt.
Post by Lance Vermilion
If I can figure this out then I will have the IPS module working for
rancid using the default clogin/rancid with only minor tweaks.
_______________________________________________
Rancid-discuss mailing list
http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
_______________________________________________
Rancid-discuss mailing list
http://www.shrubbery.net/mailman/listinfo.cgi/rancid-discuss
Loading...