#!/usr/bin/perl -w use strict; my($current_net, $q, $start_net); my $last_net=""; my $w=0; $|=1; if(0) { _fiddle(0x1c, 0x7b, 0, 8); #_fiddle(2, 7, 0, 4); #_fiddle(0, 7, 0, 4); #_fiddle(0, 15, 0, 4); die; } while(<>) { s/:/ /; $current_net=(split " ", $_)[1]; # print $current_net; $current_net=~s/\.1$/.0/g; $q=(split "\\.", $current_net)[2]; if($q != $w+1) { fiddle($start_net, $last_net) if $start_net; $start_net=$current_net; } $w=$q; $last_net=$current_net; } fiddle($start_net, $last_net) if $start_net; sub fiddle { my($start, $end)=@_; warn "$start -> $end\n"; my @q=split /\./, $start; $start=($q[0]<<24) + ($q[1]<<16) + ($q[2]<<8) + $q[3]; @q=split /\./, $end; $end=($q[0]<<24) + ($q[1]<<16) + ($q[2]<<8) + $q[3]; _fiddle($start, $end, 0, 32); # die; } sub _fiddle { my($start, $end, $q, $size)=@_; # warn sprintf "_fiddle(start=%08x end=%08x q=%i size=$size)\n", $start, $end, $q if $q==0; if($start==$end) { $size=8 if $size==32 and 0==($end & 0xffffff); $size=16 if $size==32 and 0==($end & 0xffff); $size=24 if $size==32 and 0==($end & 0xff); print_cidr($start, $size); return; } my $span=$end-$start+1; my $p2=log($span)/log(2); if($p2==int $p2) { # warn sprintf "class start=%08x end=%08x q=$q p2=$p2\n", $start, $end; print_cidr($start, $size-$p2); return; } my($mask, $c, $n); $c=0; my $max=$size-$q; foreach $n ($q..($size-1)) { $mask=(1<<(($size-1)-$n)); if(($start&$mask) == ($end&$mask)) { # warn sprintf "same start=%08x end=%08x mask=%08x n=$n q=$q c=$c common=%i\n", $start, $end, $mask, $c+$q; $c++; } else { # warn sprintf "recur start=%08x end=%08x mask=%08x n=$n q=$q c=$c common=%i\n", $start, $end, $mask, $c+$q; $mask--; my $e=($start|$mask); # warn sprintf ">_fiddle(start=%08x end=%08x q=%i)\n", $start, $e, $n; # warn sprintf ">_fiddle(start=%08x end=%08x q=%i)\n", $e+1, $end, $n; _fiddle($start, $e, $n, $size) unless $e < $start; $e++; _fiddle($e, $end, $n, $size) unless $e > $end; last; } } } sub print_cidr { my($ip, $size)=@_; # printf "%08x/$size\n", $ip, $size; printf "%i.%i.%i.%i/$size\n", ($ip>>24)&0xff, ($ip>>16)&0xff, ($ip>>8)&0xff, $ip&0xff; }