Revision: 2781
          http://ipcop.svn.sourceforge.net/ipcop/?rev=2781&view=rev
Author:   dotzball
Date:     2009-05-04 20:09:16 +0000 (Mon, 04 May 2009)

Log Message:
-----------
New code for Portforwarding rules (webgui+puzzleFwRules.pl). 

Part 1 (I split this in multiple commits)
 -> WebGUI

As I don't have enough spare hardware to test, I can't 100% say 
if portforwarding is working (correctly), from my tests it should do
it... So please test this new feature!

In old portforwarding there where created some MANGLE/MARK 
iptables rules. In setportfw.c there was this comment:
    "Note: if some one remember why the MARK rule ...."
As (in my tests which are not 100% valid!) those rules where not 
needed, but please test this in your environment...

There are some TODOs left:
-> More validation checks when creating rules, change custom 
   addresses, use custom addresses, change custom services,
   change custom services...


Those things I will do later/now but wanted to have the portforwarding 
in SVN so others can test/use it.

Modified Paths:
--------------
    ipcop/trunk/html/cgi-bin/fwrules.cgi

Modified: ipcop/trunk/html/cgi-bin/fwrules.cgi
===================================================================
--- ipcop/trunk/html/cgi-bin/fwrules.cgi        2009-05-04 14:53:24 UTC (rev 
2780)
+++ ipcop/trunk/html/cgi-bin/fwrules.cgi        2009-05-04 20:09:16 UTC (rev 
2781)
@@ -131,6 +131,9 @@
     elsif ($cgiparams{'RULETYPE'} eq 'DMZHOLES') {
         $ruletype = 'DMZHOLES';
     }
+    elsif ($cgiparams{'RULETYPE'} eq 'PORTFW') {
+        $ruletype = 'PORTFW';
+    }
     elsif ($cgiparams{'RULETYPE'} ne 'FORWARD') {
         die 'false Ruletype';
     }
@@ -228,6 +231,9 @@
     elsif ($cgiparams{'RULETYPE'} eq 'DMZHOLES') {
         $ruletype = 'DMZHOLES';
     }
+    elsif ($cgiparams{'RULETYPE'} eq 'PORTFW') {
+        $ruletype = 'PORTFW';
+    }
     elsif ($cgiparams{'RULETYPE'} ne 'FORWARD') {
         die 'false Ruletype';
     }
@@ -261,6 +267,9 @@
     elsif ($cgiparams{'RULETYPE'} eq 'DMZHOLES') {
         $ruletype = 'DMZHOLES';
     }
+    elsif ($cgiparams{'RULETYPE'} eq 'PORTFW') {
+        $ruletype = 'PORTFW';
+    }
     elsif ($cgiparams{'RULETYPE'} ne 'FORWARD') {
         die 'false Ruletype';
     }
@@ -292,6 +301,12 @@
     elsif ($cgiparams{'RULETYPE'} eq 'EXTERNAL') {
         $ruletype = 'EXTERNAL';
     }
+    elsif ($cgiparams{'RULETYPE'} eq 'DMZHOLES') {
+        $ruletype = 'DMZHOLES';
+    }
+    elsif ($cgiparams{'RULETYPE'} eq 'PORTFW') {
+        $ruletype = 'PORTFW';
+    }
     elsif ($cgiparams{'RULETYPE'} ne 'FORWARD') {
         die 'false Ruletype';
     }
@@ -447,6 +462,11 @@
         print "<br />";
     }
 
+    if ($printMode eq 'all' || $cgiparams{'RULETYPE'} eq 'PORTFW') {
+        &printCurrentRules('PORTFW', $printMode);
+        print "<br />";
+    }
+
     print <<END;
 <table>
 <tr>
@@ -511,45 +531,65 @@
     <td colspan='6' class='boldbase' align='left'>
 END
 
+    my $dst_text = $Lang::tr{'destination'};
+    my $widthAdr = '24';
+    my $widthRemark = '37';
+
     if ($type eq 'FORWARD') {
         print "<b>$Lang::tr{'other network'}:</b>";
     }
     elsif ($type eq 'INPUT') {
+         $widthRemark = '42';
         print "<b>$Lang::tr{'ipcop access'}:</b>";
     }
     elsif ($type eq 'EXTERNAL') {
+        $widthRemark = '42';
         print "<b>$Lang::tr{'external ipcop access'}:</b>";
     }
     elsif ($type eq 'DMZHOLES') {
         print "<b>$Lang::tr{'pinholes'}:</b>";
     }
+    elsif ($type eq 'PORTFW') {
+        $widthAdr = '20';
+       $widthRemark = '29';
 
+        $dst_text = $Lang::tr{'pfw internal destination'};
+        print "<b>$Lang::tr{'port forwarding configuration'}:</b>";
+    }
+
+
     print <<END;
     </td>
 </tr>
 <tr>
     <td width='1%' class='boldbase' align='center'><b>#</b></td>
     <td width='4%' class='boldbase' align='center'><b>$Lang::tr{'net br 
iface'}</b></td>
-    <td width='24%' class='boldbase' 
align='center'><b>$Lang::tr{'source'}</b></td>
+    <td width='$widthAdr%' class='boldbase' 
align='center'><b>$Lang::tr{'source'}</b></td>
+END
+
+    if($type eq 'PORTFW') {
+        print <<END;
+            <td width='2%' class='boldbase' align='center'><b></b>&nbsp;</td>
+            <td width='$widthAdr%' class='boldbase' 
align='center'><b>$Lang::tr{'pfw ipcop destination'}</b></td>
+END
+    }
+
+    print <<END;
     <td width='2%' class='boldbase' 
align='center'><b>$Lang::tr{'log'}:</b></td>
     <td width='2%' class='boldbase' align='center'><b></b>&nbsp;</td>
 END
-    if (($type eq 'INPUT' || $type eq 'EXTERNAL')
-#~         || $FW::fwSettings{'ADV_MODE_ENABLE'} ne 'on')
-        && $type ne 'DMZHOLES')
+    if (($type ne 'INPUT' && $type ne 'EXTERNAL'))
     {
         print <<END;
-    <td width='24%' class='boldbase' 
align='center'><b>$Lang::tr{'destination'}</b></td>
-    <td width='42%' class='boldbase' 
align='center'><b>$Lang::tr{'remark'}</b></td>
+    <td width='5%' class='boldbase' align='center'><b>$Lang::tr{'net br 
iface'}</b></td>
 END
+
     }
-    else {
-        print <<END;
-    <td width='5%' class='boldbase' align='center'><b>$Lang::tr{'net br 
iface'}</b></td>
-    <td width='24%' class='boldbase' 
align='center'><b>$Lang::tr{'destination'}</b></td>
-    <td width='37%' class='boldbase' 
align='center'><b>$Lang::tr{'remark'}</b></td>
+    print <<END;
+    <td width='$widthAdr%' class='boldbase' 
align='center'><b>$dst_text</b></td>
+    <td width='$widthRemark%' class='boldbase' 
align='center'><b>$Lang::tr{'remark'}</b></td>
 END
-    }
+
     my $actionTitle = "<b>$Lang::tr{'action'}</b>";
     $actionTitle = '' if ($printMode ne 'all');
 
@@ -742,6 +782,19 @@
     <td class='boldbase'>$displayID</td>
     <td align='center' class='$srcNetColor'>$srcNet</td>
     <td align='center'>$srcaddr</td>
+END
+
+        if($type eq 'PORTFW') {
+            my $extAddr = $rule->{'PORTFW_EXT_ADR'};
+            $extAddr .= "&nbsp;:&nbsp;$rule->{'PORTFW_SERVICE'}";
+
+            print <<END;
+    <td align='center'><img src='/images/$forwardgif.gif' alt='$forwardalt' 
/></td>
+    <td align='center'>$extAddr</td>
+END
+        }
+
+        print <<END;
     <td align='center'>
         <form method='post' name='frm$id' action='$ENV{'SCRIPT_NAME'}'>
             <$imageType src='/images/$loggif.gif' alt='$Lang::tr{'logging'} 
$Lang::tr{'toggle enable disable'}' />
@@ -760,7 +813,7 @@
                 . $rule->{'DST_IP'}
                 . "<strong><font color='RED'>)</font></strong>";
         }
-        if ($type eq 'FORWARD' || $type eq 'DMZHOLES') {
+        if ($type eq 'FORWARD' || $type eq 'DMZHOLES' || $type eq 'PORTFW') {
 #~             if ($FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on' || $type eq 
'DMZHOLES') {
                 print "<td align='center' class='$destNetColor'>$destNet</td>";
 #~             }
@@ -1053,15 +1106,45 @@
 
 sub validateDestParams
 {
-    unless ($cgiparams{'RULETYPE'} =~ /^(INPUT|FORWARD|EXTERNAL|DMZHOLES)$/) {
+    unless ($cgiparams{'RULETYPE'} =~ 
/^(INPUT|FORWARD|EXTERNAL|DMZHOLES|PORTFW)$/) {
         $errormessage .= "$Lang::tr{'invalid dest'}<br />";
     }
 
-    if ($cgiparams{'RULETYPE'} eq 'FORWARD' || $cgiparams{'RULETYPE'} eq 
'DMZHOLES') {
+    if($cgiparams{'RULETYPE'} eq 'PORTFW') {
+
+        ######################
+        ## IPcop external destination
+        ######################
+        if ($cgiparams{'PORTFW_EXT_ADR'} eq '') {
+            $errormessage .= "$Lang::tr{'invalid ipcop red address'}<br />";
+        }
+
+        if ($cgiparams{'PORTFW_SERVICE_TYPE'} eq 'custom') {
+
+            # validproto
+            if ($cgiparams{'PORTFW_CUST_SERVICE'} eq '' || 
$cgiparams{'PORTFW_CUST_SERVICE'} eq 'BLANK') {
+                $errormessage .= "$Lang::tr{'invalid service'}<br />";
+            }
+        }
+        elsif ($cgiparams{'PORTFW_SERVICE_TYPE'} eq 'default') {
+
+            # validproto
+            if ($cgiparams{'PORTFW_DEFAULT_SERVICE'} eq '' || 
$cgiparams{'PORTFW_DEFAULT_SERVICE'} eq 'BLANK') {
+                $errormessage .= "$Lang::tr{'invalid service'}<br />";
+            }
+        }
+        else {
+            $errormessage .= "$Lang::tr{'none service type'}<br />";
+        }
+
+        # TODO: Check for reserved ports
+    }
+
+    if ($cgiparams{'RULETYPE'} eq 'FORWARD' || $cgiparams{'RULETYPE'} eq 
'DMZHOLES' || $cgiparams{'RULETYPE'} eq 'PORTFW') {
         if ($cgiparams{'DST_NET_TYPE'} eq 'defaultDestNet') {
             my $foundIface = 0;
 
-            # Any is not allowed in Pinholes
+            # Any is not allowed in Pinholes and in Portforwarding
             if ($cgiparams{'DEFAULT_DST_NET'} eq "Any" && 
$cgiparams{'RULETYPE'} eq 'FORWARD') {
                 $foundIface = 1;
             }
@@ -1077,16 +1160,16 @@
             if ($foundIface == 0) {
                 $errormessage .= "$Lang::tr{'invalid iface'}<br />";
             }
-            if ($cgiparams{'DEFAULT_DST_NET'} eq 'Any') {
+            if ($cgiparams{'DEFAULT_DST_NET'} eq 'Any' || 
$cgiparams{'RULETYPE'} eq 'PORTFW') {
                 $cgiparams{'INV_DST_NET'} = 'off';
             }
         }
-        elsif ($cgiparams{'DST_NET_TYPE'} eq 'colorDestNet') {
+        elsif ($cgiparams{'DST_NET_TYPE'} eq 'colorDestNet' && 
$cgiparams{'RULETYPE'} ne 'PORTFW') {
             if ($cgiparams{'COLOR_DST_NET'} !~ 
/^GREEN_COLOR|BLUE_COLOR|ORANGE_COLOR|RED_COLOR$/) {
                 $errormessage .= "$Lang::tr{'invalid iface color'}<br />";
             }
         }
-        elsif ($cgiparams{'DST_NET_TYPE'} eq 'custDestNet') {
+        elsif ($cgiparams{'DST_NET_TYPE'} eq 'custDestNet' && 
$cgiparams{'RULETYPE'} ne 'PORTFW') {
             if ($cgiparams{'CUST_DST_NET'} eq '' || $cgiparams{'CUST_DST_NET'} 
eq 'BLANK') {
                 $errormessage .= "$Lang::tr{'invalid iface'}<br />";
             }
@@ -1095,11 +1178,11 @@
             $errormessage .= "$Lang::tr{'none iface type'}<br />";
         }
 
-        if ($cgiparams{'INV_DST_NET'} ne 'on') {
+        if ($cgiparams{'INV_DST_NET'} ne 'on' || $cgiparams{'RULETYPE'} eq 
'PORTFW') {
             $cgiparams{'INV_DST_NET'} = 'off';
         }
 
-        if ($cgiparams{'DST_IP_TYPE'} eq 'defaultDstIP') {
+        if ($cgiparams{'DST_IP_TYPE'} eq 'defaultDstIP' && 
$cgiparams{'RULETYPE'} ne 'PORTFW') {
             if ($cgiparams{'DEFAULT_DST_IP'} eq '') {
                 $errormessage .= "$Lang::tr{'invalid net'}<br />";
             }
@@ -1118,13 +1201,26 @@
             if ($customAdr{$cgiparams{'CUST_DST_ADR'}}{'ADDRESS_TYPE'} eq 
'mac') {
                 $errormessage .= "$Lang::tr{'mac adr not as dest'}<br />";
             }
+            elsif($cgiparams{'RULETYPE'} eq 'PORTFW') {
+                my $mask = $customAdr{$cgiparams{'CUST_DST_ADR'}}{'NETMASK'};
+                if($mask ne '32' && $mask ne '255.255.255.255') {
+                    $errormessage .= "$Lang::tr{'only host ip adr allowed in 
portfw'}<br />";
+                }
+            }
         }
         elsif ($cgiparams{'DST_IP_TYPE'} eq 'ipDestTxt') {
-            if (!&General::validipormask($cgiparams{'DEST_IP_TXT'})) {
-                $errormessage .= "$Lang::tr{'ip bad'}<br />";
+            if($cgiparams{'RULETYPE'} eq 'PORTFW') {
+                if (!&General::validip($cgiparams{'DEST_IP_TXT'})) {
+                    $errormessage .= "$Lang::tr{'ip bad'}<br />";
+                }
             }
+            else {
+                if (!&General::validipormask($cgiparams{'DEST_IP_TXT'})) {
+                    $errormessage .= "$Lang::tr{'ip bad'}<br />";
+                }
+            }
         }
-        elsif ($cgiparams{'DST_IP_TYPE'} eq 'groupDestIP') {
+        elsif ($cgiparams{'DST_IP_TYPE'} eq 'groupDestIP' && 
$cgiparams{'RULETYPE'} ne 'PORTFW') {
             if ($cgiparams{'GROUP_DST_ADR'} eq '') {
                 $errormessage .= "$Lang::tr{'invalid address group'}<br />";
             }
@@ -1133,18 +1229,18 @@
             $errormessage .= "$Lang::tr{'none address type'}<br />";
         }
 
-        if ($cgiparams{'INV_DST_IP'} ne 'on') {
+        if ($cgiparams{'INV_DST_IP'} ne 'on' || $cgiparams{'RULETYPE'} eq 
'PORTFW') {
             $cgiparams{'INV_DST_IP'} = 'off';
         }
     }
 
-    if (!defined($cgiparams{'SERVICE_ON'}) || $cgiparams{'SERVICE_ON'}ne 'on') 
{
+    if (!defined($cgiparams{'SERVICE_ON'}) || $cgiparams{'SERVICE_ON'} ne 
'on') {
         $cgiparams{'SERVICE_ON'} = 'off';
     }
 
     if ($cgiparams{'SERVICE_ON'} eq 'on') {
 
-        if ($cgiparams{'SERVICE_TYPE'} eq 'serviceGroup') {
+        if ($cgiparams{'SERVICE_TYPE'} eq 'serviceGroup' && 
$cgiparams{'RULETYPE'} ne 'PORTFW') {
 
             # validproto
             if ($cgiparams{'SERVICE_GROUP'} eq '') {
@@ -1231,6 +1327,73 @@
 sub checkBetweenParams
 {
 
+    if($cgiparams{'RULETYPE'} eq 'PORTFW') {
+
+        my $destProto = '';
+        my $destPort = 0;
+        my $isRangeDestPort = 0;
+
+        my $extProto = '';
+        my $extPort = 0;
+        my $isRangeExtPort = 0;
+
+        my %customSrv = ();
+        &DATA::readCustServices(\%customSrv);
+        my %defaultServices = ();
+        &DATA::readDefaultServices(\%defaultServices);
+
+
+        if($cgiparams{'SERVICE_TYPE'} eq 'custom' ) {
+            if($customSrv{$cgiparams{'CUST_SERVICE'}}{'PORT_INVERT'} eq 'on') {
+                $errormessage .= "$Lang::tr{'invert port not allowed in 
portfw'}<br />";
+            }
+            if($customSrv{$cgiparams{'CUST_SERVICE'}}{'PROTOCOL_INVERT'} eq 
'on') {
+                $errormessage .= "$Lang::tr{'invert proto not allowed in 
portfw'}<br />";
+            }
+            $destProto = $customSrv{$cgiparams{'CUST_SERVICE'}}{'PROTOCOL'};
+            $destPort =  $customSrv{$cgiparams{'CUST_SERVICE'}}{'PORT_NR'};
+
+            if(&General::validportrange($destPort, 'dest') ne '') {
+                $isRangeDestPort = 1;
+            }
+        }
+        else {
+            # default service
+            $destProto = 
$defaultServices{$cgiparams{'DEFAULT_SERVICE'}}{'PROTOCOL'};
+            $destPort =  
$defaultServices{$cgiparams{'DEFAULT_SERVICE'}}{'PORT_NR'};
+        }
+
+
+        if($cgiparams{'PORTFW_SERVICE_TYPE'} eq 'custom') {
+            if($customSrv{$cgiparams{'PORTFW_CUST_SERVICE'}}{'PORT_INVERT'} eq 
'on') {
+                $errormessage .= "$Lang::tr{'invert port not allowed in 
portfw'}<br />";
+            }
+            
if($customSrv{$cgiparams{'PORTFW_CUST_SERVICE'}}{'PROTOCOL_INVERT'} eq 'on') {
+                $errormessage .= "$Lang::tr{'invert proto not allowed in 
portfw'}<br />";
+            }
+
+            $extProto = 
$customSrv{$cgiparams{'PORTFW_CUST_SERVICE'}}{'PROTOCOL'};
+            $extPort =  
$customSrv{$cgiparams{'PORTFW_CUST_SERVICE'}}{'PORT_NR'};
+
+            if(&General::validportrange($extPort, 'dest') ne '') {
+                $isRangeExtPort = 1;
+            }
+        }
+        else {
+            # default service
+            $extProto = 
$defaultServices{$cgiparams{'PORTFW_DEFAULT_SERVICE'}}{'PROTOCOL'};
+            $extPort =  
$defaultServices{$cgiparams{'PORTFW_DEFAULT_SERVICE'}}{'PORT_NR'};
+        }
+
+        if( ($isRangeDestPort || $isRangeExtPort) && ($destPort ne $extPort)) {
+            $errormessage .= "$Lang::tr{'using portrange in portfw'}<br />";
+        }
+        if($destProto ne $extProto) {
+            $errormessage .= "$Lang::tr{'same proto in portfw'}<br />";
+        }
+    }
+
+
     # set destinatiion interface in "normal" mode
 #~     if ($FW::fwSettings{'ADV_MODE_ENABLE'} ne 'on' && 
$cgiparams{'RULETYPE'} ne 'DMZHOLES') {
 #~         if (   $FW::interfaces{$cgiparams{'DEFAULT_SRC_NET'}}{'COLOR'} eq 
'GREEN_COLOR'
@@ -1676,6 +1839,12 @@
     $cgiparams{'SRC_PORT_ON'}       = 'off';
     $cgiparams{'SRC_PORT'}          = '';
     $cgiparams{'INV_SRC_PORT'}      = 'off';
+
+    $cgiparams{'PORTFW_EXT_ADR'} = '--';
+    $cgiparams{'PORTFW_SERVICE_TYPE'} = 'default';
+    $cgiparams{'PORTFW_CUST_SERVICE'} = '--';
+    $cgiparams{'PORTFW_DEFAULT_SERVICE'} = '--';
+
     $cgiparams{'RULETYPE'}          = 'FORWARD';
     $cgiparams{'OLD_RULETYPE'}      = 'FORWARD';
     $cgiparams{'DST_NET_TYPE'}      = 'defaultDestNet';
@@ -1754,7 +1923,6 @@
            <input type='hidden' name='RULETYPE' value='INPUT'  />
 END
     &printHiddenFormParams('addNewRule');
-    print "</form>";
 
     if (&FW::haveBlueNet() && &FW::haveGreenNet()
         || (&FW::haveBlueNet()))
@@ -1770,6 +1938,17 @@
         &printHiddenFormParams('addNewRule');
     }
 
+        print <<END;
+        </form>
+    </td>
+    <td align='left'>
+        <form method='post' action='$ENV{'SCRIPT_NAME'}'>
+           <input type='submit' name='ACTION' value='$Lang::tr{'ssport 
forwarding'}' />
+           <input type='hidden' name='RULETYPE' value='PORTFW'  />
+END
+    &printHiddenFormParams('addNewRule');
+
+
     print <<END;
         </form>
     </td>
@@ -1830,6 +2009,9 @@
     elsif ($cgiparams{'RULETYPE'} eq 'EXTERNAL') {
         $title = $Lang::tr{'external ipcop access'};
     }
+    elsif ($cgiparams{'RULETYPE'} eq 'PORTFW') {
+        $title = $Lang::tr{'ssport forwarding'};
+    }
 
     if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) {
         &Header::openbox('100%', 'left', "$Lang::tr{'edit a rule'}: $title", 
$error);
@@ -1899,6 +2081,27 @@
 <tr>
     <td  width='4%' class='base'></td>
     <td  width='1%' class='base'>
+END
+
+    if($cgiparams{'RULETYPE'} eq 'PORTFW')
+    {
+        # we filter source by IPcop external IP (red IP, Aliases etc.) -> 
don't restrict by interface
+        print <<END;
+        <input type='hidden' name='SRC_NET_TYPE' value='defaultSrcNet'  />
+    </td>
+    <td colspan='2' class='base'>
+        <input type='hidden' name='DEFAULT_SRC_NET' value='Any'  />
+        <input type='hidden' name='CUST_SRC_NET' 
value='$cgiparams{'CUST_SRC_NET'}' />
+        <input type='hidden' name='INV_SRC_NET' value='off' />
+    </td>
+</tr>
+
+END
+
+    }
+    else
+    {
+        print <<END;
         <input type='radio' name='SRC_NET_TYPE' value='defaultSrcNet' 
$radio{'SRC_NET_TYPE'}{'defaultSrcNet'} />
     </td>
     <td colspan='2' class='base'>
@@ -1906,64 +2109,75 @@
         <select name='DEFAULT_SRC_NET'>
 END
 
-    # External Access
-    if ($cgiparams{'RULETYPE'} eq 'EXTERNAL') {
-        foreach my $iface (sort keys %FW::interfaces) {
-            next if ($FW::interfaces{$iface}{'COLOR'} ne 'RED_COLOR');
-            print "<option value='$iface'";
-            print " selected='selected'" if ($cgiparams{'DEFAULT_SRC_NET'} eq 
$iface);
-            print ">$iface</option>";
+        # External Access
+        if ($cgiparams{'RULETYPE'} eq 'EXTERNAL') {
+            foreach my $iface (sort keys %FW::interfaces) {
+                next if ($FW::interfaces{$iface}{'COLOR'} ne 'RED_COLOR');
+                print "<option value='$iface'";
+                print " selected='selected'" if ($cgiparams{'DEFAULT_SRC_NET'} 
eq $iface);
+                print ">$iface</option>";
+            }
         }
-    }
+        # DMZ Pinholes
+        elsif ($cgiparams{'RULETYPE'} eq 'DMZHOLES') {
+            foreach my $iface (sort keys %FW::interfaces) {
 
-    # DMZ Pinholes
-    elsif ($cgiparams{'RULETYPE'} eq 'DMZHOLES') {
-        foreach my $iface (sort keys %FW::interfaces) {
+                # no red and no green
+                next
+                    if ($FW::interfaces{$iface}{'COLOR'} ne 'BLUE_COLOR'
+                    && $FW::interfaces{$iface}{'COLOR'} ne 'ORANGE_COLOR');
 
-            # no red and no green
-            next
-                if ($FW::interfaces{$iface}{'COLOR'} ne 'BLUE_COLOR'
-                && $FW::interfaces{$iface}{'COLOR'} ne 'ORANGE_COLOR');
+                # blue only if there is a green interface available
+                next if ($FW::interfaces{$iface}{'COLOR'} eq 'BLUE_COLOR' && 
&FW::haveGreenNet() == 0);
 
-            # blue only if there is a green interface available
-            next if ($FW::interfaces{$iface}{'COLOR'} eq 'BLUE_COLOR' && 
&FW::haveGreenNet() == 0);
-
-            # case orange and no green and no blue needs no check as the DMZ 
Pinholes option will not be availble then
-            print "<option value='$iface'";
-            print " selected='selected'" if ($cgiparams{'DEFAULT_SRC_NET'} eq 
$iface);
-            print ">$iface</option>";
+                # case orange and no green and no blue needs no check as the 
DMZ Pinholes option will not be availble then
+                print "<option value='$iface'";
+                print " selected='selected'" if ($cgiparams{'DEFAULT_SRC_NET'} 
eq $iface);
+                print ">$iface</option>";
+            }
         }
-    }
-    else {
+#~            # Port Forwarding
+#~         elsif ($cgiparams{'RULETYPE'} eq 'PORTFW') {
+#~             foreach my $iface (sort keys %FW::interfaces) {
 
-        # Filter this option on "normal" mode when this is a ACCEPT rule!
-        if ($cgiparams{'RULEACTION'} ne 'accept' || 
$FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on') {
-            print "<option value='Any'";
-            print " selected='selected'" if ($cgiparams{'DEFAULT_SRC_NET'} eq 
'Any');
-            print ">Any</option>";
+#~                 # only red
+#~                 next if ($FW::interfaces{$iface}{'COLOR'} ne 'RED_COLOR');
+
+#~                 print "<option value='$iface'";
+#~                 print " selected='selected'" if 
($cgiparams{'DEFAULT_SRC_NET'} eq $iface);
+#~                 print ">$iface</option>";
+#~             }
+#~         }
+        else {
+
+            # Filter this option on "normal" mode when this is a ACCEPT rule!
+            if ($cgiparams{'RULEACTION'} ne 'accept' || 
$FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on') {
+                print "<option value='Any'";
+                print " selected='selected'" if ($cgiparams{'DEFAULT_SRC_NET'} 
eq 'Any');
+                print ">Any</option>";
+            }
+            foreach my $iface (sort keys %FW::interfaces) {
+                print "<option value='$iface'";
+                print " selected='selected'" if ($cgiparams{'DEFAULT_SRC_NET'} 
eq $iface);
+                print ">$iface</option>";
+            }
         }
-        foreach my $iface (sort keys %FW::interfaces) {
-            print "<option value='$iface'";
-            print " selected='selected'" if ($cgiparams{'DEFAULT_SRC_NET'} eq 
$iface);
-            print ">$iface</option>";
-        }
-    }
 
-    print <<END;
+        print <<END;
         </select>
     </td>
 </tr>
 END
 
-    my %customIfaces = ();
-    &DATA::readCustIfaces(\%customIfaces);
-    my @customInterfaces = sort keys(%customIfaces);
+        my %customIfaces_src = ();
+        &DATA::readCustIfaces(\%customIfaces_src);
+        my @customInterfaces_src = sort keys(%customIfaces_src);
 
-    if (   $#customInterfaces >= 0
-        && $FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on'
-        && $cgiparams{'RULETYPE'} ne 'DMZHOLES')
-    {    # show this option only if there are Custom Interfaces available
-        print <<END;
+        if (   $#customInterfaces_src >= 0
+            && $FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on'
+            && $cgiparams{'RULETYPE'} ne 'DMZHOLES')
+        {    # show this option only if there are Custom Interfaces available
+            print <<END;
 <tr>
     <td class='base'></td>
     <td class='base'>
@@ -1974,28 +2188,28 @@
         <select name='CUST_SRC_NET'>
 END
 
-        print "<option value='BLANK' selected='selected'>N/A</option>" if 
($#customInterfaces < 0);
-        foreach my $iface (@customInterfaces) {
-            print "<option value='$iface'";
-            print " selected='selected'" if ($cgiparams{'CUST_SRC_NET'} eq 
$iface);
-            print ">$iface</option>";
-        }
-        print <<END;
+            print "<option value='BLANK' selected='selected'>N/A</option>" if 
($#customInterfaces_src < 0);
+            foreach my $iface (@customInterfaces_src) {
+                print "<option value='$iface'";
+                print " selected='selected'" if ($cgiparams{'CUST_SRC_NET'} eq 
$iface);
+                print ">$iface</option>";
+            }
+            print <<END;
         </select>
     </td>
 </tr>
 END
-    }
-    else {
-        print
-"<tr><td colspan='4'><input type='hidden' name='CUST_SRC_NET' 
value='$cgiparams{'CUST_SRC_NET'}' /></td></tr>\n";
-    }
+        }
+        else {
+            print
+    "<tr><td colspan='4'><input type='hidden' name='CUST_SRC_NET' 
value='$cgiparams{'CUST_SRC_NET'}' /></td></tr>\n";
+        }
 
-    if (   $FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on'
-        && $cgiparams{'RULETYPE'} ne 'EXTERNAL'
-        && $cgiparams{'RULETYPE'} ne 'DMZHOLES')
-    {
-        print <<END;
+        if (   $FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on'
+            && $cgiparams{'RULETYPE'} ne 'EXTERNAL'
+            && $cgiparams{'RULETYPE'} ne 'DMZHOLES')
+        {
+            print <<END;
 <tr>
     <td class='base'></td>
     <td class='base'></td>
@@ -2005,18 +2219,21 @@
     </td>
 </tr>
 END
-    }
-    else {
-        print "<tr><td colspan='4'><input type='hidden' name='INV_SRC_NET' 
value='off' /></td></tr>\n";
-    }
-    print <<END;
+        }
+        else {
+            print "<tr><td colspan='4'><input type='hidden' name='INV_SRC_NET' 
value='off' /></td></tr>\n";
+        }
+
+        print <<END;
 <tr>
     <td></td>
     <td colspan='3' bgcolor='#000000'><img src='/images/null.gif' width='1' 
height='1' border='0' alt='--------' /></td>
 </tr>
 END
 
-    if ($cgiparams{'RULETYPE'} ne 'EXTERNAL') {
+    }
+
+    if ($cgiparams{'RULETYPE'} eq 'EXTERNAL' || $cgiparams{'RULETYPE'} eq 
'PORTFW') {
         print <<END;
 <tr>
     <td class='base'></td>
@@ -2024,6 +2241,22 @@
         <input type='radio' name='SRC_ADR_TYPE' value='defaultSrcAdr' 
$radio{'SRC_ADR_TYPE'}{'defaultSrcAdr'} />
     </td>
     <td colspan='2' class='base'>
+        $Lang::tr{'address'}:&nbsp;
+        Any&nbsp;
+        <input type='hidden' name='DEFAULT_SRC_ADR' value='Any' />
+    </td>
+</tr>
+END
+    }
+    else
+    {
+        print <<END;
+<tr>
+    <td class='base'></td>
+    <td class='base'>
+        <input type='radio' name='SRC_ADR_TYPE' value='defaultSrcAdr' 
$radio{'SRC_ADR_TYPE'}{'defaultSrcAdr'} />
+    </td>
+    <td colspan='2' class='base'>
         $Lang::tr{'default networks'}:&nbsp;
         <select name='DEFAULT_SRC_ADR'>
 END
@@ -2040,21 +2273,6 @@
 </tr>
 END
     }
-    else {
-        print <<END;
-<tr>
-    <td class='base'></td>
-    <td class='base'>
-        <input type='radio' name='SRC_ADR_TYPE' value='defaultSrcAdr' 
$radio{'SRC_ADR_TYPE'}{'defaultSrcAdr'} />
-    </td>
-    <td colspan='2' class='base'>
-        $Lang::tr{'address'}:&nbsp;
-        Any&nbsp;
-        <input type='hidden' name='DEFAULT_SRC_ADR' value='Any' />
-    </td>
-</tr>
-END
-    }
 
     print <<END;
 <tr>
@@ -2145,7 +2363,7 @@
 "<tr><td colspan='4'><input type='hidden' name='GROUP_SRC_ADR' 
value='$cgiparams{'GROUP_SRC_ADR'}' /></td></tr>\n";
     }
 #######
-    if ($FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on') {
+    if ($FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on' && $cgiparams{'RULETYPE'} 
ne 'PORTFW') {
 
         print <<END;
 <tr>
@@ -2162,7 +2380,7 @@
         print "<tr><td colspan='4'><input type='hidden' name='INV_SRC_ADR' 
value='off' /></td></tr>\n";
     }
 
-    if ($FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on') {
+    if ($FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on'|| $cgiparams{'RULETYPE'} eq 
'PORTFW') {
         print <<END;
 <tr>
     <td></td>
@@ -2186,6 +2404,9 @@
         <input type='text' name='SRC_PORT' value='$cgiparams{'SRC_PORT'}' 
size='14' maxlength='12' />
     </td>
 </tr>
+END
+        if($cgiparams{'RULETYPE'} ne 'PORTFW') {
+            print <<END;
 <tr>
     <td class='base'></td>
     <td class='base'></td>
@@ -2195,6 +2416,12 @@
     </td>
 </tr>
 END
+        }
+        else
+        {
+            print "<tr><td colspan='4'>\n";
+            print "<input type='hidden' name='INV_SRC_PORT' value='off' 
/></td></tr>\n";
+        }
     }
     else {
         print "<tr><td colspan='4'><input type='hidden' name='SRC_PORT_ON' 
value='off' />\n";
@@ -2208,17 +2435,146 @@
 </table>
 END
 
+
 
###########################################################################################
+    # IPCop external destination for Port Forwarding
+############################################################################################
+    if ($cgiparams{'RULETYPE'} eq 'PORTFW') {
+
+    $radio{'PORTFW_SERVICE_TYPE'}{'custom'}                   = '';
+    $radio{'PORTFW_SERVICE_TYPE'}{'default'}                  = '';
+    $radio{'PORTFW_SERVICE_TYPE'}{$cgiparams{'PORTFW_SERVICE_TYPE'}} = 
"checked='checked'";
+
+        print <<END;
+<table width='100%'>
+<tr>
+    <td class='base' >
+        <b>$Lang::tr{'pfw ipcop destination'}</b>
+    </td>
+</tr>
+</table>
+
+<table width='100%' cellpadding='0' cellspacing='5' border='0'>
+<tr>
+    <td  width='4%' class='base'></td>
+    <td  width='1%' class='base'></td>
+    <td colspan='2' class='base'>
+        $Lang::tr{'alias ip'}:&nbsp;
+        <select name='PORTFW_EXT_ADR'>
+END
+        foreach my $ipcopAdr (sort keys %defaultNetworks) {
+            next unless ($defaultNetworks{$ipcopAdr}{'LOCATION'} eq "IPCOP" && 
$defaultNetworks{$ipcopAdr}{'COLOR'} eq "RED_COLOR");
+
+            my $aliasIp = "";
+            $aliasIp = " ($defaultNetworks{$ipcopAdr}{'ADR'})" if($ipcopAdr ne 
'Red Address');
+            print "<option value='$ipcopAdr'";
+            print " selected='selected'" if ($cgiparams{'PORTFW_EXT_ADR'} eq 
$ipcopAdr);
+            print ">".$ipcopAdr.$aliasIp."</option>";
+        }
+
+        print <<END;
+        </select>
+    </td>
+</tr>
+END
+
+
+  my %customSrv_pfw = ();
+    &DATA::readCustServices(\%customSrv_pfw);
+    my @customServices_pfw = keys(%customSrv_pfw);
+
+    if ($#customServices_pfw >= 0) {
+        print <<END;
+<tr>
+    <td class='base'></td>
+    <td class='base'></td>
+    <td class='base'>
+        <input type='radio' name='PORTFW_SERVICE_TYPE' value='custom' 
$radio{'PORTFW_SERVICE_TYPE'}{'custom'} />
+        $Lang::tr{'custom services'}:&nbsp;
+        <select name='PORTFW_CUST_SERVICE'>
+END
+        print "<option value='BLANK' selected='selected'>N/A</option>" if 
($#customServices_pfw < 0);
+        foreach my $service (sort @customServices_pfw) {
+            print "<option value='$service'";
+            print " selected='selected'" if ($cgiparams{'PORTFW_CUST_SERVICE'} 
eq $service);
+            print ">$service</option>";
+
+        }
+        print <<END;
+        </select>
+    </td>
+</tr>
+END
+    }
+    else {
+        print
+"<tr><td colspan='3'><input type='hidden' name='PORTFW_CUST_SERVICE' 
value='$cgiparams{'PORTFW_CUST_SERVICE'}' /></td></tr>\n";
+    }
+    print <<END;
+<tr>
+    <td class='base'></td>
+    <td class='base'></td>
+    <td class='base'>
+        <input type='radio' name='PORTFW_SERVICE_TYPE' value='default' 
$radio{'PORTFW_SERVICE_TYPE'}{'default'} />
+        $Lang::tr{'default services'}:&nbsp;
+        <select name='PORTFW_DEFAULT_SERVICE'>
+END
+
+    my %defaultServices_pfw = ();
+    &DATA::readDefaultServices(\%defaultServices_pfw);
+
+    print "<option value='BLANK'";
+    print "selected='selected'" if ($cgiparams{'PORTFW_DEFAULT_SERVICE'} eq 
'');
+    print ">-- $Lang::tr{'default services'} --</option>";
+    print "<option value='BLANK'> --- </option>";
+    foreach my $defService (sort keys %defaultServices_pfw) {
+        print "<option value='$defService'";
+        print " selected='selected'" if ($cgiparams{'PORTFW_DEFAULT_SERVICE'} 
eq $defService);
+        print ">$defService 
($defaultServices_pfw{$defService}{'PORT_NR'})</option>";
+
+    }
+    print <<END;
+        </select>
+    </td>
+</tr>
+<tr>
+    <td colspan='4' bgcolor='#000000'><img src='/images/null.gif' width='1' 
height='2' border='0' alt='--------' /></td>
+</tr>
+</table>
+END
+    }
+    else {
+        print <<END;
+<table width='100%' cellpadding='0' cellspacing='0' border='0'>
+<tr>
+    <td >
+        <input type='hidden' name='PORTFW_EXT_ADR' value='--' />
+        <input type='hidden' name='PORTFW_SERVICE_TYPE' value='--' />
+        <input type='hidden' name='PORTFW_CUST_SERVICE' value='--' />
+        <input type='hidden' name='PORTFW_DEFAULT_SERVICE' value='--' />
+    </td>
+</tr>
+</table>
+END
+    }
+
+
+###########################################################################################
     # Destination
 
############################################################################################
 
     my $ruletype_text = $Lang::tr{'ipcop access'};
+    my $destination_text = $Lang::tr{'destination'};
     if ($cgiparams{'RULETYPE'} eq 'FORWARD') {
         $ruletype_text = $Lang::tr{'other network'};
     }
     elsif ($cgiparams{'RULETYPE'} eq 'DMZHOLES') {
         $ruletype_text = $Lang::tr{'pinholes'};
     }
+    elsif ($cgiparams{'RULETYPE'} eq 'PORTFW') {
+        $destination_text = $Lang::tr{'pfw internal destination'};
+        $ruletype_text = $Lang::tr{'internal network'};
+    }
     elsif ($cgiparams{'RULETYPE'} eq 'EXTERNAL') {
         $ruletype_text = $Lang::tr{'external ipcop access'};
     }
@@ -2248,6 +2604,11 @@
     $radio{'DST_IP_TYPE'}{'custDestIP'}              = '';
     $radio{'DST_IP_TYPE'}{'groupDestIP'}             = '';
     $radio{'DST_IP_TYPE'}{'ipDestTxt'}               = '';
+    if($cgiparams{'RULETYPE'} eq 'PORTFW'
+        && $cgiparams{'DST_IP_TYPE'} ne 'custDestIP'
+        && $cgiparams{'DST_IP_TYPE'} ne 'ipDestTxt') {
+        $cgiparams{'DST_IP_TYPE'} = 'custDestIP';
+    }
     $radio{'DST_IP_TYPE'}{$cgiparams{'DST_IP_TYPE'}} = "checked='checked'";
 
     $checked{'INV_DST_IP'}{'off'}                    = '';
@@ -2267,7 +2628,7 @@
 <table width='100%'>
 <tr>
     <td class='base' >
-        <b>$Lang::tr{'destination'}</b>
+        <b>$destination_text</b>
     </td>
 </tr>
 </table>
@@ -2291,7 +2652,7 @@
 END
 
     if ($cgiparams{'RULETYPE'} ne 'EXTERNAL' && $cgiparams{'RULETYPE'} ne 
'INPUT') {
-        if ($cgiparams{'RULETYPE'} eq 'DMZHOLES') {
+        if ($cgiparams{'RULETYPE'} eq 'DMZHOLES' ||  $cgiparams{'RULETYPE'} eq 
'PORTFW') {
             print <<END;
 <tr>
     <td class='base'></td>
@@ -2303,13 +2664,18 @@
 END
             foreach my $iface (sort keys %FW::interfaces) {
 
-                # no red and no Orange
-                next
-                    if ($FW::interfaces{$iface}{'COLOR'} eq 'RED_COLOR'
-                    || $FW::interfaces{$iface}{'COLOR'} eq 'ORANGE_COLOR');
+                # no red
+                next if ($FW::interfaces{$iface}{'COLOR'} eq 'RED_COLOR');
 
-                # blue only if there is a orange interface available
-                next if ($FW::interfaces{$iface}{'COLOR'} eq 'BLUE_COLOR' && 
&FW::haveOrangeNet() == 0);
+                if($cgiparams{'RULETYPE'} eq 'DMZHOLES')
+                {
+                    # no Orange
+                    next if ($FW::interfaces{$iface}{'COLOR'} eq 
'ORANGE_COLOR');
+
+                    # blue only if there is a orange interface available
+                    next if ($FW::interfaces{$iface}{'COLOR'} eq 'BLUE_COLOR' 
&& &FW::haveOrangeNet() == 0);
+                }
+
                 print "<option value='$iface'";
                 print " selected='selected'" if ($cgiparams{'DEFAULT_DST_NET'} 
eq $iface);
                 print ">$iface</option>";
@@ -2378,8 +2744,12 @@
 </tr>
 END
 
+            my %customIfaces_dst = ();
+            &DATA::readCustIfaces(\%customIfaces_dst);
+            my @customInterfaces_dst = sort keys(%customIfaces_dst);
+
             # Custom interfaces
-            if ($FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on' && 
$#customInterfaces >= 0) {
+            if ($FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on' && 
$#customInterfaces_dst >= 0) {
 
                 # show this option only if there are Custom Networks available
                 print <<END;
@@ -2391,8 +2761,8 @@
         $Lang::tr{'custom interfaces'}:&nbsp;
         <select name='CUST_DST_NET'>
 END
-                print "<option value='BLANK' selected='selected'>N/A</option>" 
if ($#customInterfaces < 0);
-                foreach my $iface (@customInterfaces) {
+                print "<option value='BLANK' selected='selected'>N/A</option>" 
if ($#customInterfaces_dst < 0);
+                foreach my $iface (@customInterfaces_dst) {
                     print "<option value='$iface'";
                     print " selected='selected'" if 
($cgiparams{'CUST_DST_NET'} eq $iface);
                     print ">$iface</option>";
@@ -2408,7 +2778,7 @@
 "<tr><td colspan='3'><input type='hidden' name='CUST_DST_NET' 
value='$cgiparams{'CUST_DST_NET'}' /></td></tr>\n";
             }
 
-            if ($FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on' ){
+            if ($FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on' &&  
$cgiparams{'RULETYPE'} ne 'PORTFW'){
                 print <<END;
 <tr>
     <td class='base'></td>
@@ -2437,6 +2807,13 @@
 <tr>
     <td colspan='3' class='base'>&nbsp;</td>
 </tr>
+END
+
+        if($cgiparams{'RULETYPE'} eq 'PORTFW') {
+            print "<tr><td colspan='3'><input type='hidden' 
name='DEFAULT_DST_IP' value='-' /></td></tr>\n";
+        }
+        else {
+            print <<END;
 <tr>
     <td class='base'></td>
     <td class='base'></td>
@@ -2445,18 +2822,19 @@
         $Lang::tr{'default networks'}:&nbsp;
         <select name='DEFAULT_DST_IP'>
 END
-        foreach my $network (sort keys %defaultNetworks) {
-            next if ($defaultNetworks{$network}{'LOCATION'} eq "IPCOP");
-            print "<option value='$network'";
-            print " selected='selected'" if ($cgiparams{'DEFAULT_DST_IP'} eq 
$network);
-            print ">$network</option>";
-        }
+            foreach my $network (sort keys %defaultNetworks) {
+                next if ($defaultNetworks{$network}{'LOCATION'} eq "IPCOP");
+                print "<option value='$network'";
+                print " selected='selected'" if ($cgiparams{'DEFAULT_DST_IP'} 
eq $network);
+                print ">$network</option>";
+            }
 
-        print <<END;
+            print <<END;
         </select>
     </td>
 </tr>
 END
+        }
 
         if ($#customAddresses >= 0) {
 
@@ -2484,12 +2862,16 @@
 END
         }
         else {
+            if($cgiparams{'RULETYPE'} eq 'PORTFW') {
+                # Fall back to text input
+                $radio{'DST_IP_TYPE'}{'ipDestTxt'} = "checked='checked'";
+            }
             print
 "<tr><td colspan='3'><input type='hidden' name='CUST_DST_ADR' 
value='$cgiparams{'CUST_DST_ADR'}' /></td></tr>\n";
         }
 
 ##########################################
-        if ($#adrGroups >= 0) {    # show this option only if there are 
address groups available
+        if ($#adrGroups >= 0 &&  $cgiparams{'RULETYPE'} ne 'PORTFW') {    # 
show this option only if there are address groups available
             print <<END;
 <tr>
     <td class='base'></td>
@@ -2517,18 +2899,22 @@
 "<tr><td colspan='3'><input type='hidden' name='GROUP_DST_ADR' 
value='$cgiparams{'GROUP_DST_ADR'}' /></td></tr>\n";
         }
 
+        my $dstIpTxtLabel = $Lang::tr{'destination ip or net'};
+        if( $cgiparams{'RULETYPE'} eq 'PORTFW') {
+            $dstIpTxtLabel =  $Lang::tr{'destination ip'};
+        }
         print <<END;
 <tr>
     <td class='base'></td>
     <td class='base'></td>
     <td class='base'>
         <input type='radio' name='DST_IP_TYPE' value='ipDestTxt' 
$radio{'DST_IP_TYPE'}{'ipDestTxt'} />
-        $Lang::tr{'destination ip or net'}:&nbsp;
+        $dstIpTxtLabel:&nbsp;
         <input type='text' name='DEST_IP_TXT' 
value='$cgiparams{'DEST_IP_TXT'}' size='21' maxlength='19' />
     </td>
 </tr>
 END
-        if ($FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on') {
+        if ($FW::fwSettings{'ADV_MODE_ENABLE'} eq 'on' &&  
$cgiparams{'RULETYPE'} ne 'PORTFW') {
 
             print <<END;
 <tr>
@@ -2580,7 +2966,7 @@
     <td class='base'>
 END
 
-if($cgiparams{'RULETYPE'} ne 'EXTERNAL') {
+    if($cgiparams{'RULETYPE'} ne 'EXTERNAL' && $cgiparams{'RULETYPE'} ne 
'PORTFW') {
         print"<input type='checkbox' name='SERVICE_ON' 
$checked{'SERVICE_ON'}{'on'} />\n";
     }
     else
@@ -2601,7 +2987,7 @@
 
     my @existingGroups      = sort(keys(%groupConf));
     my $existingGroupsCount = @existingGroups;
-    if ($existingGroupsCount > 0) {
+    if ($existingGroupsCount > 0 && $cgiparams{'RULETYPE'} ne 'PORTFW') {
         print <<END;
 <tr>
     <td class='base'></td>
@@ -3150,83 +3536,97 @@
     }
 
     $newRule{'INV_SRC_PORT'} = $cgiparams{'INV_SRC_PORT'};             # [11]
-    $newRule{'DST_NET_TYPE'} = $cgiparams{'DST_NET_TYPE'};             # [12]
 
+    $newRule{'PORTFW_EXT_ADR'} = $cgiparams{'PORTFW_EXT_ADR'};      # [12]
+    $newRule{'PORTFW_SERVICE_TYPE'} = $cgiparams{'PORTFW_SERVICE_TYPE'}; # [13]
+
+    if($cgiparams{'PORTFW_SERVICE_TYPE'} eq 'custom') {
+        $newRule{'PORTFW_SERVICE'} = $cgiparams{'PORTFW_CUST_SERVICE'}; # [14]
+    }
+    else {
+        # 'default'
+        $newRule{'PORTFW_SERVICE'} = $cgiparams{'PORTFW_DEFAULT_SERVICE'}; # 
[14]
+    }
+
+
+
+    $newRule{'DST_NET_TYPE'} = $cgiparams{'DST_NET_TYPE'};             # [15]
+
     if ($cgiparams{'DST_NET_TYPE'} eq 'defaultDestNet') {
-        $newRule{'DST_NET'} = $cgiparams{'DEFAULT_DST_NET'};           # [13]
+        $newRule{'DST_NET'} = $cgiparams{'DEFAULT_DST_NET'};           # [16]
     }
     elsif ($cgiparams{'DST_NET_TYPE'} eq 'colorDestNet') {
-        $newRule{'DST_NET'} = $cgiparams{'COLOR_DST_NET'};             # [13]
+        $newRule{'DST_NET'} = $cgiparams{'COLOR_DST_NET'};             # [16]
     }
     else {                                                             
#'custDestNet'
-        $newRule{'DST_NET'} = $cgiparams{'CUST_DST_NET'};              # [13]
+        $newRule{'DST_NET'} = $cgiparams{'CUST_DST_NET'};              # [16]
     }
 
-    $newRule{'INV_DST_NET'} = $cgiparams{'INV_DST_NET'};               # [14]
-    $newRule{'DST_IP_TYPE'} = $cgiparams{'DST_IP_TYPE'};               # [15]
+    $newRule{'INV_DST_NET'} = $cgiparams{'INV_DST_NET'};               # [17]
+    $newRule{'DST_IP_TYPE'} = $cgiparams{'DST_IP_TYPE'};               # [18]
 
     if ($cgiparams{'DST_IP_TYPE'} eq 'defaultDstIP') {
-        $newRule{'DST_IP'} = $cgiparams{'DEFAULT_DST_IP'};             # [16]
+        $newRule{'DST_IP'} = $cgiparams{'DEFAULT_DST_IP'};             # [19]
     }
     elsif ($cgiparams{'DST_IP_TYPE'} eq 'custDestIP') {
-        $newRule{'DST_IP'} = $cgiparams{'CUST_DST_ADR'};               # [16]
+        $newRule{'DST_IP'} = $cgiparams{'CUST_DST_ADR'};               # [19]
     }
     elsif ($cgiparams{'DST_IP_TYPE'} eq 'groupDestIP') {
-        $newRule{'DST_IP'} = $cgiparams{'GROUP_DST_ADR'};              # [16]
+        $newRule{'DST_IP'} = $cgiparams{'GROUP_DST_ADR'};              # [19]
     }
     else {                                                             # 
'ipDestTxt'
-        $newRule{'DST_IP'} = $cgiparams{'DEST_IP_TXT'};                # [16]
+        $newRule{'DST_IP'} = $cgiparams{'DEST_IP_TXT'};                # [19]
     }
 
-    $newRule{'INV_DST_IP'} = $cgiparams{'INV_DST_IP'};                 # [17]
+    $newRule{'INV_DST_IP'} = $cgiparams{'INV_DST_IP'};                 # [20]
 
     if ($cgiparams{'SERVICE_ON'} eq 'on') {
-        $newRule{'SERVICE_TYPE'} = $cgiparams{'SERVICE_TYPE'};         # [18]
+        $newRule{'SERVICE_TYPE'} = $cgiparams{'SERVICE_TYPE'};         # [21]
         if ($cgiparams{'SERVICE_TYPE'} eq 'custom') {
-            $newRule{'SERVICE'} = $cgiparams{'CUST_SERVICE'};          # [19]
+            $newRule{'SERVICE'} = $cgiparams{'CUST_SERVICE'};          # [22]
         }
         elsif ($cgiparams{'SERVICE_TYPE'} eq 'serviceGroup') {
-            $newRule{'SERVICE'} = $cgiparams{'SERVICE_GROUP'};         # [19]
+            $newRule{'SERVICE'} = $cgiparams{'SERVICE_GROUP'};         # [22]
         }
         else {                                                         # 
'default'
-            $newRule{'SERVICE'} = $cgiparams{'DEFAULT_SERVICE'};       # [19]
+            $newRule{'SERVICE'} = $cgiparams{'DEFAULT_SERVICE'};       # [22]
         }
     }
     else {
-        $newRule{'SERVICE_TYPE'} = "-";                                # [18]
-        $newRule{'SERVICE'}      = "-";                                # [19]
+        $newRule{'SERVICE_TYPE'} = "-";                                # [21]
+        $newRule{'SERVICE'}      = "-";                                # [22]
     }
 
-    $newRule{'LOG_ENABLED'} = $cgiparams{'LOG_ENABLED'};               # [20]
-    $newRule{'LIMIT_FOR'}   = $cgiparams{'LIMIT_FOR'};                 # [21]
+    $newRule{'LOG_ENABLED'} = $cgiparams{'LOG_ENABLED'};               # [23]
+    $newRule{'LIMIT_FOR'}   = $cgiparams{'LIMIT_FOR'};                 # [24]
 
     if ($cgiparams{'LIMIT_FOR'} eq 'none') {
-        $newRule{'LIMIT_TYPE'}  = "-";                                 # [22]
-        $newRule{'MATCH_LIMIT'} = "-";                                 # [23]
+        $newRule{'LIMIT_TYPE'}  = "-";                                 # [25]
+        $newRule{'MATCH_LIMIT'} = "-";                                 # [26]
     }
     else {
-        $newRule{'LIMIT_TYPE'} = $cgiparams{'LIMIT_TYPE'};             # [22]
+        $newRule{'LIMIT_TYPE'} = $cgiparams{'LIMIT_TYPE'};             # [25]
         if ($cgiparams{'LIMIT_TYPE'} eq 'average') {
-            $newRule{'MATCH_LIMIT'} = $cgiparams{'MATCH_LIMIT_AVG'};    # [23]
+            $newRule{'MATCH_LIMIT'} = $cgiparams{'MATCH_LIMIT_AVG'};    # [26]
         }
         else {                                                          # 
'burst'
-            $newRule{'MATCH_LIMIT'} = $cgiparams{'MATCH_LIMIT_BURST'};    # 
[23]
+            $newRule{'MATCH_LIMIT'} = $cgiparams{'MATCH_LIMIT_BURST'};    # 
[26]
         }
     }
 
-    $newRule{'MATCH_STRING_ON'} = $cgiparams{'MATCH_STRING_ON'};          # 
[24]
+    $newRule{'MATCH_STRING_ON'} = $cgiparams{'MATCH_STRING_ON'};          # 
[27]
 
     if ($cgiparams{'MATCH_STRING_ON'} eq 'on') {
-        $newRule{'MATCH_STRING'}     = $cgiparams{'MATCH_STRING'};        # 
[25]
-        $newRule{'INV_MATCH_STRING'} = $cgiparams{'INV_MATCH_STRING'};    # 
[26]
+        $newRule{'MATCH_STRING'}     = $cgiparams{'MATCH_STRING'};        # 
[28]
+        $newRule{'INV_MATCH_STRING'} = $cgiparams{'INV_MATCH_STRING'};    # 
[29]
     }
     else {
-        $newRule{'MATCH_STRING'}     = "-";                               # 
[25]
-        $newRule{'INV_MATCH_STRING'} = "-";                               # 
[26]
+        $newRule{'MATCH_STRING'}     = "-";                               # 
[28]
+        $newRule{'INV_MATCH_STRING'} = "-";                               # 
[29]
     }
-    $newRule{'RULEACTION'}        = $cgiparams{'RULEACTION'};             # 
[27]
-    $newRule{'TIMEFRAME_ENABLED'} = $cgiparams{'TIMEFRAME_ENABLED'};      # 
[28]
-    $newRule{'REMARK'}            = $cgiparams{'REMARK'};                 # 
[29]
+    $newRule{'RULEACTION'}        = $cgiparams{'RULEACTION'};             # 
[30]
+    $newRule{'TIMEFRAME_ENABLED'} = $cgiparams{'TIMEFRAME_ENABLED'};      # 
[31]
+    $newRule{'REMARK'}            = $cgiparams{'REMARK'};                 # 
[32]
 
     # Time parameter
     $newRule{'DAY_TYPE'}        = $cgiparams{'DAY_TYPE'};
@@ -3303,78 +3703,90 @@
     }
 
     $cgiparams{'INV_SRC_PORT'} = $rule->{'INV_SRC_PORT'};       # [11]
-    $cgiparams{'DST_NET_TYPE'} = $rule->{'DST_NET_TYPE'};       # [12]
 
+    $cgiparams{'PORTFW_EXT_ADR'} = $rule->{'PORTFW_EXT_ADR'};      # [12]
+    $cgiparams{'PORTFW_SERVICE_TYPE'} = $rule->{'PORTFW_SERVICE_TYPE'}; # [13]
+
+    if($rule->{'PORTFW_SERVICE_TYPE'} eq 'custom') {
+        $cgiparams{'PORTFW_SERVICE'} = $rule->{'PORTFW_CUST_SERVICE'}; # [14]
+    }
+    else {
+        # 'default'
+        $cgiparams{'PORTFW_SERVICE'} = $rule->{'PORTFW_DEFAULT_SERVICE'}; # 
[14]
+    }
+
+    $cgiparams{'DST_NET_TYPE'} = $rule->{'DST_NET_TYPE'};       # [15]
+
     if ($cgiparams{'DST_NET_TYPE'} eq 'defaultDestNet') {
-        $cgiparams{'DEFAULT_DST_NET'} = $rule->{'DST_NET'};     # [13]
+        $cgiparams{'DEFAULT_DST_NET'} = $rule->{'DST_NET'};     # [16]
     }
     elsif ($cgiparams{'DST_NET_TYPE'} eq 'colorDestNet') {
-        $cgiparams{'COLOR_DST_NET'} = $rule->{'DST_NET'};       # [13]
+        $cgiparams{'COLOR_DST_NET'} = $rule->{'DST_NET'};       # [16]
     }
     else {                                                      #'custDestNet'
-        $cgiparams{'CUST_DST_NET'} = $rule->{'DST_NET'};        # [13]
+        $cgiparams{'CUST_DST_NET'} = $rule->{'DST_NET'};        # [16]
     }
 
-    $cgiparams{'INV_DST_NET'} = $rule->{'INV_DST_NET'};         # [14]
-    $cgiparams{'DST_IP_TYPE'} = $rule->{'DST_IP_TYPE'};         # [15]
+    $cgiparams{'INV_DST_NET'} = $rule->{'INV_DST_NET'};         # [17]
+    $cgiparams{'DST_IP_TYPE'} = $rule->{'DST_IP_TYPE'};         # [18]
 
     if ($cgiparams{'DST_IP_TYPE'} eq 'defaultDstIP') {
-        $cgiparams{'DEFAULT_DST_IP'} = $rule->{'DST_IP'};       # [16]
+        $cgiparams{'DEFAULT_DST_IP'} = $rule->{'DST_IP'};       # [19]
     }
     elsif ($cgiparams{'DST_IP_TYPE'} eq 'custDestIP') {
-        $cgiparams{'CUST_DST_ADR'} = $rule->{'DST_IP'};         # [16]
+        $cgiparams{'CUST_DST_ADR'} = $rule->{'DST_IP'};         # [19]
     }
     elsif ($cgiparams{'DST_IP_TYPE'} eq 'groupDestIP') {
-        $cgiparams{'GROUP_DST_ADR'} = $rule->{'DST_IP'};        # [16]
+        $cgiparams{'GROUP_DST_ADR'} = $rule->{'DST_IP'};        # [19]
     }
     else {                                                      # 'ipDestTxt'
-        $cgiparams{'DEST_IP_TXT'} = $rule->{'DST_IP'};          # [16]
+        $cgiparams{'DEST_IP_TXT'} = $rule->{'DST_IP'};          # [19]
     }
 
-    $cgiparams{'INV_DST_IP'} = $rule->{'INV_DST_IP'};           # [17]
+    $cgiparams{'INV_DST_IP'} = $rule->{'INV_DST_IP'};           # [20]
 
     if ($rule->{'SERVICE_TYPE'} ne '-') {
         $cgiparams{'SERVICE_ON'}   = 'on';
-        $cgiparams{'SERVICE_TYPE'} = $rule->{'SERVICE_TYPE'};    # [18]
+        $cgiparams{'SERVICE_TYPE'} = $rule->{'SERVICE_TYPE'};    # [21]
         if ($cgiparams{'SERVICE_TYPE'} eq 'custom') {
-            $cgiparams{'CUST_SERVICE'} = $rule->{'SERVICE'};     # [19]
+            $cgiparams{'CUST_SERVICE'} = $rule->{'SERVICE'};     # [22]
         }
         elsif ($cgiparams{'SERVICE_TYPE'} eq 'serviceGroup') {
-            $cgiparams{'SERVICE_GROUP'} = $rule->{'SERVICE'};    # [19]
+            $cgiparams{'SERVICE_GROUP'} = $rule->{'SERVICE'};    # [22]
         }
         else {                                                   # 'default'
-            $cgiparams{'DEFAULT_SERVICE'} = $rule->{'SERVICE'};    # [19]
+            $cgiparams{'DEFAULT_SERVICE'} = $rule->{'SERVICE'};    # [22]
         }
     }
     else {
         $cgiparams{'SERVICE_ON'} = 'off';
     }
 
-    $cgiparams{'LOG_ENABLED'} = $rule->{'LOG_ENABLED'};            # [20]
-    $cgiparams{'LIMIT_FOR'}   = $rule->{'LIMIT_FOR'};              # [21]
+    $cgiparams{'LOG_ENABLED'} = $rule->{'LOG_ENABLED'};            # [23]
+    $cgiparams{'LIMIT_FOR'}   = $rule->{'LIMIT_FOR'};              # [24]
 
     if ($cgiparams{'LIMIT_FOR'} ne 'none') {
-        $cgiparams{'LIMIT_TYPE'} = $rule->{'LIMIT_TYPE'};          # [22]
+        $cgiparams{'LIMIT_TYPE'} = $rule->{'LIMIT_TYPE'};          # [25]
         if ($cgiparams{'LIMIT_TYPE'} eq 'average') {
-            $cgiparams{'MATCH_LIMIT_AVG'} = $rule->{'MATCH_LIMIT'};    # [23]
+            $cgiparams{'MATCH_LIMIT_AVG'} = $rule->{'MATCH_LIMIT'};    # [26]
         }
         else {                                                         # 
'burst'
-            $cgiparams{'MATCH_LIMIT_BURST'} = $rule->{'MATCH_LIMIT'};    # [23]
+            $cgiparams{'MATCH_LIMIT_BURST'} = $rule->{'MATCH_LIMIT'};    # [26]
         }
     }
 
-    $cgiparams{'MATCH_STRING_ON'} = $rule->{'MATCH_STRING_ON'};          # [24]
+    $cgiparams{'MATCH_STRING_ON'} = $rule->{'MATCH_STRING_ON'};          # [27]
 
     if ($cgiparams{'MATCH_STRING_ON'} eq 'on') {
-        $cgiparams{'MATCH_STRING'}     = $rule->{'MATCH_STRING'};        # [25]
-        $cgiparams{'INV_MATCH_STRING'} = $rule->{'INV_MATCH_STRING'};    # [26]
+        $cgiparams{'MATCH_STRING'}     = $rule->{'MATCH_STRING'};        # [28]
+        $cgiparams{'INV_MATCH_STRING'} = $rule->{'INV_MATCH_STRING'};    # [29]
     }
-    $cgiparams{'RULEACTION'} = $rule->{'RULEACTION'};                    # [27]
+    $cgiparams{'RULEACTION'} = $rule->{'RULEACTION'};                    # [30]
 
-    $cgiparams{'TIMEFRAME_ENABLED'} = $rule->{'TIMEFRAME_ENABLED'};      # [28]
+    $cgiparams{'TIMEFRAME_ENABLED'} = $rule->{'TIMEFRAME_ENABLED'};      # [31]
     if (defined $rule->{'REMARK'}) {
-        $cgiparams{'REMARK'} = $rule->{'REMARK'};
-    }                                                                    # [29]
+        $cgiparams{'REMARK'} = $rule->{'REMARK'}; # [32]
+    }
 
     if ($cgiparams{'TIMEFRAME_ENABLED'} eq 'on') {
 
@@ -3443,6 +3855,11 @@
         <input type='hidden' name='SRC_PORT' value='$cgiparams{'SRC_PORT'}' />
         <input type='hidden' name='INV_SRC_PORT' 
value='$cgiparams{'INV_SRC_PORT'}' />
 
+        <input type='hidden' name='PORTFW_EXT_ADR' 
value='$cgiparams{'PORTFW_EXT_ADR'}' />
+        <input type='hidden' name='PORTFW_SERVICE_TYPE' 
value='$cgiparams{'PORTFW_SERVICE_TYPE'}' />
+        <input type='hidden' name='PORTFW_CUST_SERVICE' 
value='$cgiparams{'PORTFW_CUST_SERVICE'}' />
+        <input type='hidden' name='PORTFW_DEFAULT_SERVICE' 
value='$cgiparams{'PORTFW_DEFAULT_SERVICE'}' />
+
         <input type='hidden' name='DST_NET_TYPE' 
value='$cgiparams{'DST_NET_TYPE'}' />
         <input type='hidden' name='DEFAULT_DST_NET' 
value='$cgiparams{'DEFAULT_DST_NET'}' />
         <input type='hidden' name='COLOR_DST_NET' 
value='$cgiparams{'COLOR_DST_NET'}' />
@@ -3524,13 +3941,18 @@
         $src_adr_inv      = " <strong><font color='RED'>! (</font></strong>";
         $src_adr_inv_tail = "<strong><font color='RED'>)</font></strong>";
     }
-    my $ruleTypeTxt = "$Lang::tr{'other network'}";
+    my $ruleTypeTxt = $Lang::tr{'other network'};
+    my  $destination_text = $Lang::tr{'destination'};
     if ($cgiparams{'RULETYPE'} eq 'INPUT') {
-        $ruleTypeTxt = "$Lang::tr{'ipcop access'}";
+        $ruleTypeTxt = $Lang::tr{'ipcop access'};
     }
     elsif ($cgiparams{'RULETYPE'} eq 'EXTERNAL') {
-        $ruleTypeTxt = "$Lang::tr{'external ipcop access'}";
+        $ruleTypeTxt = $Lang::tr{'external ipcop access'};
     }
+    elsif ($cgiparams{'RULETYPE'} eq 'PORTFW') {
+        $destination_text = $Lang::tr{'pfw internal destination'};
+        $ruleTypeTxt = $Lang::tr{'internal network'};
+    }
 
     my $src_net = "\u$cgiparams{'DEFAULT_SRC_NET'}";
     if ($cgiparams{'SRC_NET_TYPE'} eq 'custSrcNet') {
@@ -3590,18 +4012,53 @@
 </tr>
 END
     }
+
+    if($cgiparams{'RULETYPE'} eq 'PORTFW') {
+
+        my $ext_service = $cgiparams{'PORTFW_CUST_SERVICE'};
+        if ($cgiparams{'PORTFW_SERVICE_TYPE'} eq 'default') {
+            $ext_service = $cgiparams{'PORTFW_DEFAULT_SERVICE'};
+        }
+
+        print <<END;
+<tr>
+    <td colspan='3' class='base'>&nbsp;</td>
+</tr>
+<tr>
+    <td colspan='3' class='base'>
+        <font class='boldbase'><b>$Lang::tr{'pfw ipcop 
destination'}:</b></font>
+    </td>
+</tr>
+<tr>
+    <td class='base' ></td>
+    <td class='base' >
+        <font class='boldbase'>$Lang::tr{'alias ip'}:</font>&nbsp;
+    </td>
+    <td class='base' ><b>$cgiparams{'PORTFW_EXT_ADR'}</b></td>
+</tr>
+<tr>
+    <td class='base' ></td>
+    <td class='base' >
+        <font class='boldbase'>$Lang::tr{'service'}:</font>&nbsp;
+    </td>
+    <td class='base' ><b>$ext_service</b></td>
+</tr>
+END
+
+    }
+
     print <<END;
 <tr>
     <td colspan='3' class='base'>&nbsp;</td>
 </tr>
 <tr>
     <td colspan='2' class='base'>
-        <font class='boldbase'><b>$Lang::tr{'destination'}:&nbsp; </b></font>
+        <font class='boldbase'><b>$destination_text:&nbsp; </b></font>
     </td>
     <td class='base' ><b>$ruleTypeTxt</b></td>
 </tr>
 END
-    if ($cgiparams{'RULETYPE'} eq 'FORWARD' || $cgiparams{'RULETYPE'} eq 
'DMZHOLES') {
+    if ($cgiparams{'RULETYPE'} eq 'FORWARD' || $cgiparams{'RULETYPE'} eq 
'DMZHOLES' || $cgiparams{'RULETYPE'} eq 'PORTFW') {
         my $dst_net_inv      = "";
         my $dst_net_inv_tail = "";
         if ($cgiparams{'INV_DST_NET'} eq 'on') {
@@ -3746,6 +4203,9 @@
     elsif (defined($ruleConfig{'DMZHOLES'}) && $cgiparams{'RULETYPE'} eq 
'DMZHOLES') {
         $ruleCount = @{$ruleConfig{'DMZHOLES'}};
     }
+    elsif (defined($ruleConfig{'PORTFW'}) && $cgiparams{'RULETYPE'} eq 
'PORTFW') {
+        $ruleCount = @{$ruleConfig{'PORTFW'}};
+    }
 
     $cgiparams{'RULE_POSITION'} = $ruleCount if ($cgiparams{'RULE_POSITION'} < 
0);
 


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Register Now & Save for Velocity, the Web Performance & Operations 
Conference from O'Reilly Media. Velocity features a full day of 
expert-led, hands-on workshops and two days of sessions from industry 
leaders in dedicated Performance & Operations tracks. Use code vel09scf 
and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf
_______________________________________________
Ipcop-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ipcop-svn

Reply via email to