#!/usr/local/bin/perl # find_free.cgi # Looks for free IP numbers # by Ivan Andrian, , 11/07/2000 require './bind8-lib.pl'; &ReadParse(); $conf = &get_config(); if ($in{'view'} ne '') { $conf = $conf->[$in{'view'}]->{'members'}; } $zconf = $conf->[$in{'index'}]->{'members'}; $type = &find("type", $zconf)->{'value'}; $file = &find("file", $zconf)->{'value'}; $dom = $conf->[$in{'index'}]->{'value'}; if (!$access{'findfree'}) {&error($text{'findfree_nofind'})}; $desc = &text('findfree_header', &arpa_to_ip($dom)); &ui_print_header($desc, &text('findfree_title'), ""); my $cf=1; if (@in == 2) { &find_ips ($in{'index'}, $in{'from'}); } elsif (@in == 3) { &find_ips ($in{'index'}, $in{'from'}, $in{'to'}); } elsif (@in == 4) { $cf=$in{'cf'}; &find_ips ($in{'index'}, $in{'from'}, $in{'to'}, $in{'cf'}); } else { &find_ips ($in{'index'}); } if (@in >= 3) { #we need to do the search! @recs = &read_zone_file($file, $dom); @recs = grep { ($_->{'type'} eq 'A') || ($_->{'type'} eq 'PTR')} @recs; my $freeXXXcount=0; my $freemaccount=0; if (@recs) { @recs = &sort_records(@recs); my %frecs = &build_iprange($in{'from'}, $in{'to'}); for($i=0; $i<@recs; $i++) { my $hip; # host IP my $hname; # hostname if ($recs[$i]->{'type'} eq 'A') { $hip=$recs[$i]->{'values'}->[0]; # IP no. in 'values' field $hname=$recs[$i]->{'name'}; # name in 'name' field } else { $hip=&arpa_to_ip($recs[$i]->{'name'}); # IP no. in 'name' field $hname=$recs[$i]->{'values'}->[0]; # name in 'values' field } # print "evaluating ", $hip, " ", $hname, "...
"; #debug if($cf & ($hname=~ /^free.*/) & exists $frecs{$hip}) { # 'freeXXX' hostnames are free IP's! # update # print "  updating: ",$hip, "...
"; #debug $frecs{$hip}->{'ttl'}=$recs[$i]->{'ttl'}; $frecs{$hip}->{'name'}=$hname; $freeXXXcount++; if($hname=~ /^freemac.*/) {$freemaccount++;} } else { # print "  deleting: ",$hip, "...
"; #debug delete $frecs{$hip}; } } my @frecs=sort ffree_ip_sort_func values %frecs; my $mid = int((@frecs+1)/2); print "

Found " . @frecs . " free IP number" . (@frecs==1?"\n":"s\n"); if ($cf) { print " ($freeXXXcount ". ($freeXXXcount==1?" is":"are") . " `freeXXX'" . " of which $freemaccount ". ($freemaccount==1?" is":"are") . " `freemac')" ; print "

\n"; } print "
\n"; &frecs_table(@frecs[0 .. $mid-1]); print "\n"; if ($mid < @frecs) { &frecs_table(@frecs[$mid .. $#frecs]); } print "

\n"; print "

\n"; } # if(@recs) } # if(@in >= 3) &ui_print_footer("edit_$type.cgi?index=$in{'index'}&view=$in{'view'}", $text{'recs_return'}); # build_iprange(fromIP, toIP) # Returns a list of IP numbers from fromIP to toIP sub build_iprange { $_[0] =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)/; my @from = ($1, $2, $3, $4); return @from if (@from != 4); #I want a correct IPv4 # $_[1] =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)/; my @to = ($1, $2, $3, $4); return @to if (@to != 4); for ($i=0;$i<4;$i++) { $from[$i]=$from[$i]==0?1:$from[$i]; $to[$i]=$to[$i]==255?254:$to[$i]; } my %frecs; for ($byte0=$from[0]; $byte0<=$to[0]; $byte0++) { for ($byte1=$byte0==$from[0]?$from[1]:1; $byte1<=(($byte0==$to[0]?$to[1]:254)); $byte1++) { ##print "================
"; for ($byte2=($byte0==$from[0])&&($byte1==$from[1])?$from[2]:1; $byte2<=(($byte0==$to[0])&&($byte1==$to[1])?$to[2]:254); $byte2++) { ##print "----------------
"; for ($byte3=($byte0==$from[0])&&($byte1==$from[1])&&($byte2==$from[2])?$from[3]:1; $byte3<=(($byte0==$to[0])&&($byte1==$to[1])&&($byte2==$to[2])?$to[3]:254); $byte3++) { $frecs{"$byte0.$byte1.$byte2.$byte3"}->{'ip'}="$byte0.$byte1.$byte2.$byte3"; $frecs{"$byte0.$byte1.$byte2.$byte3"}->{'ttl'}=$text{'default'}; $frecs{"$byte0.$byte1.$byte2.$byte3"}->{'name'}=''; ##push(@frecs, "$byte0.$byte1.$byte2.$byte3"); ##print "$byte0.$byte1.$byte2.$byte3
"; } #for $byte3 } #for $byte2 } #for $byte1 } #for $byte0 return %frecs; } # sub build_iprange # find_ips (zoneindex, from_ip, to_ip, consider_freeXX_names) # Display a form for searching for free IP nos sub find_ips { print "

\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
$text{'findfree_sopt'}
\n"; print "\n"; print "\n"; if (@_ >= 2) { # there is a "from" field on the URL print "\n"; } else { print "\n"; } print "\n"; print "\n"; if (@_ >= 3) { # there is a "to" field on the URL print "\n"; } else { print "\n"; } print "\n"; print "\n"; print "
$text{'findfree_IPrange'}$text{'findfree_from'}
 $text{'findfree_to'}
$text{'findfree_cf'}\n"; $cfy=$cf?'checked':''; $cfn=(!$cf)?'checked':''; print "   $text{'yes'}\n"; print " $text{'no'}
\n"; } # end of find_ips # frecs_table(array_of_freerecords) sub frecs_table { print "\n"; print "", "\n", "\n", "\n"; for($i=0; $i<@_; $i++) { $r = $_[$i]; print "\n", "\n", "\n", "\n"; } print "
", $text{'recs_addr'},"$text{'recs_ttl'}$text{'recs_name'}
$r->{'ip'}",$r->{'ttl'} ? $r->{'ttl'} : $text{'default'},"",$r->{'name'}?$r->{'name'}:' ',"
\n"; } sub ffree_ip_sort_func { $a->{'ip'} =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)/; local ($a1, $a2, $a3, $a4) = ($1, $2, $3, $4); $b->{'ip'} =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)/; return $a1 < $1 ? -1 : $a1 > $1 ? 1 : $a2 < $2 ? -1 : $a2 > $2 ? 1 : $a3 < $3 ? -1 : $a3 > $3 ? 1 : $a4 < $4 ? -1 : $a4 > $4 ? 1 : 0; } #EOF