--- /etc/inc/filter.inc.orig	2009-02-24 15:11:55.000000000 -0500
+++ /etc/inc/filter.inc	2009-02-24 19:38:51.000000000 -0500
@@ -494,7 +494,7 @@
 }
 
 /* Generate a 'nat on' or 'no nat on' rule for given interface */
-function filter_nat_rules_generate_if($if, $src = "any", $srcport = "", $dst = "any", $dstport = "", $natip = "", $natport = "", $nonat = false, $staticnatport = false) {
+function filter_nat_rules_generate_if($if, $src = "any", $proto = "any", $srcport = "", $dst = "any", $dstport = "", $natip = "", $natport = "", $nonat = false, $staticnatport = false) {
 	global $config;
 
 	/* XXX: billm - any idea if this code is needed? */
@@ -507,6 +507,12 @@
         else
                 $tgt = "($if)";
 
+	/* Add the protocol, if defined */
+	if (($proto != "") && ($proto != "any"))
+		$protocol = " proto {$proto}";
+	else
+		$protocol = "";
+
 	/* Add the hard set source port (useful for ISAKMP) */
         if ($natport != "")
 		$tgt .= " port {$natport}";
@@ -546,7 +552,7 @@
 
 	/* Put all the pieces together */
 	if($if_friendly)
-		$natrule = "{$nat} on \${$if_friendly} from {$src} to {$dst} {$target}{$staticnatport_txt}\n";
+		$natrule = "{$nat} on \${$if_friendly} {$protocol} from {$src} to {$dst} {$target}{$staticnatport_txt}\n";
 
 	return $natrule;
 }
@@ -654,6 +660,7 @@
 
 				$natrules .= filter_nat_rules_generate_if($natif,
 					$src,
+					$obent['protocol'],
 					$obent['sourceport'],
 					$dst,
 					$obent['dstport'],
@@ -669,9 +676,9 @@
 		update_filter_reload_status("Creating outbound NAT rules");
 
 		$natrules .= filter_nat_rules_generate_if($wanif,
-			"{$lansa}/{$lancfg['subnet']}", 500, "", 500, null, 500, false);
+			"{$lansa}/{$lancfg['subnet']}", "any", 500, "", 500, null, 500, false);
 		$natrules .= filter_nat_rules_generate_if($wanif,
-			"{$lansa}/{$lancfg['subnet']}", 5060, "", 5060, null, 5060, false);
+			"{$lansa}/{$lancfg['subnet']}", "any", 5060, "", 5060, null, 5060, false);
 		$natrules .= filter_nat_rules_generate_if($wanif,
 			"{$lansa}/{$lancfg['subnet']}");
 
@@ -683,9 +690,9 @@
 			$opt_interface = $oc['if'];
 			if (interface_has_gateway("$opt_interface")) {
 				$natrules .= filter_nat_rules_generate_if($opt_interface,
-					"{$lansa}/{$lancfg['subnet']}", 500, "", 500, null, 500, false);
+					"{$lansa}/{$lancfg['subnet']}", "any", 500, "", 500, null, 500, false);
 				$natrules .= filter_nat_rules_generate_if($opt_interface,
-					"{$lansa}/{$lancfg['subnet']}", 5060, "", 5060, null, 5060, false);
+					"{$lansa}/{$lancfg['subnet']}", "any", 5060, "", 5060, null, 5060, false);
 				$natrules .= filter_nat_rules_generate_if($opt_interface,
 					"{$lansa}/{$lancfg['subnet']}");
 			}
@@ -701,22 +708,22 @@
 
 				/* create outbound nat entries for primary wan */
 				$natrules .= filter_nat_rules_generate_if($wanif,
-					"{$optsa}/{$optcfg['subnet']}", 500, "", 500, null, 500, false);
+					"{$optsa}/{$optcfg['subnet']}", "any", 500, "", 500, null, 500, false);
 				$natrules .= filter_nat_rules_generate_if($wanif,
-					"{$optsa}/{$optcfg['subnet']}", 5060, "", 5060, null, 5060, false);
+					"{$optsa}/{$optcfg['subnet']}", "any", 5060, "", 5060, null, 5060, false);
 				$natrules .= filter_nat_rules_generate_if($wanif,
-					"{$optsa}/{$optcfg['subnet']}", null, "", null, null, null, isset($optcfg['nonat']));
+					"{$optsa}/{$optcfg['subnet']}", "any", null, "", null, null, null, isset($optcfg['nonat']));
 
 				/* create outbound nat entries for all opt wans */
 				foreach($optints as $oc) {
 					$opt_interface = $oc['if'];
 					if (interface_has_gateway("$opt_interface")) {
 						$natrules .= filter_nat_rules_generate_if($opt_interface,
-							"{$optsa}/{$optcfg['subnet']}", 500, "", 500, null, 500, false);
+							"{$optsa}/{$optcfg['subnet']}", "any", 500, "", 500, null, 500, false);
 						$natrules .= filter_nat_rules_generate_if($opt_interface,
-							"{$optsa}/{$optcfg['subnet']}", 5060, "", 5060, null, 5060, false);
+							"{$optsa}/{$optcfg['subnet']}", "any", 5060, "", 5060, null, 5060, false);
 						$natrules .= filter_nat_rules_generate_if($opt_interface,
-							"{$optsa}/{$optcfg['subnet']}", null, "", null, null, null, isset($optcfg['nonat']));
+							"{$optsa}/{$optcfg['subnet']}", "any", null, "", null, null, null, isset($optcfg['nonat']));
 					}
 				}
 			}
@@ -728,9 +735,9 @@
 			if($config['pptp']['pptp_subnet'] <> "")
 				$pptp_subnet = $config['pptp']['pptp_subnet'];
 			$natrules .= filter_nat_rules_generate_if($wanif,
-				"{$pptpdcfg['remoteip']}/{$pptp_subnet}", 500, "", 500, null, 500, false);
+				"{$pptpdcfg['remoteip']}/{$pptp_subnet}", "any", 500, "", 500, null, 500, false);
 			$natrules .= filter_nat_rules_generate_if($wanif,
-				"{$pptpdcfg['remoteip']}/{$pptp_subnet}", 5060, "", 5060, null, 5060, false);
+				"{$pptpdcfg['remoteip']}/{$pptp_subnet}", "any", 5060, "", 5060, null, 5060, false);
 			$natrules .= filter_nat_rules_generate_if($wanif,
 				"{$pptpdcfg['remoteip']}/{$pptp_subnet}");
 
@@ -739,9 +746,9 @@
 				$opt_interface = $oc['if'];
 				if ((is_private_ip($pptpdcfg['remoteip'])) && (interface_has_gateway($opt_interface))) {
 					$natrules .= filter_nat_rules_generate_if($opt_interface,
-						"{$pptpdcfg['remoteip']}/{$pptp_subnet}", 500, "", 500, null, 500, false);
+						"{$pptpdcfg['remoteip']}/{$pptp_subnet}", "any", 500, "", 500, null, 500, false);
 					$natrules .= filter_nat_rules_generate_if($opt_interface,
-						"{$pptpdcfg['remoteip']}/{$pptp_subnet}", 5060, "", 5060, null, 5060, false);
+						"{$pptpdcfg['remoteip']}/{$pptp_subnet}", "any", 5060, "", 5060, null, 5060, false);
 					$natrules .= filter_nat_rules_generate_if($opt_interface,
 						"{$pptpdcfg['remoteip']}/{$pptp_subnet}");
 				}
@@ -754,20 +761,20 @@
 			if($config['pppoe']['pppoe_subnet'] <> "")
 				$pppoe_subnet = $config['pppoe']['pppoe_subnet'];
 			$natrules .= filter_nat_rules_generate_if($wanif,
-				"{$pppoecfg['remoteip']}/{$pppoe_subnet}", 500, "", 500, null, 500, false);
+				"{$pppoecfg['remoteip']}/{$pppoe_subnet}", "any", 500, "", 500, null, 500, false);
 			$natrules .= filter_nat_rules_generate_if($wanif,
-				"{$pppoecfg['remoteip']}/{$pppoe_subnet}", 5060, "", 5060, null, 5060, false);
+				"{$pppoecfg['remoteip']}/{$pppoe_subnet}", "any", 5060, "", 5060, null, 5060, false);
 			$natrules .= filter_nat_rules_generate_if($wanif,
-				"{$pppoecfg['remoteip']}/{$pppoe_subnet}");
+				"{$pppoecfg['remoteip']}/{$pppoe_subnet}", "any");
 
 			/* generate nat mappings for opts with a gateway opts */
 			foreach($optints as $oc) {
 				$opt_interface = $oc['if'];
 				if ((is_private_ip($pppoecfg['remoteip'])) && (interface_has_gateway($opt_interface))) {
 					$natrules .= filter_nat_rules_generate_if($opt_interface,
-						"{$pppoecfg['remoteip']}/{$pppoe_subnet}", 500, "", 500, null, 500, false);
+						"{$pppoecfg['remoteip']}/{$pppoe_subnet}", "any", 500, "", 500, null, 500, false);
 					$natrules .= filter_nat_rules_generate_if($opt_interface,
-						"{$pppoecfg['remoteip']}/{$pppoe_subnet}", 5060, "", 5060, null, 5060, false);
+						"{$pppoecfg['remoteip']}/{$pppoe_subnet}", "any", 5060, "", 5060, null, 5060, false);
 					$natrules .= filter_nat_rules_generate_if($opt_interface,
 						"{$pppoecfg['remoteip']}/{$pppoe_subnet}");
 				}
@@ -780,22 +787,22 @@
 				$netip = explode("/", $route['network']);
 				if ((! interface_has_gateway($route['interface'])) && (is_private_ip($netip[0]))) {
 					$natrules .= filter_nat_rules_generate_if($wanif,
-						"{$route['network']}", 500, "", 500, null, 500, false);
+						"{$route['network']}", "any", 500, "", 500, null, 500, false);
 					$natrules .= filter_nat_rules_generate_if($wanif,
-						"{$route['network']}", 5060, "", 5060, null, 5060, false);
+						"{$route['network']}", "any", 5060, "", 5060, null, 5060, false);
 					$natrules .= filter_nat_rules_generate_if($wanif,
-						"{$route['network']}", "", null);
+						"{$route['network']}", "any", "", null);
 				}
 				/* generate nat mapping for static routes on opts */
 				foreach($optints as $oc) {
 					$opt_interface = $oc['if'];
 					if ((! interface_has_gateway($route['interface'])) && (is_private_ip($netip[0])) && (interface_has_gateway($opt_interface))) {
 						$natrules .= filter_nat_rules_generate_if($opt_interface,
-							"{$route['network']}", 500, "", 500, null, 500, false);
+							"{$route['network']}", "any", 500, "", 500, null, 500, false);
 						$natrules .= filter_nat_rules_generate_if($opt_interface,
-							"{$route['network']}", 5060, "", 5060, null, 5060, false);
+							"{$route['network']}", "any", 5060, "", 5060, null, 5060, false);
 						$natrules .= filter_nat_rules_generate_if($opt_interface,
-							"{$route['network']}", "", null);
+							"{$route['network']}", "any", "", null);
 					}
 				}
 
--- /usr/local/www-orig/firewall_nat_out.php	2008-01-07 21:14:44.000000000 -0500
+++ /usr/local/www/firewall_nat_out.php	2009-02-24 18:21:20.000000000 -0500
@@ -102,6 +102,7 @@
 				$natent['interface'] = "wan";
 				$natent['destination']['any'] = true;
 				$natent['natport'] = "";
+				$natent['protocol'] = "any";
 				$a_out[] = $natent;
 			}
 			$savemsg = "Default rules for each interface have been created.";
@@ -265,6 +266,11 @@
                                                  echo "LAN";                                                
 					else
 						echo htmlspecialchars($config['interfaces'][$natent['interface']]['descr']);
+
+					if (($natent['protocol'] != "any") && ($natent['protocol'] != ""))
+						$proto = $natent['protocol'] . "/";
+					else
+						$proto = "";
 					?>
                                         &nbsp;
                   </td>
@@ -273,10 +279,11 @@
                   </td>
                   <td class="listr" onClick="fr_toggle(<?=$nnats;?>)" id="frd<?=$nnats;?>" ondblclick="document.location='firewall_nat_out_edit.php?id=<?=$nnats;?>';">
                     <?php
+
                       if (!$natent['sourceport'])
-                          echo "*";
+                          echo  $proto . "*";
                       else
-                          echo $natent['sourceport'];
+                          echo $proto . $natent['sourceport'];
                     ?>
                   </td>
                   <td class="listr" onClick="fr_toggle(<?=$nnats;?>)" id="frd<?=$nnats;?>" ondblclick="document.location='firewall_nat_out_edit.php?id=<?=$nnats;?>';">
@@ -293,9 +300,9 @@
                   <td class="listr" onClick="fr_toggle(<?=$nnats;?>)" id="frd<?=$nnats;?>" ondblclick="document.location='firewall_nat_out_edit.php?id=<?=$nnats;?>';">
                     <?php
                       if (!$natent['dstport'])
-                          echo "*";
+                          echo $proto . "*";
                       else
-                          echo $natent['dstport'];
+                          echo $proto . $natent['dstport'];
                     ?>
                   </td>
                   <td class="listr" onClick="fr_toggle(<?=$nnats;?>)" id="frd<?=$nnats;?>" ondblclick="document.location='firewall_nat_out_edit.php?id=<?=$nnats;?>';">
--- /usr/local/www-orig/firewall_nat_out_edit.php	2008-11-08 17:53:23.000000000 -0500
+++ /usr/local/www/firewall_nat_out_edit.php	2009-02-25 12:07:33.000000000 -0500
@@ -49,6 +49,7 @@
 }
 
 if (isset($id) && $a_out[$id]) {
+    $pconfig['proto'] = $a_out[$id]['protocol'];
     list($pconfig['source'],$pconfig['source_subnet']) = explode('/', $a_out[$id]['source']['network']);
     $pconfig['sourceport'] = $a_out[$id]['sourceport'];
     address_to_pconfig($a_out[$id]['destination'], $pconfig['destination'],
@@ -170,6 +171,9 @@
 		if (!$natent['interface'])
 			$natent['interface'] == "wan";
 
+		if ($natent['proto'] != $_POST['proto'])
+			continue;			
+
 		if (($natent['interface'] == $_POST['interface']) && ($natent['source']['network'] == $osn)) {
 			if (isset($natent['destination']['not']) == isset($_POST['destination_not'])) {
 				if ((isset($natent['destination']['any']) && ($ext == "any")) ||
@@ -188,6 +192,7 @@
         $natent['descr'] = $_POST['descr'];
         $natent['target'] = $_POST['target'];
         $natent['interface'] = $_POST['interface'];
+        $natent['protocol'] = $_POST['proto'];
 
 		/* static-port */
 		if(isset($_POST['staticnatport']))
@@ -316,6 +321,17 @@
                      Hint: in most cases, you'll want to use WAN here.</span></td>
                 </tr>
                 <tr>
+                  <td width="22%" valign="top" class="vncellreq">Protocol</td>
+                  <td width="78%" class="vtable">
+                    <select name="proto" class="formfld" onChange="proto_change(); check_for_aliases();">
+                      <?php $protocols = explode(" ", "any TCP UDP GRE ESP AH L2TP ICMP"); foreach ($protocols as $proto): ?>
+                      <option value="<?=strtolower($proto);?>" <?php if (strtolower($proto) == $pconfig['proto']) echo "selected"; ?>><?=htmlspecialchars($proto);?></option>
+                      <?php endforeach; ?>
+                    </select> <br> <span class="vexpl">Choose which IP protocol
+                    this rule should match.<br>
+                    Hint: in most cases, you should specify <em>any</em> &nbsp;here.</span></td>
+                </tr>
+                <tr>
                   <td width="22%" valign="top" class="vncellreq">Source</td>
                   <td width="78%" class="vtable">
                     <table border="0" cellspacing="1" cellpadding="1">