#!/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 RRDs; 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"; require "${General::swroot}/graphs.pl"; my %qossettings = (); my %checked = (); my %netsettings = (); my $message = ''; my $errormessage = ""; my $c = ""; my $direntry = ""; my $classentry = ""; my $subclassentry = ""; my $l7ruleentry = ""; my $portruleentry = ""; my $tosruleentry = ""; my @tmp = (); my @classes = (); my @subclasses = (); my @l7rules = (); my @portrules = (); my @tosrules = (); my @tmpline = (); my @classline = (); my @subclassline = (); my @l7ruleline = (); my @portruleline = (); my @tosruleline = (); my @proto = (); my %selected= (); my @checked = (); my $classfile = "/var/ipfire/qos/classes"; my $subclassfile = "/var/ipfire/qos/subclasses"; my $level7file = "/var/ipfire/qos/level7config"; my $portfile = "/var/ipfire/qos/portconfig"; my $tosfile = "/var/ipfire/qos/tosconfig"; &General::readhash("${General::swroot}/ethernet/settings", \%netsettings); $qossettings{'ENABLED'} = 'off'; $qossettings{'EDIT'} = 'no'; $qossettings{'OUT_SPD'} = ''; $qossettings{'INC_SPD'} = ''; $qossettings{'DEF_OUT_SPD'} = ''; $qossettings{'DEF_INC_SPD'} = ''; $qossettings{'DEFCLASS_INC'} = ''; $qossettings{'DEFCLASS_OUT'} = ''; $qossettings{'ACK'} = ''; $qossettings{'RED_DEV'} = 'ppp0'; $qossettings{'IMQ_DEV'} = 'imq0'; $qossettings{'VALID'} = 'yes'; ### Values that have to be initialized $qossettings{'ACTION'} = ''; $qossettings{'ACTIONDEF'} = ''; $qossettings{'ACTIONBW'} = ''; $qossettings{'RED_DEV_SEL'} = ''; $qossettings{'IMQ_DEV_SEL'} = ''; $qossettings{'PRIO'} = ''; $qossettings{'SPD'} = ''; $qossettings{'CLASS'} = ''; $qossettings{'SCLASS'} = ''; $qossettings{'QPORT'} = ''; $qossettings{'DPORT'} = ''; $qossettings{'QIP'} = ''; $qossettings{'DIP'} = ''; $qossettings{'PPROT'} = ''; $qossettings{'L7PROT'} = ''; $qossettings{'DEVICE'} = ''; $qossettings{'MINBWDTH'} = ''; $qossettings{'MAXBWDTH'} = ''; $qossettings{'BURST'} = ''; $qossettings{'CBURST'} = ''; $qossettings{'DOCLASS'} = ''; $qossettings{'DOSCLASS'} = ''; $qossettings{'DOLEVEL7'} = ''; $qossettings{'DOPORT'} = ''; $qossettings{'CLASS'} = ''; $qossettings{'CLASSPRFX'} = ''; $qossettings{'DEV'} = ''; $qossettings{'TOS'} = ''; &General::readhash("${General::swroot}/qos/settings", \%qossettings); &Header::getcgihash(\%qossettings); $qossettings{'RED_DEV'} = `cat /var/ipfire/red/iface`; my %color = (); my %mainsettings = (); &General::readhash("${General::swroot}/main/settings", \%mainsettings); &General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color); my @querry = split(/\?/,$ENV{'QUERY_STRING'}); $querry[0] = '' unless defined $querry[0]; $querry[1] = 'hour' unless defined $querry[1]; if ( $querry[0] ne ""){ print "Content-type: image/png\n\n"; binmode(STDOUT); &Graphs::updateqosgraph($querry[0],$querry[1]); }else{ &Header::showhttpheaders(); &Header::openpage('QoS', 1, ''); &Header::openbigbox('100%', 'left', '', $errormessage); ############################################################################################################################ ############################################################################################################################ if ($qossettings{'DOCLASS'} eq $Lang::tr{'save'}) { &validclass(); &validminbwdth(); &validmaxbwdth(); if ( $qossettings{'VALID'} eq 'yes' ) { open( FILE, ">> $classfile" ) or die "Unable to write $classfile"; print FILE <; close FILE; open( FILE, "> $classfile" ) or die "Unable to write $classfile"; foreach $classentry (sort @classes) { @classline = split( /\;/, $classentry ); if ( $classline[1] ne $qossettings{'CLASS'} ) { print FILE $classentry; } else { $qossettings{'DEVICE'} = $classline[0]; $qossettings{'PRIO'} = $classline[2]; $qossettings{'MINBWDTH'} = $classline[3]; $qossettings{'MAXBWDTH'} = $classline[4]; $qossettings{'BURST'} = $classline[5]; $qossettings{'CBURST'} = $classline[6]; $qossettings{'TOS'} = $classline[7]; $qossettings{'REMARK'} = $classline[8]; $qossettings{'EDIT'} = 'yes'; } } close FILE; &parentclass(); &Header::closebigbox(); &Header::closepage(); exit } elsif ($qossettings{'DOCLASS'} eq $Lang::tr{'delete'}) { open( FILE, "< $classfile" ) or die "Unable to read $classfile"; @tmp = ; close FILE; open( FILE, "> $classfile" ) or die "Unable to write $classfile"; foreach $classentry (sort @tmp) { @tmpline = split( /\;/, $classentry ); if ( $tmpline[1] ne $qossettings{'CLASS'} ) { print FILE $classentry; } } close FILE; open( FILE, "< $subclassfile" ) or die "Unable to read $classfile"; @tmp = ; close FILE; open( FILE, "> $subclassfile" ) or die "Unable to write $classfile"; foreach $subclassentry (sort @tmp) { @tmpline = split( /\;/, $subclassentry ); if ( $tmpline[1] ne $qossettings{'CLASS'} ) { print FILE $subclassentry; } } close FILE; $message = "$Lang::tr{'Class'} $qossettings{'CLASS'} $Lang::tr{'Class was deleted'}"; } ############################################################################################################################ ############################################################################################################################ if ($qossettings{'DOSCLASS'} eq $Lang::tr{'save'}) { &validsubclass(); &validminbwdth(); if ( $qossettings{'VALID'} eq 'yes' ) { open( FILE, ">> $subclassfile" ) or die "Unable to write $subclassfile"; print FILE <; close FILE; open( FILE, "> $subclassfile" ) or die "Unable to write $classfile"; foreach $subclassentry (sort @tmp) { @tmpline = split( /\;/, $subclassentry ); if ( $tmpline[2] ne $qossettings{'CLASS'} ) { print FILE $subclassentry; } } close FILE; $message = "$Lang::tr{'Subclass'} $qossettings{'CLASS'} $Lang::tr{'was deleted'}."; } ############################################################################################################################ ############################################################################################################################ if ($qossettings{'DOLEVEL7'} eq $Lang::tr{'save'}) { if ( $qossettings{'QIP'} ne '' ) { if ((!&General::validipandmask($qossettings{'QIP'})) && (!&General::validip($qossettings{'QIP'}))) { $qossettings{'VALID'} = 'no'; $message = $Lang::tr{'The source IP address is invalid.'}; } } if ( $qossettings{'DIP'} ne '' ) { if ((!&General::validipandmask($qossettings{'DIP'})) && (!&General::validip($qossettings{'DIP'}))) { $qossettings{'VALID'} = 'no'; $message = $Lang::tr{'The destination IP address is invalid.'}; } } if ($qossettings{'CLASS'} >= 100 && $qossettings{'CLASS'} < 121) { $qossettings{'DEVICE'} = $qossettings{'RED_DEV'}; } elsif ($qossettings{'CLASS'} >= 1000 && $qossettings{'CLASS'} < 1021) { $qossettings{'DEVICE'} = $qossettings{'RED_DEV'}; } elsif ($qossettings{'CLASS'} >= 200 && $qossettings{'CLASS'} < 221) { $qossettings{'DEVICE'} = $qossettings{'IMQ_DEV'}; } elsif ($qossettings{'CLASS'} >= 2000 && $qossettings{'CLASS'} < 2021) { $qossettings{'DEVICE'} = $qossettings{'IMQ_DEV'}; } if ( $qossettings{'VALID'} eq 'yes' ) { open( FILE, ">> $level7file" ) or die "Unable to write $level7file"; print FILE <; close FILE; system("rm $level7file"); foreach $l7ruleentry (sort @l7rules) { @l7ruleline = split( /\;/, $l7ruleentry ); if ( ($l7ruleline[0] eq $qossettings{'CLASS'}) && ($l7ruleline[2] eq $qossettings{'L7PROT'})) {$message = "$Lang::tr{'Level7 Rule'} ($qossettings{'CLASS'} - $qossettings{'L7PROT'}) $Lang::tr{'was deleted'}.";} else { open( FILE, ">> $level7file" ) or die "Unable to read $level7file"; print FILE $l7ruleentry; close FILE; } } open( FILE, "< $level7file" ) or system("touch $level7file");close FILE; } elsif ($qossettings{'DOLEVEL7'} eq $Lang::tr{'edit'}) { open( FILE, "< $level7file" ) or die "Unable to read $level7file"; @l7rules = ; close FILE; system("rm $level7file"); foreach $l7ruleentry (sort @l7rules) { @l7ruleline = split( /\;/, $l7ruleentry ); if ( ($l7ruleline[0] eq $qossettings{'CLASS'}) && ($l7ruleline[2] eq $qossettings{'L7PROT'})) {$qossettings{'QIP'} = $l7ruleline[3];$qossettings{'DIP'} = $l7ruleline[4];} else { open( FILE, ">> $level7file" ) or die "Unable to write $level7file"; print FILE $l7ruleentry; close FILE; } } &level7rule; open( FILE, "< $level7file" ) or system("touch $level7file");close FILE; } ############################################################################################################################ ############################################################################################################################ if ($qossettings{'DOPORT'} eq $Lang::tr{'save'}) { if ( $qossettings{'QIP'} ne '' ) { if ((!&General::validipandmask($qossettings{'QIP'})) && (!&General::validip($qossettings{'QIP'}))) { $qossettings{'VALID'} = 'no'; $message = $Lang::tr{'The source IP address is invalid.'}; } } if ( $qossettings{'DIP'} ne '' ) { if ((!&General::validipandmask($qossettings{'DIP'})) && (!&General::validip($qossettings{'DIP'}))) { $qossettings{'VALID'} = 'no'; $message = $Lang::tr{'The destination IP address is invalid.'}; } } if ($qossettings{'CLASS'} >= 100 && $qossettings{'CLASS'} < 121) { $qossettings{'DEVICE'} = $qossettings{'RED_DEV'}; } elsif ($qossettings{'CLASS'} >= 1000 && $qossettings{'CLASS'} < 1021) { $qossettings{'DEVICE'} = $qossettings{'RED_DEV'}; } elsif ($qossettings{'CLASS'} >= 200 && $qossettings{'CLASS'} < 221) { $qossettings{'DEVICE'} = $qossettings{'IMQ_DEV'}; } elsif ($qossettings{'CLASS'} >= 2000 && $qossettings{'CLASS'} < 2021) { $qossettings{'DEVICE'} = $qossettings{'IMQ_DEV'}; } if ( $qossettings{'VALID'} eq 'yes' ) { open( FILE, ">> $portfile" ) or die "Unable to write $portfile"; print FILE <; close FILE; open( FILE, "> $portfile" ) or die "Unable to read $portfile"; foreach $portruleentry (sort @portrules) { @portruleline = split( /\;/, $portruleentry ); unless ( ($portruleline[0] eq $qossettings{'CLASS'}) && ($portruleline[2] eq $qossettings{'PPROT'}) && ($portruleline[3] eq $qossettings{'QIP'}) && ($portruleline[4] eq $qossettings{'QPORT'}) && ($portruleline[5] eq $qossettings{'DIP'}) && ($portruleline[6] eq $qossettings{'DPORT'})) { print FILE $portruleentry; } } close FILE; $message = "$Lang::tr{'Port Rule'} ($qossettings{'CLASS'} - $qossettings{'PPROT'}) $Lang::tr{'was deleted'}."; } elsif ($qossettings{'DOPORT'} eq $Lang::tr{'edit'}) { open( FILE, "< $portfile" ) or die "Unable to read $portfile"; @portrules = ; close FILE; system("rm $portfile"); foreach $portruleentry (sort @portrules) { @portruleline = split( /\;/, $portruleentry ); if ( ($portruleline[0] eq $qossettings{'CLASS'}) && ($portruleline[2] eq $qossettings{'PPROT'}) && ($portruleline[3] eq $qossettings{'QIP'}) && ($portruleline[4] eq $qossettings{'QPORT'}) && ($portruleline[5] eq $qossettings{'DIP'}) && ($portruleline[6] eq $qossettings{'DPORT'})) {$qossettings{'CLASS'}=$portruleline[0];$qossettings{'PPROT'}=$portruleline[2];$qossettings{'QIP'}=$portruleline[3];$qossettings{'QPORT'}=$portruleline[4];$qossettings{'DIP'}=$portruleline[5];$qossettings{'DPORT'}=$portruleline[6];} else { open( FILE, ">> $portfile" ) or die "Unable to write $portfile"; print FILE $portruleentry; close FILE; } } &portrule; open( FILE, "< $portfile" ) or system("touch $portfile");close FILE; } ############################################################################################################################ ############################################################################################################################ if ($qossettings{'DOTOS'} eq $Lang::tr{'save'}) { if ($qossettings{'CLASS'} >= 100 && $qossettings{'CLASS'} < 121) { $qossettings{'DEVICE'} = $qossettings{'RED_DEV'}; } elsif ($qossettings{'CLASS'} >= 1000 && $qossettings{'CLASS'} < 1021) { $qossettings{'DEVICE'} = $qossettings{'RED_DEV'}; } elsif ($qossettings{'CLASS'} >= 200 && $qossettings{'CLASS'} < 221) { $qossettings{'DEVICE'} = $qossettings{'IMQ_DEV'}; } elsif ($qossettings{'CLASS'} >= 2000 && $qossettings{'CLASS'} < 2021) { $qossettings{'DEVICE'} = $qossettings{'IMQ_DEV'}; } open( FILE, ">> $tosfile" ) or die "Unable to write $tosfile"; print FILE <; close FILE; open( FILE, "> $tosfile" ) or die "Unable to read $tosfile"; foreach $tosruleentry (sort @tosrules) { @tosruleline = split( /\;/, $tosruleentry ); unless ( ($tosruleline[0] eq $qossettings{'CLASS'}) && ($tosruleline[2] eq $qossettings{'TOS'})) { print FILE $tosruleentry; } } close FILE; $message = "$Lang::tr{'TOS Rule'} ($qossettings{'CLASS'} - $qossettings{'TOS'}) $Lang::tr{'was deleted'}."; } elsif ($qossettings{'DOTOS'} eq $Lang::tr{'edit'}) { open( FILE, "< $tosfile" ) or die "Unable to read $tosfile"; @tosrules = ; close FILE; open( FILE, "> $tosfile" ) or die "Unable to write $tosfile"; foreach $tosruleentry (sort @tosrules) { @tosruleline = split( /\;/, $tosruleentry ); if (( $tosruleline[0] eq $qossettings{'CLASS'} ) && ( $tosruleline[2] eq $qossettings{'TOS'} )) { $qossettings{'DEVICE'} = $tosruleline[1]; $qossettings{'CLASS'} = $tosruleline[0]; $qossettings{'TOS'} = $tosruleline[2]; $qossettings{'EDIT'} = 'yes'; } else { print FILE $tosruleentry; } } close FILE; &tosrule(); &Header::closebigbox(); &Header::closepage(); exit } ############################################################################################################################ ############################################################################################################################ if ($qossettings{'ACTION'} eq $Lang::tr{'start'}) { $qossettings{'ENABLED'} = 'on'; &General::writehash("${General::swroot}/qos/settings", \%qossettings); system("/usr/local/bin/qosctrl generate >/dev/null 2>&1"); system("/usr/local/bin/qosctrl start >/dev/null 2>&1"); system("logger -t ipfire 'QoS started'"); } elsif ($qossettings{'ACTION'} eq $Lang::tr{'stop'}) { $qossettings{'ENABLED'} = 'off'; &General::writehash("${General::swroot}/qos/settings", \%qossettings); system("/usr/local/bin/qosctrl stop >/dev/null 2>&1"); system("/usr/local/bin/qosctrl generate >/dev/null 2>&1"); system("logger -t ipfire 'QoS stopped'"); } elsif ($qossettings{'ACTION'} eq $Lang::tr{'restart'}) { if ($qossettings{'ENABLED'} eq 'on'){ system("/usr/local/bin/qosctrl stop >/dev/null 2>&1"); system("/usr/local/bin/qosctrl generate >/dev/null 2>&1"); system("/usr/local/bin/qosctrl start >/dev/null 2>&1"); system("logger -t ipfire 'QoS restarted'"); } } elsif ($qossettings{'ACTION'} eq $Lang::tr{'save'}) { if ($qossettings{'DEF_INC_SPD'} eq '') { $qossettings{'DEF_INC_SPD'} = int($qossettings{'INC_SPD'} * 0.9); } if ($qossettings{'DEF_OUT_SPD'} eq '') { $qossettings{'DEF_OUT_SPD'} = int($qossettings{'OUT_SPD'} * 0.9); } &General::writehash("${General::swroot}/qos/settings", \%qossettings); } elsif ($qossettings{'ACTION'} eq $Lang::tr{'template'} ) { if (($qossettings{'OUT_SPD'} > 0) && ($qossettings{'INC_SPD'} > 0)) { my @UP; #print "UP
"; for(my $i = 1; $i <= 10; $i++) { $UP[$i] = int($qossettings{'OUT_SPD'} / $i ); #print $i."=".$UP[$i]." "; } my @DOWN; #print "

Down
"; for(my $i = 1; $i <= 20; $i++) { $DOWN[$i] = int($qossettings{'INC_SPD'} / $i); #print $i."=".$DOWN[$i]." "; } open( FILE, "> $classfile" ) or die "Unable to write $classfile"; print FILE < $level7file" ) or die "Unable to write $level7file"; print FILE < $portfile" ) or die "Unable to write $portfile"; print FILE </dev/null 2>&1"); system("/usr/local/bin/qosctrl start >/dev/null 2>&1"); system("logger -t ipfire 'QoS started'"); } else { $message = $Lang::tr{'qos enter bandwidths'}; } } elsif ($qossettings{'ACTION'} eq $Lang::tr{'status'} ) { &Header::openbox('100%', 'left', 'QoS Status'); if ($qossettings{'ENABLED'} eq 'on'){ my $output = ""; $output = `/usr/local/bin/qosctrl status`; $output = &Header::cleanhtml($output,"y"); print "
$output
\n"; } else { print "$Lang::tr{'QoS not enabled'}"; } &Header::closebox(); &Header::closebigbox(); &Header::closepage(); exit } elsif ($qossettings{'ACTION'} eq $Lang::tr{'parentclass add'} ) { &parentclass(); &Header::closebigbox(); &Header::closepage(); exit } elsif ($qossettings{'ACTION'} eq $Lang::tr{'qos add subclass'}) { &subclass(); &Header::closebigbox(); &Header::closepage(); exit } elsif ($qossettings{'ACTION'} eq $Lang::tr{'Add Rule'}) { &Header::openbox('100%', 'center', $Lang::tr{'Add Rule'}); print < $Lang::tr{'Choose Rule'} END ; &Header::closebox(); print <