3 # Looks for free IP numbers
4 # by Ivan Andrian, <ivan.andrian@elettra.trieste.it>, 11/07/2000
6 require './bind8-lib.pl';
8 $zone = &get_zone_name($in{'index'}, $in{'view'});
10 if ($in{'view'} ne '') {
11 $conf = $conf->[$in{'view'}]->{'members'};
13 $zconf = $conf->[$in{'index'}]->{'members'};
14 $type = &find("type", $zconf)->{'value'};
15 $file = &find("file", $zconf)->{'value'};
16 $dom = $conf->[$in{'index'}]->{'value'};
17 if (!$access{'findfree'}) {&error($text{'findfree_nofind'})};
18 $desc = &text('findfree_header', &arpa_to_ip($dom));
19 &ui_print_header($desc, &text('findfree_title'), "",
20 undef, undef, undef, undef, &restart_links($zone));
22 &find_ips($in{'index'}, $in{'from'}, $in{'to'}, $in{'cf'});
24 if ($in{'from'} && $in{'to'}) {
26 @recs = &read_zone_file($file, $dom);
27 @recs = grep { ($_->{'type'} eq 'A') || ($_->{'type'} eq 'PTR')} @recs;
31 @recs = &sort_records(@recs);
32 my %frecs = &build_iprange($in{'from'}, $in{'to'});
34 for($i=0; $i<@recs; $i++) {
38 if ($recs[$i]->{'type'} eq 'A') {
39 $hip=$recs[$i]->{'values'}->[0]; # IP no. in 'values' field
40 $hname=$recs[$i]->{'name'}; # name in 'name' field
43 $hip=&arpa_to_ip($recs[$i]->{'name'}); # IP no. in 'name' field
44 $hname=$recs[$i]->{'values'}->[0]; # name in 'values' field
47 # print "evaluating ", $hip, " ", $hname, "...<BR>"; #debug
49 if($in{'cf'} & ($hname=~ /^free.*/) & exists $frecs{$hip}) { # 'freeXXX' hostnames are free IP's!
51 # print " updating: ",$hip, "... <BR>"; #debug
52 $frecs{$hip}->{'ttl'}=$recs[$i]->{'ttl'};
53 $frecs{$hip}->{'name'}=$hname;
55 if($hname=~ /^freemac.*/) {$freemaccount++;}
58 # print " deleting: ",$hip, "... <BR>"; #debug
65 my @frecs=sort ffree_ip_sort_func values %frecs;
66 print "<b>",&text('findfree_msg', scalar(@frecs)),"\n";
68 print &text('findfree_msg2', $freeXXXcount, $freemaccount),"\n";
78 &ui_print_footer("edit_$type.cgi?index=$in{'index'}&view=$in{'view'}",
79 $text{'recs_return'});
81 # build_iprange(fromIP, toIP)
82 # Returns a list of IP numbers from fromIP to toIP
85 $_[0] =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)/;
86 my @from = ($1, $2, $3, $4);
87 return @from if (@from != 4); #I want a correct IPv4 #
88 $_[1] =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)/;
89 my @to = ($1, $2, $3, $4);
90 return @to if (@to != 4);
92 for ($i=0;$i<4;$i++) {
93 $from[$i]=$from[$i]==0?1:$from[$i];
94 $to[$i]=$to[$i]==255?254:$to[$i];
99 for ($byte0=$from[0]; $byte0<=$to[0]; $byte0++) {
100 for ($byte1=$byte0==$from[0]?$from[1]:1;
101 $byte1<=(($byte0==$to[0]?$to[1]:254));
103 ##print "================<BR>";
104 for ($byte2=($byte0==$from[0])&&($byte1==$from[1])?$from[2]:1;
105 $byte2<=(($byte0==$to[0])&&($byte1==$to[1])?$to[2]:254);
107 ##print "----------------<BR>";
108 for ($byte3=($byte0==$from[0])&&($byte1==$from[1])&&($byte2==$from[2])?$from[3]:1;
109 $byte3<=(($byte0==$to[0])&&($byte1==$to[1])&&($byte2==$to[2])?$to[3]:254);
111 $frecs{"$byte0.$byte1.$byte2.$byte3"}->{'ip'}="$byte0.$byte1.$byte2.$byte3";
112 $frecs{"$byte0.$byte1.$byte2.$byte3"}->{'ttl'}=$text{'default'};
113 $frecs{"$byte0.$byte1.$byte2.$byte3"}->{'name'}='';
114 ##push(@frecs, "$byte0.$byte1.$byte2.$byte3");
115 ##print "$byte0.$byte1.$byte2.$byte3<BR>";
122 } # sub build_iprange
124 # find_ips (zoneindex, from_ip, to_ip, consider_freeXX_names)
125 # Display a form for searching for free IP nos
128 print &ui_form_start("find_free.cgi");
129 print &ui_hidden("index", $_[0]);
130 print &ui_hidden("view", $in{'view'});
131 print &ui_table_start($text{'findfree_sopt'}, undef, 2);
134 print &ui_table_row($text{'findfree_fromip'},
135 &ui_textbox("from", $_[1], 20));
138 print &ui_table_row($text{'findfree_toip'},
139 &ui_textbox("to", $_[2], 20));
141 # Handle freeXXX hostnames?
142 print &ui_table_row($text{'findfree_cf'},
143 &ui_yesno_radio("cf", $_[3]));
145 print &ui_table_end();
146 print &ui_form_end([ [ undef, $text{'findfree_search'} ] ]);
149 # frecs_table(array_of_freerecords)
152 print &ui_grid_table(
153 [ map { "<a href='edit_recs.cgi?index=$in{'index'}&view=$in{'view'}".
154 "&type=A&newvalue=$_->{'ip'}'>$_->{'ip'}</a>" } @_ ],
155 4, 100, [ "width=25%", "width=25%", "width=25%", "width=25%" ]);
158 sub ffree_ip_sort_func
160 $a->{'ip'} =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)/;
161 local ($a1, $a2, $a3, $a4) = ($1, $2, $3, $4);
162 $b->{'ip'} =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)/;
163 return $a1 < $1 ? -1 :