RANCID (Really Awesome New Cisco confIg Differ) is a tool for automating the collection of hardware and configuration data from network devices. I recently upgraded an installation from version 2.3.1 to 2.3.8. And naturally, because I didn't have a ton of time to devote to this, stuff broke. It stopped pulling data from some switches. Not all switches, mind, that would be too easy to troubleshoot. Only some.

So after getting my hands dirty in PERL and TCL/expect, I found that somewhere between v2.3.1 and 2.3.8, the logic that governs the login process to a Cisco device was changed. RANCID tries to determine if at first login, it's being dropped into privileged mode or regular exec mode. In v2.3.8 it does this by hunting for two characters in the output coming off the switch during login:

  • The greater-than sign ">", meaning it's exec model, and...
  • The octothorpe! "#", meaning it's privileged mode

Well, turns out, on the switches that weren't being collected any more we use the octothorpe in the login banner. Things like "This switch is in cabinet #1234". Really innocuous stuff. However, RANCID sees this character and believes it's seeing the prompt for privileged mode. As a result, it doesn't bother issuing the "enable" command. This causes problems later on when it tries to run commands like "show run".

As per the RANCID FAQ, their take is that you need to avoid using ">" and "#" in the banners. This is annoying, especially for a character as common as "#" and also pretty challenging to drive home in a team of multiple network engineers.

My solution was to amend the regular expression that RANCID uses to find the prompt. It now looks for the ">" or "#" characters (as well as the string " (enable)" in case you're on an CatOS box) followed by optional whitespace and then a line return.

--- bin/clogin.orig     Tue Mar 20 10:00:35 2012
+++ bin/clogin  Tue Mar 20 10:22:01 2012
 @@ -750,7 +750,11 @@
 }

      # Default prompt.
 -    set prompt "(>|#| \\(enable\\))"
 +    # This has been modified from the stock regexp by adding the "\\s*$". This
 +    # works around our use of the '#' character in the login banner at $WORK.
 +    # Note that this would fail if we had the '#' character at the end of a
 +    # line in the banner, but for now, we don't.   -jknight 2012.03.20
 +    set prompt "(>|#| \\(enable\\))\\s*$"

      # look for noenable option in .cloginrc
      if { [find noenable $router] == "1" } {

For us, anchoring the regexp to the end of the line worked because we don't use the octothorpe at the end of line, just in the middle of sentences and maybe at the beginning of lines. If you have a banner like this:

#####################
# THIS IS MY SWITCH #
#####################

This won't work and you'll still have issues.