At the enterprise that I work as a consultant at, we have a need for keeping track of where hosts are connected in the data centers.
We’ve used some manual tools that queried switches via SNMP in the past to accomplish this. But its always been a pain to run it against all of the switches, and then have to combine all of the output into a useful format. The application doesn’t support any kind of automation, so it’s pretty time consuming to capture this information. We don’t do it very often.
We looked at a few open source scripts that are out there that do something similar. Some of them weren’t really designed to be used in data centers. We have lots of VLAN trunk ports going out to virtualization hosts that we care about and want to keep track of. One of the tools looked decent, but didn’t support VLAN trunks (it made the assumption that they were uplinks). Some other ones were overkill for what we need and would have been more difficult to get deployed. NetDisco falls in to this category…however the SNMP::Info Perl module that NetDisco uses was a good fit for our purposes.
I had thought about doing this for a while, but only recently got around to it. I put together some scripts to query the switches via SNMP and output a combined list of all the port / MAC / IP / DNS information we need. It was fun project to get this working.
I’ve tested this against Catalyst 6500’s, 3550’s, 2960’s, and Nexus 7k’s. I tried it against a Catalyst 2950 as well, but I think it ran into some kind of issue there. The MAC addresses weren’t returned if I remember correctly. I didn’t look too deeply in to that, because we don’t really use 2950’s for the most part. After some initial tuning, I’ve been fairly impressed performance wise compared to the commercial tool we used previously. That took about 15 minutes to run for each 6500 access switch. This script seems to take about a minute.
A couple limitations in it right now - it will only query the ARP table on one router, and when doing ARP lookups it only searches by MAC address. It ignores what L3 interface / SVI the MAC address is associated with on the router. So, if a single MAC address happens to be associated to different IP addresses on different VLAN’s, all of those IP addresses will be linked to each instance of that MAC address. I was a little worried about both of those limitations, but they don’t appear to be significant issues in our environment based on my testing.
switchmap.pl assumes all of the necessary MIBs are in the “mibs” directory. I downloaded the MIB’s from NetDisco, and moved all of the files from the sub-directories into the mibs directory itself.
It requires a few Perl modules - notably SNMP::Info and DBI. If you’re using a Red Hat system, SNMP::Info is in EPEL.
Modify the file in the input directory to match your environment (with the switches, router, SNMP strings, etc).
Run switchmap.pl. It needs two arguments. The first is the file name of the SQLite database that it will create to store the results from this run in. The second argument is the input file that should be used. A new SQLite file should be used each time the script is ran.
If you want the results in a CSV format, run show-map.pl, specifying the SQLite file to read from as an argument.
The CSV file outputted from show-map will be in this format:
Switch name, port name, trunk port (trunk or access), port description, port status (up or down), VLAN number, MAC address, IP address, and reverse DNS.
A separate line will be created for each IP address. So, if multiple IP’s and or multiple MAC’s are connected through a single port there will be multiple lines in the CSV file for that port.
Ports that are down, ports that have no MAC addresses, and ports that have MAC addresses that can’t be associated to any IP will still be displayed. If you want to pull information out differently, it should be fairly easy to do so since its stored in the SQLite database file. Data wise, I used this model / set of assumptions for the script / database:
- Each switch has multiple ports
- Each port can have multiple VLAN’s on it
- Each VLAN on each port can have multiple MAC addresses associated with it
- Each MAC address can have multiple IP addresses associated with it
- Each IP has one reverse DNS entry
I think that should cover most scenarios.
Hopefully this will be useful to other folks. If you have any questions, drop me a line.
No guarantees that this will work for your environment. Test it in your environment before you run it against anything in production. :)