Category: | Networking Code |
Author/Contact Info | Bill Farley/bill.farley@gmail.com |
Description: | Analyzes tab-delimited file with network blocks for duplicates and subnet overlaps. Created for use with CISCO SESM, but could be used with any application that uses stored network blocks. |
#!/usr/bin/perl #This program is free software: you can redistribute it and/or modify +it under the terms #of the GNU General Public License as published by the Free Software F +oundation, either #version 3 of the license, or any later version. #This program is distibuted in the hope that it will be useful, but WI +THOUT ANY WARRANTY; #without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + PARTICULAR PURPOSE. #See the GNU General Public License for more details. #You should have received a copy of the GNU General Public License alo +ng with this program. #If not, see <http://www.gnu.org/licenses/> #To contact the author of this software, send an e-mail to Bill Farley + (bill.farley@gmail.com). #This script is designed to recognize and identify duplicate network b +locks and/or overlapping #subnets from a tab delimited file. It requires that your tab delimit +ed file be in the following format: #example #1.1.1.1 255.255.0.0 #2.2.2.2 255.255.255.0 # #When finished, save your tab-delimited file to the same directory as +this script #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# system(clear); #clear user's terminal screen print "Starting Script........\n\n"; #notify user that script has s +tarted $start = localtime; #timestamp of when script started $found = 0; #counter to pass information back to the user after scr +ipt is complete. #open tab-delimited file and create an array for each line open(FILE, "<$filename") || die ("Error 103 - Could not open $filename +\n"); $line_counter = 0; #counts the number of lines in the file while (<FILE>) { chomp $_; #split the line into array variables for Network and Subnetmas +k ($network[$line_counter],$subnetmask[$line_counter]) = split(/ +\t/,$_); $line_counter++; } close(FILE); &duplicates; #check the network array for duplicate network blocks print "\n"; #prints a blank line between duplicates and overlaps wh +en displayed back to user #decriment subnetmask by one bit $snc = 0; foreach $network(@network) { $original_network = $network; #new variable will be used as a r +eference if any overlapping networks are found &slashnot; #calls subroutine to convert decimal notation for su +bnetmask to slash notation $snc++; } #provide user with status of script if($found gt 0) { print "\nScript Complete........ Please review the previous warni +ng(s) listed above.\n\n"; } else { print "\nScript Complete........ No duplicates or overlaps were f +ound.\n\n"; } $stop = localtime; #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# sub BEGIN { system(clear); #clears the user's terminal print "Subnetoverlap.pl Copyright (C) 2005, 2007 Bill Farley\n\n"; print "This program is free software: you can redistribute it and/or m +odify it under the terms\n"; print "of the GNU General Public License as published by the Free Soft +ware Foundation, either\n"; print "version 3 of the license, or any later version.\n"; print "This program comes with ABSOLUTELY NO WARRANTY.\n\n\n"; print "What is the filename of the tab-delimited file? (Example: file. +txt): "; $filename = <STDIN>; #open user provided file and remove all extra hidden characters then r +ewrite to a new file so script will execute properly $tempfilename = ("$filename" . "temp.txt"); open(TEXT,"<$filename") || die ("Error 101 - Can't open $filename"); + #user's file open(NEW, ">$tempfilename") || die ("Error 102 - Can't open $tempfilen +ame"); #new file that script will use $text_counter = 0; while (<TEXT>) { chomp $_; $_ =~ s/\r\n//g; #checking for extra hidden characters in u +ser's file and variables $_ =~s/\r//g; #checking for extra hidden characters in +user's file and variables $_ =~s/\n//g; #checking for extra hidden characters in +user's file and variables (($network[$text_counter], ($subnetmask[$text_counter])) = spl +it /\t/,$_); #separating line into two arrays chomp $network[$text_counter]; chomp $subnetmask[$text_counter +]; #removing any newline characters that may be in variables $text_counter++; } + + close(TEXT); #write array variables to new file $text_counter2 = 0; until ($text_counter2 eq $text_counter) { print NEW "$network[$text_counter2]\t$subnetmask[$text_counter +2]\n"; #writing variables into new file in tab-delimited format $text_counter2++; } + + close(NEW); #create a hash that corrolates decimal notation to slash notation %slash = ("128.0.0.0", 1,"192.0.0.0", 2,"224.0.0.0", 3,"240.0. +0.0", 4,"248.0.0.0", 5,"252.0.0.0", 6,"254.0.0.0", 7,"255.0.0.0", 8," +255.128.0.0", 9,"255.192.0.0", 10,"255.224.0.0", 11,"255.240.0.0", 12 +,"255.248.0.0", 13,"255.252.0.0", 14,"255.254.0.0", 15,"255.255.0.0", + 16,"255.255.128.0", 17,"255.255.192.0", 18,"255.255.224.0", 19,"255. +255.240.0", 20,"255.255.248.0", 21,"255.255.252.0", 22,"255.255.254.0 +", 23,"255.255.255.0", 24,"255.255.255.128", 25,"255.255.255.192", 26 +,"255.255.255.224", 27,"255.255.255.240", 28,"255.255.255.248", 29,"2 +55.255.255.252", 30,"255.255.255.254", 31,"255.255.255.255", 32,); #create a hash that corrolates slash notation to decimal notation %decimal = (1, "128.0.0.0",2, "192.0.0.0",3, "224.0.0.0",4, "240.0 +.0.0",5, "248.0.0.0",6, "252.0.0.0",7, "254.0.0.0",8, "255.0.0.0",9, +"255.128.0.0",10, "255.192.0.0",11, "255.224.0.0",12, "255.240.0.0",1 +3, "255.248.0.0",14, "255.252.0.0",15, "255.254.0.0",16, "255.255.0.0 +",17, "255.255.128.0",18, "255.255.192.0",19, "255.255.224.0",20, "25 +5.255.240.0",21, "255.255.248.0",22, "255.255.252.0",23, "255.255.254 +.0",24, "255.255.255.0",25, "255.255.255.128",26, "255.255.255.192",2 +7, "255.255.255.224",28, "255.255.255.240",29, "255.255.255.248",30, +"255.255.255.252",31, "255.255.255.254",32, "255.255.255.255",); } #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# sub duplicates { $avc = 0; #This is a counter for the array variables foreach $network(@network) { while ($avc < $line_counter) { if ($network eq $network[$avc]) { #matching +each array variable against all other variables in the array. $match++; #counter to keep track of +the variable matches since the matching variable is from #from the array, there will always + be at least one match against itself. #Looking for anything higher than +a single match to identify a true duplication if ($match gt 1) { print "WARNING!! There is a dupli +cate network match for $network.\n"; $found++; } } $avc++; } $avc = 0; $match = 0; } } #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# sub slashnot { foreach $key (keys(%slash)) { if ($key eq $subnetmask[$snc]) { $new_slash = ($slash{$subnetmask[$snc]} - 1); #decr +imenting subnetmask of original subnetmask by one bit &decimalnot; #calling subroutine to change new slash no +tation back to decimal notation } } } #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# sub decimalnot { foreach $key (keys(%decimal)) { if ($key eq $new_slash) { $new_subnetmask = $decimal{$key}; #converting slash not +ation to decimal notation &binaryand; #calling subroutine to identify new network + block address } } } #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# sub binaryand { ($ipoctet1,$ipoctet2,$ipoctet3,$ipoctet4) = split(/\./,$network +); #split up the network block and assign octet variables ($snmoctet1,$snmoctet2,$snmoctet3,$snmoctet4) = split(/\./,$new +_subnetmask); #split up the subnetmask and assign octet variables + + #Due to a bug in Perl, after the split, the new variables need + to have an mathmatical operation #performed in order to make them numeric variables rather than + string variables. $num_con1 = $snmoctet1 + $ipoctet1; $num_con2 = $snmoctet2 + $ipoctet2; $num_con3 = $snmoctet3 + $ipoctet3; $num_con4 = $snmoctet4 + $ipoctet4; + + #identify the network block address by "AND"ing the ip address + and the subnet mask. $nwoctet1 = $snmoctet1 & $ipoctet1; $nwoctet2 = $snmoctet2 & $ipoctet2; $nwoctet3 = $snmoctet3 & $ipoctet3; $nwoctet4 = $snmoctet4 & $ipoctet4; $new_network = ("$nwoctet1.$nwoctet2.$nwoctet3.$nwoctet4"); + #joining octets together into a single variable $new_subnetmask = ("$snmoctet1.$snmoctet2.$snmoctet3.$snmoctet +4"); #joining octets together into a single variable &overlap; #calling subroutine to identfy any overlappping netwo +rks } #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# sub overlap { $overlap_counter = 0; while($overlap_counter < $line_counter) { #match new subnet against all other variables in the array if (($new_network eq $network[$overlap_counter]) and ($new_sub +netmask eq $subnetmask[$overlap_counter])) { print "WARNING!! There is an overlap between $new_network + and $original_network\n"; $found++; } $overlap_counter++; } #continue to decriment subnetmask by one bit until subnetmask is a + /1 if ($new_slash ne 1) { $new_slash--; #decrimenting subnetmask slash notation by on +e bit &decimalnot; #looping to subroutine for conversion back to +decimal notation } } |
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Subnet Overlap (fixes)
by ikegami (Patriarch) on Aug 21, 2007 at 22:48 UTC | |
by bfarley (Initiate) on Aug 22, 2007 at 03:16 UTC | |
by ikegami (Patriarch) on Aug 22, 2007 at 03:23 UTC | |
Re: Subnet Overlap
by grinder (Bishop) on Aug 21, 2007 at 20:10 UTC | |
by ikegami (Patriarch) on Aug 21, 2007 at 20:22 UTC | |
by bfarley (Initiate) on Aug 22, 2007 at 03:07 UTC | |
by bfarley (Initiate) on Aug 22, 2007 at 03:01 UTC | |
Re: Subnet Overlap
by ikegami (Patriarch) on Aug 21, 2007 at 20:41 UTC |