In this blog, I will post some additional network commands which can used to poll extra information from the network devices (particularly Cisco devices).
In my previous post, these PERL scripts (i.e. rancid, jrancid, hrancid, zrancid) are used to collect information from model specific devices as defined in the router.db configuration file. For Cisco devices, the script “rancid” takes care of this process.
In the “rancid” script, look at the section which defines the array @commandtable :
# Main
@commandtable = (
{’admin show version’ => ‘ShowVersion’},
{’show version’ => ‘ShowVersion’},
{’show redundancy secondary’ => ‘ShowRedundancy’},
….
{’show debug’ => ‘ShowDebug’},
{’show running-config’ => ‘WriteTerm’},
{’write term’ => ‘WriteTerm’},
);
It is fairly straightforward to understand that if you don’t want any of these commands to be polled from the Cisco devices is to comment the lines for each command. In Perl, use the # at the start of each line to have them ignored.
Here we will now add some new commands on the array for polling additional information from the Cisco devices. These are:
show interface status
show arp
show mac addresss-table
show access-list
Any Cisco network engineer would understand the usefulness of these commands
First we will include these commands in the @commandtable array, place them anywhere within the parenthesis section:
@commandtable = (
…
{’show interfaces status’ => ‘ShowInterfaceStatus’},
{’show mac address-table’ => ‘ShowMacAddressTable’},
{’show arp’ => ‘ShowArpTable’},
{’show access-list’ => ‘ShowAccessList’},
);
Then we need to define the subroutine for each of these commands. Below are scripts that I managed to get working for these commands. Some are rudimentary with some parsing based on the behavior of some Cisco devices I have encountered. You might need to fine-tune them further based on the results from your end.
Subroutine for “show interface status” command:
sub ShowInterfaceStatus {
print STDERR ” In ShowInterfaceStatus: $_” if ($debug);
while (<INPUT>) {
tr/\015//d;
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
return(1) if /^\s*\^\s*$/;
return(1) if /Invalid input detected/;
return(1) if /Unknown command/;
return(-1) if (/command authorization failed/i);
# the pager can not be disabled per-session on the PIX
if (/^(< -+ More -+>)/) {
my($len) = length($1);
s/^$1\s{$len}//;
}
ProcessHistory(”INTERFACES”,”",”",”!INTERFACES: $_”);
}
ProcessHistory(”INTERFACES”,”",”",”!\n”);
return(0);
}
Subroutine for “show arp” command:
sub ShowArpTable {
print STDERR ” In ShowArpTable: $_” if ($debug);
while (<INPUT>) {
tr/\015//d;
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
return(1) if /^\s*\^\s*$/;
return(1) if /Invalid input detected/;
return(1) if /Unknown command/;
return(-1) if (/command authorization failed/i);
# the pager can not be disabled per-session on the PIX
if (/^(< -+ More -+>)/) {
my($len) = length($1);
s/^$1\s{$len}//;
}
if (/^Internet\s+(\d+\.\d+\.\d+\.\d+)\s+/) {
my($ip) = $1;
my($line) = $_;
my(@arp) = split(/\s+/, $line);
my($line) = “$arp[0]\t$arp[1]\t$arp[3]\t$arp[4]\t$arp[5]\n”;
ProcessHistory(”ARPTABLE”,”ipsort”,”$1″,”$line”);
} elsif (/\S+\s+(\d+\.\d+\.\d+\.\d+)\s+/){
my($ip) = $1;
my($line) = $_;
my(@arp) = split(/\s+/, $line);
my($line) = “$arp[0]\t$arp[1]\t$arp[2]\t$arp[3]\n”;
ProcessHistory(”ARPTABLE”,”ipsort”,”$1″,”$line”);
} else {
ProcessHistory(”ARPTABLE”,”",”",”$_”);
}
next;
}
ProcessHistory(”ARPTABLE”,”",”",”!\n”);
return(0);
}
Subroutine for “show mac address-table” command:
sub ShowMacAddressTable {
print STDERR ” In ShowMacAddressTable: $_” if ($debug);
while (<INPUT>) {
tr/\015//d;
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
return(1) if /^\s*\^\s*$/;
return(1) if /Invalid input detected/;
return(1) if /Unknown command/;
return(-1) if (/command authorization failed/i);
# the pager can not be disabled per-session on the PIX
if (/^(< -+ More -+>)/) {
my($len) = length($1);
s/^$1\s{$len}//;
}
ProcessHistory(”MACTABLE”,”",”",”!MACTABLE: $_”);
}
ProcessHistory(”MACTABLE”,”",”",”!\n”);
return(0);
}
Subroutine for “show access-list” command:
sub ShowAccessList {
print STDERR ” In ShowAccessList: $_” if ($debug);
while (<INPUT>) {
tr/\015//d;
last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
return(1) if /^\s*\^\s*$/;
return(1) if /Invalid input detected/;
return(1) if /Unknown command/;
return(-1) if (/command authorization failed/i);
# the pager can not be disabled per-session on the PIX
if (/^(< -+ More -+>)/) {
my($len) = length($1);
s/^$1\s{$len}//;
}
ProcessHistory(”ACCESS-LIST”,”",”",”!ACCESS-LIST: $_”);
}
ProcessHistory(”ACCESS-LIST”,”",”",”!\n”);
return(0);
}
To test the results of the additional commands, perform RANCID collection on one of your Cisco devices defined already in the router.db with the credentials in .cloginrc.
sudo -u rancid -H /usr/bin/rancid-run -r <DEVICE>
where DEVICE is the hostname or IP address of the device.
Let me know if you have issues with these additional scripts. Enjoy!