Friday, December 17, 2010

Generate DNS Import from Solarwinds Orion NCM

It's nice to have entries in your internal DNS for router interface names; it makes stuff like traceroute a whole lot easier to read. Many small-to-mid-size companies use Solarwinds products for network management.

This perl script takes the output that you get from using Solarwinds Network Configuration Manager to run the "show ip interface brief | exclude unassigned" command on a group of Cisco IOS devices and massages it into a format that looks like this:

hostname-interfaceName-interfaceNumber a.b.c.d

where a.b.c.d is the IP address assigned to the interface. This format is suitable for import into many DNS servers.

This code doesn't attempt to abbreviate interface names at all, but it could easily be modified to do so.

I run this on Windows using Cygwin and it works fine. The only caveat is that you need to have the dig command installed.

#!/usr/bin/perl
#
# takes output from a Solarwinds Orion NCM command script
# that runs "show ip interface brief | exclude unassigned"
# and produces a "hostname IP" output for import into DNS
# this makes traceroutes more readable
#
# usage: ./interface2dns.pl < inputfile.txt
# inputfile.txt will look like this
# when produced by Orion NCM 6.x:
#
# routerA.test.com  (10.38.16.126)
# Interface   IP-Address      OK? Method Status Protocol   
# Loopback0   172.29.255.1    YES NVRAM  up     up     
# Vlan163     10.38.16.126    YES NVRAM  up     up     
# Vlan165     10.38.16.117    YES NVRAM  up     up  
#
#
while (<>){
   
    chomp; # remove newline characters

# find the line with the hostname in it by searching

# for the "(" character
if ($_=~/\(/) {

    # split that line on the . character
    @hostnameFields = split /\./,$_;
    # hostname is the first element before the first .
    $hostname=$hostnameFields[0];

}

# identify lines with "up" in them to remove garbage
if ($_=~/\s+up\s+/) {

    #split the good lines into space-separated fields
    @fields=split  /\s+/,$_;
   
    #find RFC1918-like addresses only
    if ($fields[1]=~/^10\.|172\.|192\./){
     
        # skip IP addresses that are already in DNS
          unless (`dig -x $fields[1] +short`) {
     
          #substitute - for / and : in dns names
          $fields[0]=~s/\/|:/-/g;
 
          #print in "hostname-interface ipaddr" format
          print "$hostname-$fields[0] $fields[1]\n";    
         }
     }
}
}

2 comments:

Anonymous said...

you network guys make everything so hard. ask a DBA to run a select query from the config table next time.

jswan said...

If you could comment with a query that does everything the script does (such as filter for interface state, private addresses, and eliminate illegal characters), that would be quite helpful.