Pakfire laedt die Listen jetzt besser und hat eine veraenderte Oberflaeche bekommen.
[people/pmueller/ipfire-2.x.git] / html / cgi-bin / wireless.cgi
CommitLineData
ac1cfefa
MT
1#!/usr/bin/perl
2#
78331e30 3# IPFire CGIs
ac1cfefa
MT
4#
5# This code is distributed under the terms of the GPL
6#
7# (c) 2003 Alan Hourihane <alanh@fairlite.demon.co.uk>
8# (c) 2005 Eric Oberlander, Robert Kerr - Inline editing & DHCP leases
9#
10# $Id: wireless.cgi,v 1.4.2.15 2005/06/11 12:14:49 eoberlander Exp $
11#
12
13use strict;
14use Time::Local;
15
16# enable only the following on debugging purpose
17#use warnings;
18#use CGI::Carp 'fatalsToBrowser';
19
986e08d9 20require '/var/ipfire/general-functions.pl';
ac1cfefa
MT
21require "${General::swroot}/lang.pl";
22require "${General::swroot}/header.pl";
23
24#workaround to suppress a warning when a variable is used only once
25my @dummy = ( ${Header::colouryellow} );
26undef (@dummy);
27
28my %cgiparams=();
29my %checked=();
30my $errormessage = '';
31my $filename = "${General::swroot}/wireless/config";
32my $hostsfile = "${General::swroot}/main/hosts";
33our %dhcpsettings=();
34our %netsettings=();
35
36$cgiparams{'ENABLED'} = 'off';
37$cgiparams{'ACTION'} = '';
38$cgiparams{'VALID'} = '';
39$cgiparams{'SOURCE_IP'} ='';
40$cgiparams{'SOURCE_MAC'} ='';
41$cgiparams{'REMARK'} ='';
42
43&Header::getcgihash(\%cgiparams);
44
45&General::readhash("${General::swroot}/dhcp/settings", \%dhcpsettings);
46&General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
47
48&Header::showhttpheaders();
49
50open(FILE, $filename) or die 'Unable to open config file.';
51my @current = <FILE>;
52close(FILE);
53
54if ($cgiparams{'ACTION'} eq 'add')
55{
56
57 if ($cgiparams{'SOURCE_IP'} eq '' && $cgiparams{'SOURCE_MAC'} eq '')
58 {
59 goto ADDEXIT;
60 }
61
62 $cgiparams{'SOURCE_MAC'} =~ tr/-/:/;
63
64 my $key = 0;
65 foreach my $line (@current)
66 {
67 $key++;
68 my @temp = split(/\,/,$line);
69
70 if ($temp[1] ne '' && $cgiparams{'SOURCE_IP'} eq $temp[1] && $cgiparams{'EDITING'} ne $key)
71 {
72 $errormessage = $Lang::tr{'duplicate ip'};
73 goto ADDERROR;
74 }
75 if ($temp[2] ne '' && lc($cgiparams{'SOURCE_MAC'}) eq lc($temp[2]) && $cgiparams{'EDITING'} ne $key)
76 {
77 $errormessage = $Lang::tr{'duplicate mac'};
78 goto ADDERROR;
79 }
80 }
81
82 if ($cgiparams{'SOURCE_IP'} eq '')
83 {
84 $cgiparams{'SOURCE_IP'} = 'NONE';
85 } else {
86 unless(&General::validip($cgiparams{'SOURCE_IP'}))
87 {
88 $errormessage = $Lang::tr{'invalid fixed ip address'};
89 goto ADDERROR;
90 }
91 }
92 if ($cgiparams{'SOURCE_MAC'} eq '')
93 {
94 $cgiparams{'SOURCE_MAC'} = 'NONE';
95 } else {
96 unless(&General::validmac($cgiparams{'SOURCE_MAC'}))
97 {
98 $errormessage = $Lang::tr{'invalid fixed mac address'};
99 }
100 }
101
102ADDERROR:
103 if ($errormessage)
104 {
105 $cgiparams{'SOURCE_MAC'} = '' if $cgiparams{'SOURCE_MAC'} eq 'NONE';
106 $cgiparams{'SOURCE_IP'} = '' if $cgiparams{'SOURCE_IP'} eq 'NONE';
107 } else {
108 if ($cgiparams{'EDITING'} eq 'no') {
109 open(FILE,">>$filename") or die 'Unable to open config file.';
110 flock FILE, 2;
111 print FILE "$key,$cgiparams{'SOURCE_IP'},$cgiparams{'SOURCE_MAC'},$cgiparams{'ENABLED'},$cgiparams{'REMARK'}\n";
112 } else {
113 open(FILE,">$filename") or die 'Unable to open config file.';
114 flock FILE, 2;
115 my $id = 0;
116 foreach my $line (@current)
117 {
118 $id++;
119 if ($cgiparams{'EDITING'} eq $id) {
120 print FILE "$id,$cgiparams{'SOURCE_IP'},$cgiparams{'SOURCE_MAC'},$cgiparams{'ENABLED'},$cgiparams{'REMARK'}\n";
121 } else { print FILE "$line"; }
122 }
123 }
124 close(FILE);
125 undef %cgiparams;
126 &General::log($Lang::tr{'wireless config added'});
900832fa 127 system('/usr/local/bin/wirelessctrl');
ac1cfefa
MT
128 }
129ADDEXIT:
130}
131
132if ($cgiparams{'ACTION'} eq 'edit')
133{
134 my $id = 0;
135 foreach my $line (@current)
136 {
137 $id++;
138 if ($cgiparams{'ID'} eq $id)
139 {
140 chomp($line);
141 my @temp = split(/\,/,$line);
142 $cgiparams{'SOURCE_IP'} = $temp[1];
143 $cgiparams{'SOURCE_MAC'} = $temp[2];
144 $cgiparams{'ENABLED'} = $temp[3];
145 $cgiparams{'REMARK'} = $temp[4];
146 $cgiparams{'SOURCE_IP'} = '' if $cgiparams{'SOURCE_IP'} eq 'NONE';
147 $cgiparams{'SOURCE_MAC'} = '' if $cgiparams{'SOURCE_MAC'} eq 'NONE';
148 }
149 }
150 &General::log($Lang::tr{'wireless config changed'});
900832fa 151 system('/usr/local/bin/wirelessctrl');
ac1cfefa
MT
152}
153
154if ($cgiparams{'ACTION'} eq 'remove' || $cgiparams{'ACTION'} eq 'toggle')
155{
156 my $id = 0;
157 open(FILE, ">$filename") or die 'Unable to open config file.';
158 flock FILE, 2;
159 foreach my $line (@current)
160 {
161 $id++;
162 unless ($cgiparams{'ID'} eq $id) { print FILE "$line"; }
163 elsif ($cgiparams{'ACTION'} eq 'toggle')
164 {
165 chomp($line);
166 my @temp = split(/\,/,$line);
167 print FILE "$temp[0],$temp[1],$temp[2],$cgiparams{'ENABLE'},$temp[4]\n";
168 }
169 }
170 close(FILE);
171 &General::log($Lang::tr{'wireless config changed'});
900832fa 172 system('/usr/local/bin/wirelessctrl');
ac1cfefa
MT
173}
174
175
176$checked{'ENABLED'}{'off'} = '';
177$checked{'ENABLED'}{'on'} = '';
178$checked{'ENABLED'}{$cgiparams{'ENABLED'}} = "checked='checked'";
179
180
181&Header::openpage($Lang::tr{'wireless configuration'}, 1, '');
182
183&Header::openbigbox('100%', 'left', '', $errormessage);
184
185if ($errormessage) {
186 &Header::openbox('100%', 'left', $Lang::tr{'error messages'});
187 print "<class name='base'>$errormessage\n";
188 print "&nbsp;</class>\n";
189 &Header::closebox();
190}
191
192print "<form method='post' action='$ENV{'SCRIPT_NAME'}'>\n";
193
194my $buttontext = $Lang::tr{'add'};
195if ($cgiparams{'ACTION'} eq 'edit') {
196 &Header::openbox('100%', 'left', "$Lang::tr{'edit device'}");
197 $buttontext = $Lang::tr{'update'};
198} else {
199 &Header::openbox('100%', 'left', "$Lang::tr{'add device'}");
200}
201
202print <<END
203<table width='100%'>
204<tr>
205<td width='25%' class='base'>$Lang::tr{'source ip'}:&nbsp;</td>
206<td width='25%' ><input type='text' name='SOURCE_IP' value='$cgiparams{'SOURCE_IP'}' size='25' /></td>
207<td width='25%' class='base' align='right'>$Lang::tr{'enabled'}&nbsp;</td>
208<td width='25%'><input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} /></td>
209</tr>
210<tr>
211<td width='25%' class='base'>$Lang::tr{'source'} $Lang::tr{'mac address'}:&nbsp;</td>
212<td colspan='3'><input type='text' name='SOURCE_MAC' value='$cgiparams{'SOURCE_MAC'}' size='25' /></td>
213</tr>
214<tr>
215<td width='25%' class='base'>$Lang::tr{'remark'}:&nbsp;<img src='/blob.gif' alt='*' /></td>
216<td colspan='3'><input type='text' name='REMARK' value='$cgiparams{'REMARK'}' size='40' /></td>
217</tr>
218</table>
219<hr />
220<table width='100%'>
221<tr>
222 <td class='base' valign='top'><img src='/blob.gif' alt='*' /></td>
223 <td width='55%' class='base'>$Lang::tr{'this field may be blank'}</td>
224 <td width='40%' align='center'>
225 <input type='hidden' name='ACTION' value='add' />
226 <input type='submit' name='SUBMIT' value='$buttontext' />
227 </td>
39a7cc11 228 <td width='5%' align='right'>&nbsp;</td>
ac1cfefa
MT
229</tr>
230</table>
231END
232;
233
234if ($cgiparams{'ACTION'} eq 'edit') {
235 print "<input type='hidden' name='EDITING' value='$cgiparams{'ID'}' />\n";
236} else {
237 print "<input type='hidden' name='EDITING' value='no' />\n";
238}
239
240&Header::closebox();
241
242print "</form>\n";
243
244&Header::openbox('100%', 'left', "$Lang::tr{'devices on blue'}");
245print <<END
246<div align='center'>
247END
248;
249open (FILE, "$filename");
250my @current = <FILE>;
251close (FILE);
252
253print <<END
254<table width='100%'>
255<tr>
256<td align='center' width='20%'><b>$Lang::tr{'hostname'}</b></td>
257<td align='center' width='20%'><b>$Lang::tr{'source ip'}</b></td>
258<td align='center' width='20%'><b>$Lang::tr{'mac address'}</b></td>
259<td align='center' width='35%'><b>$Lang::tr{'remark'}</b></td>
260<td align='center' colspan='3'><b>$Lang::tr{'action'}</b></td>
261</tr>
262END
263;
264
265my $id = 0;
266
267open (HOSTFILE, "$hostsfile");
268my @curhosts = <HOSTFILE>;
269close (HOSTFILE);
270
271my $connstate = &Header::connectionstatus();
272my @arp = `/sbin/arp -n`;
273shift @arp;
274
275foreach my $line (@current)
276{
277 $id++;
278 chomp($line);
279 my $gif = "";
280 my $gdesc = "";
281 my $hname = "";
282 my $toggle = "";
283 my @temp = split(/\,/,$line);
284 my $wirelessid = $temp[0];
285 my $sourceip = $temp[1];
286 my $sourcemac = $temp[2];
287 if ( $sourceip eq 'NONE' ) {
288 foreach my $aline ( @arp )
289 {
290 chomp($aline);
291 my @atemp = split( m{\s+}, $aline );
292 my $aipaddr = $atemp[0];
293 my $amacaddr = lc( $atemp[2] );
294 if ( $amacaddr eq $sourcemac ) {
295 $sourceip = $aipaddr;
296 last;
297 }
298 }
299 }
300
301 # SourceIP could now have been set by the ARP probe.
302 if ( $sourceip ne 'NONE' ) {
303 foreach my $hline (@curhosts)
304 {
305 chomp($hline);
306 my @htemp = split(/\,/,$hline);
307 my $hkey = $htemp[0];
308 my $hipaddr = $htemp[1];
309 my $hostname = $htemp[2];
310 my $domainname = $htemp[3];
311 if ($sourceip eq $hipaddr) {
312 $hname = "$hostname.$domainname";
313 last;
314 }
315 }
316 if ( $hname eq "" ) {
317 my ($aliases, $addrtype, $length, @addrs);
318 ($hname, $aliases, $addrtype, $length, @addrs) =
319 gethostbyaddr(pack("C4", split(/\./, $sourceip)), 2);
320 }
321 }
322
323 if ($temp[3] eq 'on') { $gif = 'on.gif'; $toggle='off'; $gdesc=$Lang::tr{'click to disable'};}
324 else { $gif = 'off.gif'; $toggle='on'; $gdesc=$Lang::tr{'click to enable'};}
325
326 my $remark = &Header::cleanhtml($temp[4]);
327
328 if ($cgiparams{'ACTION'} eq 'edit' && $cgiparams{'ID'} eq $id) {
329 print "<tr bgcolor='${Header::colouryellow}'>\n";
330 } elsif ($id % 2) {
331 print "<tr bgcolor='${Header::table1colour}'>\n";
332 } else {
333 print "<tr bgcolor='${Header::table2colour}'>\n";
334 }
335 print "<td align='center'>$hname</td>\n";
336 print "<td align='center'>$sourceip</td>\n";
337 print "<td align='center'>$sourcemac</td>\n";
338 print "<td align='center'>$remark</td>\n";
339print<<END
340<td align='center'>
341 <form method='post' name='frma$id' action='$ENV{'SCRIPT_NAME'}'>
342 <input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif' alt='$gdesc' title='$gdesc' />
343 <input type='hidden' name='ACTION' value='toggle'}' />
344 <input type='hidden' name='ID' value='$id' />
345 <input type='hidden' name='ENABLE' value='$toggle' />
346 </form>
347</td>
348
349<td align='center'>
350 <form method='post' name='frmb$id' action='$ENV{'SCRIPT_NAME'}'>
351 <input type='hidden' name='ACTION' value='edit' />
352 <input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' />
353 <input type='hidden' name='ID' value='$id' />
354 </form>
355</td>
356
357<td align='center'>
358 <form method='post' name='frmc$id' action='$ENV{'SCRIPT_NAME'}'>
359 <input type='hidden' name='ACTION' value='remove' />
360 <input type='image' name='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' />
361 <input type='hidden' name='ID' value='$id' />
362 </form>
363</td>
364END
365 ;
366 print "</tr>\n";
367}
368print "</table>\n";
369
370print "</div>\n";
371
372&Header::closebox();
373
374if ( $dhcpsettings{"ENABLE_BLUE"} eq 'on') {
375 &printblueleases;
376}
377
378&Header::closebigbox();
379
380&Header::closepage();
381
382sub printblueleases
383{
384 our %entries = ();
385
386 sub blueleasesort {
387 # Sort by IP address
388 my $qs ='IPADDR';
389 my @a = split(/\./,$entries{$a}->{$qs});
390 my @b = split(/\./,$entries{$b}->{$qs});
391 ($a[0]<=>$b[0]) ||
392 ($a[1]<=>$b[1]) ||
393 ($a[2]<=>$b[2]) ||
394 ($a[3]<=>$b[3]);
395 }
396
397 &Header::openbox('100%', 'left', "$Lang::tr{'current dhcp leases on blue'}");
398 print <<END
399<table width='100%'>
400<tr>
401<td width='25%' align='center'><b>$Lang::tr{'ip address'}</b></td>
402<td width='25%' align='center'><b>$Lang::tr{'mac address'}</b></td>
403<td width='20%' align='center'><b>$Lang::tr{'hostname'}</b></td>
404<td width='30%' align='center'><b>$Lang::tr{'lease expires'} (local time d/m/y)</b></td>
405</tr>
406END
407 ;
408
409 my ($ip, $endtime, $ether, $hostname, @record, $record);
410 open(LEASES,"/var/state/dhcp/dhcpd.leases") or die "Can't open dhcpd.leases";
411 while (my $line = <LEASES>) {
412 next if( $line =~ /^\s*#/ );
413 chomp($line);
414 my @temp = split (' ', $line);
415
416 if ($line =~ /^\s*lease/) {
417 $ip = $temp[1];
418 # All fields are not necessarily read. Clear everything
419 $endtime = 0;
420 $ether = "";
421 $hostname = "";
422 } elsif ($line =~ /^\s*ends never;/) {
423 $endtime = 'never';
424 } elsif ($line =~ /^\s*ends/) {
425 $line =~ /(\d+)\/(\d+)\/(\d+) (\d+):(\d+):(\d+)/;
426 $endtime = timegm($6, $5, $4, $3, $2 - 1, $1 - 1900);
427 } elsif ($line =~ /^\s*hardware ethernet/) {
428 $ether = $temp[2];
429 $ether =~ s/;//g;
430 } elsif ($line =~ /^\s*client-hostname/) {
431 shift (@temp);
432 $hostname = join (' ',@temp);
433 $hostname =~ s/;//g;
434 $hostname =~ s/\"//g;
435 } elsif ($line eq "}") {
436 # Select records in Blue subnet
437 if ( &General::IpInSubnet ( $ip,
438 $netsettings{"BLUE_NETADDRESS"},
439 $netsettings{"BLUE_NETMASK"} ) ) {
440 @record = ('IPADDR',$ip,'ENDTIME',$endtime,'ETHER',$ether,'HOSTNAME',$hostname);
441 $record = {}; # create a reference to empty hash
442 %{$record} = @record; # populate that hash with @record
443 $entries{$record->{'IPADDR'}} = $record; # add this to a hash of hashes
444 }
445 }
446 }
447 close(LEASES);
448
449 my $id = 0;
450 foreach my $key (sort blueleasesort keys %entries) {
451
452 my $hostname = &Header::cleanhtml($entries{$key}->{HOSTNAME},"y");
453
454 if ($id % 2) {
455 print "<tr bgcolor='$Header::table2colour'>";
456 } else {
457 print "<tr bgcolor='$Header::table1colour'>";
458 }
459
460 print <<END
461<td align='center'>$entries{$key}->{IPADDR}</td>
462<td align='center'>$entries{$key}->{ETHER}</td>
463<td align='center'>&nbsp;$hostname </td>
464<td align='center'>
465END
466 ;
467
468 if ($entries{$key}->{ENDTIME} eq 'never') {
469 print "$Lang::tr{'no time limit'}";
470 } else {
471 my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $dst);
472 ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $dst) = localtime ($entries{$key}->{ENDTIME});
473 my $enddate = sprintf ("%02d/%02d/%d %02d:%02d:%02d",$mday,$mon+1,$year+1900,$hour,$min,$sec);
474
475 if ($entries{$key}->{ENDTIME} < time() ){
476 print "<strike>$enddate</strike>";
477 } else {
478 print "$enddate";
479 }
480 }
481
482 if ( $hostname eq '' ) {
483 $hostname = $Lang::tr{'device'};
484 }
485
486 print <<END
487<td align='center'>
488 <form method='post' name='frmd$id' action='$ENV{'SCRIPT_NAME'}'>
489 <input type='hidden' name='ACTION' value='add' />
490 <input type='hidden' name='SOURCE_IP' value='' />
491 <input type='hidden' name='SOURCE_MAC' value='$entries{$key}->{ETHER}' />
492 <input type='hidden' name='REMARK' value='$hostname $Lang::tr{'added from dhcp lease list'}' />
493 <input type='hidden' name='ENABLED' value='on' />
494 <input type='hidden' name='EDITING' value='no' />
495 <input type='image' name='$Lang::tr{'add device'}' src='/images/addblue.gif' alt='$Lang::tr{'add device'}' title='$Lang::tr{'add device'}' />
496 </form>
497</td></tr>
498END
499 ;
500 $id++;
501 }
502
503 print "</table>";
504 &Header::closebox();
505}
506