Thanks for your informative reply.
If I had know that mod::Net::IPTrie or mod::Tree::Trie existed I would have use them, unfortunately I did not know they existed and did not know the terminology to search for them on CPAN, and I thought it would take to long to implement something myself.
Instead I wrote some code using string representations of the binary bits in a database using DBIx::Class.
My DBIC table defintion looks like this:
__PACKAGE__->table('tblSubNet');
__PACKAGE__->add_columns(
'id' => { data_type=>'int', is_auto_increment=>1
+ },
'ip' => { data_type=>'varchar', size=>15
+ },
'mask' => { data_type=>'int'
+ },
'name' => { data_type=>'varchar', size=>255, is_nullable=>1
+ },
'start' => { data_type=>'int'
+ }, # the IP address as A 32 bit number
'bitpattern' => { data_type=>'varchar', size=>32
+ },
);
__PACKAGE__->set_primary_key('id');
__PACKAGE__->add_unique_constraint(['bitpattern']);
Once I have populated the table of subnets, I then search it like this:
my $order_by_size_rs = $all_subnets_rs->search({'source'=>$source},{'o
+rder_by'=>{'-asc','mask'}});
while( my $network = $order_by_size_rs->next )
{
my $overlaping_nets_rs = $net_rs->search({
'mask' => { '>', $network->mask() },
'bitpattern' => { 'like', $network->bitpattern().'%' },
},
{
'order_by'=>{'-asc',['mask','start']}
});
if( $overlaping_nets_rs->count )
{
printf "Subnet %s/%d (%s) has %d overlaps:\n",
$network->ip, $network->mask,
$network->name,
$overlaping_nets_rs->count;
... # Code to add the overlaps to the report.
}
}
Using this algorithm I was able to search through the 50_000 subnets searching for overlaps in about 10 minutes. (On a 3GHz Linux box).
|