Open earendilfr opened 2 years ago
I also experimented with including CDP neighbor info and came up with this code. I spent some time on sorting the output to avoid oscillation. I also tried to mimic the way Cisco sorts "show int" outputs: G0/11 stands after G0/2, etc. My code skips reporting softphones because they tend to oscillate as well.
# This routine processes "show cdp neighbors detail"
sub ShowCDPNeighbors {
my($INPUT, $OUTPUT, $cmd) = @_;
my $neighbor = 0;
my $deviceID = '';
my $ipAddress = '';
my $localInterface = '';
my $remoteInterface = '';
print STDERR " In ShowCDPNeighbors $_" if ($debug);
while (<$INPUT>) {
tr/\015//d;
next if (/^(\s*|\s*$cmd\s*)$/);
next if (/^\s+\^$/);
return(1) if (/Line has invalid autocommand /);
return(1) if (/(invalid (input|command) detected|type help or )/i);
return(-1) if (/command authorization failed/i);
last if (/^% CDP is not enabled/);
last if (/^Total cdp entries displayed\s+:\s+0$/);
if (/^-------------------------$/ && $neighbor == 0) {
$neighbor++;
next;
}
if (/^Device ID: (.*)$/) {
$deviceID = $1;
#$deviceID =~ s/\..*//i; # remove domain from device ID
next;
}
if (/^ IP address: (.*)$/ && $ipAddress eq '') {
$ipAddress = $1;
next;
}
if (/^Interface: (..)[^0-9]*(.*), Port ID \(outgoing port\): (..)[^0-9]*(.*)$/) {
$localInterface = $1 . $2;
$remoteInterface = $3 . $4;
next;
}
if (/^-------------------------$/ || /^$prompt/) {
my $sort = $neighbor; # fallback to neighbor number if nothing else to sort by
# Sort by local Interface
## First: sort by ASCII code of first letter in Port description
if ($localInterface ne '') {
$sort = ord($localInterface);
## Second: sort by concatenated number from all numbers of Port description with up to 2 leading zeros
(my $portnum = $localInterface) =~ s/(\d+)/sprintf('%03u',$1)/eg;
$portnum =~ s/[^0-9]//g;
$sort = $sort * 1000000000 + $portnum;
}
## Third: sort by remote neighbor IP address converted to decimal
if ($ipAddress ne '') {
(my $a = $ipAddress) =~ s/(\d+)/sprintf('%02x',$1)/eg;
$a =~ s/\.//g;
$sort = $sort * 4228250626 + hex($a);
}
$ipAddress = '<unknown IP>' if ($ipAddress eq '');
$remoteInterface = '<unknown remote Interface>' if ($remoteInterface eq '');
my $pad = ' ' x (11 - length($localInterface));
if ($deviceID !~ m/^(SEP|IPC_|ATA)/) { # skip VoIP phones (hardphones + softphones) and ATAs
ProcessHistory("CDP","keynsort","$sort","!CDP: $localInterface$pad$deviceID ($ipAddress, $remoteInterface)\n");
}
$deviceID = $ipAddress = $localInterface = $remoteInterface = '';
$neighbor++;
last if (/^$prompt/);
next;
}
}
ProcessHistory("CDP","","","!\n") if ($neighbor > 0);
return(0);
}
Some proposal on IOS and NXOS modules:
Only for IOS, add the possiblity to launch the following commands