]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - html/cgi-bin/firewall.cgi
Merge branch 'next' of ssh://git.ipfire.org/pub/git/ipfire-2.x into next-suricata
[ipfire-2.x.git] / html / cgi-bin / firewall.cgi
index badee6b3c02ac115f4d9eda0abc02ae928ebd896..fb1c25dfd577a016a3fefdf76456f7c39811fcb9 100644 (file)
@@ -31,8 +31,10 @@ no warnings 'uninitialized';
 #use CGI::Carp 'fatalsToBrowser';
 
 require '/var/ipfire/general-functions.pl';
+require '/var/ipfire/network-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"); }
@@ -47,6 +49,7 @@ my %defaultNetworks=();
 my %netsettings=();
 my %customhost=();
 my %customgrp=();
+my %customgeoipgrp=();
 my %customnetworks=();
 my %customservice=();
 my %customservicegrp=();
@@ -66,6 +69,7 @@ my %ipsecsettings=();
 my %aliases=();
 my %optionsfw=();
 my %ifaces=();
+my %rulehash=();
 
 my @PROTOCOLS = ("TCP", "UDP", "ICMP", "IGMP", "AH", "ESP", "GRE","IPv6","IPIP");
 
@@ -73,6 +77,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";
@@ -153,6 +158,19 @@ print<<END;
                        \$("#actions").toggle();
                });
 
+               // Hide SNAT items when DNAT is selected and vice versa.
+               if (\$('input[name=nat]:checked').val() == 'dnat') {
+                       \$('.snat').hide();
+               } else {
+                       \$('.dnat').hide();
+               }
+
+               // Show/Hide elements when SNAT/DNAT get changed.
+               \$('input[name=nat]').change(function() {
+                       \$('.snat').toggle();
+                       \$('.dnat').toggle();
+               });
+
                // Time constraints
                if(!\$("#USE_TIME_CONSTRAINTS").attr("checked")) {
                        \$("#TIME_CONSTRAINTS").hide();
@@ -194,6 +212,7 @@ if ($fwdfwsettings{'ACTION'} eq 'saverule')
        &General::readhasharray("$configfwdfw", \%configfwdfw);
        &General::readhasharray("$configinput", \%configinputfw);
        &General::readhasharray("$configoutgoing", \%configoutgoingfw);
+       my $maxkey;
        #Set Variables according to the JQuery code in protocol section
        if ($fwdfwsettings{'PROT'} eq 'TCP' || $fwdfwsettings{'PROT'} eq 'UDP')
        {
@@ -222,165 +241,84 @@ if ($fwdfwsettings{'ACTION'} eq 'saverule')
                        $checkorange='on';
                }
        }
-       #check useless rules
-       if(     ($fwdfwsettings{$fwdfwsettings{'grp1'}} eq 'ORANGE' || $checkorange eq 'on') && $fwdfwsettings{'grp2'} eq 'ipfire'){
-               $errormessage.=$Lang::tr{'fwdfw useless rule'}."<br>";
-       }
        #check if we try to break rules
        if(     $fwdfwsettings{'grp1'} eq 'ipfire_src' && $fwdfwsettings{'grp2'} eq 'ipfire'){
                $errormessage=$Lang::tr{'fwdfw err same'};
        }
-       #INPUT part
-       if($fwdfwsettings{'grp2'} eq 'ipfire' && $fwdfwsettings{$fwdfwsettings{'grp1'}} ne 'ORANGE'){
+       # INPUT part
+       if ($fwdfwsettings{'grp2'} eq 'ipfire' && $fwdfwsettings{$fwdfwsettings{'grp1'}} ne 'ORANGE'){
                $fwdfwsettings{'config'}=$configinput;
                $fwdfwsettings{'chain'} = 'INPUTFW';
-               my $maxkey=&General::findhasharraykey(\%configinputfw);
-               #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'},$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';
-                                               }
-                               }
-                       }
-               }
-               #check Rulepos on new Rule
-               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'},$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{'nosave'} eq 'on' && $fwdfwsettings{'updatefwrule'} eq 'on'){
-                               $errormessage='';
-                               $fwdfwsettings{'nosave2'} = 'on';
-                       }
-               }
-               if (!$errormessage){
-                       if($fwdfwsettings{'nosave2'} ne 'on'){
-                               &saverule(\%configinputfw,$configinput);
-                       }
-               }
-       }elsif($fwdfwsettings{'grp1'} eq 'ipfire_src' ){
+               $maxkey=&General::findhasharraykey(\%configinputfw);
+               %rulehash=%configinputfw;
+       }elsif ($fwdfwsettings{'grp1'} eq 'ipfire_src' ){
        # OUTGOING PART
                $fwdfwsettings{'config'}=$configoutgoing;
                $fwdfwsettings{'chain'} = 'OUTGOINGFW';
-               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'},$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';
-                                               }
-                               }
-                       }
-               }
-               #check Rulepos on new Rule
-               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'},$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{'nosave'} eq 'on' && $fwdfwsettings{'updatefwrule'} eq 'on'){
-                               $fwdfwsettings{'nosave2'} = 'on';
-                               $errormessage='';
-                       }
-               }
-               #increase counters
-               if (!$errormessage){
-                       if ($fwdfwsettings{'nosave2'} ne 'on'){
-                               &saverule(\%configoutgoingfw,$configoutgoing);
-                       }
-               }
-       }else{
-               #FORWARD PART
+               $maxkey=&General::findhasharraykey(\%configoutgoingfw);
+               %rulehash=%configoutgoingfw;
+       }else {
+       # FORWARD PART
                $fwdfwsettings{'config'}=$configfwdfw;
                $fwdfwsettings{'chain'} = 'FORWARDFW';
-               my $maxkey=&General::findhasharraykey(\%configfwdfw);
-               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'},$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>";
-                                               }
-                                               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';
-                                               }
-                               }
+               $maxkey=&General::findhasharraykey(\%configfwdfw);
+               %rulehash=%configfwdfw;
+       }
+       #check if we have an identical rule already
+       if($fwdfwsettings{'oldrulenumber'} eq $fwdfwsettings{'rulepos'}){
+               foreach my $key (sort keys %rulehash){
+                       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{'ruleremark'},$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 "$rulehash{$key}[0],$rulehash{$key}[2],$rulehash{$key}[3],$rulehash{$key}[4],$rulehash{$key}[5],$rulehash{$key}[6],$rulehash{$key}[7],$rulehash{$key}[8],$rulehash{$key}[9],$rulehash{$key}[10],$rulehash{$key}[11],$rulehash{$key}[12],$rulehash{$key}[13],$rulehash{$key}[14],$rulehash{$key}[15],$rulehash{$key}[16],$rulehash{$key}[17],$rulehash{$key}[18],$rulehash{$key}[19],$rulehash{$key}[20],$rulehash{$key}[21],$rulehash{$key}[22],$rulehash{$key}[23],$rulehash{$key}[24],$rulehash{$key}[25],$rulehash{$key}[26],$rulehash{$key}[27],$rulehash{$key}[28],$rulehash{$key}[29],$rulehash{$key}[30],$rulehash{$key}[31],$rulehash{$key}[32],$rulehash{$key}[33],$rulehash{$key}[34],$rulehash{$key}[35],$rulehash{$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';
+                                       }
                        }
                }
-               #check Rulepos on new Rule
-               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'},$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 Rulepos on new Rule
+       if($fwdfwsettings{'rulepos'} > 0 && !$fwdfwsettings{'oldrulenumber'}){
+               $fwdfwsettings{'oldrulenumber'}=$maxkey;
+               foreach my $key (sort keys %rulehash){
+                       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 "$rulehash{$key}[0],$rulehash{$key}[2],$rulehash{$key}[3],$rulehash{$key}[4],$rulehash{$key}[5],$rulehash{$key}[6],$rulehash{$key}[7],$rulehash{$key}[8],$rulehash{$key}[9],$rulehash{$key}[10],$rulehash{$key}[11],$rulehash{$key}[12],$rulehash{$key}[13],$rulehash{$key}[14],$rulehash{$key}[15],$rulehash{$key}[18],$rulehash{$key}[19],$rulehash{$key}[20],$rulehash{$key}[21],$rulehash{$key}[22],$rulehash{$key}[23],$rulehash{$key}[24],$rulehash{$key}[25],$rulehash{$key}[26],$rulehash{$key}[27],$rulehash{$key}[28],$rulehash{$key}[29],$rulehash{$key}[30],$rulehash{$key}[31],$rulehash{$key}[32],$rulehash{$key}[33],$rulehash{$key}[34],$rulehash{$key}[35],$rulehash{$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{'nosave'} eq 'on' && $fwdfwsettings{'updatefwrule'} eq 'on'){
-                               $fwdfwsettings{'nosave2'} = 'on';
-                               $errormessage='';
-                       }
+       }
+       #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{'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 max concurrent connections per ip address
+       if ($fwdfwsettings{'LIMIT_CON_CON'} eq 'ON'){
+               if (!($fwdfwsettings{'concon'} =~ /^(\d+)$/)) {
+                       $errormessage.=$Lang::tr{'fwdfw err concon'};
                }
-               #check ratelimit value
-               if ($fwdfwsettings{'RATE_LIMIT'} eq 'ON'){
-                       if (!($fwdfwsettings{'ratecon'} =~ /^(\d+)$/)) {
-                               $errormessage.=$Lang::tr{'fwdfw err ratecon'};
-                       }
-               }else{
-                       $fwdfwsettings{'ratecon'}='';
+       }else{
+               $fwdfwsettings{'concon'}='';
+       }
+       #check ratelimit value
+       if ($fwdfwsettings{'RATE_LIMIT'} eq 'ON'){
+               if (!($fwdfwsettings{'ratecon'} =~ /^(\d+)$/)) {
+                       $errormessage.=$Lang::tr{'fwdfw err ratecon'};
                }
-               #increase counters
-               if (!$errormessage){
-                       if ($fwdfwsettings{'nosave2'} ne 'on'){
-                               &saverule(\%configfwdfw,$configfwdfw);
-                       }
+       }else{
+               $fwdfwsettings{'ratecon'}='';
+       }
+       #increase counters
+       if (!$errormessage){
+               if ($fwdfwsettings{'nosave2'} ne 'on'){
+                       &saverule(\%rulehash,$fwdfwsettings{'config'});
                }
        }
        if ($errormessage){
@@ -524,6 +462,9 @@ sub checksource
                        }
                }
                if ($fwdfwsettings{'isip'} eq 'on'){
+                       #remove leading zero
+                       $ip = &Network::ip_remove_zero($ip);
+
                        ##check if ip is valid
                        if (! &General::validip($ip)){
                                $errormessage.=$Lang::tr{'fwdfw err src_addr'}."<br>";
@@ -594,16 +535,6 @@ sub checktarget
        #check DNAT settings (has to be single Host and single Port or portrange)
        if ($fwdfwsettings{'USE_NAT'} eq 'ON' && $fwdfwsettings{'nat'} eq 'dnat'){
                if($fwdfwsettings{'grp2'} eq 'tgt_addr' || $fwdfwsettings{'grp2'} eq 'cust_host_tgt' || $fwdfwsettings{'grp2'} eq 'ovpn_host_tgt'){
-                       #check if manual ip is a single Host (if set)
-                       if ($fwdfwsettings{'grp2'} eq 'tgt_addr'){
-                               my @tmp= split (/\./,$fwdfwsettings{$fwdfwsettings{'grp2'}});
-                               my @tmp1= split ("/",$tmp[3]);
-                               if (($tmp1[0] eq "0") || ($tmp1[0] eq "255"))
-                               {
-                                       $errormessage=$Lang::tr{'fwdfw dnat error'}."<br>";
-                                       return $errormessage;
-                               }
-                       }
                        #check if Port is a single Port or portrange
                        if ($fwdfwsettings{'nat'} eq 'dnat' &&  $fwdfwsettings{'grp3'} eq 'TGT_PORT'){
                                if(($fwdfwsettings{'PROT'} ne 'TCP'|| $fwdfwsettings{'PROT'} ne 'UDP') && $fwdfwsettings{'TGT_PORT'} eq ''){
@@ -628,11 +559,15 @@ sub checktarget
                        ($ip,$subnet)=split (/\//,$fwdfwsettings{'tgt_addr'});
                        $subnet = &General::iporsubtocidr($subnet);
                }
+
                #check if only ip
                if($fwdfwsettings{'tgt_addr'}=~/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/){
                        $ip=$fwdfwsettings{'tgt_addr'};
                        $subnet='32';
                }
+               #remove leading zero
+               $ip = &Network::ip_remove_zero($ip);
+
                #check if ip is valid
                if (! &General::validip($ip)){
                        $errormessage.=$Lang::tr{'fwdfw err tgt_addr'}."<br>";
@@ -656,7 +591,7 @@ sub checktarget
                &General::readhasharray("$confighost", \%customhost);
                foreach my $grpkey (sort keys %customgrp){
                        foreach my $hostkey (sort keys %customhost){
-                               if ($customgrp{$grpkey}[2] eq $customhost{$hostkey}[0] && $customhost{$hostkey}[1] eq 'mac'){
+                               if ($customgrp{$grpkey}[2] eq $customhost{$hostkey}[0] && $customgrp{$grpkey}[2] eq $fwdfwsettings{$fwdfwsettings{'grp2'}} && $customhost{$hostkey}[1] eq 'mac'){
                                        $hint=$Lang::tr{'fwdfw hint mac'};
                                        return $hint;
                                }
@@ -865,7 +800,7 @@ sub checkrule
                $errormessage.=$Lang::tr{'fwdfw err remark'}."<br>";
        }
        #check if source and target identical
-       if ($fwdfwsettings{$fwdfwsettings{'grp1'}} eq $fwdfwsettings{$fwdfwsettings{'grp2'}} && $fwdfwsettings{$fwdfwsettings{'grp1'}} ne 'ALL'){
+       if ($fwdfwsettings{$fwdfwsettings{'grp1'}} eq $fwdfwsettings{$fwdfwsettings{'grp2'}} && $fwdfwsettings{$fwdfwsettings{'grp1'}} ne 'ALL' && $fwdfwsettings{'grp2'} ne 'ipfire'){
                $errormessage=$Lang::tr{'fwdfw err same'};
                return $errormessage;
        }
@@ -1135,6 +1070,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
@@ -1174,11 +1157,31 @@ END
        #IPsec netze
        foreach my $key (sort { ncmp($ipsecconf{$a}[1],$ipsecconf{$b}[1]) } keys %ipsecconf) {
                if ($ipsecconf{$key}[3] eq 'net' || ($optionsfw{'SHOWDROPDOWN'} eq 'on' && $ipsecconf{$key}[3] ne 'host')){
-                       print"<tr><td valign='top'><input type='radio' name='$grp' value='ipsec_net_$srctgt' $checked{$grp}{'ipsec_net_'.$srctgt}></td><td >$Lang::tr{'fwhost ipsec net'}</td><td align='right'><select name='ipsec_net_$srctgt' style='width:200px;'>" if ($show eq '');
+                       print"<tr><td valign='top'><input type='radio' name='$grp' id='ipsec_net_$srctgt' value='ipsec_net_$srctgt' $checked{$grp}{'ipsec_net_'.$srctgt}></td><td >$Lang::tr{'fwhost ipsec net'}</td><td align='right'><select name='ipsec_net_$srctgt' style='width:200px;'>" if ($show eq '');
                        $show='1';
+
+                       #Check if we have more than one REMOTE subnet in config
+                       my @arr1 = split /\|/, $ipsecconf{$key}[11];
+                       my $cnt1 += @arr1;
+
                        print "<option ";
-                       print "selected='selected'" if ($fwdfwsettings{$fwdfwsettings{$grp}} eq $ipsecconf{$key}[1]);
-                       print ">$ipsecconf{$key}[1]</option>";
+                       print "value=$ipsecconf{$key}[1]";
+                       print " selected " if ($fwdfwsettings{$fwdfwsettings{$grp}} eq "$ipsecconf{$key}[1]");
+                       print ">$ipsecconf{$key}[1] ";
+                       print "($Lang::tr{'fwdfw all subnets'})" if $cnt1 > 1; #If this Conenction has more than one subnet, print one option for all subnets
+                       print "</option>";
+
+                       if ($cnt1 > 1){
+                               foreach my $val (@arr1){
+                                       #normalize subnet to cidr notation
+                                       my ($val1,$val2) = split /\//, $val;
+                                       my $val3 = &General::iporsubtocidr($val2);
+                                       print "<option ";
+                                       print "value='$ipsecconf{$key}[1]|$val1/$val3'";
+                                       print "selected " if ($fwdfwsettings{$fwdfwsettings{$grp}} eq "$ipsecconf{$key}[1]|$val1/$val3");
+                                       print ">$ipsecconf{$key}[1] ($val1/$val3)</option>";
+                               }
+                       }
                }
        }
        if($optionsfw{'SHOWDROPDOWN'} eq 'on' && $show eq ''){
@@ -1472,6 +1475,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=();
@@ -1666,7 +1670,7 @@ END
                                $Lang::tr{'fwdfw use nat'}
                        </label>
                        <div class="NAT">
-                               <table width='100%' border='0'>
+                               <table class='fw-nat' width='100%' border='0'>
                                        <tr>
                                                <td width='5%'></td>
                                                <td width='40%'>
@@ -1678,9 +1682,9 @@ END
 END
 
        print <<END;
-                                               <td width='25%' align='right'>$Lang::tr{'dnat address'}:</td>
+                                               <td width='25%' align='right'><span class='dnat'>$Lang::tr{'dnat address'}:</span></td>
                                                <td width='30%'>
-                                                       <select name='dnat' style='width: 100%;'>
+                                                       <select name='dnat' class='dnat' style='width: 100%;'>
                                                                <option value='AUTO' $selected{'dnat'}{'AUTO'}>- $Lang::tr{'automatic'} -</option>
                                                                <option value='Default IP' $selected{'dnat'}{'Default IP'}>$Lang::tr{'red1'} ($redip)</option>
 END
@@ -1711,9 +1715,9 @@ END
                                                                $Lang::tr{'fwdfw snat'}
                                                        </label>
                                                </td>
-                                               <td width='25%' align='right'>$Lang::tr{'snat new source ip address'}:</td>
+                                               <td width='25%' align='right'><span class='snat'>$Lang::tr{'snat new source ip address'}:</span></td>
                                                <td width='30%'>
-                                                       <select name='snat' style='width: 100%;'>
+                                                       <select name='snat' class='snat' style='width: 100%;'>
 END
 
                foreach my $alias (sort keys %aliases) {
@@ -2587,6 +2591,11 @@ END
                        #SOURCE
                        my $ipfireiface;
                        &getcolor($$hash{$key}[3],$$hash{$key}[4],\%customhost);
+                       # Check SRC Host and replace "|" with space
+                       if ($$hash{$key}[4] =~ /\|/){
+                               $$hash{$key}[4] =~ s/\|/ (/g;
+                               $$hash{$key}[4] = $$hash{$key}[4].")";
+                       }
                        print"<td align='center' width='30%' $tdcolor>";
                        if ($$hash{$key}[3] eq 'ipfire_src'){
                                $ipfireiface=$Lang::tr{'fwdfw iface'};
@@ -2600,6 +2609,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'){
@@ -2645,6 +2661,11 @@ END
                        print<<END;
                                        <td align='center' $tdcolor>
 END
+                       # Check TGT Host and replace "|" with space
+                       if ($$hash{$key}[6] =~ /\|/){
+                               $$hash{$key}[6] =~ s/\|/ (/g;
+                               $$hash{$key}[6] = $$hash{$key}[6].")";
+                       }
                        #Is this a DNAT rule?
                        my $natstring;
                        if ($$hash{$key}[31] eq 'dnat' && $$hash{$key}[28] eq 'ON'){
@@ -2676,6 +2697,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'){
@@ -2693,7 +2721,6 @@ END
                        #RULE ACTIVE
                        if($$hash{$key}[2] eq 'ON'){
                                $gif="/images/on.gif"
-                               
                        }else{
                                $gif="/images/off.gif"
                        }