Config parsing

A quick post so I can reference later. I’m starting to play with RANCID after a suggestion from a coworker. While I’m not necessarily doing config diffs it does provide a platform to quickly connect to a variety of Cisco devices and spit out desired output. In the last week I’ve used this to enumerate some devices and find autonomous access points. I’ll write up a proper post on how I did that sometime in the future (hopefully) but for now let’s just look at what I did tonight to get an IP listing for RANCID.

Starting from about 10-15 backed up switch config files, I wanted to get a quick management IP address listing to use with my RANCID stuff. I did not configure these switches myself and the network is not well known to me at all so this was a gem lurking in my configs that I couldn’t just pluck from my brain. Knowing that my management vlan is 150 I figured I could just grep out the IP set on that SVI from each file. From the directory with all my switch configs (in a Linux VM) I ran the following to parse out my VLAN 150 line and the line after that containing the IP address. (In retrospect I should make this first command a bit more intelligent. I got lucky in the fact that there weren’t switches with description or some other command right after the interface.)

ubuntu-vm:~$ grep -A1 Vlan150 * > step1

Output looks like this:

--
switch-poe2960-confg:interface Vlan150
switch-poe2960-confg- ip address 192.168.150.53 255.255.255.0
--

Then I use grep again with some regex to strip out stuff that looks like IP addresses and place it on it’s own line.

ubuntu-vm:~$ grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' step1 > step2

Output looks like this:

192.168.150.53
255.255.255.0
192.168.150.54
255.255.255.0
192.168.150.51
255.255.255.0

One more grep to get rid of the subnet masks that I don’t care about. Initially I matched on a specific /24 but I realized maybe someone could fat finger or there could be other masks. I settled on this command which was quick enough to do the job.

ubuntu-vm:~$ grep -v 255.* step2 > step3

Output looks like this:

192.168.150.53
192.168.150.54
192.168.150.51

Finally for good measure sort and remove any dupes

ubuntu-vm:~$ sort step3 | uniq > final

Output looks like this:

192.168.150.51
192.168.150.53
192.168.150.54

What I have in the end is a listing of the IP addresses of the SVIs for vlan 150. This is then used as input for a script that does a few for loops with rancid. One file for IPs and one for commands letting RANCID do the harder login work and providing me with a single file as an output. In this case I was doing a show cdp neighbor to look for my APs.

This was a pretty quick operation while watching a movie so I know it’s not as tight as it could be. It relies on regex pretty heavily so if you aren’t familiar it could be confusing. Google it and take some time to learn, it’s a very useful method of parsing data. I could probably string it all together in one massively long piped command but it’s not something I’ll hopefully be repeating often so it’s not needed. I also like to do things in steps like this so I can verify my output along the way. Typically I’ll run the command and watch what it spits out and if it looks good I’ll run again using the output modifier to write to a file. If I pushed it all together in one string from the get go, It’d be quite difficult to figure out what the heck went wrong when something unexpected shows up. This also gives me some checks and balances along the way if steps 1 to X look good but X+1 is funky. I don’t have to throw away everything I did previously, just look at what happened at X+1.

This is pretty basic stuff but hopefully someone else finds this useful. If not at least I can come back to grab and reuse the regex and grep flags :)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>