Detect Devices that Your Spectrum Doesn't Know

Abstract

CA's Spectrum is a nice network management tool. But how can you find out, if there are devices in your network that Spectrum doesn't know of? In this article I present a simple PERL script that provides a solution to this problem.

Detect Devices that Spectrum Doesn't Know

CA's Spectrum is a nice network management tool. But how can you find out if there are devices on your network that Spectrum doesn't know of? There is no button: List all devices that Spectrum does not manage.

Note

Well, perhaps there is, but I did not find it.

In this article I present a simple PERL script that lists alien, hidden or misconfigured devices, that Spectrum has no access to, but your networks knows of.

Spectrum API

The first step is to ask Spectrum about all devices it knows. In Spectrum speak these devices are called models. The SpectroServer offers a nice API that you can ask. Under the URL http://$specserver/spectrum/restful/devices it published information about all devices it manages. Please note the variable $specserver. CA also offers a good API Reference Guide where you can read about all the details.

Note

The output is written in XML, so you need a proper library to parse it.

Since Spectrum knows a lot about the devices, you have to filter the requested information to get only that data that you really need. In my use case I just need the name (attribute 0x1006e) and the IP address (attribute 0x12d7f) from all models.

Neighbourhood Discovery

How do you find out about the devices that are there, but your Spectrum doesn't know?

Very easy: You ask the known devices, what devices else they know. Most network equipment knows about its neighbourhood because the devices talk to each other. The most common protocols are CDP (a proprietary protocol from Cisco) and LLDP, the standardised counterpart. So if you ask a Cisco router what other equipment it discovered using CDP, it will list many other devices on your network. Of course you also can use LLDP, or other techniques like the routing table or the ARP table to find out about other devices.

Now you compare that new list with the devices that Spectrum knows. If it is listed in the table you got from the first step, everything is ok. If your seed device discovered a device with CDP (LLDP, ...) that Spectrum doesn't know the admin gets a new ticket assigned: "Please find out what this is."

SNMP

The most simple protocol to request the neighbourhood from devices is SNMP. The CDP or LLDP information is organized according to their MIBs and tables. On the command line the following, simple command shows you all CDP information your router knows. Amongst this information is the system name and the IP address of all neighbours. In my script I will use exactly this information to check if Spectrum already knows the devices that my router discovered.

$ snmpwalk <router> 1.3.6.1.4.1.9.9.23

Putting it Together

The script below puts all three steps together:

  • Requesting and parsing the output from Spectrum.
  • Walking the devices and asking for the neighbours.
  • Checking if the neighbours are known to the Spectrum system.

Please note that the script only checks for known neighbours that are recognised via CDP. I did not implement LLDP or the other methods yet. If you need a complete system that does exactly do this task, see: NeDI. Install it and you get all these information presented in your web browser.

#!/usr/bin/perl

# use XML::Simple qw(:strict);
use Getopt::Std;
use XML::Simple;

my %options=();
getopts("hu:p:s:", \%options);

if ($options{h}) { usage(); exit; }

# Configurables
$specserver = $options{s} || "127.0.0.1:8080";
$user = $options{u} || "username";
$pass = $options{p} || "password";

# NON - configurables
$CDPOID = "1.3.6.1.4.1.9.9.23.1.2.1.1.6";

# get all devices and their IP addresses
@args = ("wget", "--http-user=$user", "--http-password=$pass", "-Odevices.xml", "http://$specserver/spectrum/restful/devices?attr=0x1006e&attr=0x12d7f");
system(@args) == 0 or die "system @args failed: $?";

# now parse the XML oupout of the
my $xml = new XML::Simple;
my $device = $xml->XMLin("devices.xml");

my %devhash = ();

foreach ( @{$device->{'model-responses'}->{'model'} } ) {
  $devhash { $_->{'attribute'}->{'0x1006e'}->{'content'} } = $_->{'attribute'}->{'0x12d7f'}->{'content'};
}

# Now look on all devices if it knows neighbours
# In my example I do this with CDP, but you could modify if for LLDP
# or all known MAC addresses on routers ...
while ( my ($key, $value) = each (%devhash) ) {

  # I know, I should use Net::SNMP.
  # But htis is not available on my RHEL 5.8
  my @result = `snmpwalk -r 2 -Oqve $value $CDPOID 2>/dev/null`;

  foreach $neighbour ( @result ) {

    # parse the result to get rid of the delimiters
    # some devices (i.e. nexus) report also their serial number in CDP
    # so the parsing should be improved to remove everything in (...)
    $neighbour =~ s/["\x0D\x0A]//g;
    print "$key: $neighbour\n" if !exists $devhash {$neighbour};
  }
}

# Finally finish the script
exit 0;

sub usage ()
{
  print STDERR << "EOF";

    This program looks for devices a Spectrum server doesn't know about
    by scanning the neighbours of all known hosts.

    usage: $0 [-h] [-u user] [-p password] [-s server]

     -h        : this message
     -u user   : user to use for the connection to the Spectroserver
     -p pass   : password to use for the connection to the Spectroserver
     -s server : Spectroserver. Default 127.0.0.1

    example: $0 -u user -p password -s spectrum.example.com

EOF

  exit;
}

Some devices do not report their neighbours properly. Sometimes the serial number is included. The script also lists a lot of access points and other stuff that speaks CDP but no SNMP. But you will know how to grep the output of my script.

Michael Schwartzkopff, 05. November 2013