]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blobdiff - html/cgi-bin/forwardfw.cgi
Forward Firewall: added SNAT multiport support
[people/teissler/ipfire-2.x.git] / html / cgi-bin / forwardfw.cgi
index 0bf3a31c3de423c7a01fff4f0929cd75e1000d32..7bd3fa52f6ddf2db7cf02c010140262fe67b37ae 100755 (executable)
@@ -77,7 +77,7 @@ my %aliases=();
 my %optionsfw=();
 my %ifaces=();
 
-my $VERSION='0.9.8.7';
+my $VERSION='0.9.9.4';
 my $color;
 my $confignet          = "${General::swroot}/fwhosts/customnetworks";
 my $confighost         = "${General::swroot}/fwhosts/customhosts";
@@ -133,6 +133,7 @@ if ($fwdfwsettings{'ACTION'} eq 'saverule')
        $errormessage=&checksource;
        if(!$errormessage){&checktarget;}
        if(!$errormessage){&checkrule;}
+       
        #check if manual ip (source) is orange network
        if ($fwdfwsettings{'grp1'} eq 'src_addr'){
                my ($sip,$scidr) = split("/",$fwdfwsettings{$fwdfwsettings{'grp1'}});
@@ -160,26 +161,27 @@ if ($fwdfwsettings{'ACTION'} eq 'saverule')
                #check if we have an identical rule already
                if($fwdfwsettings{'oldrulenumber'} eq $fwdfwsettings{'rulepos'}){
                        foreach my $key (sort keys %confignatfw){
-                               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{'snatport'},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'}"
-                                       eq "$confignatfw{$key}[0],$confignatfw{$key}[2],$confignatfw{$key}[3],$confignatfw{$key}[4],$confignatfw{$key}[5],$confignatfw{$key}[6],$confignatfw{$key}[7],$confignatfw{$key}[8],$confignatfw{$key}[9],$confignatfw{$key}[10],$confignatfw{$key}[11],$confignatfw{$key}[12],$confignatfw{$key}[13],$confignatfw{$key}[14],$confignatfw{$key}[15],$confignatfw{$key}[17],$confignatfw{$key}[19],$confignatfw{$key}[20],$confignatfw{$key}[21],$confignatfw{$key}[22],$confignatfw{$key}[23],$confignatfw{$key}[24],$confignatfw{$key}[25],$confignatfw{$key}[26],$confignatfw{$key}[27],$confignatfw{$key}[28],$confignatfw{$key}[29],$confignatfw{$key}[30],$confignatfw{$key}[31],$confignatfw{$key}[32]"){
-                                               $errormessage.=$Lang::tr{'fwdfw err ruleexists'};                               
-                                               if ($fwdfwsettings{'oldruleremark'} ne $fwdfwsettings{'ruleremark'} && $fwdfwsettings{'updatefwrule'} eq 'on' ){
-                                                       $errormessage='';                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
-                                               }elsif($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'} eq $fwdfwsettings{'ruleremark'}){
-                                                       $fwdfwsettings{'nosave'} = 'on';
-                                               }
+                               if ("$confignatfw{$key}[0],$confignatfw{$key}[1],$confignatfw{$key}[2],$confignatfw{$key}[3],$confignatfw{$key}[4],$confignatfw{$key}[5],$confignatfw{$key}[6],$confignatfw{$key}[11],$confignatfw{$key}[12],$confignatfw{$key}[14],$confignatfw{$key}[15],$confignatfw{$key}[28],$confignatfw{$key}[29],$confignatfw{$key}[30],$confignatfw{$key}[31]"
+                               eq "$fwdfwsettings{'RULE_ACTION'},NAT_DESTINATION,$fwdfwsettings{'ACTIVE'},$fwdfwsettings{'grp1'},$fwdfwsettings{$fwdfwsettings{'grp1'}},$fwdfwsettings{'grp2'},$fwdfwsettings{$fwdfwsettings{'grp2'}},$fwdfwsettings{'USESRV'},$fwdfwsettings{'TGT_PROT'},$fwdfwsettings{'grp3'},$fwdfwsettings{$fwdfwsettings{'grp3'}},$fwdfwsettings{'USE_NAT'},$fwdfwsettings{$fwdfwsettings{'nat'}},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'}"){
+                                       $errormessage.=$Lang::tr{'fwdfw err ruleexists'};
+                                       if ($fwdfwsettings{'oldruleremark'} ne $fwdfwsettings{'ruleremark'} && $fwdfwsettings{'updatefwrule'} eq 'on' ){
+                                               $errormessage='';
+                                       }elsif($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'} 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 %confignatfw){
-                               print"$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{'snatport'},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'}<br>";
-                               print"$confignatfw{$key}[0],$confignatfw{$key}[2],$confignatfw{$key}[3],$confignatfw{$key}[4],$confignatfw{$key}[5],$confignatfw{$key}[6],$confignatfw{$key}[7],$confignatfw{$key}[8],$confignatfw{$key}[9],$confignatfw{$key}[10],$confignatfw{$key}[11],$confignatfw{$key}[12],$confignatfw{$key}[13],$confignatfw{$key}[14],$confignatfw{$key}[15],$confignatfw{$key}[17],$confignatfw{$key}[19],$confignatfw{$key}[20],$confignatfw{$key}[21],$confignatfw{$key}[22],$confignatfw{$key}[23],$confignatfw{$key}[24],$confignatfw{$key}[25],$confignatfw{$key}[26],$confignatfw{$key}[27],$confignatfw{$key}[28],$confignatfw{$key}[29],$confignatfw{$key}[30],$confignatfw{$key}[31],$confignatfw{$key}[32]<br>";
+                               #print"$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{'snatport'},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'}<br>";
+                               #print"$confignatfw{$key}[0],$confignatfw{$key}[2],$confignatfw{$key}[3],$confignatfw{$key}[4],$confignatfw{$key}[5],$confignatfw{$key}[6],$confignatfw{$key}[7],$confignatfw{$key}[8],$confignatfw{$key}[9],$confignatfw{$key}[10],$confignatfw{$key}[11],$confignatfw{$key}[12],$confignatfw{$key}[13],$confignatfw{$key}[14],$confignatfw{$key}[15],$confignatfw{$key}[17],$confignatfw{$key}[19],$confignatfw{$key}[20],$confignatfw{$key}[21],$confignatfw{$key}[22],$confignatfw{$key}[23],$confignatfw{$key}[24],$confignatfw{$key}[25],$confignatfw{$key}[26],$confignatfw{$key}[27],$confignatfw{$key}[28],$confignatfw{$key}[29],$confignatfw{$key}[30],$confignatfw{$key}[31],$confignatfw{$key}[32]<br>";
                                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{'snatport'},$fwdfwsettings{'dnatport'},$fwdfwsettings{'nat'}"
                                        eq "$confignatfw{$key}[0],$confignatfw{$key}[2],$confignatfw{$key}[3],$confignatfw{$key}[4],$confignatfw{$key}[5],$confignatfw{$key}[6],$confignatfw{$key}[7],$confignatfw{$key}[8],$confignatfw{$key}[9],$confignatfw{$key}[10],$confignatfw{$key}[11],$confignatfw{$key}[12],$confignatfw{$key}[13],$confignatfw{$key}[14],$confignatfw{$key}[15],$confignatfw{$key}[17],$confignatfw{$key}[19],$confignatfw{$key}[20],$confignatfw{$key}[21],$confignatfw{$key}[22],$confignatfw{$key}[23],$confignatfw{$key}[24],$confignatfw{$key}[25],$confignatfw{$key}[26],$confignatfw{$key}[27],$confignatfw{$key}[28],$confignatfw{$key}[29],$confignatfw{$key}[30],$confignatfw{$key}[31],$confignatfw{$key}[32]"){
                                                $errormessage.=$Lang::tr{'fwdfw err ruleexists'};
@@ -589,9 +591,9 @@ sub addrule
 {
        &error;
        if (-f "${General::swroot}/forward/reread"){
-               print "<table border='0'><form method='post'><td><input type='submit' name='ACTION' value='$Lang::tr{'fwdfw reread'}' style='font-face: Comic Sans MS; color: red; font-weight: bold;'>$Lang::tr{'fwhost reread'}</td></tr></table></form><hr><br>";
+               print "<table border='0'><form method='post'><td><div style='font-size:11pt; font-weight: bold;vertical-align: middle; '><input type='submit' name='ACTION' value='$Lang::tr{'fwdfw reread'}' style='font-face: Comic Sans MS; color: red; font-weight: bold; font-size: 14pt;'>&nbsp &nbsp $Lang::tr{'fwhost reread'}</div</td></tr></table></form><hr><br>";
        }
-       &Header::openbox('100%', 'left', $Lang::tr{'fwdfw addrule'});
+       &Header::openbox('100%', 'left', "");
        print "<form method='post'>";
        print "<table border='0'>";
        print "<tr><td><input type='submit' name='ACTION' value='$Lang::tr{'fwdfw newrule'}'></td>";
@@ -730,7 +732,7 @@ sub checksource
                my @values=();
                foreach (@parts){
                        chomp($_);
-                       if ($_ =~ /^(\d+)\:(\d+)$/) {
+                       if ($_ =~ /^(\d+)\-(\d+)$/ || $_ =~ /^(\d+)\:(\d+)$/) {
                                my $check;
                                #change dashes with :
                                $_=~ tr/-/:/;
@@ -738,11 +740,11 @@ sub checksource
                                        push(@values,"1:65535");
                                        $check='on';
                                }
-                               if ($_ =~ /^(\D)\:(\d+)$/) {
+                               if ($_ =~ /^(\D)\:(\d+)$/ || $_ =~ /^(\D)\-(\d+)$/) {
                                        push(@values,"1:$2");
                                        $check='on';
                                }
-                               if ($_ =~ /^(\d+)\:(\D)$/) {
+                               if ($_ =~ /^(\d+)\:(\D)$/ || $_ =~ /^(\d+)\-(\D)$/ ) {
                                        push(@values,"$1:65535");
                                        $check='on'
                                }
@@ -765,7 +767,35 @@ sub checksource
 sub checktarget
 {
        my ($ip,$subnet);
-
+       &General::readhasharray("$configsrv", \%customservice);
+       #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'){
+                       if ($fwdfwsettings{'USESRV'} eq '' && $fwdfwsettings{'dnatport'} eq ''){
+                               $errormessage=$Lang::tr{'fwdfw target'}.": ".$Lang::tr{'fwdfw dnat porterr'}."<br>";
+                       }
+                       #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>";
+                               }
+                       }
+                       #check if Port is a single Port or portrange
+                       if ($fwdfwsettings{'nat'} eq 'dnat' &&  $fwdfwsettings{'grp3'} eq 'TGT_PORT'){
+                               if(($fwdfwsettings{'TGT_PROT'} ne 'TCP'|| $fwdfwsettings{'TGT_PROT'} ne 'UDP') && $fwdfwsettings{'TGT_PORT'} eq ''){
+                                       $errormessage=$Lang::tr{'fwdfw target'}.": ".$Lang::tr{'fwdfw dnat porterr'}."<br>";
+                               }
+                               if (($fwdfwsettings{'TGT_PROT'} eq 'TCP'|| $fwdfwsettings{'TGT_PROT'} eq 'UDP') && $fwdfwsettings{'TGT_PORT'} ne '' && !&check_natport($fwdfwsettings{'TGT_PORT'})){
+                                       $errormessage=$Lang::tr{'fwdfw target'}.": ".$Lang::tr{'fwdfw dnat porterr'}."<br>";
+                               }
+                       }
+               }else{
+                       $errormessage=$Lang::tr{'fwdfw dnat error'}."<br>";
+               }
+       }
        if ($fwdfwsettings{'tgt_addr'} eq $fwdfwsettings{$fwdfwsettings{'grp2'}} && $fwdfwsettings{'tgt_addr'} ne ''){
                #check if ip with subnet
                if ($fwdfwsettings{'tgt_addr'} =~ /^(.*?)\/(.*?)$/) {
@@ -785,15 +815,12 @@ sub checktarget
                if(!&General::validipandmask($fwdfwsettings{'tgt_addr'})){
                        $errormessage.=$Lang::tr{'fwdfw err tgt_addr'}."<br>";
                }
-
        }elsif($fwdfwsettings{'tgt_addr'} eq $fwdfwsettings{$fwdfwsettings{'grp2'}} && $fwdfwsettings{'tgt_addr'} eq ''){
                $errormessage.=$Lang::tr{'fwdfw err notgtip'};
                return $errormessage;
        }
-
        #check empty fields
        if ($fwdfwsettings{$fwdfwsettings{'grp2'}} eq ''){ $errormessage.=$Lang::tr{'fwdfw err notgt'}."<br>";}
-
        #check tgt services
        if ($fwdfwsettings{'USESRV'} eq 'ON'){
                if ($fwdfwsettings{'grp3'} eq 'cust_srv'){
@@ -811,11 +838,14 @@ sub checktarget
                if ($fwdfwsettings{'grp3'} eq 'TGT_PORT'){
                        if ($fwdfwsettings{'TGT_PROT'} eq 'TCP' || $fwdfwsettings{'TGT_PROT'} eq 'UDP'){
                                if ($fwdfwsettings{'TGT_PORT'} ne ''){
+                                       if ($fwdfwsettings{'TGT_PORT'} =~ "," && $fwdfwsettings{'USE_NAT'} && $fwdfwsettings{'nat'} eq 'dnat') {
+                                               $errormessage=$Lang::tr{'fwdfw dnat porterr'}."<br>";
+                                       }
                                        my @parts=split(",",$fwdfwsettings{'TGT_PORT'});
                                        my @values=();
                                        foreach (@parts){
                                                chomp($_);
-                                               if ($_ =~ /^(\d+)\:(\d+)$/) {
+                                               if ($_ =~ /^(\d+)\-(\d+)$/ || $_ =~ /^(\d+)\:(\d+)$/) {
                                                        my $check;
                                                        #change dashes with :
                                                        $_=~ tr/-/:/;
@@ -823,11 +853,11 @@ sub checktarget
                                                                push(@values,"1:65535");
                                                                $check='on';
                                                        }
-                                                       if ($_ =~ /^(\D)\:(\d+)$/) {
+                                                       if ($_ =~ /^(\D)\:(\d+)$/ || $_ =~ /^(\D)\-(\d+)$/) {
                                                                push(@values,"1:$2");
                                                                $check='on';
                                                        }
-                                                       if ($_ =~ /^(\d+)\:(\D)$/) {
+                                                       if ($_ =~ /^(\d+)\:(\D)$/ || $_ =~ /^(\d+)\-(\D)$/) {
                                                                push(@values,"$1:65535");
                                                                $check='on'
                                                        }
@@ -875,7 +905,6 @@ sub checktarget
        if ($fwdfwsettings{'USESRV'} ne 'ON'){
                $fwdfwsettings{'grp3'}='';
                $fwdfwsettings{$fwdfwsettings{'grp3'}}='';
-               $fwdfwsettings{'TGT_PROT'}='';
                $fwdfwsettings{'ICMP_TGT'}='';
        }
        #check timeframe
@@ -886,8 +915,88 @@ sub checktarget
        }
        return $errormessage;
 }
+sub check_natport
+{
+       my $val=shift;
+       if($fwdfwsettings{'USE_NAT'} eq 'ON' && $fwdfwsettings{'nat'} eq 'dnat' && $fwdfwsettings{'dnatport'} ne ''){
+               if ($fwdfwsettings{'dnatport'} =~ /^(\d+)\-(\d+)$/) {
+                       $fwdfwsettings{'dnatport'} =~ tr/-/:/;
+                       if ($fwdfwsettings{'dnatport'} eq "*") {
+                               $fwdfwsettings{'dnatport'}="1:65535";
+                       }
+                       if ($fwdfwsettings{'dnatport'} =~ /^(\D)\:(\d+)$/) {
+                               $fwdfwsettings{'dnatport'} = "1:$2";
+                       }
+                       if ($fwdfwsettings{'dnatport'} =~ /^(\d+)\:(\D)$/) {
+                               $fwdfwsettings{'dnatport'} ="$1:65535";
+                       }
+               }
+               return 1;
+       }
+       if ($val =~ "," || $val>65536 || $val<0){
+               return 0;
+       }
+       return 1;
+}
 sub checkrule
 {
+       #check valid port for NAT
+       if($fwdfwsettings{'USE_NAT'} eq 'ON'){
+               #if no port is given in nat area, take target host port
+               if($fwdfwsettings{'nat'} eq 'dnat' && $fwdfwsettings{'grp3'} eq 'TGT_PORT' && $fwdfwsettings{'dnatport'} eq ''){$fwdfwsettings{'dnatport'}=$fwdfwsettings{'TGT_PORT'};}
+               #check if port given in nat area is a single valid port or portrange
+               if($fwdfwsettings{'nat'} eq 'dnat' && $fwdfwsettings{'TGT_PORT'} ne '' && !&check_natport($fwdfwsettings{'dnatport'})){
+                       $errormessage=$Lang::tr{'fwdfw target'}.": ".$Lang::tr{'fwdfw dnat porterr'}."<br>";
+               }elsif($fwdfwsettings{'USESRV'} eq 'ON' && $fwdfwsettings{'grp3'} eq 'cust_srv'){
+                       my $custsrvport;
+                       #get servcie Protocol and Port
+                       foreach my $key (sort keys %customservice){
+                               if($fwdfwsettings{$fwdfwsettings{'grp3'}} eq $customservice{$key}[0]){
+                                       if ($customservice{$key}[2] ne 'TCP' && $customservice{$key}[2] ne 'UDP'){
+                                               $errormessage=$Lang::tr{'fwdfw target'}.": ".$Lang::tr{'fwdfw dnat porterr'}."<br>";
+                                       }
+                                       $custsrvport= $customservice{$key}[1];
+                               }
+                       }
+                       if($fwdfwsettings{'nat'} eq 'dnat' && $fwdfwsettings{'dnatport'} eq ''){$fwdfwsettings{'dnatport'}=$custsrvport;}
+               }
+               #check if DNAT port is multiple
+               if($fwdfwsettings{'nat'} eq 'dnat' && $fwdfwsettings{'dnatport'} ne ''){
+                       my @parts=split(",",$fwdfwsettings{'dnatport'});
+                                       my @values=();
+                                       foreach (@parts){
+                                               chomp($_);
+                                               if ($_ =~ /^(\d+)\-(\d+)$/ || $_ =~ /^(\d+)\:(\d+)$/) {
+                                                       my $check;
+                                                       #change dashes with :
+                                                       $_=~ tr/-/:/;
+                                                       if ($_ eq "*") {
+                                                               push(@values,"1:65535");
+                                                               $check='on';
+                                                       }
+                                                       if ($_ =~ /^(\D)\:(\d+)$/ || $_ =~ /^(\D)\-(\d+)$/) {
+                                                               push(@values,"1:$2");
+                                                               $check='on';
+                                                       }
+                                                       if ($_ =~ /^(\d+)\:(\D)$/ || $_ =~ /^(\d+)\-(\D)$/) {
+                                                               push(@values,"$1:65535");
+                                                               $check='on'
+                                                       }
+                                                       $errormessage .= &General::validportrange($_, 'destination');
+                                                       if(!$check){
+                                                               push (@values,$_);
+                                                       }
+                                               }else{
+                                                       if (&General::validport($_)){
+                                                               push (@values,$_);
+                                                       }else{
+                                                               
+                                                       }
+                                               }
+                                       }
+                                       $fwdfwsettings{'dnatport'}=join("|",@values);
+               }
+       }
        #check valid remark
        if ($fwdfwsettings{'ruleremark'} ne '' && !&validremark($fwdfwsettings{'ruleremark'})){
                $errormessage.=$Lang::tr{'fwdfw err remark'}."<br>";
@@ -897,12 +1006,10 @@ sub checkrule
                $errormessage.=$Lang::tr{'fwdfw err same'};
                return $errormessage;
        }
-
        #get source and targetip address if possible
        my ($sip,$scidr,$tip,$tcidr);
        ($sip,$scidr)=&get_ip("src","grp1");
        ($tip,$tcidr)=&get_ip("tgt","grp2");
-
        #check same iprange in source and target
        if ($sip ne '' && $scidr ne '' && $tip ne '' && $tcidr ne ''){
                my $networkip1=&General::getnetworkip($sip,$scidr);
@@ -924,7 +1031,6 @@ sub checkrule
                        }
                }
        }
-
        #check source and destination protocol if manual
        if( $fwdfwsettings{'USE_SRC_PORT'} eq 'ON' && $fwdfwsettings{'USESRV'} eq 'ON'){
                        if($fwdfwsettings{'PROT'} ne $fwdfwsettings{'TGT_PROT'} && $fwdfwsettings{'grp3'} eq 'TGT_PORT'){
@@ -932,7 +1038,6 @@ sub checkrule
                }
                #check source and destination protocol if source manual and dest servicegrp
                if ($fwdfwsettings{'grp3'} eq 'cust_srv'){
-                       &General::readhasharray("$configsrv", \%customservice);
                        foreach my $key (sort keys %customservice){
                                if($customservice{$key}[0] eq $fwdfwsettings{$fwdfwsettings{'grp3'}}){
                                        if ($customservice{$key}[2] ne $fwdfwsettings{'PROT'}){
@@ -1442,6 +1547,7 @@ sub newrule
        $checked{'TIME_FRI'}{$fwdfwsettings{'TIME_FRI'}}                = 'CHECKED';
        $checked{'TIME_SAT'}{$fwdfwsettings{'TIME_SAT'}}                = 'CHECKED';
        $checked{'TIME_SUN'}{$fwdfwsettings{'TIME_SUN'}}                = 'CHECKED';
+       $checked{'USE_NAT'}{$fwdfwsettings{'USE_NAT'}}                  = 'CHECKED';
        $selected{'TIME_FROM'}{$fwdfwsettings{'TIME_FROM'}}             = 'selected';
        $selected{'TIME_TO'}{$fwdfwsettings{'TIME_TO'}}                 = 'selected';
        $selected{'ipfire'}{$fwdfwsettings{$fwdfwsettings{'grp2'}}} ='selected';
@@ -1481,10 +1587,9 @@ sub newrule
                                $fwdfwsettings{'TIME_FROM'}                             = $hash{$key}[26];
                                $fwdfwsettings{'TIME_TO'}                               = $hash{$key}[27];
                                $fwdfwsettings{'USE_NAT'}                               = $hash{$key}[28];
-                               $fwdfwsettings{'nat'}                                   = $hash{$key}[32]; #changed order
+                               $fwdfwsettings{'nat'}                                   = $hash{$key}[31]; #changed order
                                $fwdfwsettings{$fwdfwsettings{'nat'}}   = $hash{$key}[29];
-                               $fwdfwsettings{'snatport'}                              = $hash{$key}[30];
-                               $fwdfwsettings{'dnatport'}                              = $hash{$key}[31];
+                               $fwdfwsettings{'dnatport'}                              = $hash{$key}[30];
                                $checked{'grp1'}{$fwdfwsettings{'grp1'}}                                = 'CHECKED';
                                $checked{'grp2'}{$fwdfwsettings{'grp2'}}                                = 'CHECKED';
                                $checked{'grp3'}{$fwdfwsettings{'grp3'}}                                = 'CHECKED';
@@ -1551,11 +1656,7 @@ sub newrule
                }       
        }
        &Header::openbox('100%', 'left', $Lang::tr{'fwdfw addrule'});
-       if ($fwdfwsettings{'TIME'} eq 'ON'){    
-               $fwdfwsettings{'TIME_FROM'} = &timeconvert($fwdfwsettings{'TIME_FROM'},'');
-               $fwdfwsettings{'TIME_TO'} = &timeconvert($fwdfwsettings{'TIME_TO'},'');
-       }
-print "<form method='post'>";
+       print "<form method='post'>";
        &Header::closebox();
        &Header::openbox('100%', 'left', $Lang::tr{'fwdfw source'});
        #------SOURCE-------------------------------------------------------
@@ -1686,37 +1787,23 @@ END
                &Header::openbox('100%', 'left', 'NAT');
                print<<END;
                <table width='100%' border='0'>
-               <tr><td width='1%'><input type='checkbox' name='USE_NAT' value='ON' $checked{'USE_NAT'}{'ON'}></td><td>USE NAT</td><td colspan='5'></td></tr>
-               <tr><td colspan='2'></td><td width='1%'><input type='radio' name='nat' value='dnat' checked ></td><td width='20%'> DNAT</td>
+               <tr><td width='1%'><input type='checkbox' name='USE_NAT' value='ON' $checked{'USE_NAT'}{'ON'}></td><td width='15%'>$Lang::tr{'fwdfw use nat'}</td><td colspan='5'></td></tr>
+               <tr><td colspan='2'></td><td width='1%'><input type='radio' name='nat' value='dnat' checked ></td><td width='50%'>$Lang::tr{'fwdfw dnat'}</td>
 END
-               if (! -z "${General::swroot}/ethernet/aliases"){
-                       print"<td width='8%'>IPFire: </td><td width='20% align='right'><select name='dnat' style='width:140px;'>";
-                       print "<option value='ALL' $selected{'dnat'}{$Lang::tr{'all'}}>$Lang::tr{'all'}</option>";
-                       print "<option value='Default IP' $selected{'dnat'}{'Default IP'}>Default IP</option>";
-
-                       foreach my $alias (sort keys %aliases)
-                       {
-                               print "<option value='$alias' $selected{'dnat'}{$alias}>$alias</option>";
-                       }
-                       #foreach my $network (sort keys %defaultNetworks)
-                       #{
-                               #next if($defaultNetworks{$network}{'NAME'} eq "RED");
-                               #next if($defaultNetworks{$network}{'NAME'} eq "IPFire");
-                               #next if($defaultNetworks{$network}{'NAME'} eq "ALL");
-                               #print "<option value='$defaultNetworks{$network}{'NAME'}'";
-                               #print " selected='selected'" if ($fwdfwsettings{'snatipfire'} eq $defaultNetworks{$network}{'NAME'});
-                               #print ">$network</option>";
-                       #}
-               }else{
-                       print"<td></td><td style='width:200px;'><input type='hidden' name ='ipfire' value='Default IP'>";
+               print"<td width='8%'>IPFire: </td><td width='20%' align='right'><select name='dnat' style='width:140px;'>";
+               print "<option value='ALL' $selected{'dnat'}{$Lang::tr{'all'}}>$Lang::tr{'all'}</option>";
+               print "<option value='Default IP' $selected{'dnat'}{'Default IP'}>Default IP</option>";
+               foreach my $alias (sort keys %aliases)
+               {
+                       print "<option value='$alias' $selected{'dnat'}{$alias}>$alias</option>";
                }
                print"</td></tr>";
+               $fwdfwsettings{'dnatport'}=~ tr/|/,/;
                print"<tr><td colspan='4'></td><td>Port: </td><td align='right'><input type='text' name='dnatport' style='width:130px;' value=$fwdfwsettings{'dnatport'}> </td></tr>";
                print"<tr><td colspan='8'><br></td></tr>";
                #SNAT
-               print"<tr><td colspan='2'></td><td width='1%'><input type='radio' name='nat' value='snat'  $checked{'nat'}{'snat'}></td><td width='20%'> SNAT</td>";
-               print"<td width='8%'>IPFire: </td><td width='20% align='right'><select name='snat' style='width:140px;'>";
-               print "<option value='ALL' $selected{'snat'}{$Lang::tr{'all'}}>$Lang::tr{'all'}</option>";
+               print"<tr><td colspan='2'></td><td width='1%'><input type='radio' name='nat' value='snat'  $checked{'nat'}{'snat'}></td><td width='20%'>$Lang::tr{'fwdfw snat'}</td>";
+               print"<td width='8%'>IPFire: </td><td width='20%' align='right'><select name='snat' style='width:140px;'>";
                print "<option value='Default IP' $selected{'snat'}{'Default IP'}>Default IP</option>";
                foreach my $alias (sort keys %aliases)
                        {
@@ -1727,11 +1814,11 @@ END
                        next if($defaultNetworks{$network}{'NAME'} eq "RED");
                        next if($defaultNetworks{$network}{'NAME'} eq "IPFire");
                        next if($defaultNetworks{$network}{'NAME'} eq "ALL");
+                       next if($defaultNetworks{$network}{'NAME'} =~ /OpenVPN/i);
                        print "<option value='$defaultNetworks{$network}{'NAME'}'";
                        print " selected='selected'" if ($fwdfwsettings{$fwdfwsettings{'nat'}} eq $defaultNetworks{$network}{'NAME'});
                        print ">$network</option>";
                }
-               print"<tr><td colspan='4'></td><td>Port: </td><td align='right'><input type='text' name='snatport' style='width:130px;'value=$fwdfwsettings{'snatport'} > </td></tr>";
                print"</table>";
                print"<hr>";
                &Header::closebox();
@@ -1969,7 +2056,7 @@ sub saverule
                        #print"6";
                }
                #check if we change a DMZ to a FORWARD/DMZ
-               elsif($fwdfwsettings{'oldruletype'} eq 'DMZ'  && $fwdfwsettings{'chain'} eq 'FORWARDFW' ){
+               elsif($fwdfwsettings{'oldruletype'} eq 'DMZ'  && $fwdfwsettings{'chain'} eq 'FORWARDFW' && $fwdfwsettings{$fwdfwsettings{'grp1'}} ne 'ORANGE'){
                        &changerule($configdmz);
                        #print"7";
                }
@@ -2026,12 +2113,6 @@ sub saverule
                        &changerule($configfwdfw);
                        #print"17";
                }               
-               #Cleanup some values for NAT if they are not used
-               if($fwdfwsettings{'nat'} eq 'dnat'){
-                       $fwdfwsettings{'snatport'}='';
-               }else{
-                       $fwdfwsettings{'dnatport'}='';
-               }
                if ($fwdfwsettings{'updatefwrule'} ne 'on'){
                        my $key = &General::findhasharraykey ($hash);
                        $$hash{$key}[0]  = $fwdfwsettings{'RULE_ACTION'};
@@ -2065,9 +2146,8 @@ sub saverule
                        if($fwdfwsettings{'USE_NAT'} eq 'ON'){
                                $$hash{$key}[28] = $fwdfwsettings{'USE_NAT'};
                                $$hash{$key}[29] = $fwdfwsettings{$fwdfwsettings{'nat'}};
-                               $$hash{$key}[30] = $fwdfwsettings{'snatport'};
-                               $$hash{$key}[31] = $fwdfwsettings{'dnatport'};
-                               $$hash{$key}[32] = $fwdfwsettings{'nat'};
+                               $$hash{$key}[30] = $fwdfwsettings{'dnatport'};
+                               $$hash{$key}[31] = $fwdfwsettings{'nat'};
                        }
                        &General::writehasharray("$config", $hash);
                }else{
@@ -2104,9 +2184,8 @@ sub saverule
                                        if($fwdfwsettings{'USE_NAT'} eq 'ON'){
                                                $$hash{$key}[28] = $fwdfwsettings{'USE_NAT'};
                                                $$hash{$key}[29] = $fwdfwsettings{$fwdfwsettings{'nat'}};
-                                               $$hash{$key}[30] = $fwdfwsettings{'snatport'};
-                                               $$hash{$key}[31] = $fwdfwsettings{'dnatport'};
-                                               $$hash{$key}[32] = $fwdfwsettings{'nat'};
+                                               $$hash{$key}[30] = $fwdfwsettings{'dnatport'};
+                                               $$hash{$key}[31] = $fwdfwsettings{'nat'};
                                        }
                                        last;
                                }
@@ -2193,11 +2272,11 @@ sub validremark
 sub viewtablerule
 {
        &General::readhash("/var/ipfire/ethernet/settings", \%netsettings);
-       &viewtablenew(\%configdmzfw,$configdmz,$Lang::tr{'fwdfw rules'},"DMZ" );
+       &viewtablenew(\%confignatfw,$confignat,"$Lang::tr{'fwdfw rules'}","Portforward / SNAT" );
        &viewtablenew(\%configfwdfw,$configfwdfw,"","Forward" );
-       &viewtablenew(\%configinputfw,$configinput,"",$Lang::tr{'external access'} );
        &viewtablenew(\%configoutgoingfw,$configoutgoing,"","Outgoing" );
-       &viewtablenew(\%confignatfw,$confignat,"","NAT" );
+       &viewtablenew(\%configinputfw,$configinput,"",$Lang::tr{'fwdfw xt access'} );
+       &viewtablenew(\%configdmzfw,$configdmz,"","DMZ" );
 }
 sub viewtablenew
 {
@@ -2288,12 +2367,7 @@ END
                                $tooltip='REJECT';
                                $rulecolor=$color{'color16'};
                        }
-                       if($$hash{$key}[28] eq 'ON'){
-                               print"<td bgcolor='$color' align='center' width='20'></td>";
-                               $rulecolor=$color;
-                       }else{
-                               print"<td bgcolor='$rulecolor' align='center' width='20'><span title='$tooltip'><b>$ruletype</b></span></td>";
-                       }
+                       print"<td bgcolor='$rulecolor' align='center' width='20'><span title='$tooltip'><b>$ruletype</b></span></td>";
                        &getcolor($$hash{$key}[3],$$hash{$key}[4],\%customhost);
                        print"<td align='center' width='160' $tdcolor>";
                        if ($$hash{$key}[3] eq 'std_net_src'){
@@ -2304,7 +2378,7 @@ END
                        $tdcolor='';
                        &getsrcport(\%$hash,$key);
                        #Is this a SNAT rule?
-                       if ($$hash{$key}[32] eq 'snat'){
+                       if ($$hash{$key}[31] eq 'snat'){
                                print"<br>SNAT -> $$hash{$key}[29]";
                                if ($$hash{$key}[30] ne ''){
                                        print": $$hash{$key}[30]";
@@ -2329,10 +2403,11 @@ END
                        <td align='center' width='160' $tdcolor>
 END
                        #Is this a DNAT rule?
-                       if ($$hash{$key}[32] eq 'dnat'){
+                       if ($$hash{$key}[31] eq 'dnat'){
                                print "IPFire ($$hash{$key}[29])";
-                               if($$hash{$key}[31] ne ''){
-                                       print": $$hash{$key}[31]";
+                               if($$hash{$key}[30] ne ''){
+                                       $$hash{$key}[30]=~ tr/|/,/;
+                                       print": $$hash{$key}[30]";
                                }
                                print"<br> DNAT->";
                        }