#!/usr/bin/perl -Twl use strict; use Net::IP (); use Net::Netmask (); use Data::Dumper; use constant DEBUG => 0; delete $ENV{$_} for qw(PATH CDPATH ENV); my $B = {}; *OVERLAP = sub { my ($b1, $b2) = @_; @ARGV ? _taz_overlap( $B->{$b1}{net}, $B->{$b1}{mask}, $B->{$b2}{net}, $B->{$b2}{mask} ) : _mituc_overlap( $B->{$b1}{inet}, $B->{$b1}{ibcast}, $B->{$b2}{inet}, $B->{$b2}{ibcast} ); }; sub _taz_overlap { qx{./taz-overlap @_} =~ /overlap/ } sub _mituc_overlap { my ($netaddr1, $broadcast1, $netaddr2, $broadcast2) = @_; ($netaddr1>$netaddr2 || $broadcast1>=$netaddr2) && ($netaddr2<=$broadcast1 || $broadcast1<=$broadcast2); }; # populate network blocks while () { chomp; if (exists $B->{$_}) { warn "Duplicate block '$_'\n"; next; } my $ip = Net::IP->new($_); unless ($ip) { warn "Invalid block '$_'\n"; next; } $B->{$_} = { len => $ip->prefixlen, net => $ip->ip, bcast => $ip->last_ip, mask => $ip->mask, inet => $ip->intip->bstr, ibcast => Net::IP->new($ip->last_ip)->intip->bstr, }; } print Dumper $B if DEBUG; # store a sorted blocks list my @blocks = sort { $B->{$a}{inet} <=> $B->{$b}{inet} or $B->{$a}{len} <=> $B->{$b}{len} } keys %$B; # overlapping check up foreach (0 .. $#blocks-1) { my $b1 = $blocks[$_]; foreach my $b2 ((@blocks)[$_+1 .. $#blocks]) { if (OVERLAP($b1, $b2)) { warn "OVERLAP: $b1 vs. $b2\n"; warn " $B->{$b1}{net}-$B->{$b1}{bcast} vs. $B->{$b2}{net}-$B->{$b2}{bcast})\n" if DEBUG; } elsif (OVERLAP($b2, $b1)) { warn "OOPS! $b2 vs. $b1 seems to OVERLAP but $b1 vs. $b2 does NOT!\n"; warn " $B->{$b1}{net}-$B->{$b1}{bcast} vs. $B->{$b2}{net}-$B->{$b2}{bcast})\n" if DEBUG; } } } __DATA__ 10.0.0.5/22 10.0.0.0/8 10.0.0.0/14 10.0.0.0/14 10.1.0.0/16 10.128.0.0/22 255.255.255.255 10.11.11.11 10.11.11.0/24