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