Das Build wird jetzt im Browserkopf angezeigt
[ipfire-2.x.git] / config / cfgroot / header.pl
1 # SmoothWall CGIs
2 #
3 # This code is distributed under the terms of the GPL
4 #
5 # (c) The SmoothWall Team
6 # Copyright (C) 2002 Alex Hudson - getcgihash() rewrite
7 # Copyright (C) 2002 Bob Grant <bob@cache.ucr.edu> - validmac()
8 # Copyright (c) 2002/04/13 Steve Bootes - add alias section, helper functions
9 # Copyright (c) 2002/08/23 Mark Wormgoor <mark@wormgoor.com> validfqdn()
10 # Copyright (c) 2003/09/11 Darren Critchley <darrenc@telus.net> srtarray()
11 #
12 package Header;
13
14 use CGI();
15 use Socket;
16 use Time::Local;
17
18 $|=1; # line buffering
19
20 $Header::revision = 'final';
21 $Header::swroot = '/var/ipfire';
22 $Header::pagecolour = '#ffffff';
23 #$Header::tablecolour = '#a0a0a0';
24 $Header::tablecolour = '#FFFFFF';
25 $Header::bigboxcolour = '#F6F4F4';
26 $Header::boxcolour = '#EAE9EE';
27 $Header::bordercolour = '#000000';
28 $Header::table1colour = '#E0E0E0';
29 $Header::table2colour = '#F0F0F0';
30 $Header::colourred = '#993333';
31 $Header::colourorange = '#FF9933';
32 $Header::colouryellow = '#FFFF00';
33 $Header::colourgreen = '#339933';
34 $Header::colourblue = '#333399';
35 $Header::colourovpn = '#339999';
36 $Header::colourfw = '#000000';
37 $Header::colourvpn = '#990099';
38 $Header::colourerr = '#FF0000';
39 $Header::viewsize = 150;
40 $Header::errormessage = '';
41 my %menuhash = ();
42 my $menu = \%menuhash;
43 %settings = ();
44 %ethsettings = ();
45 @URI = ();
46 $Header::supported=0;
47
48 ### Make sure this is an SSL request
49 if ($ENV{'SERVER_ADDR'} && $ENV{'HTTPS'} ne 'on') {
50     print "Status: 302 Moved\r\n";
51     print "Location: https://$ENV{'SERVER_ADDR'}:10443/$ENV{'PATH_INFO'}\r\n\r\n";
52     exit 0;
53 }
54
55 ### Initialize environment
56 &readhash("${swroot}/main/settings", \%settings);
57 &readhash("${swroot}/ethernet/settings", \%ethsettings);
58 $language = $settings{'LANGUAGE'};
59 $hostname = $settings{'HOSTNAME'};
60 $hostnameintitle = 0;
61
62 ### Initialize language
63 if ($language =~ /^(\w+)$/) {$language = $1;}
64
65 ### Read English Files
66 if ( -d "/var/ipfire/langs/en/" ) {
67     opendir(DIR, "/var/ipfire/langs/en/");
68     @names = readdir(DIR) or die "Cannot Read Directory: $!\n";
69     foreach $name(@names) {
70         next if ($name eq ".");
71         next if ($name eq "..");
72         next if (!($name =~ /\.pl$/));
73         require "${swroot}/langs/en/${name}";
74     };
75 };
76
77
78 ### Enable Language Files
79 if ( -d "/var/ipfire/langs/${language}/" ) {
80     opendir(DIR, "/var/ipfire/langs/${language}/");
81     @names = readdir(DIR) or die "Cannot Read Directory: $!\n";
82     foreach $name(@names) {
83         next if ($name eq ".");
84         next if ($name eq "..");
85         next if (!($name =~ /\.pl$/));
86         require "${swroot}/langs/${language}/${name}";
87     };
88 };
89
90 ### Read IPFire Buildversion
91 $FIREBUILD = "Datei firebuild nicht gefunden\n";
92 if (open(MYFile, "<${swroot}/firebuild")) {
93     $FIREBUILD = <MYFile>;
94     $FIREBUILD = "(Build: $FIREBUILD)";
95     close(_File);
96 };
97
98 require "${swroot}/langs/en.pl";
99 require "${swroot}/langs/${language}.pl";
100
101 sub orange_used () {
102     if ($ethsettings{'CONFIG_TYPE'} =~ /^[1357]$/) {
103         return 1;
104     }
105     return 0;
106 }
107
108 sub blue_used () {
109     if ($ethsettings{'CONFIG_TYPE'} =~ /^[4567]$/) {
110         return 1;
111     }
112     return 0;
113 }
114
115 sub is_modem {
116     if ($ethsettings{'CONFIG_TYPE'} =~ /^[0145]$/) {
117         return 1;
118     }
119     return 0;
120 }
121
122 ### Initialize menu
123 sub genmenu {
124     my %subsystemhash = ();
125     my $subsystem = \%subsystemhash;
126
127     $subsystem->{'10.home'} = {
128                                 'caption' => $tr{'alt home'},
129                                 'uri' => '/cgi-bin/index.cgi',
130                                 'title' => "$tr{'alt home'}",
131                                 'enabled' => 1,
132                                 };
133     $subsystem->{'20.passwords'} = {
134                                 'caption' => $tr{'sspasswords'},
135                                 'uri' => '/cgi-bin/changepw.cgi',
136                                 'title' => "$tr{'sspasswords'}",
137                                 'enabled' => 1,
138                                 };
139     $subsystem->{'30.ssh'} = {
140                                 'caption' => $tr{'ssh access'},
141                                 'uri' => '/cgi-bin/remote.cgi',
142                                 'title' => "$tr{'ssh access'}",
143                                 'enabled' => 1,
144                                 };
145     $subsystem->{'40.gui'} = {
146                                 'caption' => $tr{'gui settings'},
147                                 'uri' => '/cgi-bin/gui.cgi',
148                                 'title' => "$tr{'gui settings'}",
149                                 'enabled' => 1,
150                                 };
151     $subsystem->{'50.shutdown'} = {
152                                 'caption' => $tr{'shutdown'},
153                                 'uri' => '/cgi-bin/shutdown.cgi',
154                                 'title' => "$tr{'shutdown'} / $tr{'reboot'}",
155                                 'enabled' => 1,
156                                 };
157     $subsystem->{'99.credits'} = {
158                                 'caption' => $tr{'credits'},
159                                 'uri' => '/cgi-bin/credits.cgi',
160                                 'title' => "$tr{'credits'}",
161                                 'enabled' => 1,
162                                 };
163
164     my %substatushash = ();
165     my $substatus = \%substatushash;
166     $substatus->{'10.systemstatus'} = {
167                                  'caption' => $tr{'sssystem status'},
168                                  'uri' => '/cgi-bin/status.cgi',
169                                  'title' => "$tr{'sssystem status'}",
170                                  'enabled' => 1,
171                                  };
172     $substatus->{'20.networkstatus'} = {
173                                 'caption' => $tr{'ssnetwork status'},
174                                 'uri' => '/cgi-bin/netstatus.cgi',
175                                 'title' => "$tr{'ssnetwork status'}",
176                                 'enabled' => 1,
177                                 };
178     $substatus->{'30.systemgraphs'} = {
179                                 'caption' => $tr{'system graphs'},
180                                 'uri' => '/cgi-bin/graphs.cgi',
181                                 'novars' => 1,
182                                 'title' => "$tr{'system graphs'}",
183                                 'enabled' => 1,
184                                 };
185     $substatus->{'40.trafficgraphs'} = {
186                                 'caption' => $tr{'sstraffic graphs'},
187                                 'uri' => '/cgi-bin/graphs.cgi',
188                                 'vars' => 'graph=network',
189                                 'title' => "$tr{'sstraffic graphs'}",
190                                 'enabled' => 1,
191                                 };
192     $substatus->{'50.proxygraphs'} = {
193                                 'caption' => $tr{'ssproxy graphs'},
194                                 'uri' => '/cgi-bin/proxygraphs.cgi',
195                                 'title' => "$tr{'ssproxy graphs'}",
196                                 'enabled' => 1,
197                                 };
198     $substatus->{'60.fwhits'} = {
199                                   'caption' => 'Firewall-Diagramme',
200                                   'uri' => '/cgi-bin/fwhits.cgi',
201                                   'title' => "Firewall-Diagramme",
202                                  'enabled' => 1,
203                                   };
204     $substatus->{'70.hddtemp'} = {
205                                   'caption' => "$tr{'harddisk temperature graphs'}",
206                                   'uri' => '/cgi-bin/hddgraph.cgi',
207                                   'title' => "$tr{'harddisk temperature graphs'}",
208                                  'enabled' => 1,
209                                   };
210     $substatus->{'80.connections'} = {
211                                 'caption' => $tr{'connections'},
212                                 'uri' => '/cgi-bin/connections.cgi',
213                                 'title' => "$tr{'connections'}",
214                                 'enabled' => 1,
215                                 };
216     $substatus->{'90.nettraf'} = {
217                                   'caption' => $tr{'sstraffic'},
218                                   'uri' => '/cgi-bin/traffic.cgi',
219                                   'title' => "$tr{'sstraffic'}",
220                                  'enabled' => 1,
221                                   };
222     $substatus->{'99.iptable'} = {
223                                 'caption' => $tr{'iptable rules'},
224                                 'uri' => '/cgi-bin/iptables.cgi',
225                                 'title' => "$tr{'iptable rules'}",
226                                 'enabled' => 1,
227                                 };
228
229     my %subnetworkhash = ();
230     my $subnetwork = \%subnetworkhash;
231
232     $subnetwork->{'10.proxy'} = {'caption' => 'Webproxy',
233                                 'uri' => '/cgi-bin/proxy.cgi',
234                                 'title' => "Webproxy",
235                                 'enabled' => 1,
236                                 };
237     $subnetwork->{'20.urlfilter'} = {'caption' => 'URL-Filter',
238                                 'uri' => '/cgi-bin/urlfilter.cgi',
239                                 'title' => "URL-Filter",
240                                 'enabled' => 1,
241                                 };
242     $subnetwork->{'30.dhcp'} = {'caption' => $tr{'dhcp server'},
243                                  'uri' => '/cgi-bin/dhcp.cgi',
244                                  'title' => "$tr{'dhcp server'}",
245                                  'enabled' => 1,
246                                  };
247     $subnetwork->{'40.dialup'} = {
248                                   'caption' => $tr{'alt dialup'},
249                                   'uri' => '/cgi-bin/pppsetup.cgi',
250                                   'title' => "$tr{'alt dialup'}",
251                                   'enabled' => 1,
252                                   };
253     $subnetwork->{'50.hosts'} = {
254                                  'caption' => $tr{'edit hosts'},
255                                  'uri' => '/cgi-bin/hosts.cgi',
256                                  'title' => "$tr{'edit hosts'}",
257                                  'enabled' => 1,
258                                  };
259     $subnetwork->{'60.upload'} = {
260                                   'caption' => $tr{'upload'},
261                                   'uri' => '/cgi-bin/upload.cgi',
262                                   'title' => "$tr{'upload'}",
263                                   'enabled' => 0,
264                                   };
265     $subnetwork->{'70.aliases'} = {
266                                   'caption' => $tr{'aliases'},
267                                   'uri' => '/cgi-bin/aliases.cgi',
268                                   'title' => "$tr{'aliases'}",
269                                   'enabled' => 0,
270                                   };
271
272     my %subserviceshash = ();
273     my $subservices = \%subserviceshash;
274
275
276     $subservices->{'10.openvpn'} = {
277                                 'caption' => 'OpenVPN',
278                                 'uri' => '/cgi-bin/ovpnmain.cgi',
279                                 'title' => "$tr{'virtual private networking'}",
280                                'enabled' => 1,
281                                 };
282     $subservices->{'20.ipsec'} = {
283                                 'caption' => 'IPSec',
284                                 'uri' => '/cgi-bin/vpnmain.cgi',
285                                 'title' => "$tr{'virtual private networking'}",
286                                 'enabled' => 1,
287                                 };
288     $subservices->{'30.dyndns'} = {'caption' => $tr{'dynamic dns'},
289                                 'uri' => '/cgi-bin/ddns.cgi',
290                                 'title' => "$tr{'dynamic dns'}",
291                                 'enabled' => 1,
292                                 };
293     $subservices->{'40.time'} = {'caption' => $tr{'time server'},
294                                 'uri' => '/cgi-bin/time.cgi',
295                                 'title' => "$tr{'time server'}",
296                                 'enabled' => 1,
297                                 };
298     $subservices->{'50.qos'} = {'caption' => 'Quality of Service',
299                                 'uri' => '/cgi-bin/qos.cgi',
300                                 'title' => "Quality of Service",
301                                 'enabled' => 1,
302                                 };
303     $subservices->{'60.ids'} = {'caption' => $tr{'intrusion detection'},
304                                 'enabled' => 1,
305                                 'uri' => '/cgi-bin/ids.cgi',
306                                 'title' => "$tr{'intrusion detection system'}",
307                                 };
308
309
310
311     my %subfirewallhash = ();
312     my $subfirewall = \%subfirewallhash;
313
314     
315     $subfirewall->{'10.dnat'} = {
316                                  'caption' => $tr{'ssport forwarding'},
317                                  'uri' => '/cgi-bin/portfw.cgi',
318                                  'title' => "$tr{'ssport forwarding'}",
319                                  'enabled' => 1,
320                                  };
321     $subfirewall->{'20.xtaccess'} = {
322                                  'caption' => $tr{'external access'},
323                                  'uri' => '/cgi-bin/xtaccess.cgi',
324                                  'title' => "$tr{'external access'}",
325                                  'enabled' => 1,
326                                  };
327     $subfirewall->{'30.wireless'} = {
328                                 'caption' => $tr{'blue access'},
329                                 'uri' => '/cgi-bin/wireless.cgi',
330                                 'title' => "$tr{'blue access'}",
331                                 'enabled' => 1,
332                                  };
333     $subfirewall->{'40.dmz'} = {
334                                 'caption' => $tr{'ssdmz pinholes'},
335                                 'uri' => '/cgi-bin/dmzholes.cgi',
336                                 'title' => "$tr{'dmz pinhole configuration'}",
337                                 'enabled' => 1,
338                                  };
339     $subfirewall->{'50.outgoing'} = {
340                                 'caption' => $tr{'outgoing firewall'},
341                                 'uri' => '/cgi-bin/outgoingfw.cgi',
342                                 'title' => "$tr{'outgoing firewall'}",
343                                 'enabled' => 1,
344                                 };
345     $subfirewall->{'60.fwopts'} = {
346                                 'caption' => $tr{'options fw'},
347                                 'uri' => '/cgi-bin/optionsfw.cgi',
348                                 'title' => "$tr{'options fw'}",
349                                 'enabled' => 1,
350                                  };
351     
352     my %sublogshash = ();
353     my $sublogs = \%sublogshash;
354
355     $sublogs->{'10.summary'} = {'caption' => $tr{'log summary'},
356                                  'uri' => '/cgi-bin/logs.cgi/summary.dat',
357                                  'title' => "$tr{'log summary'}",
358                                  'enabled' => 1
359                                  };
360     $sublogs->{'20.settings'} = {'caption' => $tr{'log settings'},
361                                  'uri' => '/cgi-bin/logs.cgi/config.dat',
362                                  'title' => "$tr{'log settings'}",
363                                  'enabled' => 1
364                                  };
365     $sublogs->{'30.proxy'} = {'caption' => $tr{'proxy logs'},
366                                  'uri' => '/cgi-bin/logs.cgi/proxylog.dat',
367                                  'title' => "$tr{'proxy logs'}",
368                                  'enabled' => 1
369                                  };
370     $sublogs->{'40.firewall'} = {'caption' => $tr{'firewall logs'},
371                                  'uri' => '/cgi-bin/logs.cgi/firewalllog.dat',
372                                  'title' => "$tr{'firewall logs'}",
373                                  'enabled' => 1
374                                  };
375     $sublogs->{'50.ids'} = {'caption' => $tr{'ids logs'},
376                                 'uri' => '/cgi-bin/logs.cgi/ids.dat',
377                                 'title' => "$tr{'ids logs'}",
378                                 'enabled' => 1
379                                 };
380     $sublogs->{'60.urlfilter'} = {
381                                 'caption' => $tr{'urlfilter log'},
382                                 'uri' => '/cgi-bin/logs.cgi/urlfilter.dat',
383                                 'title' => "$tr{'urlfilter log'}",
384                                 'enabled' => 1,
385                                 };
386     $sublogs->{'70.openvpn'} = {'caption' => $tr{'openvpn log'},
387                                 'uri' => '/cgi-bin/logs.cgi/openvpn.dat',
388                                 'title' => "$tr{'openvpn log'}",
389                                 'enabled' => 1
390                                 };
391     $sublogs->{'80.system'} = {'caption' => $tr{'system logs'},
392                                 'uri' => '/cgi-bin/logs.cgi/log.dat',
393                                 'title' => "$tr{'system logs'}",
394                                 'enabled' => 1
395                                 };
396     $sublogs->{'90.userlog'} = {'caption' => $tr{'user proxy logs'},
397                                 'uri' => '/cgi-bin/logs.cgi/userlog.dat',
398                                 'title' => "$tr{'user log'}",
399                                 'enabled' => 1
400                                 };
401
402     my %subipfirehash = ();
403     my $subipfire = \%subipfirehash;
404     $subipfire->{'10.pakfire'} = {'caption' => 'Pakfire',
405                                   'uri' => '/cgi-bin/pakfire.cgi',
406                                   'title' => "Pakfire",
407                                   'enabled' => 1,
408                                   };
409     $subipfire->{'20.asterisk'} = {'caption' => 'Asterisk',
410                                   'uri' => '/cgi-bin/asterisk.cgi',
411                                   'title' => "Asterisk",
412                                   'enabled' => 1,
413                                   };
414     $subipfire->{'30.samba'} = {'caption' => 'Samba',
415                                   'uri' => '/cgi-bin/samba.cgi',
416                                   'title' => "Samba",
417                                   'enabled' => 1,
418                                   };
419     $subipfire->{'99.help'} = {'caption' => $tr{'help'},
420                                   'uri' => '/cgi-bin/help.cgi',
421                                   'title' => "$tr{'help'}",
422                                   'enabled' => 1,
423                                   };
424
425
426
427     $menu->{'01.system'} = {'caption' => $tr{'alt system'},
428                                 'enabled' => 1,
429                                 'subMenu' => $subsystem
430                                 };
431     $menu->{'02.status'} = {'caption' => $tr{'status'},
432                                 'enabled' => 1,
433                                 'subMenu' => $substatus
434                                 };
435     $menu->{'03.network'} = {'caption' => $tr{'network'},
436                                 'enabled' => 1,
437                                 'subMenu' => $subnetwork
438                                 };
439     $menu->{'04.services'} = {'caption' => $tr{'alt services'},
440                                 'enabled' => 1,
441                                 'subMenu' => $subservices
442                                 };
443     $menu->{'05.firewall'} = {'caption' => $tr{'firewall'},
444                                 'enabled' => 1,
445                                 'subMenu' => $subfirewall
446                                 };
447     $menu->{'06.proxy'} = {'caption' => $tr{'alt proxy'},
448                                 'enabled' => 1,
449                                 'subMenu' => $subproxy
450                                 };
451     $menu->{'07.ipfire'} = {'caption' => 'IPFire',
452                                 'enabled' => 1,
453                                 'subMenu' => $subipfire
454                                 };
455     $menu->{'08.logs'} = {'caption' => $tr{'alt logs'},
456                                 'enabled' => 1,
457                                 'subMenu' => $sublogs
458                                 };
459
460     if (! blue_used() && ! orange_used()) {
461         $menu->{'05.firewall'}{'subMenu'}->{'40.dmz'}{'enabled'} = 0;
462     }
463     if (! blue_used()) {
464         $menu->{'05.firewall'}{'subMenu'}->{'30.wireless'}{'enabled'} = 0;
465     }
466     if (! $ethsettings{'CONFIG_TYPE'} =~ /^(2|3|6|7)$/ && $ethsettings{'RED_TYPE'} eq 'STATIC' ) {
467         $menu->{'03.network'}{'subMenu'}->{'70.aliases'}{'enabled'} = 1;
468     }
469 }
470
471 sub showhttpheaders
472 {
473         print "Pragma: no-cache\n";
474         print "Cache-control: no-cache\n";
475         print "Connection: close\n";
476         print "Content-type: text/html\n\n";
477 }
478
479 sub is_menu_visible($) {
480     my $link = shift;
481     $link =~ s#\?.*$##;
482     return (-e $ENV{'DOCUMENT_ROOT'}."/../$link");
483 }
484
485
486 sub getlink($) {
487     my $root = shift;
488     if (! $root->{'enabled'}) {
489         return '';
490     }
491     if ($root->{'uri'} !~ /^$/) {
492         my $vars = '';
493         if ($root->{'vars'} !~ /^$/) {
494             $vars = '?'. $root->{'vars'};
495         }
496         if (! is_menu_visible($root->{'uri'})) {
497             return '';
498         }
499         return $root->{'uri'}.$vars;
500     }
501     my $submenus = $root->{'subMenu'};
502     if (! $submenus) {
503         return '';
504     }
505     foreach my $item (sort keys %$submenus) {
506         my $link = getlink($submenus->{$item});
507         if ($link ne '') {
508             return $link;
509         }
510     }
511     return '';
512 }
513
514
515 sub compare_url($) {
516     my $conf = shift;
517
518     my $uri = $conf->{'uri'};
519     my $vars = $conf->{'vars'};
520     my $novars = $conf->{'novars'};
521
522     if ($uri eq '') {
523         return 0;
524     }
525     if ($uri ne $URI[0]) {
526         return 0;
527     }
528     if ($novars) {
529         if ($URI[1] !~ /^$/) {
530             return 0;
531         }
532     }
533     if (! $vars) {
534         return 1;
535     }
536     return ($URI[1] eq $vars);
537 }
538
539
540 sub gettitle($) {
541     my $root = shift;
542
543     if (! $root) {
544         return '';
545     }
546     foreach my $item (sort keys %$root) {
547         my $val = $root->{$item};
548         if (compare_url($val)) {
549             $val->{'selected'} = 1;
550             if ($val->{'title'} !~ /^$/) {
551                 return $val->{'title'};
552             }
553             return 'EMPTY TITLE';
554         }
555
556         my $title = gettitle($val->{'subMenu'});
557         if ($title ne '') {
558             $val->{'selected'} = 1;
559             return $title;
560         }
561     }
562     return '';
563 }
564
565
566 sub showmenu() {
567     print <<EOF
568   <div id="menu-top">
569     <ul>
570 EOF
571 ;
572     foreach my $k1 ( sort keys %$menu ) {
573         if (! $menu->{$k1}{'enabled'}) {
574             next;
575         }
576
577         my $link = getlink($menu->{$k1});
578         if ($link eq '') {
579             next;
580         }
581         if (! is_menu_visible($link)) {
582             next;
583         }
584         if ($menu->{$k1}->{'selected'}) {
585             print '<li class="selected">';
586         } else {
587             print '<li>';
588         }
589
590         print <<EOF
591     <div class="rcorner">
592       <a href="$link">$menu->{$k1}{'caption'}</a>
593     </div>
594   </li>
595 EOF
596 ;
597     }
598
599     print <<EOF
600     </ul>
601   </div>
602 EOF
603 ;    
604 }
605
606 sub getselected($) {
607     my $root = shift;
608     if (!$root) {
609         return 0;
610     }
611
612     foreach my $item (%$root) {
613         if ($root->{$item}{'selected'}) {
614             return $root->{$item};
615         }
616     }
617 }
618
619 sub showsubsection($$) {
620     my $root = shift;
621     my $id = shift;
622     if ($id eq '') {
623         $id = 'menu-left';
624     }
625
626     if (! $root) {
627         return;
628     }
629     my $selected = getselected($root);
630     if (! $selected) {
631         return;
632     }
633     my $submenus = $selected->{'subMenu'};
634     if (! $submenus) {
635         return;
636     }
637
638     print <<EOF
639   <div id="$id">
640     <ul>
641 EOF
642 ;
643     foreach my $item (sort keys %$submenus) {
644         my $hash = $submenus->{$item};
645         if (! $hash->{'enabled'}) {
646             next;
647         }
648
649         my $link = getlink($hash);
650         if ($link eq '') {
651             next;
652         }
653         if (! is_menu_visible($link)) {
654             next;
655         }
656         if ($hash->{'selected'}) {
657             print '<li class="selected">';
658         } else {
659             print '<li>';
660         }
661
662         print <<EOF
663       <a href="$link">$hash->{'caption'}</a>
664   </li>
665 EOF
666 ;
667     }
668
669     print <<EOF
670     </ul>
671   </div>
672 EOF
673 ;    
674
675 }
676
677
678 sub showsubsubsection($) {
679     my $root = shift;
680     if (!$root) {
681         return;
682     }
683     my $selected = getselected($root);
684     if (! $selected) {
685         return
686     }
687     if (! $selected->{'subMenu'}) {
688         return
689     }
690
691     showsubsection($selected->{'subMenu'}, 'menu-subtop');
692 }
693
694
695 sub get_helpuri() {
696     my $helpfile = '';
697     if ($URI[0] =~ /.*\/([^\/]+)\.cgi/) {
698         $helpfile = $1;
699     } else {
700         return '';
701     }
702     $helpfile .= '.help.html';
703
704     my $helpuri = '/doc/'.$language.'/'.$helpfile;
705     if (! -e $ENV{'DOCUMENT_ROOT'}.$helpuri) {
706         return '';
707     }
708     return $helpuri;
709 }
710
711
712 sub openpage {
713     my $title = shift;
714     my $boh = shift;
715     my $extrahead = shift;
716
717     @URI=split ('\?',  $ENV{'REQUEST_URI'} );
718     &readhash("${swroot}/main/settings", \%settings);
719     &genmenu();
720
721     my $h2 = gettitle($menu);
722     my $helpuri = get_helpuri();
723
724     $title = "IPFire - $title $FIREBUILD";
725     if ($settings{'WINDOWWITHHOSTNAME'} eq 'on') {
726         $title =  "$settings{'HOSTNAME'}.$settings{'DOMAINNAME'} - $title"; 
727     }
728
729     print <<END
730 <!DOCTYPE html 
731      PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
732      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
733
734 <html>
735   <head>
736   <title>$title</title>
737
738     $extrahead
739     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
740     <meta http-equiv="Page-Enter" content="blendTrans(Duration=0.5,Transition=12)">
741     <meta http-equiv="Page-Exit" content="blendTrans(Duration=0.5,Transition=12)">
742     <link rel="shortcut icon" href="/favicon.ico" />
743     <style type="text/css">\@import url(/include/style.css);</style>
744     <style type="text/css">\@import url(/include/menu.css);</style>
745     <style type="text/css">\@import url(/include/content.css);</style>
746     <script language="javascript" type="text/javascript">
747       
748         function swapVisibility(id) {
749             el = document.getElementById(id);
750             if(el.style.display != 'block') {
751                 el.style.display = 'block'
752             }
753             else {
754                 el.style.display = 'none'
755             }
756         }
757     </script>
758
759   </head>
760   <body>
761 <!-- IPFIRE HEADER -->
762
763 <div id="main">
764
765 <div id="header">
766         <img id="logo-product" src="/images/logo_ipfire.gif">
767    <div id="header-icons">
768             <a href="http://users.ipfire.eu/" target="_blank"><img border="0" src="/images/help.gif"></a>
769    </div>
770 </div>
771
772 END
773 ;
774
775     &showmenu();
776
777 print <<END
778 <div id="content">
779   <table width="90%">
780     <tr>
781       <td valign="top">
782 END
783 ;
784         
785     &showsubsection($menu);
786
787     print <<END
788       <p><center><img src="/images/iptux.png" width='160px' height='160px'></center></p>
789       </td>
790         <td width="100%" valign="top">
791         <div id="page-content">
792             <h2>$h2</h2>
793 END
794     ;
795     
796     &showsubsubsection($menu);
797
798     eval {
799         require 'ipfire-network.pl';
800         $supported = check_support();
801         warn_unsupported($supported);
802     };
803 }
804
805 sub closepage () {
806     my $status = &connectionstatus();
807     $uptime = `/usr/bin/uptime`;
808         
809     print <<END
810           <div align="center">
811             <p>
812               <div style="font-size: 9px"><b>Status:</b> $status <b>Uptime:</b>$uptime</div>
813             </p>
814           </div>
815         </body>
816 </html>
817 END
818 ;
819 }
820
821 sub openbigbox
822 {
823     my $width = $_[0];
824     my $align = $_[1];
825     my $sideimg = $_[2];
826
827     if ($errormessage) {
828         $bgcolor = "style='background-color: $colourerr;'";
829     } else {
830         $bgcolor = '';
831     }
832 }
833
834 sub closebigbox
835 {
836 #       print "</td></tr></table></td></tr></table>\n" 
837 }
838
839 sub openbox
840 {
841         $width = $_[0];
842         $align = $_[1];
843         $caption = $_[2];
844
845         if ($caption) { print "<h3>$caption</h3>\n"; } else { print "&nbsp;"; }
846         
847         print "<table class=\"list\"><tr><td align=\"$align\">\n";
848 }
849
850 sub closebox
851 {
852         print "</td></tr></table><br><br>";
853 }
854
855 sub writehash
856 {
857         my $filename = $_[0];
858         my $hash = $_[1];
859         
860         # write cgi vars to the file.
861         open(FILE, ">${filename}") or die "Unable to write file $filename";
862         flock FILE, 2;
863         foreach $var (keys %$hash) 
864         {
865                 $val = $hash->{$var};
866                 # Darren Critchley Jan 17, 2003 added the following because when submitting with a graphic, the x and y
867                 # location of the mouse are submitted as well, this was being written to the settings file causing
868                 # some serious grief! This skips the variable.x and variable.y
869                 if (!($var =~ /(.x|.y)$/)) {
870                         if ($val =~ / /) {
871                                 $val = "\'$val\'"; }
872                         if (!($var =~ /^ACTION/)) {
873                                 print FILE "${var}=${val}\n"; }
874                 }
875         }
876         close FILE;
877 }
878
879 sub readhash
880 {
881         my $filename = $_[0];
882         my $hash = $_[1];
883         my ($var, $val);
884
885         open(FILE, $filename) or die "Unable to read file $filename";
886         
887         while (<FILE>)
888         {
889                 chop;
890                 ($var, $val) = split /=/, $_, 2;
891                 if ($var)
892                 {
893                         $val =~ s/^\'//g;
894                         $val =~ s/\'$//g;
895
896                         # Untaint variables read from hash
897                         $var =~ /([A-Za-z0-9_-]*)/;        $var = $1;
898                         $val =~ /([\w\W]*)/; $val = $1;
899                         $hash->{$var} = $val;
900                 }
901         }
902         close FILE;
903 }
904
905 sub getcgihash {
906         my ($hash, $params) = @_;
907         my $cgi = CGI->new ();
908         $hash->{'__CGI__'} = $cgi;
909         return if ($ENV{'REQUEST_METHOD'} ne 'POST');
910         if (!$params->{'wantfile'}) {
911                 $CGI::DISABLE_UPLOADS = 1;
912                 $CGI::POST_MAX        = 512 * 1024;
913         } else {
914                 $CGI::POST_MAX = 10 * 1024 * 1024;
915         }
916
917         $cgi->referer() =~ m/^https?\:\/\/([^\/]+)/;
918         my $referer = $1;
919         $cgi->url() =~ m/^https?\:\/\/([^\/]+)/;
920         my $servername = $1;
921         return if ($referer ne $servername);
922
923         ### Modified for getting multi-vars, split by |
924         %temp = $cgi->Vars();
925         foreach my $key (keys %temp) {
926                 $hash->{$key} = $temp{$key};
927                 $hash->{$key} =~ s/\0/|/g;
928                 $hash->{$key} =~ s/^\s*(.*?)\s*$/$1/;
929         }
930
931         if (($params->{'wantfile'})&&($params->{'filevar'})) {
932                 $hash->{$params->{'filevar'}} = $cgi->upload
933                                                 ($params->{'filevar'});
934         }
935         return;
936 }
937
938 sub log
939 {
940         my $logmessage = $_[0];
941         $logmessage =~ /([\w\W]*)/;
942         $logmessage = $1;
943         system('/usr/bin/logger', '-t', 'ipfire', $logmessage);
944 }
945
946 sub age
947 {
948         my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
949                 $atime, $mtime, $ctime, $blksize, $blocks) = stat $_[0];
950         my $now = time;
951
952         my $totalsecs = $now - $mtime;
953         my $days = int($totalsecs / 86400);
954         my $totalhours = int($totalsecs / 3600);
955         my $hours = $totalhours % 24;
956         my $totalmins = int($totalsecs / 60);
957         my $mins = $totalmins % 60;
958         my $secs = $totalsecs % 60;
959
960         return "${days}d ${hours}h ${mins}m ${secs}s";
961 }
962
963 sub validip
964 {
965         my $ip = $_[0];
966
967         if (!($ip =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/)) {
968                 return 0; }
969         else 
970         {
971                 @octets = ($1, $2, $3, $4);
972                 foreach $_ (@octets)
973                 {
974                         if (/^0./) {
975                                 return 0; }
976                         if ($_ < 0 || $_ > 255) {
977                                 return 0; }
978                 }
979                 return 1;
980         }
981 }
982
983 sub validmask
984 {
985         my $mask = $_[0];
986
987         # secord part an ip?
988         if (&validip($mask)) {
989                 return 1; }
990         # second part a number?
991         if (/^0/) {
992                 return 0; }
993         if (!($mask =~ /^\d+$/)) {
994                 return 0; }
995         if ($mask >= 0 && $mask <= 32) {
996                 return 1; }
997         return 0;
998 }
999
1000 sub validipormask
1001 {
1002         my $ipormask = $_[0];
1003
1004         # see if it is a IP only.
1005         if (&validip($ipormask)) {
1006                 return 1; }
1007         # split it into number and mask.
1008         if (!($ipormask =~ /^(.*?)\/(.*?)$/)) {
1009                 return 0; }
1010         $ip = $1;
1011         $mask = $2;
1012         # first part not a ip?
1013         if (!(&validip($ip))) {
1014                 return 0; }
1015         return &validmask($mask);
1016 }
1017
1018 sub validipandmask
1019 {
1020         my $ipandmask = $_[0];
1021
1022         # split it into number and mask.
1023         if (!($ipandmask =~ /^(.*?)\/(.*?)$/)) {
1024                 return 0; }
1025         $ip = $1;
1026         $mask = $2;
1027         # first part not a ip?
1028         if (!(&validip($ip))) {
1029                 return 0; }
1030         return &validmask($mask);
1031 }
1032
1033 sub validport
1034 {
1035         $_ = $_[0];
1036
1037         if (!/^\d+$/) {
1038                 return 0; }
1039         if (/^0./) {
1040                 return 0; }
1041         if ($_ >= 1 && $_ <= 65535) {
1042                 return 1; }
1043         return 0;
1044 }
1045
1046 sub validmac
1047 {
1048         my $checkmac = $_[0];
1049         my $ot = '[0-9a-f]{2}'; # 2 Hex digits (one octet)
1050         if ($checkmac !~ /^$ot:$ot:$ot:$ot:$ot:$ot$/i)
1051         {
1052                 return 0;
1053         }
1054         return 1;
1055 }
1056
1057 sub validhostname
1058 {
1059         # Checks a hostname against RFC1035
1060         my $hostname = $_[0];
1061
1062         # Each part should be at least two characters in length
1063         # but no more than 63 characters
1064         if (length ($hostname) < 2 || length ($hostname) > 63) {
1065                 return 0;}
1066         # Only valid characters are a-z, A-Z, 0-9 and -
1067         if ($hostname !~ /^[a-zA-Z0-9-]*$/) {
1068                 return 0;}
1069         # First character can only be a letter or a digit
1070         if (substr ($hostname, 0, 1) !~ /^[a-zA-Z0-9]*$/) {
1071                 return 0;}
1072         # Last character can only be a letter or a digit
1073         if (substr ($hostname, -1, 1) !~ /^[a-zA-Z0-9]*$/) {
1074                 return 0;}
1075         return 1;
1076 }
1077
1078 sub validdomainname
1079 {
1080         # Checks a domain name against RFC1035
1081         my $domainname = $_[0];
1082         my @parts = split (/\./, $domainname);  # Split hostname at the '.'
1083
1084         foreach $part (@parts) {
1085                 # Each part should be at least two characters in length
1086                 # but no more than 63 characters
1087                 if (length ($part) < 2 || length ($part) > 63) {
1088                         return 0;}
1089                 # Only valid characters are a-z, A-Z, 0-9 and -
1090                 if ($part !~ /^[a-zA-Z0-9-]*$/) {
1091                         return 0;}
1092                 # First character can only be a letter or a digit
1093                 if (substr ($part, 0, 1) !~ /^[a-zA-Z0-9]*$/) {
1094                         return 0;}
1095                 # Last character can only be a letter or a digit
1096                 if (substr ($part, -1, 1) !~ /^[a-zA-Z0-9]*$/) {
1097                         return 0;}
1098         }
1099         return 1;
1100 }
1101
1102 sub validfqdn
1103 {
1104         # Checks a fully qualified domain name against RFC1035
1105         my $fqdn = $_[0];
1106         my @parts = split (/\./, $fqdn);        # Split hostname at the '.'
1107         if (scalar(@parts) < 2) {               # At least two parts should
1108                 return 0;}                      # exist in a FQDN
1109                                                 # (i.e. hostname.domain)
1110         foreach $part (@parts) {
1111                 # Each part should be at least two characters in length
1112                 # but no more than 63 characters
1113                 if (length ($part) < 2 || length ($part) > 63) {
1114                         return 0;}
1115                 # Only valid characters are a-z, A-Z, 0-9 and -
1116                 if ($part !~ /^[a-zA-Z0-9-]*$/) {
1117                         return 0;}
1118                 # First character can only be a letter or a digit
1119                 if (substr ($part, 0, 1) !~ /^[a-zA-Z0-9]*$/) {
1120                         return 0;}
1121                 # Last character can only be a letter or a digit
1122                 if (substr ($part, -1, 1) !~ /^[a-zA-Z0-9]*$/) {
1123                         return 0;}
1124         }
1125         return 1;
1126 }
1127
1128 sub validportrange # used to check a port range 
1129 {
1130         my $port = $_[0]; # port values
1131         $port =~ tr/-/:/; # replace all - with colons just in case someone used -
1132         my $srcdst = $_[1]; # is it a source or destination port
1133
1134         if (!($port =~ /^(\d+)\:(\d+)$/)) {
1135         
1136                 if (!(&validport($port))) {      
1137                         if ($srcdst eq 'src'){
1138                                 return $tr{'source port numbers'};
1139                         } else  {
1140                                 return $tr{'destination port numbers'};
1141                         } 
1142                 }
1143         }
1144         else 
1145         {
1146                 @ports = ($1, $2);
1147                 if ($1 >= $2){
1148                         if ($srcdst eq 'src'){
1149                                 return $tr{'bad source range'};
1150                         } else  {
1151                                 return $tr{'bad destination range'};
1152                         } 
1153                 }
1154                 foreach $_ (@ports)
1155                 {
1156                         if (!(&validport($_))) {
1157                                 if ($srcdst eq 'src'){
1158                                         return $tr{'source port numbers'}; 
1159                                 } else  {
1160                                         return $tr{'destination port numbers'};
1161                                 } 
1162                         }
1163                 }
1164                 return;
1165         }
1166 }
1167
1168 # Test if IP is within a subnet
1169 # Call: IpInSubnet (Addr, Subnet, Subnet Mask)
1170 #       Subnet can be an IP of the subnet: 10.0.0.0 or 10.0.0.1
1171 #       Everything in dottted notation
1172 # Return: TRUE/FALSE
1173 sub IpInSubnet
1174 {
1175     $ip = unpack('N', inet_aton(shift));
1176     $start = unpack('N', inet_aton(shift));
1177     $mask  = unpack('N', inet_aton(shift));
1178     $start &= $mask;  # base of subnet...
1179     $end   = $start + ~$mask;
1180     return (($ip >= $start) && ($ip <= $end));
1181 }
1182
1183 sub validemail {
1184     my $mail = shift;
1185     return 0 if ( $mail !~ /^[0-9a-zA-Z\.\-\_]+\@[0-9a-zA-Z\.\-]+$/ );
1186     return 0 if ( $mail =~ /^[^0-9a-zA-Z]|[^0-9a-zA-Z]$/);
1187     return 0 if ( $mail !~ /([0-9a-zA-Z]{1})\@./ );
1188     return 0 if ( $mail !~ /.\@([0-9a-zA-Z]{1})/ );
1189     return 0 if ( $mail =~ /.\.\-.|.\-\..|.\.\..|.\-\-./g );
1190     return 0 if ( $mail =~ /.\.\_.|.\-\_.|.\_\..|.\_\-.|.\_\_./g );
1191     return 0 if ( $mail !~ /\.([a-zA-Z]{2,3})$/ );
1192     return 1;
1193 }
1194
1195 sub readhasharray {
1196     my ($filename, $hash) = @_;
1197
1198     open(FILE, $filename) or die "Unable to read file $filename";
1199
1200     while (<FILE>) {
1201         my ($key, $rest, @temp);
1202         chomp;
1203         ($key, $rest) = split (/,/, $_, 2);
1204         if ($key =~ /^[0-9]+$/ && $rest) {
1205             @temp = split (/,/, $rest);
1206             $hash->{$key} = \@temp;
1207         }
1208     }
1209     close FILE;
1210     return;
1211 }
1212
1213 sub writehasharray {
1214     my ($filename, $hash) = @_;
1215     my ($key, @temp);
1216
1217     open(FILE, ">$filename") or die "Unable to write to file $filename";
1218
1219     foreach $key (keys %$hash) {
1220         if ( $hash->{$key} ) {
1221             print FILE "$key";
1222             foreach $i (0 .. $#{$hash->{$key}}) {
1223                 print FILE ",$hash->{$key}[$i]";
1224             }
1225         }
1226         print FILE "\n";
1227     }
1228     close FILE;
1229     return;
1230 }
1231
1232 sub findhasharraykey {
1233     foreach my $i (1 .. 1000000) {
1234         if ( ! exists $_[0]{$i}) {
1235              return $i;
1236         }
1237     }
1238 }
1239
1240 sub cleanhtml
1241 {
1242         my $outstring =$_[0];
1243         $outstring =~ tr/,/ / if not defined $_[1] or $_[1] ne 'y';
1244         $outstring =~ s/&/&amp;/g;
1245         $outstring =~ s/\'/&#039;/g;
1246         $outstring =~ s/\"/&quot;/g;
1247         $outstring =~ s/</&lt;/g;
1248         $outstring =~ s/>/&gt;/g;
1249         return $outstring;
1250 }
1251
1252 sub connectionstatus
1253 {
1254     my %pppsettings = ();
1255     my %netsettings = ();
1256     my $iface='';
1257
1258     $pppsettings{'PROFILENAME'} = 'None';
1259     &General::readhash("${General::swroot}/ppp/settings", \%pppsettings);
1260     &General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
1261
1262     my $profileused='';
1263     if ( ! ( $netsettings{'CONFIG_TYPE'} =~ /^(2|3|6|7)$/ && $netsettings{'RED_TYPE'} =~ /^(DHCP|STATIC)$/ ) ) {
1264         $profileused="- $pppsettings{'PROFILENAME'}";
1265     }
1266
1267     if ( ( $pppsettings{'METHOD'} eq 'DHCP' && $netsettings{'RED_TYPE'} ne 'PPTP') 
1268                                                 || $netsettings{'RED_TYPE'} eq 'DHCP' ) {
1269                 if (open(IFACE, "${General::swroot}/red/iface")) {
1270                         $iface = <IFACE>;
1271                         close IFACE;
1272                         chomp ($iface);
1273                         $iface =~ /([a-zA-Z0-9]*)/; $iface = $1;
1274                 }
1275     }
1276
1277     my ($timestr, $connstate);
1278     if ($netsettings{'CONFIG_TYPE'} =~ /^(0|1|4|5)$/ &&  $pppsettings{'TYPE'} =~ /^isdn/) {
1279         # Count ISDN channels
1280         my ($idmap, $chmap, $drmap, $usage, $flags, $phone);
1281         my @phonenumbers;
1282         my $count=0;
1283
1284         open (FILE, "/dev/isdninfo");
1285
1286         $idmap = <FILE>; chop $idmap;
1287         $chmap = <FILE>; chop $chmap;
1288         $drmap = <FILE>; chop $drmap;
1289         $usage = <FILE>; chop $usage;
1290         $flags = <FILE>; chop $flags;
1291         $phone = <FILE>; chop $phone;
1292
1293         $phone =~ s/^phone(\s*):(\s*)//;
1294
1295         @phonenumbers = split / /, $phone;
1296
1297         foreach (@phonenumbers) {
1298                 if ($_ ne '???') {
1299                         $count++;
1300                 }
1301         }
1302         close (FILE);
1303
1304         ## Connection status
1305         my $number;
1306         if ($count == 0) {
1307                 $number = 'none!';
1308         } elsif ($count == 1) {
1309                 $number = 'single';
1310         } else {
1311                 $number = 'dual';
1312         }
1313
1314         if (-e "${General::swroot}/red/active") {
1315                 $timestr = &General::age("${General::swroot}/red/active");
1316                 $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'connected'} - $number channel (<span class='ipcop_StatusBigRed'>$timestr</span>) $profileused</span>";
1317         } else {
1318                 if ($count == 0) {
1319                         if (-e "${General::swroot}/red/dial-on-demand") {
1320                                 $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'dod waiting'} $profileused</span>";
1321                         } else {
1322                                 $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'idle'} $profileused</span>";
1323                         }
1324                 } else {
1325                         $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'connecting'} $profileused</span>";
1326                 }
1327         }
1328     } elsif ($netsettings{'RED_TYPE'} eq "STATIC" || $pppsettings {'METHOD'} eq 'STATIC') {
1329         if (-e "${General::swroot}/red/active") {
1330                 $timestr = &General::age("${General::swroot}/red/active");
1331                 $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'connected'} (<span class='ipcop_StatusBigRed'>$timestr</span>) $profileused</span>";
1332         } else {
1333                 $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'idle'} $profileused</span>";
1334         }
1335     } elsif ( ( (-e "${General::swroot}/dhcpc/dhcpcd-$iface.pid") && $netsettings{'RED_TYPE'} ne 'PPTP' ) || 
1336         !system("/bin/ps -ef | /bin/grep -q '[p]ppd'") || !system("/bin/ps -ef | /bin/grep -q '[c]onnectioncheck'")) {
1337         if (-e "${General::swroot}/red/active") {
1338                 $timestr = &General::age("${General::swroot}/red/active");
1339                 if ($pppsettings{'TYPE'} =~ /^(modem|bewanadsl|conexantpciadsl|eagleusbadsl)$/) {
1340                         my $speed;
1341                         if ($pppsettings{'TYPE'} eq 'modem') {
1342                                 open(CONNECTLOG, "/var/log/connect.log");
1343                                 while (<CONNECTLOG>) {
1344                                         if (/CONNECT/) {
1345                                                 $speed = (split / /)[6];
1346                                         }
1347                                 }
1348                                 close (CONNECTLOG);
1349                         } elsif ($pppsettings{'TYPE'} eq 'bewanadsl') {
1350                                 $speed = `/usr/bin/unicorn_status | /bin/grep Rate | /usr/bin/cut -f2 -d ':'`;
1351                         } elsif ($pppsettings{'TYPE'} eq 'conexantpciadsl') {
1352                                 $speed = `/bin/cat /proc/net/atm/CnxAdsl:* | /bin/grep 'Line Rates' | /bin/sed -e 's+Line Rates:   Receive+Rx+' -e 's+Transmit+Tx+'`;
1353                         } elsif ($pppsettings{'TYPE'} eq 'eagleusbadsl') {
1354                                 $speed = `/usr/sbin/eaglestat | /bin/grep Rate`;
1355                         }
1356                         $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'connected'} (<span class='ipcop_StatusBigRed'>$timestr</span>) $profileused (\@$speed)</span>";
1357                 } else {
1358                         $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'connected'} (<span class='ipcop_StatusBigRed'>$timestr</span>) $profileused</span>";
1359                 }
1360         } else {
1361                 if (-e "${General::swroot}/red/dial-on-demand") {
1362                     $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'dod waiting'} $profileused</span>";
1363                 } else {
1364                     $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'connecting'} $profileused</span>";
1365                 }
1366         }
1367     } else {
1368         $connstate = "<span class='ipcop_StatusBig'>$Lang::tr{'idle'} $profileused</span>";
1369     }
1370     return $connstate;
1371 }
1372
1373 sub srtarray 
1374 # Darren Critchley - darrenc@telus.net - (c) 2003
1375 # &srtarray(SortOrder, AlphaNumeric, SortDirection, ArrayToBeSorted)
1376 # This subroutine will take the following parameters:
1377 #   ColumnNumber = the column which you want to sort on, starts at 1
1378 #   AlphaNumberic = a or n (lowercase) defines whether the sort should be alpha or numberic
1379 #   SortDirection = asc or dsc (lowercase) Ascending or Descending sort
1380 #   ArrayToBeSorted = the array that wants sorting
1381 #
1382 #   Returns an array that is sorted to your specs
1383 #
1384 #   If SortOrder is greater than the elements in array, then it defaults to the first element
1385
1386 {
1387         my ($colno, $alpnum, $srtdir, @tobesorted) = @_;
1388         my @tmparray;
1389         my @srtedarray;
1390         my $line;
1391         my $newline;
1392         my $ttlitems = scalar @tobesorted; # want to know the number of rows in the passed array
1393         if ($ttlitems < 1){ # if no items, don't waste our time lets leave
1394                 return (@tobesorted);
1395         }
1396         my @tmp = split(/\,/,$tobesorted[0]);
1397         $ttlitems = scalar @tmp; # this should be the number of elements in each row of the passed in array
1398
1399         # Darren Critchley - validate parameters
1400         if ($colno > $ttlitems){$colno = '1';}
1401         $colno--; # remove one from colno to deal with arrays starting at 0
1402         if($colno < 0){$colno = '0';}
1403         if ($alpnum ne '') { $alpnum = lc($alpnum); } else { $alpnum = 'a'; }
1404         if ($srtdir ne '') { $srtdir = lc($srtdir); } else { $srtdir = 'src'; }
1405
1406         foreach $line (@tobesorted)
1407         {
1408                 chomp($line);
1409                 if ($line ne '') {
1410                         my @temp = split(/\,/,$line);
1411                         # Darren Critchley - juggle the fields so that the one we want to sort on is first
1412                         my $tmpholder = $temp[0];
1413                         $temp[0] = $temp[$colno];
1414                         $temp[$colno] = $tmpholder;
1415                         $newline = "";
1416                         for ($ctr=0; $ctr < $ttlitems ; $ctr++) {
1417                                 $newline=$newline . $temp[$ctr] . ",";
1418                         }
1419                         chop($newline);
1420                         push(@tmparray,$newline);
1421                 }
1422         }
1423         if ($alpnum eq 'n') {
1424                 @tmparray = sort {$a <=> $b} @tmparray;
1425         } else {
1426                 @tmparray = (sort @tmparray);
1427         }
1428         foreach $line (@tmparray)
1429         {
1430                 chomp($line);
1431                 if ($line ne '') {
1432                         my @temp = split(/\,/,$line);
1433                         my $tmpholder = $temp[0];
1434                         $temp[0] = $temp[$colno];
1435                         $temp[$colno] = $tmpholder;
1436                         $newline = "";
1437                         for ($ctr=0; $ctr < $ttlitems ; $ctr++){
1438                                 $newline=$newline . $temp[$ctr] . ",";
1439                         }
1440                         chop($newline);
1441                         push(@srtedarray,$newline);
1442                 }
1443         }
1444
1445         if ($srtdir eq 'dsc') {
1446                 @tmparray = reverse(@srtedarray);
1447                 return (@tmparray);
1448         } else {
1449                 return (@srtedarray);
1450         }
1451 }
1452
1453 sub speedtouchversion
1454 {
1455         if (-f "/proc/bus/usb/devices")
1456         {
1457                 $speedtouch=`/bin/cat /proc/bus/usb/devices | /bin/grep 'Vendor=06b9 ProdID=4061' | /usr/bin/cut -d ' ' -f6`;
1458                 if ($speedtouch eq '') {
1459                         $speedtouch= $tr{'connect the modem'};
1460                 }
1461         } else {
1462                 $speedtouch='USB '.$tr{'not running'};
1463         }
1464         return $speedtouch
1465 }
1466
1467 sub CheckSortOrder {
1468 #Sorting of allocated leases
1469     if ($ENV{'QUERY_STRING'} =~ /^IPADDR|^ETHER|^HOSTNAME|^ENDTIME/ ) {
1470         my $newsort=$ENV{'QUERY_STRING'};
1471         &readhash("${swroot}/dhcp/settings", \%dhcpsettings);
1472         $act=$dhcpsettings{'SORT_LEASELIST'};
1473         #Reverse actual ?
1474         if ($act =~ $newsort) {
1475             if ($act !~ 'Rev') {$Rev='Rev'};
1476             $newsort.=$Rev
1477         };
1478
1479         $dhcpsettings{'SORT_LEASELIST'}=$newsort;
1480         &writehash("${swroot}/dhcp/settings", \%dhcpsettings);
1481         $dhcpsettings{'ACTION'} = 'SORT';  # avoid the next test "First lauch"
1482     }
1483
1484 }
1485
1486 sub PrintActualLeases
1487 {
1488     &openbox('100%', 'left', $tr{'current dynamic leases'});
1489     print <<END
1490 <table width='100%'>
1491 <tr>
1492 <td width='25%' align='center'><a href='$ENV{'SCRIPT_NAME'}?IPADDR'><b>$tr{'ip address'}</b></a></td>
1493 <td width='25%' align='center'><a href='$ENV{'SCRIPT_NAME'}?ETHER'><b>$tr{'mac address'}</b></a></td>
1494 <td width='20%' align='center'><a href='$ENV{'SCRIPT_NAME'}?HOSTNAME'><b>$tr{'hostname'}</b></a></td>
1495 <td width='30%' align='center'><a href='$ENV{'SCRIPT_NAME'}?ENDTIME'><b>$tr{'lease expires'} (local time d/m/y)</b></a></td>
1496 </tr>
1497 END
1498     ;
1499
1500     open(LEASES,"/var/state/dhcp/dhcpd.leases") or die "Can't open dhcpd.leases";
1501     while ($line = <LEASES>) {
1502         next if( $line =~ /^\s*#/ );
1503         chomp($line);
1504         @temp = split (' ', $line);
1505
1506         if ($line =~ /^\s*lease/) {
1507             $ip = $temp[1];
1508             #All field are not necessarily read. Clear everything
1509             $endtime = 0;
1510             $ether = "";
1511             $hostname = "";
1512         }
1513
1514         if ($line =~ /^\s*ends/) {
1515             $line =~ /(\d+)\/(\d+)\/(\d+) (\d+):(\d+):(\d+)/;
1516             $endtime = timegm($6, $5, $4, $3, $2 - 1, $1 - 1900);
1517         }
1518
1519         if ($line =~ /^\s*hardware ethernet/) {
1520             $ether = $temp[2];
1521             $ether =~ s/;//g;
1522         }
1523
1524         if ($line =~ /^\s*client-hostname/) {
1525             $hostname = "$temp[1] $temp[2] $temp[3]";
1526             $hostname =~ s/;//g;
1527             $hostname =~ s/\"//g;
1528         }
1529
1530         if ($line eq "}") {
1531             @record = ('IPADDR',$ip,'ENDTIME',$endtime,'ETHER',$ether,'HOSTNAME',$hostname);
1532             $record = {};                                       # create a reference to empty hash
1533             %{$record} = @record;                               # populate that hash with @record
1534             $entries{$record->{'IPADDR'}} = $record;    # add this to a hash of hashes
1535         }
1536     }
1537     close(LEASES);
1538
1539     my $id = 0;
1540     foreach my $key (sort leasesort keys %entries) {
1541
1542         my $hostname = &cleanhtml($entries{$key}->{HOSTNAME},"y");
1543
1544         if ($id % 2) {
1545             print "<tr bgcolor='$table1colour'>"; 
1546         }
1547         else {
1548             print "<tr bgcolor='$table2colour'>"; 
1549         }
1550
1551         print <<END
1552 <td align='center'>$entries{$key}->{IPADDR}</td>
1553 <td align='center'>$entries{$key}->{ETHER}</td>
1554 <td align='center'>&nbsp;$hostname </td>
1555 <td align='center'>
1556 END
1557         ;
1558
1559         ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $dst) = localtime ($entries{$key}->{ENDTIME});
1560         $enddate = sprintf ("%02d/%02d/%d %02d:%02d:%02d",$mday,$mon+1,$year+1900,$hour,$min,$sec);
1561
1562         if ($entries{$key}->{ENDTIME} < time() ){
1563             print "<strike>$enddate</strike>";
1564         } else {
1565             print "$enddate";
1566         }
1567         print "</td></tr>";
1568         $id++;
1569     }
1570
1571     print "</table>";
1572     &closebox();
1573 }
1574
1575
1576 # This sub is used during display of actives leases
1577 sub leasesort {
1578     if (rindex ($dhcpsettings{'SORT_LEASELIST'},'Rev') != -1)
1579     {
1580         $qs=substr ($dhcpsettings{'SORT_LEASELIST'},0,length($dhcpsettings{'SORT_LEASELIST'})-3);
1581         if ($qs eq 'IPADDR') {
1582             @a = split(/\./,$entries{$a}->{$qs});
1583             @b = split(/\./,$entries{$b}->{$qs});
1584             ($b[0]<=>$a[0]) ||
1585             ($b[1]<=>$a[1]) ||
1586             ($b[2]<=>$a[2]) ||
1587             ($b[3]<=>$a[3]);
1588         }else {
1589             $entries{$b}->{$qs} cmp $entries{$a}->{$qs};
1590         }
1591     }
1592     else #not reverse
1593     {
1594         $qs=$dhcpsettings{'SORT_LEASELIST'};
1595         if ($qs eq 'IPADDR') {
1596             @a = split(/\./,$entries{$a}->{$qs});
1597             @b = split(/\./,$entries{$b}->{$qs});
1598             ($a[0]<=>$b[0]) ||
1599             ($a[1]<=>$b[1]) ||
1600             ($a[2]<=>$b[2]) ||
1601             ($a[3]<=>$b[3]);
1602         }else {
1603             $entries{$a}->{$qs} cmp $entries{$b}->{$qs};
1604         }
1605     }
1606 }
1607
1608 sub get_uplinks() {
1609     my @uplinks = ();
1610     opendir(DIR, "${swroot}/uplinks/") || return \@uplinks;
1611     foreach my $dir (readdir(DIR)) {
1612         next if ($dir =~ /^\./);
1613         next if (-f "${swroot}/uplinks/$dir");
1614         push(@uplinks, $dir);
1615     }
1616     closedir(DIR);
1617     return \@uplinks;
1618 }
1619
1620 sub get_iface($) {
1621     my $filename = shift;
1622     chomp($filename);
1623     open (F, $filename) || return "";
1624     my $iface = <F>;
1625     close(F);
1626     chomp($iface);
1627     return $iface;
1628 }
1629
1630 sub get_red_ifaces_by_type($) {
1631     my $type=shift;
1632     my @gottypeiface = ();
1633     my @gottypeuplink = ();
1634     my @gottype = ();
1635
1636     my $ref=get_uplinks();
1637     my @uplinks=@$ref;
1638     my %set = ();
1639     foreach my $link (@uplinks) {
1640         eval {
1641             &readhash("${swroot}/uplinks/$link/settings", \%set);
1642         };
1643         push(@gottype, $link);
1644
1645         my $iface = $set{'RED_DEV'};
1646         if (!$iface) {
1647             $iface = get_iface("${swroot}/uplinks/$link/interface");
1648         }
1649         next if (!$iface);
1650
1651         if ($set{'RED_TYPE'} eq $type) {
1652             push(@gottypeiface, $iface);
1653             push(@gottypeuplink, $link);
1654         }
1655     }
1656     return (\@gottypeiface, \@gottypeuplink, \@gottype);
1657 }
1658
1659 sub get_red_ifaces() {
1660     return `cat ${swroot}/uplinks/*/interface 2>/dev/null`;
1661 }
1662
1663 sub get_zone_devices($) {
1664     my $bridge = shift;
1665     my @ifaces = ();
1666     open (FILE, "${swroot}/ethernet/$bridge") || return "";
1667     foreach my $line (<FILE>) {
1668         chomp($line);
1669         next if (!$line);
1670         push(@ifaces, $line);
1671     }
1672     close(FILE);
1673     return \@ifaces;
1674 }