#!/usr/bin/perl # # IPFire CGIs # # This code is distributed under the terms of the GPL # # (c) The IPFire Team # 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"; my %qossettings = (); my %checked = (); my %netsettings = (); my $message = ""; my $errormessage = ""; my $c = ""; my $direntry = ""; my $classentry = ""; my $subclassentry = ""; my $l7ruleentry = ""; my @tmp = (); my @classes = (); my @subclasses = (); my @l7rules = (); my @tmpline = (); my @classline = (); my @subclassline = (); my @l7ruleline = (); my @proto = (); my %selected= () ; my $classfile = "/var/ipfire/qos/classes"; my $subclassfile = "/var/ipfire/qos/subclasses"; my $level7file = "/var/ipfire/qos/level7config"; &General::readhash("${General::swroot}/ethernet/settings", \%netsettings); &Header::showhttpheaders(); $qossettings{'ENABLED'} = 'off'; $qossettings{'EDIT'} = 'no'; $qossettings{'OUT_SPD'} = ''; $qossettings{'INC_SPD'} = ''; $qossettings{'DEFCLASS_INC'} = ''; $qossettings{'DEFCLASS_OUT'} = ''; $qossettings{'ACK'} = ''; $qossettings{'RED_DEV'} = `cat /var/ipfire/red/iface`; $qossettings{'IMQ_DEV'} = 'imq0'; $qossettings{'VALID'} = 'yes'; &General::readhash("${General::swroot}/qos/settings", \%qossettings); &Header::getcgihash(\%qossettings); &Header::openpage('QoS', 1, ''); print < END ; &Header::openbigbox('100%', 'left', '', $errormessage); if ($qossettings{'DO_CLASS'} 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{'EDIT'} = 'yes'; } } close FILE; &parentclass(); &Header::closebigbox(); &Header::closepage(); exit } elsif ($qossettings{'DO_CLASS'} eq 'Loeschen') { 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; $message = "Klasse $qossettings{'CLASS'} wurde geloescht."; } if ($qossettings{'DO_SCLASS'} eq $Lang::tr{'save'}) { if ($qossettings{'SCLASS'} >= 1000 && $qossettings{'CLASS'} < 1021) { $qossettings{'DEVICE'} = $qossettings{'RED_DEV'}; } elsif ($qossettings{'SCLASS'} >= 2000 && $qossettings{'CLASS'} < 2021) { $qossettings{'DEVICE'} = $qossettings{'IMQ_DEV'}; } &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 = "Unterklasse $qossettings{'CLASS'} wurde geloescht."; } if ($qossettings{'DO_LEVEL7'} eq $Lang::tr{'save'}) { if ( $qossettings{'QIP'} ne '' ) { unless ( &General::validip($qossettings{'QIP'}) ) { $qossettings{'VALID'} = 'no'; $message = "Die Quell-IP-Adresse ist ungueltig."; } } if ( $qossettings{'DIP'} ne '' ) { unless ( &General::validip($qossettings{'DIP'}) ) { $qossettings{'VALID'} = 'no'; $message = "Die Ziel-IP-Adresse ist ungueltig."; } } 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; open( FILE, "> $level7file" ) or die "Unable to read $level7file"; foreach $l7ruleentry (sort @l7rules) { @l7ruleline = split( /\;/, $l7ruleentry ); if ( ($l7ruleline[0] ne $qossettings{'CLASS'}) && ($l7ruleline[2] ne $qossettings{'L7PROT'})) { print FILE $l7ruleentry; } } close FILE; $message = "Level7-Regel ($qossettings{'CLASS'} - $qossettings{'L7PROT'}) wurde geloescht."; } if ($qossettings{'ACTION'} eq 'Start') { system("/bin/touch /var/ipfire/qos/enable"); $qossettings{'ENABLED'} = 'on'; &General::writehash("${General::swroot}/qos/settings", \%qossettings); } elsif ($qossettings{'ACTION'} eq 'Stop') { unlink "/var/ipfire/qos/enable"; $qossettings{'ENABLED'} = 'off'; &General::writehash("${General::swroot}/qos/settings", \%qossettings); } elsif ($qossettings{'ACTION'} eq $Lang::tr{'save'}) { &General::writehash("${General::swroot}/qos/settings", \%qossettings); } elsif ($qossettings{'ACTION'} eq 'Parentklasse hinzufuegen') { &parentclass(); &Header::closebigbox(); &Header::closepage(); exit } elsif ($qossettings{'ACTION'} eq 'Unterklasse hinzufuegen') { &subclass(); &Header::closebigbox(); &Header::closepage(); exit } elsif ($qossettings{'ACTION'} eq 'Level7-Regel hinzufuegen') { &level7rule(); &Header::closebigbox(); &Header::closepage(); exit } elsif ($qossettings{'ACTION'} eq 'Port-Regel hinzufuegen') { &portrule(); &Header::closebigbox(); &Header::closepage(); exit } if ($qossettings{'ACTION_BW'} eq 'Andern') { &changebandwidth(); &Header::closebigbox(); &Header::closepage(); exit } if ($qossettings{'ACTION_DEF'} eq 'Andern') { &changedefclasses(); &Header::closebigbox(); &Header::closepage(); exit } &General::readhash("${General::swroot}/qos/settings", \%qossettings); my $status = $Lang::tr{'stopped'}; my $statuscolor = $Header::colourred; if ( $qossettings{'ENABLED'} eq 'on' ) { $status = $Lang::tr{'running'}; $statuscolor = $Header::colourgreen; } if ( $netsettings{'RED_TYPE'} ne 'PPPOE' ) { $qossettings{'RED_DEV'} = $netsettings{'RED_DEV'}; } if ($errormessage) { &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); print "$errormessage\n"; print " \n"; &Header::closebox(); } ############################################################################################################################ ############################################################################################################################ &Header::openbox('100%', 'center', 'Quality of Service'); print < END ; if ( $message ne "" ) { print "
$message"; } print <Quality of Service: $status
END ; if (($qossettings{'OUT_SPD'} ne '') && ($qossettings{'INC_SPD'} ne '')) { print < 
Downloadgeschwindigkeit: $qossettings{'INC_SPD'} kbps
Uploadgeschwindigkeit: $qossettings{'OUT_SPD'} kbps END ; } if (($qossettings{'DEFCLASS_OUT'} ne '') && ($qossettings{'DEFCLASS_INC'} ne '')&& ($qossettings{'ACK'} ne '')) { print <
Downloadstandardklasse: $qossettings{'DEFCLASS_INC'}
Uploadstandardklasse: $qossettings{'DEFCLASS_OUT'}
ACKs: $qossettings{'ACK'}

END ; } print "
"; &Header::closebox(); if ( ($qossettings{'OUT_SPD'} eq '') || ($qossettings{'INC_SPD'} eq '') ) { &changebandwidth(); &Header::closebox(); &Header::closebigbox(); &Header::closepage(); exit } if ( ($qossettings{'DEFCLASS_INC'} eq '') || ($qossettings{'DEFCLASS_OUT'} eq '') || ($qossettings{'ACK'} eq '') ) { &changedefclasses(); &Header::closebigbox(); &Header::closepage(); exit } &showclasses(); &showl7rules(); &Header::closebigbox(); &Header::closepage(); ############################################################################################################################ ############################################################################################################################ sub changedefclasses { &Header::openbox('100%', 'center', 'Standardklassen:'); print <
Legen sie hier die Standardklassen fest durch die nicht-gefilterte Pakete gehen.
Download: 
Upload: 

Legen sie hier die ACK-Klasse fest
und klicken Sie danach auf Speichern.
ACKs:
END ; &Header::closebox(); } sub changebandwidth { &Header::openbox('100%', 'center', 'Bandbreiteneinstellungen'); if ($qossettings{'ENABLED'} eq 'on') { print "Sie koennen die Bandbreiteneinstellungen nicht bearbeiten, wenn QoS eingeschaltet ist. Schalten sie es zuerst dazu aus.

"; print "Zurueck"; } else { print <
Geben Sie bitte hier ihre Download- bzw. Upload-Geschwindigkeit ein
und klicken Sie danach auf Speichern.
Download-Geschwindigkeit:   kbps  
Upload-Geschwindigkeit:   kbps  
END ; } &Header::closebox(); } sub parentclass { &Header::openbox('100%', 'center', 'Parentklasse'); print < END ; if ( $message ne "" ) { print "
$message"; } if ( $qossettings{'EDIT'} eq 'yes' ) { print ""; print ""; } print <Geben sie die Daten ein
und klicken Sie danach auf Speichern.
Interface: END ; if ( $qossettings{'EDIT'} eq 'yes' ) { print ""; } if ( $qossettings{'DEVICE'} eq $qossettings{'RED_DEV'} ) { $qossettings{'RED_DEV_SEL'} = 'selected'; } elsif ( $qossettings{'DEVICE'} eq $qossettings{'IMQ_DEV'} ) { $qossettings{'IMQ_DEV_SEL'} = 'selected'; } print <$qossettings{'RED_DEV'}  
Klasse: END ; if ( $qossettings{'EDIT'} eq 'yes' ) { print ""; } for ( $c = 100 ; $c <= 120 ; $c++ ) { if ( $qossettings{'CLASS'} ne $c ) { print "\n"; } else { print "\n"; } } for ( $c = 200 ; $c <= 220 ; $c++ ) { if ( $qossettings{'CLASS'} ne $c ) { print "\n"; } else { print "\n"; } } print <  
Prioritaet:
Garantierte Bandbreite:  
Maximale Bandbreite:  
Burst:  
Ceilburst:  
END ; &Header::closebox(); } sub subclass { &Header::openbox('100%', 'center', 'Unterklasse'); print < END ; if ( $message ne "" ) { print "
$message"; } print <Aktuelle Klasse: $qossettings{'CLASS'}
Geben sie die Daten ein
und klicken Sie danach auf Speichern.
Unterklasse: 
Prioritaet:
Garantierte Bandbreite:  
Maximale Bandbreite:  
Burst:  
Ceilburst:  
END ; &Header::closebox(); } sub level7rule { &Header::openbox('100%', 'center', 'Level7-Regel'); print < END ; if ( $message ne "" ) { print "
$message"; } print <Aktuelle Klasse: $qossettings{'CLASS'}
Geben sie die Daten ein
und klicken Sie danach auf Speichern.
Protokoll:  
Quell-IP-Adresse:  
Ziel-IP-Adresse:
END ; &Header::closebox(); } sub portrule { &Header::openbox('100%', 'center', 'Port-Regel hinzufuegen'); print <
Geben sie die Daten ein
und klicken Sie danach auf Speichern.
Name:  
Protokoll:  
Quell-Port:  
Ziel-Port:  
Quell-IP-Adresse:  
Ziel-IP-Adresse:
END ; &Header::closebox(); } sub showclasses { open( FILE, "< $classfile" ) or die "Unable to read $classfile"; @classes = ; close FILE; if (@classes) { open( FILE, "< $subclassfile" ) or die "Unable to read $subclassfile"; @subclasses = ; close FILE; &Header::openbox('100%', 'center', 'Klassen'); print < Interface Klasse Prioritaet Garantierte Bandbreite Maximale Bandbreite Burst Ceil Burst Aktionen END ; foreach $classentry (sort @classes) { @classline = split( /\;/, $classentry ); if ( $classline[0] eq $qossettings{'RED_DEV'} ) { print < $classline[0] $classline[1] $classline[2] $classline[3] $classline[4] $classline[5] $classline[6]         END ; foreach $subclassentry (sort @subclasses) { @subclassline = split( /\;/, $subclassentry ); if ( $subclassline[1] eq $classline[1] ) { print < Subklasse: $subclassline[2] $subclassline[3] $subclassline[4] $subclassline[5] $subclassline[6] $subclassline[7]       END ; } } } } print "\t"; foreach $classentry (sort @classes) { @classline = split( /\;/, $classentry ); if ( $classline[0] eq $qossettings{'IMQ_DEV'} ) { print < $classline[0] $classline[1] $classline[2] $classline[3] $classline[4] $classline[5] $classline[6]         END ; foreach $subclassentry (sort @subclasses) { @subclassline = split( /\;/, $subclassentry ); if ( $subclassline[1] eq $classline[1] ) { print < Subklasse: $subclassline[2] $subclassline[3] $subclassline[4] $subclassline[5] $subclassline[6] $subclassline[7]       END ; } } } } print "\t\n"; &Header::closebox(); } } sub showl7rules { open( FILE, "< $level7file" ) or die "Unable to read $level7file"; @l7rules = ; close FILE; if (@l7rules) { &Header::openbox('100%', 'center', 'Level7-Regeln'); print < Interface Klasse Protokoll Quell-IP-Adresse Ziel-IP-Adresse Aktionen END ; foreach $l7ruleentry (sort @l7rules) { @l7ruleline = split( /\;/, $l7ruleentry ); if ( $l7ruleline[1] eq $qossettings{'RED_DEV'} ) { print < $l7ruleline[1] $l7ruleline[0] $l7ruleline[2] $l7ruleline[3] $l7ruleline[4]   END ; } } print "\t"; foreach $l7ruleentry (sort @l7rules) { @l7ruleline = split( /\;/, $l7ruleentry ); if ( $l7ruleline[1] eq $qossettings{'IMQ_DEV'} ) { print < $l7ruleline[1] $l7ruleline[0] $l7ruleline[2] $l7ruleline[3] $l7ruleline[4]   END ; } } print "\t\n"; &Header::closebox(); } } sub validminbwdth { if ( $qossettings{'VALID'} eq 'yes' ) { if ( $qossettings{'DEVICE'} eq $qossettings{'RED_DEV'} ) { $qossettings{'SPD'} = $qossettings{'OUT_SPD'}; } elsif ( $qossettings{'DEVICE'} eq $qossettings{'IMQ_DEV'} ) { $qossettings{'SPD'} = $qossettings{'INC_SPD'}; } unless ( ( $qossettings{'MINBDWTH'} >= 0 ) && ( $qossettings{'MINBDWTH'} <= $qossettings{'SPD'} ) ) { $qossettings{'VALID'} = 'no'; $message = "Mindestbandbreite ist ungueltig."; } $qossettings{'SPD'} = ''; } } sub validmaxbwdth { if ( $qossettings{'VALID'} eq 'yes' ) { if ( $qossettings{'DEVICE'} eq $qossettings{'RED_DEV'} ) { $qossettings{'SPD'} = $qossettings{'OUT_SPD'}; } elsif ( $qossettings{'DEVICE'} eq $qossettings{'IMQ_DEV'} ) { $qossettings{'SPD'} = $qossettings{'INC_SPD'}; } unless ( ( $qossettings{'MAXBDWTH'} >= 0 ) && ($qossettings{'MAXBDWTH'} >= $qossettings{'MINBDWTH'}) &&( $qossettings{'MAXBDWTH'} <= $qossettings{'SPD'} ) ) { $qossettings{'VALID'} = 'no'; $message = "Mamimalbandbreite ist ungueltig."; } $qossettings{'SPD'} = ''; } } sub validclass { if ( $qossettings{'VALID'} eq 'yes' ) { if ( $qossettings{'DEVICE'} eq $qossettings{'RED_DEV'} ) { if ($qossettings{'CLASS'} lt 100 || $qossettings{'CLASS'} ge 121) { $qossettings{'VALID'} = 'no'; $message = "Die Klassennummer passt nicht zum angegebenen Interface."; } } elsif ( $qossettings{'DEVICE'} eq $qossettings{'IMQ_DEV'} ) { if ($qossettings{'CLASS'} lt 200 || $qossettings{'CLASS'} ge 221) { $qossettings{'VALID'} = 'no'; $message = "Die Klassennummer passt nicht zum angegebenen Interface."; } } open( FILE, "< $classfile" ) or die "Unable to read $classfile"; @tmp = ; close FILE; foreach $classentry (sort @tmp) { @tmpline = split( /\;/, $classentry ); if ( $tmpline[1] eq $qossettings{'CLASS'} ) { $qossettings{'VALID'} = 'no'; $message = "Die aktuelle Klasse wird bereits verwendet."; last } } } } sub validsubclass { if ( $qossettings{'VALID'} eq 'yes' ) { open( FILE, "< $subclassfile" ) or die "Unable to read $subclassfile"; @tmp = ; close FILE; foreach $subclassentry (sort @tmp) { @tmpline = split( /\;/, $subclassentry ); if ( $tmpline[2] eq $qossettings{'SCLASS'} ) { $qossettings{'VALID'} = 'no'; $message = "Die aktuelle Klasse wird bereits verwendet."; last } } } }