How many times have you tried to run a standard diff against two configuration files, only to be presented with a load of differences without any context at all? Configuration files tend to be hierarchical and usually use indentation to denote sections. To demonstrate what I mean, lets use a simple example where I have two interfaces on a Cisco router.
interface GigabitEthernet0/0/1/0 description >> Connection to R2 (Gi0/0/2/0) << ip address 192.0.2.1 255.255.255.252 ! interface GigabitEthernet0/0/1/1 description >> Connection to R3 (Gi0/0/2/0) << ip address 192.0.2.5 255.255.255.252 !
A user logs onto our router and performs a shutdown of one of the interfaces and updates a description. As part of a routine audit, I want to compare the differences between the router configuration pre and post change so I attempt to use the standard Unix diff command to compare them:
$ diff a.cfg b.cfg 3a4 > shutdown 7c8 < description >> Connection to R3 (Gi0/0/2/0) << --- > description >> Connection to R3 (Gi0/0/7/1) <<
In the context of our audit, this is pretty useless as it doesn't easily identify which interface was shutdown or had it's description updated. This is where a diff tool that maintains context comes into it's own - lets compare the same files with cdiff:
$ cdiff a.cfg b.cfg interface GigabitEthernet0/0/1/0 + shutdown interface GigabitEthernet0/0/1/1 - description >> Connection to R3 (Gi0/0/2/0) << + description >> Connection to R3 (Gi0/0/7/1) <<
The cdiff tool works by converting the configurations into a trie type structure and then compares the two structures together. When differences are found, it has the ability to output them within the context they are found, as it knows the parent branches up to the root of the trie. Although I have included the vendor "Cisco" specifically in the title, it should work on any configuration file that uses consistent indentation - the reason it specifically mentions "Cisco", is because I have added support for processing "banners" which are a special use case.
The cdiff tool is written in Perl and doesn't require any special libraries. You can download the latest version using the link below:General Cisco