Handle hostnames with upper-case letters
[webmin.git] / bind8 / find_free.cgi
1 #!/usr/local/bin/perl
2 # find_free.cgi
3 # Looks for free IP numbers
4 # by Ivan Andrian, <ivan.andrian@elettra.trieste.it>, 11/07/2000
5
6 require './bind8-lib.pl';
7 &ReadParse();
8 $zone = &get_zone_name($in{'index'}, $in{'view'});
9 $conf = &get_config();
10 if ($in{'view'} ne '') {
11         $conf = $conf->[$in{'view'}]->{'members'};
12         }
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));
21
22 &find_ips($in{'index'}, $in{'from'}, $in{'to'}, $in{'cf'});
23
24 if ($in{'from'} && $in{'to'}) {
25    # Do the search
26    @recs = &read_zone_file($file, $dom);
27    @recs = grep { ($_->{'type'} eq 'A') || ($_->{'type'} eq 'PTR')} @recs;
28    my $freeXXXcount=0;
29    my $freemaccount=0;
30    if (@recs) {
31         @recs = &sort_records(@recs);
32         my %frecs = &build_iprange($in{'from'}, $in{'to'});
33
34         for($i=0; $i<@recs; $i++) {
35                 my $hip;        # host IP
36                 my $hname;      # hostname
37                 
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
41                 }
42                 else {
43                         $hip=&arpa_to_ip($recs[$i]->{'name'});  # IP no. in 'name' field
44                         $hname=$recs[$i]->{'values'}->[0];              # name   in 'values' field
45                 }
46                 
47 #       print "evaluating ", $hip, " ", $hname, "...<BR>"; #debug
48                 
49                 if($in{'cf'} & ($hname=~ /^free.*/) & exists $frecs{$hip}) {    # 'freeXXX' hostnames are free IP's!
50                         # update
51 #       print "&nbsp;&nbsp;updating: ",$hip, "... <BR>"; #debug
52                         $frecs{$hip}->{'ttl'}=$recs[$i]->{'ttl'};
53                         $frecs{$hip}->{'name'}=$hname;
54                         $freeXXXcount++;
55                         if($hname=~ /^freemac.*/) {$freemaccount++;}
56                 }
57                 else {
58 #       print "&nbsp;&nbsp;deleting: ",$hip, "... <BR>"; #debug
59                         delete $frecs{$hip};
60                 }
61         }
62         
63         
64         # Show a message
65         my @frecs=sort ffree_ip_sort_func values %frecs; 
66         print "<b>",&text('findfree_msg', scalar(@frecs)),"\n";
67         if ($in{'cf'}) {
68                 print &text('findfree_msg2', $freeXXXcount, $freemaccount),"\n";
69                 }
70         print "...</b><p>\n";
71
72         # Show all the IPs
73         &frecs_table(@frecs);
74
75     } # if(@recs)
76 } # if(@in >= 3)
77
78 &ui_print_footer("edit_$type.cgi?index=$in{'index'}&view=$in{'view'}",
79         $text{'recs_return'});
80
81 # build_iprange(fromIP, toIP)
82 # Returns a list of IP numbers from fromIP to toIP
83 sub build_iprange
84 {
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);
91
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];
95 }
96
97 my %frecs;
98
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));
102                         $byte1++) {
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);
106                                 $byte2++) {
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);
110                                         $byte3++) {
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>";
116                         } #for $byte3
117                 } #for $byte2
118         } #for $byte1
119 } #for $byte0
120
121 return %frecs;
122 } # sub build_iprange
123
124 # find_ips (zoneindex, from_ip, to_ip, consider_freeXX_names)
125 # Display a form for searching for free IP nos
126 sub find_ips
127 {
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);
132
133 # Range start
134 print &ui_table_row($text{'findfree_fromip'},
135         &ui_textbox("from", $_[1], 20));
136
137 # Range end
138 print &ui_table_row($text{'findfree_toip'},
139         &ui_textbox("to", $_[2], 20));
140
141 # Handle freeXXX hostnames?
142 print &ui_table_row($text{'findfree_cf'},
143         &ui_yesno_radio("cf", $_[3]));
144
145 print &ui_table_end();
146 print &ui_form_end([ [ undef, $text{'findfree_search'} ] ]);
147 }
148
149 # frecs_table(array_of_freerecords)
150 sub frecs_table
151 {
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%" ]);
156 }
157
158 sub ffree_ip_sort_func
159 {
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 :
164         $a1 > $1 ? 1 :
165         $a2 < $2 ? -1 :
166         $a2 > $2 ? 1 :
167         $a3 < $3 ? -1 :
168         $a3 > $3 ? 1 :
169         $a4 < $4 ? -1 :
170         $a4 > $4 ? 1 : 0;
171 }
172
173
174 #EOF