]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - html/cgi-bin/firewall.cgi
firewall.cgi: Add support for GeoIP locations / GeoIP groups.
[ipfire-2.x.git] / html / cgi-bin / firewall.cgi
index 3eac4f9d614db8d5684d65a4379938a7860c8a8c..12152700fb15c0a71487a1761554d9402c5bf63a 100644 (file)
 
 use strict;
 use Sort::Naturally;
+use utf8;
+use feature 'unicode_strings';
+
 no warnings 'uninitialized';
+
 # enable only the following on debugging purpose
 #use warnings;
 #use CGI::Carp 'fatalsToBrowser';
@@ -29,6 +33,7 @@ no warnings 'uninitialized';
 require '/var/ipfire/general-functions.pl';
 require "${General::swroot}/lang.pl";
 require "${General::swroot}/header.pl";
+require "${General::swroot}/geoip-functions.pl";
 require "/usr/lib/firewall/firewall-lib.pl";
 
 unless (-d "${General::swroot}/firewall")                      { system("mkdir ${General::swroot}/firewall"); }
@@ -43,6 +48,7 @@ my %defaultNetworks=();
 my %netsettings=();
 my %customhost=();
 my %customgrp=();
+my %customgeoipgrp=();
 my %customnetworks=();
 my %customservice=();
 my %customservicegrp=();
@@ -69,6 +75,7 @@ my $color;
 my $confignet          = "${General::swroot}/fwhosts/customnetworks";
 my $confighost         = "${General::swroot}/fwhosts/customhosts";
 my $configgrp          = "${General::swroot}/fwhosts/customgroups";
+my $configgeoipgrp     = "${General::swroot}/fwhosts/customgeoipgrp";
 my $configsrv          = "${General::swroot}/fwhosts/customservices";
 my $configsrvgrp       = "${General::swroot}/fwhosts/customservicegrp";
 my $configccdnet       = "${General::swroot}/ovpn/ccd.conf";
@@ -97,7 +104,7 @@ my @protocols;
 &General::readhasharray("$configipsec", \%ipsecconf);
 &Header::showhttpheaders();
 &Header::getcgihash(\%fwdfwsettings);
-&Header::openpage($Lang::tr{'fwdfw menu'}, 1, '');
+&Header::openpage($Lang::tr{'firewall rules'}, 1, '');
 &Header::openbigbox('100%', 'center',$errormessage);
 #### JAVA SCRIPT ####
 print<<END;
@@ -157,6 +164,22 @@ print<<END;
                        \$("#TIME_CONSTRAINTS").toggle();
                });
 
+               // Limit concurrent connections per ip
+               if(!\$("#USE_LIMIT_CONCURRENT_CONNECTIONS_PER_IP").attr("checked")) {
+                       \$("#LIMIT_CON").hide();
+               }
+               \$("#USE_LIMIT_CONCURRENT_CONNECTIONS_PER_IP").change(function() {
+                       \$("#LIMIT_CON").toggle();
+               });
+
+               // Rate-limit new connections
+               if(!\$("#USE_RATELIMIT").attr("checked")) {
+                       \$("#RATELIMIT").hide();
+               }
+               \$("#USE_RATELIMIT").change(function() {
+                       \$("#RATELIMIT").toggle();
+               });
+
                // Automatically select radio buttons when corresponding
                // dropdown menu changes.
                \$("select").change(function() {
@@ -218,12 +241,15 @@ if ($fwdfwsettings{'ACTION'} eq 'saverule')
                #check if we have an identical rule already
                if($fwdfwsettings{'oldrulenumber'} eq $fwdfwsettings{'rulepos'}){
                        foreach my $key (sort keys %configinputfw){
-                               if (   "$fwdfwsettings{'RULE_ACTION'},$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USE_SRC_PORT'},$fwdfwsettings{'PROT'},$fwdfwsettings{'ICMP_TYPES'},$fwdfwsettings{'SRC_PORT'},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'ICMP_TGT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'LOG'},$fwdfwsettings{'TIME'},$fwdfwsettings{'TIME_MON'},$fwdfwsettings{'TIME_TUE'},$fwdfwsettings{'TIME_WED'},$fwdfwsettings{'TIME_THU'},$fwdfwsettings{'TIME_FRI'},$fwdfwsettings{'TIME_SAT'},$fwdfwsettings{'TIME_SUN'},$fwdfwsettings{'TIME_FROM'},$fwdfwsettings{'TIME_TO'},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'}"
-                                       eq "$configinputfw{$key}[0],$configinputfw{$key}[2],$configinputfw{$key}[3],$configinputfw{$key}[4],$configinputfw{$key}[5],$configinputfw{$key}[6],$configinputfw{$key}[7],$configinputfw{$key}[8],$configinputfw{$key}[9],$configinputfw{$key}[10],$configinputfw{$key}[11],$configinputfw{$key}[12],$configinputfw{$key}[13],$configinputfw{$key}[14],$configinputfw{$key}[15],$configinputfw{$key}[17],$configinputfw{$key}[18],$configinputfw{$key}[19],$configinputfw{$key}[20],$configinputfw{$key}[21],$configinputfw{$key}[22],$configinputfw{$key}[23],$configinputfw{$key}[24],$configinputfw{$key}[25],$configinputfw{$key}[26],$configinputfw{$key}[27],$configinputfw{$key}[28],$configinputfw{$key}[29],$configinputfw{$key}[30],$configinputfw{$key}[31]"){
+                               if (   "$fwdfwsettings{'RULE_ACTION'},$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USE_SRC_PORT'},$fwdfwsettings{'PROT'},$fwdfwsettings{'ICMP_TYPES'},$fwdfwsettings{'SRC_PORT'},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'ICMP_TGT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'LOG'},$fwdfwsettings{'TIME'},$fwdfwsettings{'TIME_MON'},$fwdfwsettings{'TIME_TUE'},$fwdfwsettings{'TIME_WED'},$fwdfwsettings{'TIME_THU'},$fwdfwsettings{'TIME_FRI'},$fwdfwsettings{'TIME_SAT'},$fwdfwsettings{'TIME_SUN'},$fwdfwsettings{'TIME_FROM'},$fwdfwsettings{'TIME_TO'},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'},$fwdfwsettings{'LIMIT_CON_CON'},$fwdfwsettings{'concon'},$fwdfwsettings{'RATE_LIMIT'},$fwdfwsettings{'ratecon'},$fwdfwsettings{'RATETIME'}"
+                                       eq "$configinputfw{$key}[0],$configinputfw{$key}[2],$configinputfw{$key}[3],$configinputfw{$key}[4],$configinputfw{$key}[5],$configinputfw{$key}[6],$configinputfw{$key}[7],$configinputfw{$key}[8],$configinputfw{$key}[9],$configinputfw{$key}[10],$configinputfw{$key}[11],$configinputfw{$key}[12],$configinputfw{$key}[13],$configinputfw{$key}[14],$configinputfw{$key}[15],$configinputfw{$key}[17],$configinputfw{$key}[18],$configinputfw{$key}[19],$configinputfw{$key}[20],$configinputfw{$key}[21],$configinputfw{$key}[22],$configinputfw{$key}[23],$configinputfw{$key}[24],$configinputfw{$key}[25],$configinputfw{$key}[26],$configinputfw{$key}[27],$configinputfw{$key}[28],$configinputfw{$key}[29],$configinputfw{$key}[30],$configinputfw{$key}[31],$configinputfw{$key}[32],$configinputfw{$key}[33],$configinputfw{$key}[34],$configinputfw{$key}[35],$configinputfw{$key}[36]"){
                                                $errormessage.=$Lang::tr{'fwdfw err ruleexists'};
                                                if($fwdfwsettings{'oldruleremark'} ne $fwdfwsettings{'ruleremark'} && $fwdfwsettings{'updatefwrule'} eq 'on' && $fwdfwsettings{'ruleremark'} ne '' && !&validremark($fwdfwsettings{'ruleremark'})){
                                                        $errormessage=$Lang::tr{'fwdfw err remark'}."<br>";
                                                }
+                                               if($fwdfwsettings{'oldruleremark'} ne $fwdfwsettings{'ruleremark'} && $fwdfwsettings{'updatefwrule'} eq 'on' && $fwdfwsettings{'ruleremark'} ne '' && &validremark($fwdfwsettings{'ruleremark'})){
+                                                       $errormessage='';
+                                               }
                                                if ($fwdfwsettings{'oldruleremark'} eq $fwdfwsettings{'ruleremark'}){
                                                        $fwdfwsettings{'nosave'} = 'on';
                                                }
@@ -234,14 +260,14 @@ if ($fwdfwsettings{'ACTION'} eq 'saverule')
                if($fwdfwsettings{'rulepos'} > 0 && !$fwdfwsettings{'oldrulenumber'}){
                        $fwdfwsettings{'oldrulenumber'}=$maxkey;
                        foreach my $key (sort keys %configinputfw){
-                               if (   "$fwdfwsettings{'RULE_ACTION'},$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USE_SRC_PORT'},$fwdfwsettings{'PROT'},$fwdfwsettings{'ICMP_TYPES'},$fwdfwsettings{'SRC_PORT'},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'ICMP_TGT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'LOG'},$fwdfwsettings{'TIME'},$fwdfwsettings{'TIME_MON'},$fwdfwsettings{'TIME_TUE'},$fwdfwsettings{'TIME_WED'},$fwdfwsettings{'TIME_THU'},$fwdfwsettings{'TIME_FRI'},$fwdfwsettings{'TIME_SAT'},$fwdfwsettings{'TIME_SUN'},$fwdfwsettings{'TIME_FROM'},$fwdfwsettings{'TIME_TO'},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'}"
-                                       eq "$configinputfw{$key}[0],$configinputfw{$key}[2],$configinputfw{$key}[3],$configinputfw{$key}[4],$configinputfw{$key}[5],$configinputfw{$key}[6],$configinputfw{$key}[7],$configinputfw{$key}[8],$configinputfw{$key}[9],$configinputfw{$key}[10],$configinputfw{$key}[11],$configinputfw{$key}[12],$configinputfw{$key}[13],$configinputfw{$key}[14],$configinputfw{$key}[15],$configinputfw{$key}[17],$configinputfw{$key}[18],$configinputfw{$key}[19],$configinputfw{$key}[20],$configinputfw{$key}[21],$configinputfw{$key}[22],$configinputfw{$key}[23],$configinputfw{$key}[24],$configinputfw{$key}[25],$configinputfw{$key}[26],$configinputfw{$key}[27],$configinputfw{$key}[28],$configinputfw{$key}[29],$configinputfw{$key}[30],$configinputfw{$key}[31]"){
+                               if (   "$fwdfwsettings{'RULE_ACTION'},$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USE_SRC_PORT'},$fwdfwsettings{'PROT'},$fwdfwsettings{'ICMP_TYPES'},$fwdfwsettings{'SRC_PORT'},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'ICMP_TGT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'LOG'},$fwdfwsettings{'TIME'},$fwdfwsettings{'TIME_MON'},$fwdfwsettings{'TIME_TUE'},$fwdfwsettings{'TIME_WED'},$fwdfwsettings{'TIME_THU'},$fwdfwsettings{'TIME_FRI'},$fwdfwsettings{'TIME_SAT'},$fwdfwsettings{'TIME_SUN'},$fwdfwsettings{'TIME_FROM'},$fwdfwsettings{'TIME_TO'},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'},$fwdfwsettings{'LIMIT_CON_CON'},$fwdfwsettings{'concon'},$fwdfwsettings{'RATE_LIMIT'},$fwdfwsettings{'ratecon'},$fwdfwsettings{'RATETIME'}"
+                                       eq "$configinputfw{$key}[0],$configinputfw{$key}[2],$configinputfw{$key}[3],$configinputfw{$key}[4],$configinputfw{$key}[5],$configinputfw{$key}[6],$configinputfw{$key}[7],$configinputfw{$key}[8],$configinputfw{$key}[9],$configinputfw{$key}[10],$configinputfw{$key}[11],$configinputfw{$key}[12],$configinputfw{$key}[13],$configinputfw{$key}[14],$configinputfw{$key}[15],$configinputfw{$key}[17],$configinputfw{$key}[18],$configinputfw{$key}[19],$configinputfw{$key}[20],$configinputfw{$key}[21],$configinputfw{$key}[22],$configinputfw{$key}[23],$configinputfw{$key}[24],$configinputfw{$key}[25],$configinputfw{$key}[26],$configinputfw{$key}[27],$configinputfw{$key}[28],$configinputfw{$key}[29],$configinputfw{$key}[30],$configinputfw{$key}[31],$configinputfw{$key}[32],$configinputfw{$key}[33],$configinputfw{$key}[34],$configinputfw{$key}[35],$configinputfw{$key}[36]"){
                                                $errormessage.=$Lang::tr{'fwdfw err ruleexists'};
                                }
                        }
                }
                #check if we just close a rule
-               if( $fwdfwsettings{'oldgrp1a'} eq  $fwdfwsettings{'grp1'} && $fwdfwsettings{'oldgrp1b'} eq $fwdfwsettings{$fwdfwsettings{'grp1'}} && $fwdfwsettings{'oldgrp2a'} eq  $fwdfwsettings{'grp2'} && $fwdfwsettings{'oldgrp2b'} eq $fwdfwsettings{$fwdfwsettings{'grp2'}} &&  $fwdfwsettings{'oldgrp3a'} eq $fwdfwsettings{'grp3'} && $fwdfwsettings{'oldgrp3b'} eq  $fwdfwsettings{$fwdfwsettings{'grp3'}} && $fwdfwsettings{'oldusesrv'} eq $fwdfwsettings{'USESRV'} && $fwdfwsettings{'oldruleremark'} eq $fwdfwsettings{'ruleremark'} && $fwdfwsettings{'oldruletype'} eq $fwdfwsettings{'chain'}) {
+               if( $fwdfwsettings{'oldgrp1a'} eq  $fwdfwsettings{'grp1'} && $fwdfwsettings{'oldgrp1b'} eq $fwdfwsettings{$fwdfwsettings{'grp1'}} && $fwdfwsettings{'oldgrp2a'} eq  $fwdfwsettings{'grp2'} && $fwdfwsettings{'oldgrp2b'} eq $fwdfwsettings{$fwdfwsettings{'grp2'}} &&  $fwdfwsettings{'oldgrp3a'} eq $fwdfwsettings{'grp3'} && $fwdfwsettings{'oldgrp3b'} eq  $fwdfwsettings{$fwdfwsettings{'grp3'}} && $fwdfwsettings{'oldusesrv'} eq $fwdfwsettings{'USESRV'} && $fwdfwsettings{'oldruleremark'} eq $fwdfwsettings{'ruleremark'} && $fwdfwsettings{'oldruletype'} eq $fwdfwsettings{'chain'} ) {
                        if($fwdfwsettings{'nosave'} eq 'on' && $fwdfwsettings{'updatefwrule'} eq 'on'){
                                $errormessage='';
                                $fwdfwsettings{'nosave2'} = 'on';
@@ -259,12 +285,15 @@ if ($fwdfwsettings{'ACTION'} eq 'saverule')
                my $maxkey=&General::findhasharraykey(\%configoutgoingfw);
                if($fwdfwsettings{'oldrulenumber'} eq $fwdfwsettings{'rulepos'}){
                        foreach my $key (sort keys %configoutgoingfw){
-                               if (   "$fwdfwsettings{'RULE_ACTION'},$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USE_SRC_PORT'},$fwdfwsettings{'PROT'},$fwdfwsettings{'ICMP_TYPES'},$fwdfwsettings{'SRC_PORT'},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'ICMP_TGT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'LOG'},$fwdfwsettings{'TIME'},$fwdfwsettings{'TIME_MON'},$fwdfwsettings{'TIME_TUE'},$fwdfwsettings{'TIME_WED'},$fwdfwsettings{'TIME_THU'},$fwdfwsettings{'TIME_FRI'},$fwdfwsettings{'TIME_SAT'},$fwdfwsettings{'TIME_SUN'},$fwdfwsettings{'TIME_FROM'},$fwdfwsettings{'TIME_TO'},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'}"
-                                       eq "$configoutgoingfw{$key}[0],$configoutgoingfw{$key}[2],$configoutgoingfw{$key}[3],$configoutgoingfw{$key}[4],$configoutgoingfw{$key}[5],$configoutgoingfw{$key}[6],$configoutgoingfw{$key}[7],$configoutgoingfw{$key}[8],$configoutgoingfw{$key}[9],$configoutgoingfw{$key}[10],$configoutgoingfw{$key}[11],$configoutgoingfw{$key}[12],$configoutgoingfw{$key}[13],$configoutgoingfw{$key}[14],$configoutgoingfw{$key}[15],$configoutgoingfw{$key}[17],$configoutgoingfw{$key}[18],$configoutgoingfw{$key}[19],$configoutgoingfw{$key}[20],$configoutgoingfw{$key}[21],$configoutgoingfw{$key}[22],$configoutgoingfw{$key}[23],$configoutgoingfw{$key}[24],$configoutgoingfw{$key}[25],$configoutgoingfw{$key}[26],$configoutgoingfw{$key}[27],$configoutgoingfw{$key}[28],$configoutgoingfw{$key}[29],$configoutgoingfw{$key}[30],$configoutgoingfw{$key}[31]"){
+                               if (   "$fwdfwsettings{'RULE_ACTION'},$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USE_SRC_PORT'},$fwdfwsettings{'PROT'},$fwdfwsettings{'ICMP_TYPES'},$fwdfwsettings{'SRC_PORT'},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'ICMP_TGT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'LOG'},$fwdfwsettings{'TIME'},$fwdfwsettings{'TIME_MON'},$fwdfwsettings{'TIME_TUE'},$fwdfwsettings{'TIME_WED'},$fwdfwsettings{'TIME_THU'},$fwdfwsettings{'TIME_FRI'},$fwdfwsettings{'TIME_SAT'},$fwdfwsettings{'TIME_SUN'},$fwdfwsettings{'TIME_FROM'},$fwdfwsettings{'TIME_TO'},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'},$fwdfwsettings{'LIMIT_CON_CON'},$fwdfwsettings{'concon'},$fwdfwsettings{'RATE_LIMIT'},$fwdfwsettings{'ratecon'},$fwdfwsettings{'RATETIME'}"
+                                       eq "$configoutgoingfw{$key}[0],$configoutgoingfw{$key}[2],$configoutgoingfw{$key}[3],$configoutgoingfw{$key}[4],$configoutgoingfw{$key}[5],$configoutgoingfw{$key}[6],$configoutgoingfw{$key}[7],$configoutgoingfw{$key}[8],$configoutgoingfw{$key}[9],$configoutgoingfw{$key}[10],$configoutgoingfw{$key}[11],$configoutgoingfw{$key}[12],$configoutgoingfw{$key}[13],$configoutgoingfw{$key}[14],$configoutgoingfw{$key}[15],$configoutgoingfw{$key}[17],$configoutgoingfw{$key}[18],$configoutgoingfw{$key}[19],$configoutgoingfw{$key}[20],$configoutgoingfw{$key}[21],$configoutgoingfw{$key}[22],$configoutgoingfw{$key}[23],$configoutgoingfw{$key}[24],$configoutgoingfw{$key}[25],$configoutgoingfw{$key}[26],$configoutgoingfw{$key}[27],$configoutgoingfw{$key}[28],$configoutgoingfw{$key}[29],$configoutgoingfw{$key}[30],$configoutgoingfw{$key}[31],$configoutgoingfw{$key}[32],$configoutgoingfw{$key}[33],$configoutgoingfw{$key}[34],$configoutgoingfw{$key}[35],$configoutgoingfw{$key}[36]"){
                                                $errormessage.=$Lang::tr{'fwdfw err ruleexists'};
                                                if($fwdfwsettings{'oldruleremark'} ne $fwdfwsettings{'ruleremark'} && $fwdfwsettings{'updatefwrule'} eq 'on' && $fwdfwsettings{'ruleremark'} ne '' && !&validremark($fwdfwsettings{'ruleremark'})){
                                                        $errormessage=$Lang::tr{'fwdfw err remark'}."<br>";
                                                }
+                                               if($fwdfwsettings{'oldruleremark'} ne $fwdfwsettings{'ruleremark'} && $fwdfwsettings{'updatefwrule'} eq 'on' && $fwdfwsettings{'ruleremark'} ne '' && &validremark($fwdfwsettings{'ruleremark'})){
+                                                       $errormessage='';
+                                               }
                                                if ($fwdfwsettings{'oldruleremark'} eq $fwdfwsettings{'ruleremark'}){
                                                        $fwdfwsettings{'nosave'} = 'on';
                                                }
@@ -275,14 +304,14 @@ if ($fwdfwsettings{'ACTION'} eq 'saverule')
                if($fwdfwsettings{'rulepos'} > 0 && !$fwdfwsettings{'oldrulenumber'}){
                        $fwdfwsettings{'oldrulenumber'}=$maxkey;
                        foreach my $key (sort keys %configoutgoingfw){
-                               if (   "$fwdfwsettings{'RULE_ACTION'},$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USE_SRC_PORT'},$fwdfwsettings{'PROT'},$fwdfwsettings{'ICMP_TYPES'},$fwdfwsettings{'SRC_PORT'},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'ICMP_TGT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'LOG'},$fwdfwsettings{'TIME'},$fwdfwsettings{'TIME_MON'},$fwdfwsettings{'TIME_TUE'},$fwdfwsettings{'TIME_WED'},$fwdfwsettings{'TIME_THU'},$fwdfwsettings{'TIME_FRI'},$fwdfwsettings{'TIME_SAT'},$fwdfwsettings{'TIME_SUN'},$fwdfwsettings{'TIME_FROM'},$fwdfwsettings{'TIME_TO'},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'}"
-                                       eq "$configoutgoingfw{$key}[0],$configoutgoingfw{$key}[2],$configoutgoingfw{$key}[3],$configoutgoingfw{$key}[4],$configoutgoingfw{$key}[5],$configoutgoingfw{$key}[6],$configoutgoingfw{$key}[7],$configoutgoingfw{$key}[8],$configoutgoingfw{$key}[9],$configoutgoingfw{$key}[10],$configoutgoingfw{$key}[11],$configoutgoingfw{$key}[12],$configoutgoingfw{$key}[13],$configoutgoingfw{$key}[14],$configoutgoingfw{$key}[15],$configoutgoingfw{$key}[17],$configoutgoingfw{$key}[18],$configoutgoingfw{$key}[19],$configoutgoingfw{$key}[20],$configoutgoingfw{$key}[21],$configoutgoingfw{$key}[22],$configoutgoingfw{$key}[23],$configoutgoingfw{$key}[24],$configoutgoingfw{$key}[25],$configoutgoingfw{$key}[26],$configoutgoingfw{$key}[27],$configoutgoingfw{$key}[28],$configoutgoingfw{$key}[29],$configoutgoingfw{$key}[30],$configoutgoingfw{$key}[31]"){
+                               if (   "$fwdfwsettings{'RULE_ACTION'},$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USE_SRC_PORT'},$fwdfwsettings{'PROT'},$fwdfwsettings{'ICMP_TYPES'},$fwdfwsettings{'SRC_PORT'},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'ICMP_TGT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'LOG'},$fwdfwsettings{'TIME'},$fwdfwsettings{'TIME_MON'},$fwdfwsettings{'TIME_TUE'},$fwdfwsettings{'TIME_WED'},$fwdfwsettings{'TIME_THU'},$fwdfwsettings{'TIME_FRI'},$fwdfwsettings{'TIME_SAT'},$fwdfwsettings{'TIME_SUN'},$fwdfwsettings{'TIME_FROM'},$fwdfwsettings{'TIME_TO'},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'},$fwdfwsettings{'LIMIT_CON_CON'},$fwdfwsettings{'concon'},$fwdfwsettings{'RATE_LIMIT'},$fwdfwsettings{'ratecon'},$fwdfwsettings{'RATETIME'}"
+                                       eq "$configoutgoingfw{$key}[0],$configoutgoingfw{$key}[2],$configoutgoingfw{$key}[3],$configoutgoingfw{$key}[4],$configoutgoingfw{$key}[5],$configoutgoingfw{$key}[6],$configoutgoingfw{$key}[7],$configoutgoingfw{$key}[8],$configoutgoingfw{$key}[9],$configoutgoingfw{$key}[10],$configoutgoingfw{$key}[11],$configoutgoingfw{$key}[12],$configoutgoingfw{$key}[13],$configoutgoingfw{$key}[14],$configoutgoingfw{$key}[15],$configoutgoingfw{$key}[17],$configoutgoingfw{$key}[18],$configoutgoingfw{$key}[19],$configoutgoingfw{$key}[20],$configoutgoingfw{$key}[21],$configoutgoingfw{$key}[22],$configoutgoingfw{$key}[23],$configoutgoingfw{$key}[24],$configoutgoingfw{$key}[25],$configoutgoingfw{$key}[26],$configoutgoingfw{$key}[27],$configoutgoingfw{$key}[28],$configoutgoingfw{$key}[29],$configoutgoingfw{$key}[30],$configoutgoingfw{$key}[31],$configoutgoingfw{$key}[32],$configoutgoingfw{$key}[33],$configoutgoingfw{$key}[34],$configoutgoingfw{$key}[35],$configoutgoingfw{$key}[36]"){
                                                $errormessage.=$Lang::tr{'fwdfw err ruleexists'};
                                }
                        }
                }
                #check if we just close a rule
-               if( $fwdfwsettings{'oldgrp1a'} eq  $fwdfwsettings{'grp1'} && $fwdfwsettings{'oldgrp1b'} eq $fwdfwsettings{$fwdfwsettings{'grp1'}} && $fwdfwsettings{'oldgrp2a'} eq  $fwdfwsettings{'grp2'} && $fwdfwsettings{'oldgrp2b'} eq $fwdfwsettings{$fwdfwsettings{'grp2'}} &&  $fwdfwsettings{'oldgrp3a'} eq $fwdfwsettings{'grp3'} && $fwdfwsettings{'oldgrp3b'} eq  $fwdfwsettings{$fwdfwsettings{'grp3'}} && $fwdfwsettings{'oldusesrv'} eq $fwdfwsettings{'USESRV'} && $fwdfwsettings{'oldruleremark'} eq $fwdfwsettings{'ruleremark'} && $fwdfwsettings{'oldruletype'} eq $fwdfwsettings{'chain'}) {
+               if( $fwdfwsettings{'oldgrp1a'} eq  $fwdfwsettings{'grp1'} && $fwdfwsettings{'oldgrp1b'} eq $fwdfwsettings{$fwdfwsettings{'grp1'}} && $fwdfwsettings{'oldgrp2a'} eq  $fwdfwsettings{'grp2'} && $fwdfwsettings{'oldgrp2b'} eq $fwdfwsettings{$fwdfwsettings{'grp2'}} &&  $fwdfwsettings{'oldgrp3a'} eq $fwdfwsettings{'grp3'} && $fwdfwsettings{'oldgrp3b'} eq  $fwdfwsettings{$fwdfwsettings{'grp3'}} && $fwdfwsettings{'oldusesrv'} eq $fwdfwsettings{'USESRV'} && $fwdfwsettings{'oldruleremark'} eq $fwdfwsettings{'ruleremark'} && $fwdfwsettings{'oldruletype'} eq $fwdfwsettings{'chain'} ) {
                        if($fwdfwsettings{'nosave'} eq 'on' && $fwdfwsettings{'updatefwrule'} eq 'on'){
                                $fwdfwsettings{'nosave2'} = 'on';
                                $errormessage='';
@@ -302,8 +331,8 @@ if ($fwdfwsettings{'ACTION'} eq 'saverule')
                if($fwdfwsettings{'oldrulenumber'} eq $fwdfwsettings{'rulepos'}){
                        #check if we have an identical rule already
                        foreach my $key (sort keys %configfwdfw){
-                               if (   "$fwdfwsettings{'RULE_ACTION'},$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USE_SRC_PORT'},$fwdfwsettings{'PROT'},$fwdfwsettings{'ICMP_TYPES'},$fwdfwsettings{'SRC_PORT'},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'ICMP_TGT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'TIME'},$fwdfwsettings{'TIME_MON'},$fwdfwsettings{'TIME_TUE'},$fwdfwsettings{'TIME_WED'},$fwdfwsettings{'TIME_THU'},$fwdfwsettings{'TIME_FRI'},$fwdfwsettings{'TIME_SAT'},$fwdfwsettings{'TIME_SUN'},$fwdfwsettings{'TIME_FROM'},$fwdfwsettings{'TIME_TO'},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'}"
-                                       eq "$configfwdfw{$key}[0],$configfwdfw{$key}[2],$configfwdfw{$key}[3],$configfwdfw{$key}[4],$configfwdfw{$key}[5],$configfwdfw{$key}[6],$configfwdfw{$key}[7],$configfwdfw{$key}[8],$configfwdfw{$key}[9],$configfwdfw{$key}[10],$configfwdfw{$key}[11],$configfwdfw{$key}[12],$configfwdfw{$key}[13],$configfwdfw{$key}[14],$configfwdfw{$key}[15],$configfwdfw{$key}[18],$configfwdfw{$key}[19],$configfwdfw{$key}[20],$configfwdfw{$key}[21],$configfwdfw{$key}[22],$configfwdfw{$key}[23],$configfwdfw{$key}[24],$configfwdfw{$key}[25],$configfwdfw{$key}[26],$configfwdfw{$key}[27],$configfwdfw{$key}[28],$configfwdfw{$key}[29],$configfwdfw{$key}[30],$configfwdfw{$key}[31]"){
+                               if (   "$fwdfwsettings{'RULE_ACTION'},$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USE_SRC_PORT'},$fwdfwsettings{'PROT'},$fwdfwsettings{'ICMP_TYPES'},$fwdfwsettings{'SRC_PORT'},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'ICMP_TGT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'TIME'},$fwdfwsettings{'TIME_MON'},$fwdfwsettings{'TIME_TUE'},$fwdfwsettings{'TIME_WED'},$fwdfwsettings{'TIME_THU'},$fwdfwsettings{'TIME_FRI'},$fwdfwsettings{'TIME_SAT'},$fwdfwsettings{'TIME_SUN'},$fwdfwsettings{'TIME_FROM'},$fwdfwsettings{'TIME_TO'},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'},$fwdfwsettings{'LIMIT_CON_CON'},$fwdfwsettings{'concon'},$fwdfwsettings{'RATE_LIMIT'},$fwdfwsettings{'ratecon'},$fwdfwsettings{'RATETIME'}"
+                                       eq "$configfwdfw{$key}[0],$configfwdfw{$key}[2],$configfwdfw{$key}[3],$configfwdfw{$key}[4],$configfwdfw{$key}[5],$configfwdfw{$key}[6],$configfwdfw{$key}[7],$configfwdfw{$key}[8],$configfwdfw{$key}[9],$configfwdfw{$key}[10],$configfwdfw{$key}[11],$configfwdfw{$key}[12],$configfwdfw{$key}[13],$configfwdfw{$key}[14],$configfwdfw{$key}[15],$configfwdfw{$key}[18],$configfwdfw{$key}[19],$configfwdfw{$key}[20],$configfwdfw{$key}[21],$configfwdfw{$key}[22],$configfwdfw{$key}[23],$configfwdfw{$key}[24],$configfwdfw{$key}[25],$configfwdfw{$key}[26],$configfwdfw{$key}[27],$configfwdfw{$key}[28],$configfwdfw{$key}[29],$configfwdfw{$key}[30],$configfwdfw{$key}[31],$configfwdfw{$key}[32],$configfwdfw{$key}[33],$configfwdfw{$key}[34],$configfwdfw{$key}[35],$configfwdfw{$key}[36]"){
                                                $errormessage.=$Lang::tr{'fwdfw err ruleexists'};
                                                if($fwdfwsettings{'oldruleremark'} ne $fwdfwsettings{'ruleremark'} && $fwdfwsettings{'updatefwrule'} eq 'on' && $fwdfwsettings{'ruleremark'} ne '' && !&validremark($fwdfwsettings{'ruleremark'})){
                                                        $errormessage=$Lang::tr{'fwdfw err remark'}."<br>";
@@ -321,19 +350,35 @@ if ($fwdfwsettings{'ACTION'} eq 'saverule')
                if($fwdfwsettings{'rulepos'} > 0 && !$fwdfwsettings{'oldrulenumber'}){
                        $fwdfwsettings{'oldrulenumber'}=$maxkey;
                        foreach my $key (sort keys %configfwdfw){
-                               if (   "$fwdfwsettings{'RULE_ACTION'},$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USE_SRC_PORT'},$fwdfwsettings{'PROT'},$fwdfwsettings{'ICMP_TYPES'},$fwdfwsettings{'SRC_PORT'},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'ICMP_TGT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'TIME'},$fwdfwsettings{'TIME_MON'},$fwdfwsettings{'TIME_TUE'},$fwdfwsettings{'TIME_WED'},$fwdfwsettings{'TIME_THU'},$fwdfwsettings{'TIME_FRI'},$fwdfwsettings{'TIME_SAT'},$fwdfwsettings{'TIME_SUN'},$fwdfwsettings{'TIME_FROM'},$fwdfwsettings{'TIME_TO'},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'}"
-                                       eq "$configfwdfw{$key}[0],$configfwdfw{$key}[2],$configfwdfw{$key}[3],$configfwdfw{$key}[4],$configfwdfw{$key}[5],$configfwdfw{$key}[6],$configfwdfw{$key}[7],$configfwdfw{$key}[8],$configfwdfw{$key}[9],$configfwdfw{$key}[10],$configfwdfw{$key}[11],$configfwdfw{$key}[12],$configfwdfw{$key}[13],$configfwdfw{$key}[14],$configfwdfw{$key}[15],$configfwdfw{$key}[18],$configfwdfw{$key}[19],$configfwdfw{$key}[20],$configfwdfw{$key}[21],$configfwdfw{$key}[22],$configfwdfw{$key}[23],$configfwdfw{$key}[24],$configfwdfw{$key}[25],$configfwdfw{$key}[26],$configfwdfw{$key}[27],$configfwdfw{$key}[28],$configfwdfw{$key}[29],$configfwdfw{$key}[30],$configfwdfw{$key}[31]"){
+                               if (   "$fwdfwsettings{'RULE_ACTION'},$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USE_SRC_PORT'},$fwdfwsettings{'PROT'},$fwdfwsettings{'ICMP_TYPES'},$fwdfwsettings{'SRC_PORT'},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'ICMP_TGT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'TIME'},$fwdfwsettings{'TIME_MON'},$fwdfwsettings{'TIME_TUE'},$fwdfwsettings{'TIME_WED'},$fwdfwsettings{'TIME_THU'},$fwdfwsettings{'TIME_FRI'},$fwdfwsettings{'TIME_SAT'},$fwdfwsettings{'TIME_SUN'},$fwdfwsettings{'TIME_FROM'},$fwdfwsettings{'TIME_TO'},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'},$fwdfwsettings{'LIMIT_CON_CON'},$fwdfwsettings{'concon'},$fwdfwsettings{'RATE_LIMIT'},$fwdfwsettings{'ratecon'},$fwdfwsettings{'RATETIME'}"
+                                       eq "$configfwdfw{$key}[0],$configfwdfw{$key}[2],$configfwdfw{$key}[3],$configfwdfw{$key}[4],$configfwdfw{$key}[5],$configfwdfw{$key}[6],$configfwdfw{$key}[7],$configfwdfw{$key}[8],$configfwdfw{$key}[9],$configfwdfw{$key}[10],$configfwdfw{$key}[11],$configfwdfw{$key}[12],$configfwdfw{$key}[13],$configfwdfw{$key}[14],$configfwdfw{$key}[15],$configfwdfw{$key}[18],$configfwdfw{$key}[19],$configfwdfw{$key}[20],$configfwdfw{$key}[21],$configfwdfw{$key}[22],$configfwdfw{$key}[23],$configfwdfw{$key}[24],$configfwdfw{$key}[25],$configfwdfw{$key}[26],$configfwdfw{$key}[27],$configfwdfw{$key}[28],$configfwdfw{$key}[29],$configfwdfw{$key}[30],$configfwdfw{$key}[31],$configfwdfw{$key}[32],$configfwdfw{$key}[33],$configfwdfw{$key}[34],$configfwdfw{$key}[35],$configfwdfw{$key}[36]"){
                                                $errormessage.=$Lang::tr{'fwdfw err ruleexists'};
                                }
                        }
                }
                #check if we just close a rule
-               if( $fwdfwsettings{'oldgrp1a'} eq  $fwdfwsettings{'grp1'} && $fwdfwsettings{'oldgrp1b'} eq $fwdfwsettings{$fwdfwsettings{'grp1'}} && $fwdfwsettings{'oldgrp2a'} eq  $fwdfwsettings{'grp2'} && $fwdfwsettings{'oldgrp2b'} eq $fwdfwsettings{$fwdfwsettings{'grp2'}} &&  $fwdfwsettings{'oldgrp3a'} eq $fwdfwsettings{'grp3'} && $fwdfwsettings{'oldgrp3b'} eq  $fwdfwsettings{$fwdfwsettings{'grp3'}} && $fwdfwsettings{'oldusesrv'} eq $fwdfwsettings{'USESRV'} && $fwdfwsettings{'oldruleremark'} eq $fwdfwsettings{'ruleremark'} && $fwdfwsettings{'oldruletype'} eq $fwdfwsettings{'chain'}) {
+               if( $fwdfwsettings{'oldgrp1a'} eq  $fwdfwsettings{'grp1'} && $fwdfwsettings{'oldgrp1b'} eq $fwdfwsettings{$fwdfwsettings{'grp1'}} && $fwdfwsettings{'oldgrp2a'} eq  $fwdfwsettings{'grp2'} && $fwdfwsettings{'oldgrp2b'} eq $fwdfwsettings{$fwdfwsettings{'grp2'}} &&  $fwdfwsettings{'oldgrp3a'} eq $fwdfwsettings{'grp3'} && $fwdfwsettings{'oldgrp3b'} eq  $fwdfwsettings{$fwdfwsettings{'grp3'}} && $fwdfwsettings{'oldusesrv'} eq $fwdfwsettings{'USESRV'} && $fwdfwsettings{'oldruleremark'} eq $fwdfwsettings{'ruleremark'} && $fwdfwsettings{'oldruletype'} eq $fwdfwsettings{'chain'}){
                        if($fwdfwsettings{'nosave'} eq 'on' && $fwdfwsettings{'updatefwrule'} eq 'on'){
                                $fwdfwsettings{'nosave2'} = 'on';
                                $errormessage='';
                        }
                }
+               #check max concurrent connections per ip address
+               if ($fwdfwsettings{'LIMIT_CON_CON'} eq 'ON'){
+                       if (!($fwdfwsettings{'concon'} =~ /^(\d+)$/)) {
+                               $errormessage.=$Lang::tr{'fwdfw err concon'};
+                       }
+               }else{
+                       $fwdfwsettings{'concon'}='';
+               }
+               #check ratelimit value
+               if ($fwdfwsettings{'RATE_LIMIT'} eq 'ON'){
+                       if (!($fwdfwsettings{'ratecon'} =~ /^(\d+)$/)) {
+                               $errormessage.=$Lang::tr{'fwdfw err ratecon'};
+                       }
+               }else{
+                       $fwdfwsettings{'ratecon'}='';
+               }
                #increase counters
                if (!$errormessage){
                        if ($fwdfwsettings{'nosave2'} ne 'on'){
@@ -502,8 +547,8 @@ sub checksource
                        return $errormessage;
                }
        }elsif($fwdfwsettings{'src_addr'} eq $fwdfwsettings{$fwdfwsettings{'grp1'}} && $fwdfwsettings{'src_addr'} eq ''){
-               $errormessage.=$Lang::tr{'fwdfw err nosrcip'};
-               return $errormessage;
+               $fwdfwsettings{'grp1'}='std_net_src';
+               $fwdfwsettings{$fwdfwsettings{'grp1'}} = 'ALL';
        }
 
        #check empty fields
@@ -574,8 +619,10 @@ sub checktarget
                                }
                        }
                }else{
-                       $errormessage=$Lang::tr{'fwdfw dnat error'}."<br>";
-                       return $errormessage;
+                       if ($fwdfwsettings{'grp2'} ne 'ipfire'){
+                               $errormessage=$Lang::tr{'fwdfw dnat error'}."<br>";
+                               return $errormessage;
+                       }
                }
        }
        if ($fwdfwsettings{'tgt_addr'} eq $fwdfwsettings{$fwdfwsettings{'grp2'}} && $fwdfwsettings{'tgt_addr'} ne ''){
@@ -603,8 +650,8 @@ sub checktarget
                        return $errormessage;
                }
        }elsif($fwdfwsettings{'tgt_addr'} eq $fwdfwsettings{$fwdfwsettings{'grp2'}} && $fwdfwsettings{'tgt_addr'} eq ''){
-               $errormessage.=$Lang::tr{'fwdfw err notgtip'};
-               return $errormessage;
+               $fwdfwsettings{'grp2'}='std_net_tgt';
+               $fwdfwsettings{$fwdfwsettings{'grp2'}} = 'ALL';
        }
        #check for mac in targetgroup
        if ($fwdfwsettings{'grp2'} eq 'cust_grp_tgt'){
@@ -979,6 +1026,12 @@ sub deleterule
                &base;
        }
 }
+sub del_double
+{
+       my %all=();
+       @all{@_}=1;
+       return (keys %all);
+}
 sub disable_rule
 {
        my $key1=shift;
@@ -1046,7 +1099,6 @@ print<<END;
 END
        foreach my $network (sort keys %defaultNetworks)
                {
-                       next if($defaultNetworks{$network}{'NAME'} eq "RED" && $srctgt eq 'src');
                        next if($defaultNetworks{$network}{'NAME'} eq "IPFire");
                        print "<option value='$defaultNetworks{$network}{'NAME'}'";
                        print " selected='selected'" if ($fwdfwsettings{$fwdfwsettings{$grp}} eq $defaultNetworks{$network}{'NAME'});
@@ -1086,6 +1138,54 @@ END
                }
                print"</select></td>";
        }
+       # geoip locations / groups.
+       my @geoip_locations = &fwlib::get_geoip_locations();
+
+       print "<tr>\n";
+       print "<td valign='top'><input type='radio' name='$grp' id='cust_geoip_$srctgt' value='cust_geoip_$srctgt' $checked{$grp}{'cust_geoip_'.$srctgt}></td>\n";
+       print "<td>$Lang::tr{'geoip'}</td>\n";
+       print "<td align='right'><select name='cust_geoip_$srctgt' style='width:200px;'>\n";
+
+       # Add GeoIP groups to dropdown.
+       if (!-z $configgeoipgrp) {
+               print "<optgroup label='$Lang::tr{'fwhost cust geoipgroup'}'>\n";
+               foreach my $key (sort { ncmp($customgeoipgrp{$a}[0],$customgeoipgrp{$b}[0]) } keys %customgeoipgrp) {
+                       my $selected;
+
+                       # Generate stored value for select detection.
+                       my $stored = join(':', "group",$customgeoipgrp{$key}[0]);
+
+                       # Only show a group once and group with elements.
+                       if($helper ne $customgeoipgrp{$key}[0] && $customgeoipgrp{$key}[2] ne 'none') {
+                               # Mark current entry as selected.
+                               if ($fwdfwsettings{$fwdfwsettings{$grp}} eq $stored) {
+                                       $selected = "selected='selected'";
+                               }
+                                print"<option $selected value='group:$customgeoipgrp{$key}[0]'>$customgeoipgrp{$key}[0]</option>\n";
+                        }
+                        $helper=$customgeoipgrp{$key}[0];
+                }
+               print "</optgroup>\n";
+       }
+
+       # Add locations.
+       print "<optgroup label='$Lang::tr{'fwhost cust geoiplocation'}'>\n";
+       foreach my $location (@geoip_locations) {
+               # Get country name.
+               my $country_name = &GeoIP::get_full_country_name($location);
+
+               # Mark current entry as selected.
+               my $selected;
+               if ($fwdfwsettings{$fwdfwsettings{$grp}} eq $location) {
+                       $selected = "selected='selected'";
+               }
+               print "<option $selected value='$location'>$location - $country_name</option>\n";
+       }
+       print "</optgroup>\n";
+
+       # Close GeoIP dropdown.
+       print "</select></td>\n";
+
        #End left table. start right table (vpn)
        print"</tr></table></td><td valign='top'><table width='95%' border='0' align='right'><tr>";
        # CCD networks
@@ -1242,10 +1342,8 @@ sub get_serviceports
        my $name=shift;
        &General::readhasharray("$configsrv", \%customservice);
        &General::readhasharray("$configsrvgrp", \%customservicegrp);
-       my $tcp;
-       my $udp;
-       my $icmp;
        @protocols=();
+       my @specprot=("IPIP","IPV6","IGMP","GRE","AH","ESP");
        if($type eq 'service'){
                foreach my $key (sort { ncmp($customservice{$a}[0],$customservice{$b}[0]) } keys %customservice){
                        if ($customservice{$key}[0] eq $name){
@@ -1255,33 +1353,23 @@ sub get_serviceports
        }elsif($type eq 'group'){
                foreach my $key (sort { ncmp($customservicegrp{$a}[0],$customservicegrp{$b}[0]) } keys %customservicegrp){
                        if ($customservicegrp{$key}[0] eq $name){
-                               foreach my $key1 (sort { ncmp($customservice{$a}[0],$customservice{$b}[0]) } keys %customservice){
-                                       if ($customservice{$key1}[0] eq $customservicegrp{$key}[2]){
-                                               if($customservice{$key1}[2] eq 'TCP'){
-                                                       $tcp='TCP';
-                                               }elsif($customservice{$key1}[2] eq 'ICMP'){
-                                                       $icmp='ICMP';
-                                               }elsif($customservice{$key1}[2] eq 'UDP'){
-                                                       $udp='UDP';
+                               if ($customservicegrp{$key}[2] ~~ @specprot){
+                                       push (@protocols," ".$customservicegrp{$key}[2]);
+                               }else{
+                                       foreach my $key1 (sort { ncmp($customservice{$a}[0],$customservice{$b}[0]) } keys %customservice){
+                                               if ($customservice{$key1}[0] eq $customservicegrp{$key}[2]){
+                                                       if (!grep(/$customservice{$key1}[2]/, @protocols)){
+                                                               push (@protocols,$customservice{$key1}[2]);}
                                                }
                                        }
                                }
                        }
                }
        }
-       if($tcp && $udp && $icmp){
-               push (@protocols,"TCP,UDP, <br>ICMP");
-               return @protocols;
-       }
-       if($tcp){
-               push (@protocols,"TCP");
-       }
-       if($udp){
-               push (@protocols,"UDP");
-       }
-       if($icmp){
-               push (@protocols,"ICMP");
-       }
+
+       # Sort protocols alphabetically.
+       @protocols = sort(@protocols);
+
        return @protocols;
 }
 sub getcolor
@@ -1290,6 +1378,12 @@ sub getcolor
        my $val=shift;
        my $hash=shift;
        if($optionsfw{'SHOWCOLORS'} eq 'on'){
+               # Don't colourise MAC addresses
+               if (&General::validmac($val)) {
+                       $tdcolor = "";
+                       return;
+               }
+
                #custom Hosts
                if ($nettype eq 'cust_host_src' || $nettype eq 'cust_host_tgt'){
                        foreach my $key (sort keys %$hash){
@@ -1322,7 +1416,7 @@ sub getcolor
                        return;
                }elsif($val =~ /^(.*?)\/(.*?)$/){
                        my ($sip,$scidr) = split ("/",$val);
-                       if ( &General::IpInSubnet($sip,$netsettings{'ORANGE_ADDRESS'},$netsettings{'ORANGE_NETMASK'})){
+                       if ( &Header::orange_used() && &General::IpInSubnet($sip,$netsettings{'ORANGE_ADDRESS'},$netsettings{'ORANGE_NETMASK'})){
                                $tdcolor="style='background-color: $Header::colourorange;color:white;'";
                                return;
                        }
@@ -1330,7 +1424,7 @@ sub getcolor
                                $tdcolor="style='background-color: $Header::colourgreen;color:white;'";
                                return;
                        }
-                       if ( &General::IpInSubnet($sip,$netsettings{'BLUE_ADDRESS'},$netsettings{'BLUE_NETMASK'})){
+                       if ( &Header::blue_used() && &General::IpInSubnet($sip,$netsettings{'BLUE_ADDRESS'},$netsettings{'BLUE_NETMASK'})){
                                $tdcolor="style='background-color: $Header::colourblue;color:white;'";
                                return;
                        }
@@ -1377,11 +1471,13 @@ sub getcolor
                        }
                        #Check if IP is part of a IPsec N2N network
                        foreach my $key (sort keys %ipsecconf){
-                               my ($a,$b) = split("/",$ipsecconf{$key}[11]);
-                               $b=&General::iporsubtodec($b);
-                               if (&General::IpInSubnet($c,$a,$b)){
-                                       $tdcolor="style='background-color: $Header::colourvpn;color:white;'";
-                                       return;
+                               if ($ipsecconf{$key}[11]){
+                                       my ($a,$b) = split("/",$ipsecconf{$key}[11]);
+                                       $b=&General::iporsubtodec($b);
+                                       if (&General::IpInSubnet($c,$a,$b)){
+                                               $tdcolor="style='background-color: $Header::colourvpn;color:white;'";
+                                               return;
+                                       }
                                }
                        }
                }
@@ -1427,6 +1523,7 @@ sub newrule
        &General::readhasharray("$confighost", \%customhost);
        &General::readhasharray("$configccdhost", \%ccdhost);
        &General::readhasharray("$configgrp", \%customgrp);
+       &General::readhasharray("$configgeoipgrp", \%customgeoipgrp);
        &General::readhasharray("$configipsec", \%ipsecconf);
        &General::get_aliases(\%aliases);
        my %checked=();
@@ -1503,6 +1600,11 @@ sub newrule
                                $fwdfwsettings{'nat'}                                   = $hash{$key}[31]; #changed order
                                $fwdfwsettings{$fwdfwsettings{'nat'}}   = $hash{$key}[29];
                                $fwdfwsettings{'dnatport'}                              = $hash{$key}[30];
+                               $fwdfwsettings{'LIMIT_CON_CON'}                 = $hash{$key}[32];
+                               $fwdfwsettings{'concon'}                                = $hash{$key}[33];
+                               $fwdfwsettings{'RATE_LIMIT'}                    = $hash{$key}[34];
+                               $fwdfwsettings{'ratecon'}                               = $hash{$key}[35];
+                               $fwdfwsettings{'RATETIME'}                              = $hash{$key}[36];
                                $checked{'grp1'}{$fwdfwsettings{'grp1'}}                                = 'CHECKED';
                                $checked{'grp2'}{$fwdfwsettings{'grp2'}}                                = 'CHECKED';
                                $checked{'grp3'}{$fwdfwsettings{'grp3'}}                                = 'CHECKED';
@@ -1520,10 +1622,15 @@ sub newrule
                                $checked{'TIME_SUN'}{$fwdfwsettings{'TIME_SUN'}}                = 'CHECKED';
                                $checked{'USE_NAT'}{$fwdfwsettings{'USE_NAT'}}                  = 'CHECKED';
                                $checked{'nat'}{$fwdfwsettings{'nat'}}                                  = 'CHECKED';
+                               $checked{'LIMIT_CON_CON'}{$fwdfwsettings{'LIMIT_CON_CON'}}      = 'CHECKED';
+                               $checked{'RATE_LIMIT'}{$fwdfwsettings{'RATE_LIMIT'}}    = 'CHECKED';
                                $selected{'TIME_FROM'}{$fwdfwsettings{'TIME_FROM'}}             = 'selected';
                                $selected{'TIME_TO'}{$fwdfwsettings{'TIME_TO'}}                 = 'selected';
                                $selected{'ipfire'}{$fwdfwsettings{$fwdfwsettings{'grp2'}}} ='selected';
                                $selected{'ipfire_src'}{$fwdfwsettings{$fwdfwsettings{'grp1'}}} ='selected';
+                               $selected{'dnat'}{$fwdfwsettings{'dnat'}}                               ='selected';
+                               $selected{'snat'}{$fwdfwsettings{'snat'}}                               ='selected';
+                               $selected{'RATETIME'}{$fwdfwsettings{'RATETIME'}}               ='selected';
                        }
                }
                $fwdfwsettings{'oldgrp1a'}=$fwdfwsettings{'grp1'};
@@ -1536,6 +1643,11 @@ sub newrule
                $fwdfwsettings{'oldruleremark'}=$fwdfwsettings{'ruleremark'};
                $fwdfwsettings{'oldnat'}=$fwdfwsettings{'USE_NAT'};
                $fwdfwsettings{'oldruletype'}=$fwdfwsettings{'chain'};
+               $fwdfwsettings{'oldconcon'}=$fwdfwsettings{'LIMIT_CON_CON'};
+               $fwdfwsettings{'olduseratelimit'}=$fwdfwsettings{'RATE_LIMIT'};
+               $fwdfwsettings{'olduseratelimitamount'}=$fwdfwsettings{'ratecon'};
+               $fwdfwsettings{'oldratelimittime'}=$fwdfwsettings{'RATETIME'};
+
                #check if manual ip (source) is orange network
                if ($fwdfwsettings{'grp1'} eq 'src_addr'){
                        my ($sip,$scidr) = split("/",$fwdfwsettings{$fwdfwsettings{'grp1'}});
@@ -1557,6 +1669,7 @@ sub newrule
                $fwdfwsettings{'oldusesrv'}=$fwdfwsettings{'USESRV'};
                $fwdfwsettings{'oldruleremark'}=$fwdfwsettings{'ruleremark'};
                $fwdfwsettings{'oldnat'}=$fwdfwsettings{'USE_NAT'};
+               $fwdfwsettings{'oldconcon'}=$fwdfwsettings{'LIMIT_CON_CON'};
                #check if manual ip (source) is orange network
                if ($fwdfwsettings{'grp1'} eq 'src_addr'){
                        my ($sip,$scidr) = split("/",$fwdfwsettings{$fwdfwsettings{'grp1'}});
@@ -1586,7 +1699,7 @@ END
                if (! -z "${General::swroot}/ethernet/aliases"){
                        foreach my $alias (sort keys %aliases)
                        {
-                               print "<option value='$alias' $selected{'ipfire'}{$alias}>$alias</option>";
+                               print "<option value='$alias' $selected{'ipfire_src'}{$alias}>$alias ($aliases{$alias}{'IPT'})</option>";
                        }
                }
                print<<END;
@@ -1616,25 +1729,28 @@ END
                                                </td>
 END
 
-               if (%aliases) {
-                       print <<END;
+       print <<END;
                                                <td width='25%' align='right'>$Lang::tr{'dnat address'}:</td>
                                                <td width='30%'>
                                                        <select name='dnat' style='width: 100%;'>
-                                                               <option value='Default IP' $selected{'dnat'}{'Default IP'}>$Lang::tr{'default ip'} ($netsettings{'RED_ADDRESS'})</option>
+                                                               <option value='AUTO' $selected{'dnat'}{'AUTO'}>- $Lang::tr{'automatic'} -</option>
+                                                               <option value='Default IP' $selected{'dnat'}{'Default IP'}>$Lang::tr{'red1'} ($redip)</option>
 END
+               if (%aliases) {
                        foreach my $alias (sort keys %aliases) {
                                print "<option value='$alias' $selected{'dnat'}{$alias}>$alias ($aliases{$alias}{'IPT'})</option>";
                        }
-
-                       print "</select>";
-               } else {
-                       print <<END;
-                                               <td colspan="2" width='55%'>
-                                                       <input type='hidden' name='dnat' value='Default IP'>
-                                               </td>
-END
                }
+               #DNAT Dropdown
+               foreach my $network (sort keys %defaultNetworks)
+               {
+                       if ($defaultNetworks{$network}{'NAME'} eq 'BLUE'||$defaultNetworks{$network}{'NAME'} eq 'GREEN' ||$defaultNetworks{$network}{'NAME'} eq 'ORANGE'){
+                               print "<option value='$defaultNetworks{$network}{'NAME'}'";
+                               print " selected='selected'" if ($fwdfwsettings{'dnat'} eq $defaultNetworks{$network}{'NAME'});
+                               print ">$network ($defaultNetworks{$network}{'NET'})</option>";
+                       }
+               }
+               print "</select>";
                print "</tr>";
 
                #SNAT
@@ -1655,19 +1771,14 @@ END
                foreach my $alias (sort keys %aliases) {
                        print "<option value='$alias' $selected{'snat'}{$alias}>$alias ($aliases{$alias}{'IPT'})</option>";
                }
-
-               # XXX this is composed in a very ugly fashion
+               # SNAT Dropdown
                foreach my $network (sort keys %defaultNetworks) {
-                       next if($defaultNetworks{$network}{'NAME'} eq "IPFire");
-                       next if($defaultNetworks{$network}{'NAME'} eq "ALL");
-                       next if($defaultNetworks{$network}{'NAME'} =~ /OpenVPN/i);
-                       next if($defaultNetworks{$network}{'NAME'} =~ /IPsec/i);
-
-                       print "<option value='$defaultNetworks{$network}{'NAME'}'";
-                       print " selected='selected'" if ($fwdfwsettings{$fwdfwsettings{'nat'}} eq $defaultNetworks{$network}{'NAME'});
-                       print ">$network ($defaultNetworks{$network}{'NET'})</option>";
+                       if ($defaultNetworks{$network}{'NAME'} eq 'BLUE'||$defaultNetworks{$network}{'NAME'} eq 'GREEN' ||$defaultNetworks{$network}{'NAME'} eq 'ORANGE'){
+                               print "<option value='$defaultNetworks{$network}{'NAME'}'";
+                               print " selected='selected'" if ($fwdfwsettings{'snat'} eq $defaultNetworks{$network}{'NAME'});
+                               print ">$network ($defaultNetworks{$network}{'NET'})</option>";
+                       }
                }
-
                print <<END;
                                                        </select>
                                                </td>
@@ -1692,7 +1803,7 @@ END
                if (! -z "${General::swroot}/ethernet/aliases"){
                        foreach my $alias (sort keys %aliases)
                        {
-                               print "<option value='$alias' $selected{'ipfire'}{$alias}>$alias</option>";
+                               print "<option value='$alias' $selected{'ipfire'}{$alias}>$alias ($aliases{$alias}{'IPT'})</option>";
                        }
                }
                print<<END;
@@ -1998,6 +2109,44 @@ END
                                        </table>
                                </td>
                        </tr>
+                       <tr>
+                               <td width='1%'>
+                                       <input type='checkbox' name='LIMIT_CON_CON' id="USE_LIMIT_CONCURRENT_CONNECTIONS_PER_IP" value='ON' $checked{'LIMIT_CON_CON'}{'ON'}>
+                               </td>
+                               <td>$Lang::tr{'fwdfw limitconcon'}</td>
+                       </tr>
+                       <tr id="LIMIT_CON">
+                               <td colspan='2'>
+                                       <table width='66%' border='0'>
+                                               <tr>
+                                                       <td width="20em">&nbsp;</td>
+                                                       <td>$Lang::tr{'fwdfw maxconcon'}: <input type='text' name='concon' size='2' value="$fwdfwsettings{'concon'}"></td>
+                                               </tr>
+                                       </table>
+                               </td>
+                       </tr>
+                       <tr>
+                               <td width='1%'>
+                                       <input type='checkbox' name='RATE_LIMIT' id="USE_RATELIMIT" value='ON' $checked{'RATE_LIMIT'}{'ON'}>
+                               </td>
+                               <td>$Lang::tr{'fwdfw ratelimit'}</td>
+                       </tr>
+                       <tr id="RATELIMIT">
+                               <td colspan='2'>
+                                       <table width='66%' border='0'>
+                                               <tr>
+                                                       <td width="20em">&nbsp;</td>
+                                                       <td>$Lang::tr{'fwdfw numcon'}: <input type='text' name='ratecon' size='2' value="$fwdfwsettings{'ratecon'}"> /
+                                                               <select name='RATETIME' style='width:100px;'>
+                                                                       <option value='second' $selected{'RATETIME'}{'second'}>$Lang::tr{'age second'}</option>
+                                                                       <option value='minute' $selected{'RATETIME'}{'minute'}>$Lang::tr{'minute'}</option>
+                                                                       <option value='hour' $selected{'RATETIME'}{'hour'}>$Lang::tr{'hour'}</option>
+                                                               </select>
+                                                       </td>
+                                               </tr>
+                                       </table>
+                               </td>
+                       </tr>
                </table>
                <br>
 END
@@ -2030,6 +2179,7 @@ END
                        <input type='hidden' name='oldorange' value='$fwdfwsettings{'oldorange'}' />
                        <input type='hidden' name='oldnat' value='$fwdfwsettings{'oldnat'}' />
                        <input type='hidden' name='oldruletype' value='$fwdfwsettings{'oldruletype'}' />
+                       <input type='hidden' name='oldconcon' value='$fwdfwsettings{'oldconcon'}' />
                        <input type='hidden' name='ACTION' value='saverule' ></form><form method='post' style='display:inline'><input type='submit' value='$Lang::tr{'fwhost back'}' style='min-width:100px;'><input type='hidden' name='ACTION' value'reset'></td></td>
                        </table></form>
 END
@@ -2129,6 +2279,8 @@ sub saverule
                        &changerule($configfwdfw);
                        #print"6";
                }
+               $fwdfwsettings{'ruleremark'}=~ s/,/;/g;
+               utf8::decode($fwdfwsettings{'ruleremark'});
                $fwdfwsettings{'ruleremark'}=&Header::escape($fwdfwsettings{'ruleremark'});
                if ($fwdfwsettings{'updatefwrule'} ne 'on'){
                        my $key = &General::findhasharraykey ($hash);
@@ -2164,6 +2316,11 @@ sub saverule
                        $$hash{$key}[29] = $fwdfwsettings{$fwdfwsettings{'nat'}};
                        $$hash{$key}[30] = $fwdfwsettings{'dnatport'};
                        $$hash{$key}[31] = $fwdfwsettings{'nat'};
+                       $$hash{$key}[32] = $fwdfwsettings{'LIMIT_CON_CON'};
+                       $$hash{$key}[33] = $fwdfwsettings{'concon'};
+                       $$hash{$key}[34] = $fwdfwsettings{'RATE_LIMIT'};
+                       $$hash{$key}[35] = $fwdfwsettings{'ratecon'};
+                       $$hash{$key}[36] = $fwdfwsettings{'RATETIME'};
                        &General::writehasharray("$config", $hash);
                }else{
                        foreach my $key (sort {$a <=> $b} keys %$hash){
@@ -2200,6 +2357,11 @@ sub saverule
                                        $$hash{$key}[29] = $fwdfwsettings{$fwdfwsettings{'nat'}};
                                        $$hash{$key}[30] = $fwdfwsettings{'dnatport'};
                                        $$hash{$key}[31] = $fwdfwsettings{'nat'};
+                                       $$hash{$key}[32] = $fwdfwsettings{'LIMIT_CON_CON'};
+                                       $$hash{$key}[33] = $fwdfwsettings{'concon'};
+                                       $$hash{$key}[34] = $fwdfwsettings{'RATE_LIMIT'};
+                                       $$hash{$key}[35] = $fwdfwsettings{'ratecon'};
+                                       $$hash{$key}[36] = $fwdfwsettings{'RATETIME'};
                                        last;
                                }
                        }
@@ -2266,7 +2428,14 @@ sub validremark
 {
        # Checks a hostname against RFC1035
        my $remark = $_[0];
-       $remark =~ s/,/;/g;
+
+       # Try to decode $remark into UTF-8. If this doesn't work,
+       # we assume that the string it not sane.
+       if (!utf8::decode($remark)) {
+               return 0;
+       }
+
+       # Check if the string only contains of printable characters.
        if ($remark =~ /^[[:print:]]*$/) {
                return 1;
        }
@@ -2277,8 +2446,8 @@ sub viewtablerule
        &General::readhash("/var/ipfire/ethernet/settings", \%netsettings);
 
        &viewtablenew(\%configfwdfw, $configfwdfw, $Lang::tr{'firewall rules'});
-       &viewtablenew(\%configinputfw, $configinput, $Lang::tr{'external access'});
-       &viewtablenew(\%configoutgoingfw, $configoutgoing, $Lang::tr{'outgoing firewall'});
+       &viewtablenew(\%configinputfw, $configinput, $Lang::tr{'incoming firewall access'});
+       &viewtablenew(\%configoutgoingfw, $configoutgoing, $Lang::tr{'outgoing firewall access'});
 }
 sub viewtablenew
 {
@@ -2350,26 +2519,18 @@ END
                                if($$hash{$key}[3] eq  'ipsec_net_src'){
                                        if(&fwlib::get_ipsec_net_ip($host,11) eq ''){
                                                $coloryellow='on';
-                                               &disable_rule($key);
-                                               $$hash{$key}[2]='';
                                        }
                                }elsif($$hash{$key}[3] eq  'ovpn_net_src'){
                                        if(&fwlib::get_ovpn_net_ip($host,1) eq ''){
                                                $coloryellow='on';
-                                               &disable_rule($key);
-                                               $$hash{$key}[2]='';
                                        }
                                }elsif($$hash{$key}[3] eq  'ovpn_n2n_src'){
                                        if(&fwlib::get_ovpn_n2n_ip($host,27) eq ''){
                                                $coloryellow='on';
-                                               &disable_rule($key);
-                                               $$hash{$key}[2]='';
                                        }
                                }elsif($$hash{$key}[3] eq  'ovpn_host_src'){
                                        if(&fwlib::get_ovpn_host_ip($host,33) eq ''){
                                                $coloryellow='on';
-                                               &disable_rule($key);
-                                               $$hash{$key}[2]='';
                                        }
                                }
                        }
@@ -2377,26 +2538,18 @@ END
                                if($$hash{$key}[5] eq 'ipsec_net_tgt'){
                                        if(&fwlib::get_ipsec_net_ip($host,11) eq ''){
                                                $coloryellow='on';
-                                               &disable_rule($key);
-                                               $$hash{$key}[2]='';
                                        }
                                }elsif($$hash{$key}[5] eq 'ovpn_net_tgt'){
                                        if(&fwlib::get_ovpn_net_ip($host,1) eq ''){
                                                $coloryellow='on';
-                                               &disable_rule($key);
-                                               $$hash{$key}[2]='';
                                        }
                                }elsif($$hash{$key}[5] eq 'ovpn_n2n_tgt'){
                                        if(&fwlib::get_ovpn_n2n_ip($host,27) eq ''){
                                                $coloryellow='on';
-                                               &disable_rule($key);
-                                               $$hash{$key}[2]='';
                                        }
                                }elsif($$hash{$key}[5] eq 'ovpn_host_tgt'){
                                        if(&fwlib::get_ovpn_host_ip($host,33) eq ''){
                                                $coloryellow='on';
-                                               &disable_rule($key);
-                                               $$hash{$key}[2]='';
                                        }
                                }
                        }
@@ -2404,15 +2557,11 @@ END
                        foreach my $netgroup (sort keys %customgrp){
                                if(($$hash{$key}[4] eq $customgrp{$netgroup}[0] || $$hash{$key}[6] eq $customgrp{$netgroup}[0]) && $customgrp{$netgroup}[2] eq 'none'){
                                        $coloryellow='on';
-                                       &disable_rule($key);
-                                       $$hash{$key}[2]='';
                                }
                        }
                        foreach my $srvgroup (sort keys %customservicegrp){
                                if($$hash{$key}[15] eq $customservicegrp{$srvgroup}[0] && $customservicegrp{$srvgroup}[2] eq 'none'){
                                        $coloryellow='on';
-                                       &disable_rule($key);
-                                       $$hash{$key}[2]='';
                                }
                        }
                        $$hash{'ACTIVE'}=$$hash{$key}[2];
@@ -2472,7 +2621,7 @@ END
                                push (@protocols,$Lang::tr{'all'});
                        }
 
-                       my $protz=join(",",@protocols);
+                       my $protz=join(", ",@protocols);
                        if($protz eq 'ICMP' && $$hash{$key}[9] ne 'All ICMP-Types' && $$hash{$key}[14] ne 'cust_srvgrp'){
                                &General::readhasharray("${General::swroot}/fwhosts/icmp-types", \%icmptypes);
                                foreach my $keyicmp (sort { ncmp($icmptypes{$a}[0],$icmptypes{$b}[0]) }keys %icmptypes){
@@ -2481,6 +2630,8 @@ END
                                                last;
                                        }
                                }
+                       }elsif($#protocols gt '3'){
+                               print"<td align='center'><span title='$protz'>$Lang::tr{'fwdfw many'}</span></td>";
                        }else{
                                print"<td align='center'>$protz</td>";
                        }
@@ -2501,6 +2652,13 @@ END
                                }else{
                                        print $$hash{$key}[4];
                                }
+                       }elsif ($$hash{$key}[3] eq 'cust_geoip_src') {
+                               my ($split1,$split2) = split(":", $$hash{$key}[4]);
+                               if ($split2) {
+                                       print "$split2\n";
+                               }else{
+                                       print "$Lang::tr{'geoip'}: $$hash{$key}[4]\n";
+                               }
                        }elsif ($$hash{$key}[4] eq 'RED1'){
                                print "$ipfireiface $Lang::tr{'fwdfw red'}";
                        }elsif ($$hash{$key}[4] eq 'ALL'){
@@ -2547,8 +2705,21 @@ END
                                        <td align='center' $tdcolor>
 END
                        #Is this a DNAT rule?
+                       my $natstring;
                        if ($$hash{$key}[31] eq 'dnat' && $$hash{$key}[28] eq 'ON'){
-                               print "Firewall ($$hash{$key}[29])";
+                               if ($$hash{$key}[29] eq 'Default IP'){$$hash{$key}[29]=$Lang::tr{'red1'};}
+                               if ($$hash{$key}[29] eq 'AUTO'){
+                                       my @src_addresses=&fwlib::get_addresses(\%$hash,$key,'src');
+                                       my @nat_ifaces;
+                                       foreach my $val (@src_addresses){
+                                               push (@nat_ifaces,&fwlib::get_nat_address($$hash{$key}[29],$val));
+                                       }
+                                       @nat_ifaces=&del_double(@nat_ifaces);
+                                       $natstring = "";
+                               }else{
+                                       $natstring = "($$hash{$key}[29])";
+                               }
+                               print "$Lang::tr{'firewall'} $natstring";
                                if($$hash{$key}[30] ne ''){
                                        $$hash{$key}[30]=~ tr/|/,/;
                                        print": $$hash{$key}[30]";
@@ -2564,6 +2735,13 @@ END
                                }else{
                                        print $$hash{$key}[6];
                                }
+                       }elsif ($$hash{$key}[5] eq 'cust_geoip_tgt') {
+                               my ($split1,$split2) = split(":", $$hash{$key}[6]);
+                               if ($split2) {
+                                       print "$split2\n";
+                               }else{
+                                       print "$Lang::tr{'geoip'}: $$hash{$key}[6]\n";
+                               }
                        }elsif ($$hash{$key}[5] eq 'tgt_addr'){
                                my ($split1,$split2) = split("/",$$hash{$key}[6]);
                                if ($split2 eq '32'){
@@ -2581,7 +2759,6 @@ END
                        #RULE ACTIVE
                        if($$hash{$key}[2] eq 'ON'){
                                $gif="/images/on.gif"
-                               
                        }else{
                                $gif="/images/off.gif"
                        }