From a5b0d8bf9eba230f06f2b09810cc04e0a39c58ae Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Wed, 6 Jul 2011 19:29:36 +0200 Subject: [PATCH] Added new routing cgi. --- config/rootfiles/common/apache2 | 1 + html/cgi-bin/routing.cgi | 446 ++++++++++++++++++++++++++++++++ langs/de/cgi-bin/de.pl | 2 + langs/en/cgi-bin/en.pl | 2 + langs/es/cgi-bin/es.pl | 2 + langs/fr/cgi-bin/fr.pl | 2 + langs/pl/cgi-bin/pl.pl | 2 + 7 files changed, 457 insertions(+) create mode 100644 html/cgi-bin/routing.cgi diff --git a/config/rootfiles/common/apache2 b/config/rootfiles/common/apache2 index 970598e38e..2eab3b5e72 100644 --- a/config/rootfiles/common/apache2 +++ b/config/rootfiles/common/apache2 @@ -1404,6 +1404,7 @@ srv/web/ipfire/cgi-bin/pppsetup.cgi srv/web/ipfire/cgi-bin/proxy.cgi srv/web/ipfire/cgi-bin/qos.cgi srv/web/ipfire/cgi-bin/remote.cgi +srv/web/ipfire/cgi-bin/routing.cgi srv/web/ipfire/cgi-bin/services.cgi srv/web/ipfire/cgi-bin/speed.cgi srv/web/ipfire/cgi-bin/system.cgi diff --git a/html/cgi-bin/routing.cgi b/html/cgi-bin/routing.cgi new file mode 100644 index 0000000000..86e04293a4 --- /dev/null +++ b/html/cgi-bin/routing.cgi @@ -0,0 +1,446 @@ +#!/usr/bin/perl +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007-2011 IPFire Team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +use strict; + +# enable only the following on debugging purpose +#use warnings; +#use CGI::Carp 'fatalsToBrowser'; + +require '/var/ipfire/general-functions.pl'; +require "${General::swroot}/lang.pl"; +require "${General::swroot}/header.pl"; + +#workaround to suppress a warning when a variable is used only once +my @dummy = ( ${Header::colouryellow} ); +undef (@dummy); + +# Files used +my $setting = "${General::swroot}/main/settings"; +our $datafile = "${General::swroot}/main/routing"; #(our: used in subroutine) + +my %color = (); +my %mainsettings = (); +&General::readhash("${General::swroot}/main/settings", \%mainsettings); +&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color); + +our %settings = (); + +$settings{'EN'} = ''; # reuse for dummy field in position zero +$settings{'IP'} = ''; +$settings{'GATEWAY'} = ''; +$settings{'REMARK'} = ''; +my @nosaved=('EN','IP','GATEWAY','REMARK'); # List here ALL setting2 fields. Mandatory + +$settings{'ACTION'} = ''; # add/edit/remove +$settings{'KEY1'} = ''; # point record for ACTION + +#Define each field that can be used to sort columns +my $sortstring='^IP|^GATEWAY|^REMARK'; +$settings{'SORT_GATEWAYLIST'} = 'GATEWAY'; +my $errormessage = ''; +my $warnmessage = ''; + +&Header::showhttpheaders(); + +#Get GUI values +&Header::getcgihash(\%settings); + +############### +# DEBUG DEBUG +#&Header::openbox('100%', 'left', 'DEBUG'); +#my $debugCount = 0; +#foreach my $line (sort keys %settings) { +#print "$line = $settings{$line}
\n"; +# $debugCount++; +#} +#print " Count: $debugCount\n"; +#&Header::closebox(); +# DEBUG DEBUG +############### + +# Load multiline data +our @current = (); +if (open(FILE, "$datafile")) { + @current = ; + close (FILE); +} + +## Settings1 Box not used... +&General::readhash("${General::swroot}/main/settings", \%settings); + + +## Now manipulate the multi-line list with Settings2 +# Basic actions are: +# toggle the check box +# add/update a new line +# begin editing a line +# remove a line + + +# Toggle enable/disable field. Field is in second position +if ($settings{'ACTION'} eq $Lang::tr{'toggle enable disable'}) { + #move out new line + chomp(@current[$settings{'KEY1'}]); + my @temp = split(/\,/,@current[$settings{'KEY1'}]); + + $temp[0] = $temp[0] ne '' ? '' : 'on'; # Toggle the field + @current[$settings{'KEY1'}] = join (',',@temp)."\n"; + $settings{'KEY1'} = ''; # End edit mode + + &General::log($Lang::tr{'routing config changed'}); + + #Save current + open(FILE, ">$datafile") or die 'routing datafile error'; + print FILE @current; + close(FILE); + + # Rebuild configuration file + &BuildConfiguration; +} + +if ($settings{'ACTION'} eq $Lang::tr{'add'}) { + +# Validate inputs + if (( !&General::validip($settings{'IP'})) and ( !&General::validipandmask($settings{'IP'}))){ + $errormessage = $Lang::tr{'invalid ip'}." / ".$Lang::tr{'invalid netmask'}; + } + + if ($settings{'IP'} =~ /0.0.0.0/){ + $errormessage = $Lang::tr{'invalid ip'}." - 0.0.0.0"; + } + + if( !&General::validip($settings{'GATEWAY'}) ) { + $errormessage = $Lang::tr{'invalid ip'}. " - ".$Lang::tr{'gateway ip'}; + } + + unless ($errormessage) { + if ($settings{'KEY1'} eq '') { #add or edit ? + unshift (@current, "$settings{'EN'},$settings{'IP'},$settings{'GATEWAY'},$settings{'REMARK'}\n"); + &General::log($Lang::tr{'routing config added'}); + } else { + @current[$settings{'KEY1'}] = "$settings{'EN'},$settings{'IP'},$settings{'GATEWAY'},$settings{'REMARK'}\n"; + $settings{'KEY1'} = ''; # End edit mode + &General::log($Lang::tr{'routing config changed'}); + } + + # Write changes to config file. + &SortDataFile; # sort newly added/modified entry + &BuildConfiguration; # then re-build routing + + #map ($settings{$_}='' ,@nosaved); # Clear fields + } +} + +if ($settings{'ACTION'} eq $Lang::tr{'edit'}) { + #move out new line + my $line = @current[$settings{'KEY1'}]; # KEY1 is the index in current + chomp($line); + my @temp = split(/\,/, $line); + $settings{'EN'}=$temp[0]; # Prepare the screen for editing + $settings{'IP'}=$temp[1]; + $settings{'GATEWAY'}=$temp[2]; + $settings{'REMARK'}=$temp[3]; + &BuildConfiguration; +} + +if ($settings{'ACTION'} eq $Lang::tr{'remove'}) { + splice (@current,$settings{'KEY1'},1); # Delete line + open(FILE, ">$datafile") or die 'route datafile error'; + print FILE @current; + close(FILE); + $settings{'KEY1'} = ''; # End remove mode + &General::log($Lang::tr{'route config changed'}); + + &BuildConfiguration; # then re-build conf which use new data +} + +## Check if sorting is asked +# If same column clicked, reverse the sort. +if ($ENV{'QUERY_STRING'} =~ /$sortstring/ ) { + my $newsort=$ENV{'QUERY_STRING'}; + my $actual=$settings{'SORT_GATEWAYLIST'}; + #Reverse actual sort ? + if ($actual =~ $newsort) { + my $Rev=''; + if ($actual !~ 'Rev') { + $Rev='Rev'; + } + $newsort.=$Rev; + } + $settings{'SORT_GATEWAYLIST'}=$newsort; + map (delete ($settings{$_}) ,(@nosaved,'ACTION','KEY1'));# Must never be saved + &General::writehash($setting, \%settings); + &SortDataFile; + $settings{'ACTION'} = 'SORT'; # Create an 'ACTION' + map ($settings{$_} = '' ,@nosaved,'KEY1'); # and reinit vars to empty +} + +if ($settings{'ACTION'} eq '' ) { # First launch from GUI + # Place here default value when nothing is initialized + $settings{'EN'} = 'on'; + $settings{'GATEWAY'} = ''; + $settings{'IP'} = ''; +} + +&Header::openpage($Lang::tr{'routing table entries'}, 1, ''); +&Header::openbigbox('100%', 'left', '', $errormessage); +my %checked=(); # Checkbox manipulations + +if ($errormessage) { + &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); + print "$errormessage "; + &Header::closebox(); +} + +# + +$checked{'EN'}{'on'} = ($settings{'EN'} eq '' ) ? '' : "checked='checked'"; + +my $buttontext = $Lang::tr{'add'}; +if ($settings{'KEY1'} ne '') { + $buttontext = $Lang::tr{'update'}; + &Header::openbox('100%', 'left', $Lang::tr{'Edit an existing route'}); +} else { + &Header::openbox('100%', 'left', $Lang::tr{'Add a route'}); +} + +#Edited line number (KEY1) passed until cleared by 'save' or 'remove' or 'new sort order' +print < + + + + + + + + + + + + + + + +
$Lang::tr{'host ip'} / $Lang::tr{'network'}: 
$Lang::tr{'gateway'}: $Lang::tr{'enabled'}
$Lang::tr{'remark'}: 
+
+ + + + +
+ +END +; +&Header::closebox(); + +&Header::openbox('100%', 'left', $Lang::tr{'routing table'}); +print < + + + + + + + +END +; + +# +# Print each line of @current list +# + +my $key = 0; +foreach my $line (@current) { + chomp($line); # remove newline + my @temp=split(/\,/,$line); + $temp[2] ='' unless defined $temp[2]; # not always populated + $temp[3] ='' unless defined $temp[2]; # not always populated + + #Choose icon for checkbox + my $gif = ''; + my $gdesc = ''; + if ($temp[0] ne '' ) { + $gif = 'on.gif'; + $gdesc = $Lang::tr{'click to disable'}; + } else { + $gif = 'off.gif'; + $gdesc = $Lang::tr{'click to enable'}; + } + + #Colorize each line + if ($settings{'KEY1'} eq $key) { + print ""; + } elsif ($key % 2) { + print ""; + } else { + print ""; + } + print <$temp[1] + + + + + + + + +END +; + $key++; +} +print "
$Lang::tr{'host ip'} / $Lang::tr{'network'}$Lang::tr{'gateway'}$Lang::tr{'remark'}$Lang::tr{'action'}
$temp[2]$temp[3] +
+ + + +
+
+
+ + + +
+
+
+ + + +
+
"; + +# If table contains entries, print 'Key to action icons' +if ($key) { +print < + +  $Lang::tr{'legend'}:  + $Lang::tr{ + $Lang::tr{'click to disable'} +    + $Lang::tr{ + $Lang::tr{'click to enable'} +    + $Lang::tr{ + $Lang::tr{'edit'} +    + $Lang::tr{ + $Lang::tr{'remove'} + + +END +; +} + +&Header::closebox(); + +my $output = `/sbin/ip route show table static`; +$output = &Header::cleanhtml($output,"y"); + +if ( $output != "" ) { + &Header::openbox('100%', 'left', $Lang::tr{'routing table entries'}); + print "
$output
\n"; + &Header::closebox(); +} + +&Header::closebigbox(); +&Header::closepage(); + +## Ouf it's the end ! + +# Sort the "current" array according to choices +sub SortDataFile +{ + our %entries = (); + + # Sort pair of record received in $a $b special vars. + # When IP is specified use numeric sort else alpha. + # If sortname ends with 'Rev', do reverse sort. + # + sub fixedleasesort { + my $qs=''; # The sort field specified minus 'Rev' + if (rindex ($settings{'SORT_GATEWAYLIST'},'Rev') != -1) { + $qs=substr ($settings{'SORT_GATEWAYLIST'},0,length($settings{'SORT_GATEWAYLIST'})-3); + if ($qs eq 'IP') { + my @a = split(/\./,$entries{$a}->{$qs}); + my @b = split(/\./,$entries{$b}->{$qs}); + ($b[0]<=>$a[0]) || + ($b[1]<=>$a[1]) || + ($b[2]<=>$a[2]) || + ($b[3]<=>$a[3]); + } else { + $entries{$b}->{$qs} cmp $entries{$a}->{$qs}; + } + } else { #not reverse + $qs=$settings{'SORT_GATEWAYLIST'}; + if ($qs eq 'IP') { + my @a = split(/\./,$entries{$a}->{$qs}); + my @b = split(/\./,$entries{$b}->{$qs}); + ($a[0]<=>$b[0]) || + ($a[1]<=>$b[1]) || + ($a[2]<=>$b[2]) || + ($a[3]<=>$b[3]); + } else { + $entries{$a}->{$qs} cmp $entries{$b}->{$qs}; + } + } + } + + #Use an associative array (%entries) + my $key = 0; + foreach my $line (@current) { + chomp( $line); #remove newline because can be on field 5 or 6 (addition of REMARK) + my @temp = ( '','','', ''); + @temp = split (',',$line); + + # Build a pair 'Field Name',value for each of the data dataline. + # Each SORTABLE field must have is pair. + # Other data fields (non sortable) can be grouped in one + + my @record = ('KEY',$key++,'EN',$temp[0],'IP',$temp[1],'GATEWAY',$temp[2],'REMARK',$temp[3]); + my $record = {}; # create a reference to empty hash + %{$record} = @record; # populate that hash with @record + $entries{$record->{KEY}} = $record; # add this to a hash of hashes + } + + open(FILE, ">$datafile") or die 'routing datafile error'; + + # Each field value is printed , with the newline ! Don't forget separator and order of them. + foreach my $entry (sort fixedleasesort keys %entries) { + print FILE "$entries{$entry}->{EN},$entries{$entry}->{IP},$entries{$entry}->{GATEWAY},$entries{$entry}->{REMARK}\n"; + } + + close(FILE); + # Reload sorted @current + open (FILE, "$datafile"); + @current = ; + close (FILE); +} + +# +# Build the configuration file +# +sub BuildConfiguration { + system '/usr/local/bin/rebuildroutes'; +} \ No newline at end of file diff --git a/langs/de/cgi-bin/de.pl b/langs/de/cgi-bin/de.pl index d97dee037f..34d7b03004 100644 --- a/langs/de/cgi-bin/de.pl +++ b/langs/de/cgi-bin/de.pl @@ -2,6 +2,8 @@ %tr, 'Act as' => 'Konfiguriert als', +'Edit an existing route' => 'Eine existierende Route editieren', +'Add a route' => 'Eine Route hinzufügen', 'Add Level7 rule' => 'Level7-Regel hinzufügen', 'Add Port Rule' => 'Port Regel hinzufügen', 'Add Rule' => 'Regel hinzufügen', diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl index 67451bef48..46b10a1bdb 100644 --- a/langs/en/cgi-bin/en.pl +++ b/langs/en/cgi-bin/en.pl @@ -4,6 +4,8 @@ 'Act as' => 'Act as:', 'Add Level7 rule' => 'Add Level7 rule', 'Add Port Rule' => 'Add port rule', +'Edit an existing route' => 'Edit an existing route', +'Add a route' => 'Add a route', 'Add Rule' => 'Add rule', 'Async logging enabled' => 'Enable asynchronous writing of the syslog file', 'Choose Rule' => 'Choose one of the following rules.', diff --git a/langs/es/cgi-bin/es.pl b/langs/es/cgi-bin/es.pl index 41c0917f50..3f0fe78d32 100644 --- a/langs/es/cgi-bin/es.pl +++ b/langs/es/cgi-bin/es.pl @@ -5,6 +5,8 @@ 'Add Level7 rule' => 'añadir regla de Nivel 7', 'Add Port Rule' => 'Añadir Regla de Puerto', 'Add Rule' => 'Añadir Regla', +'Edit an existing route' => 'Editar una route existente', +'Add a route' => 'Añadir una route', 'Choose Rule' => 'Seleccione una de las siguientes reglas.', 'Class' => 'Clase', 'Class was deleted' => 'con subclases potenciales fué eliminado', diff --git a/langs/fr/cgi-bin/fr.pl b/langs/fr/cgi-bin/fr.pl index 62bfb28d70..bfc2cc5fac 100644 --- a/langs/fr/cgi-bin/fr.pl +++ b/langs/fr/cgi-bin/fr.pl @@ -5,6 +5,8 @@ 'Add Level7 rule' => 'Ajouter une règle Level7', 'Add Port Rule' => 'Ajouter une règle de port', 'Add Rule' => 'Ajouter une règle', +'Edit an existing route' => 'Modifier une route existante', +'Add a route' => 'Ajouter une route', 'Async logging enabled' => 'Activer l\'écriture asynchrone du fichier syslog', 'Choose Rule' => 'Choisissez une des règles suivantes.', 'Class' => 'Classe', diff --git a/langs/pl/cgi-bin/pl.pl b/langs/pl/cgi-bin/pl.pl index 8283fa330e..31bff32e14 100644 --- a/langs/pl/cgi-bin/pl.pl +++ b/langs/pl/cgi-bin/pl.pl @@ -8,6 +8,8 @@ 'Async logging enabled' => 'WłÄ…cz asynchroniczny zapis do pliku syslog', 'Choose Rule' => 'Wybierz jedną z poniższych reguł.', 'Class' => 'Klasa', +'Edit an existing route' => 'Edytuj istniejaca trase', +'Add a route' => 'Dodaj trase', 'Class was deleted' => 'wraz z ewentualnymi podklasami została usunięta', 'Client status and controlc' => 'Client status and control:', 'ConnSched action' => 'Zadanie:', -- 2.39.2