This patch adds the initial support for layer7 protocol inspection gui.

This commit is contained in:
Helder Pereira 2008-12-20 23:57:09 +00:00
parent adc986ed5e
commit f63d5b66b4
8 changed files with 1120 additions and 8 deletions

View File

@ -3032,6 +3032,392 @@ class dnqueue_class extends dummynet_class {
}
}
// List of layer7 objects
$layer7_rules_list = array();
class layer7 {
var $rname; //alias
var $rdescription; //alias description
var $rport; //divert port
var $renabled; //rule enabled
var $rsets = array(); //array of l7 associations
// Auxiliary functions
function GetRName() {
return $this->rname;
}
function SetRName($rname) {
$this->rname = $rname;
}
function GetRDescription() {
return $this->rdescription;
}
function SetRDescription($rdescription) {
$this->rdescription = $rdescription;
}
function GetRPort() {
return $this->rport;
}
function SetRPort($rport) {
$this->rport = $rport;
}
function GetREnabled() {
return $this->renabled;
}
function SetREnabled($value) {
$this->renabled = $value;
}
function GetRl7() {
return $this->rsets;
}
function SetRl7($rsets) {
$this->rsets = $rsets;
}
//Add a tuple (rule,sctructure,element) to the $rsets
function add_rule($l7set) {
$this->rsets[] = $l7set;
}
// Build the layer7 rules
function build_l7_rules() {
if($this->GetREnabled() == "") {
return;
}
//$l7rules = "#" . $this->rdescription . "\n";
foreach ($this->rsets as $rl7) {
$l7rules .= $rl7->build_rules();
}
return $l7rules;
}
// Read the config from array
function ReadConfig(&$qname, &$q) {
$this->SetRName($qname);
$this->SetREnabled($q['enabled']);
$this->SetRPort($q['divert_port']);
if(isset($q['description']) && $q['description'] <> "")
$this->SetRDescription($q['description']);
$rsets = $q['l7rules'];
//Put individual rules in the array
if(is_array($rsets)) {
foreach($rsets as $l7r) {
$l7obj = new l7rule();
$l7obj->SetRProtocol($l7r['protocol']);
$l7obj->SetRStructure($l7r['structure']);
$l7obj->SetRBehaviour($l7r['behaviour']);
$this->add_rule($l7obj);
}
}
}
//Generate a random port for the divert socket
function gen_divert_port() {
$dports = get_divert_ports(); //array of used ports
$divert_port = rand(40000, 60000);
while(true) {
foreach($dports as $dport) {
$dupe = false;
if($dport == $divert_port) {
$divert_port = rand(40000, 60000);
$dupe = true;
break;
}
}
if(!$dupe) {
break;
}
}
return $divert_port;
}
//Helps building the left tree
function build_tree() {
$tree = " <li><a href=\"firewall_shaper_layer7.php?container=" . $this->GetRName() ."&action=show\">";
$tree .= $this->GetRName() . "</a>";
$tree .= "</li>";
return $tree;
}
function build_form() {
$form = "<tr><td valign=\"top\" class=\"vncellreq\"><br>";
$form .= "Enable/Disable";
$form .= "</td><td class=\"vncellreq\">";
$form .= " <input type=\"checkbox\" id=\"enabled\" name=\"enabled\"";
if ($this->GetREnabled()) {
$form .= "checked = \"CHECKED\"";
}
$form .= " ><span class=\"vexpl\"> Enable/Disable layer7 Container</span>";
$form .= "</td></tr>";
$form .= "<tr><td valign=\"top\" class=\"vncellreq\"><br><span class=\"vexpl\">Name</span></td>";
$form .= "<td class=\"vncellreq\">";
$form .= "<input type=\"text\" id=\"container\" name=\"container\" value=\"";
$form .= $this->GetRName()."\">";
$form .= "</td></tr>";
$form .= "<tr><td valign=\"top\" class=\"vncellreq\">Description</td>";
$form .= "<td class=\"vncellreq\">";
$form .= "<input type=\"text\" class=\"formfld unknown\" size=\"50%\" id=\"description\" name=\"description\" value=\"";
$form .= $this->GetRDescription();
$form .= "\">";
$form .= "<br> <span class=\"vexpl\">";
$form .= "You may enter a description here ";
$form .= "for your reference (not parsed).</span>";
$form .= "</td></tr>";
return $form;
}
//Write the setting to the $config array
function wconfig() {
global $config;
if(!is_array($config['l7shaper']['container'])) {
$config['l7shaper']['container'] = array();
}
//
$cflink =& get_l7c_reference_to_me_in_config($this->GetRName());
// Test if this rule does exists already
if(!$cflink) {
$cflink =& $config['l7shaper']['container'][];
}
$cflink['name'] = $this->GetRName();
$cflink['enabled'] = $this->GetREnabled();
$cflink['description'] = $this->GetRDescription();
$cflink['divert_port'] = $this->GetRPort();
//Destroy previously existent rules
if(is_array($cflink['rules'])) {
unset($cflink['l7rules']);
}
$cflink['l7rules'] = array();
$i = 0;
foreach($this->rsets as $rulel7) {
$cflink['l7rules'][$i]['protocol'] = $rulel7->GetRProtocol();
$cflink['l7rules'][$i]['structure'] = $rulel7->GetRStructure();
$cflink['l7rules'][$i]['behaviour'] = $rulel7->GetRBehaviour();
$i++;
}
}
//This function is necessary to help producing the overload options for keep state
function get_unique_structures() {
$unique_structures = array("action" => false, "dummynet" => false, "altq" => false);
foreach($this->rsets as $l7rule) {
if($l7rule->GetRStructure() == "action")
$unique_structures['action'] = true;
else if($l7rule->GetRStructure() == "limiter")
$unique_structures['dummynet'] = true;
else
$unique_structures['altq'] = true;
}
//Delete non used structures so we don't have to check this in filter.inc
foreach($unique_structures as $key => $value)
if(!$value)
unset($unique_structures[$key]);
return $unique_structures;
}
function validate_input($data, &$input_errors) {
$reqfields[] = "container";
$reqdfieldsn[] = "Name";
shaper_do_input_validation($data, $reqdfields, $reqdfieldsn, $input_errors);
if (!preg_match("/^[a-zA-Z0-9_-]+$/", $data['container']))
$input_errors[] = "Queue names must be alphanumeric and _ or - only.";
}
function delete_l7c() {
unset_l7_object_by_reference($this->GetRName());
cleanup_l7_from_rules($this->GetRName());
}
}
class l7rule {
var $rprotocol; //protocol
var $rstructure; //action, limiter, queue
var $rbehaviour; //allow, block, queue_name, pipe_number ...
//Auxiliary Functions
function GetRProtocol() {
return $this->rprotocol;
}
function SetRProtocol($rprotocol) {
$this->rprotocol = $rprotocol;
}
function GetRStructure() {
return $this->rstructure;
}
function SetRStructure($rstructure) {
$this->rstructure = $rstructure;
}
function GetRBehaviour() {
return $this->rbehaviour;
}
function SetRBehaviour($rbehaviour) {
$this->rbehaviour = $rbehaviour;
}
//XXX Do we need to test any particularity for AltQ queues?
function build_rules() {
global $dummynet_pipe_list;
switch ($this->GetRStructure()) {
case "limiter":
read_dummynet_config();
$dn_list =& get_unique_dnqueue_list();
$found = false;
if(is_array($dn_list)) {
foreach($dn_list as $key => $value) {
if($key == $this->GetRBehaviour()) {
if($value[0] == "?")
$l7rule = $this->GetRProtocol() . " = dnqueue " . substr($value, 1) . "\n";
else
$l7rule = $this->GetRProtocol() . " = dnpipe " . $value . "\n";
$found = true;
}
if($found)
break;
}
}
break;
default: //This is for action and for altq
$l7rule = $this->GetRProtocol() . " = " . $this->GetRStructure() . " " . $this->GetRBehaviour() . "\n";
break;
}
return $l7rule;
}
}
/*
* This function allows to return an array with all the used divert socket ports
*/
function get_divert_ports() {
global $layer7_rules_list;
$dports = array();
foreach($layer7_rules_list as $l7r)
$dports[] = $l7r->GetRPort();
return $dports;
}
function &get_l7c_reference_to_me_in_config(&$name) {
global $config;
$ptr = NULL;
if(is_array($config['l7shaper']['container'])) {
foreach($config['l7shaper']['container'] as $key => $value) {
if($value['name'] == $name)
$ptr =& $config['l7shaper']['container'][$key];
}
}
return $ptr;
// $ptr can be null. has to be checked later
}
function unset_l7_object_by_reference(&$name) {
global $config;
if(is_array($config['l7shaper']['container'])) {
foreach($config['l7shaper']['container'] as $key => $value) {
if($value['name'] == $name) {
unset($config['l7shaper']['container'][$key]['l7rules']);
unset($config['l7shaper']['container'][$key]);
break;
}
}
}
}
function read_layer7_config() {
global $layer7_rules_list, $config;
$l7cs = &$config['l7shaper']['container'];
$layer7_rules_list = array();
if (!is_array($config['l7shaper']['container']) || !count($config['l7shaper']['container']))
return;
foreach ($l7cs as $conf) {
if (empty($conf['name']))
continue; /* XXX: grrrrrr at php */
$root =& new layer7();
$root->ReadConfig($conf['name'],$conf);
$layer7_rules_list[$root->GetRName()] = &$root;
}
}
function generate_layer7_files() {
global $layer7_rules_list;
read_layer7_config();
if (!empty($layer7_rules_list)) {
mwexec("kldload ipdivert.ko");
mwexec("killall -9 ipfw-classifyd");
}
foreach($layer7_rules_list as $l7rules) {
if($l7rules->GetREnabled()) {
$filename = $l7rules->GetRName() . ".l7";
$path = "/tmp/" . $filename;
$rules = $l7rules->build_l7_rules();
$fp = fopen($path,'w');
fwrite($fp,$rules);
fclose($fp);
$ipfw_classifyd_init = "ipfw-classifyd -c " . $path . " -p " . $l7rules->GetRPort() . " -P /usr/local/share/protocols";
mwexec($ipfw_classifyd_init);
}
}
}
// This function uses /usr/local/share/protocols as a default directory for searching .pat files
function generate_protocols_array() {
$protocols = return_dir_as_array("/usr/local/share/protocols");
if(is_array($protocols)) {
foreach($protocols as $key => $proto)
$protocols[$key] =& str_replace(".pat", "", $proto);
sort($protocols);
}
return $protocols;
}
function get_l7_unique_list() {
global $layer7_rules_list;
$l7list = array();
if(is_array($layer7_rules_list))
foreach($layer7_rules_list as $l7c)
if($l7c->GetREnabled())
$l7list[] = $l7c->GetRName();
return $l7list;
}
// Disable a removed l7 container from the filter
function cleanup_l7_from_rules(&$name) {
global $config;
foreach ($config['filter']['rule'] as $key => $rule) {
//We have to change this
if ($rule['l7container'] == $name)
unset($config['filter']['rule'][$key]['l7container']);
}
}
/*
* XXX: TODO Make a class shaper to hide all these function
@ -3290,14 +3676,14 @@ $default_shaper_msg = "<tr><td align=\"center\" width=\"80%\" >";
$default_shaper_msg .= "<span class=\"vexpl\"><strong><p><b>Welcome to the pfSense Traffic Shaper.</b><br />";
$default_shaper_msg .= "The tree on the left helps you navigate through the queues <br />";
$default_shaper_msg .= "buttons at the bottom represent queue actions and are activated accordingly.";
$default_shaper_ms .= " </p></strong></span>";
$default_shaper_msg .= " </p></strong></span>";
$default_shaper_msg .= "</td></tr>";
$dn_default_shaper_msg = "<tr><td align=\"center\" width=\"80%\" >";
$dn_default_shaper_msg .= "<span class=\"vexpl\"><strong><p><b>Welcome to the pfSense Traffic Shaper.</b><br />";
$dn_default_shaper_msg .= "The tree on the left helps you navigate through the queues <br />";
$dn_default_shaper_msg .= "buttons at the bottom represent queue actions and are activated accordingly.";
$dn_default_shaper_ms .= " </p></strong></span>";
$dn_default_shaper_msg .= " </p></strong></span>";
$dn_default_shaper_msg .= "</td></tr>";

View File

@ -36,11 +36,11 @@ function listtags() {
* I know it's a pain, but it's a pain to find stuff too if it's not
*/
$ret = explode(" ",
"alias aliasurl allowedip authserver bridged ca cacert cert config ".
"alias aliasurl allowedip authserver bridged ca cacert cert config container ".
"columnitem depends_on_package disk dnsserver dnsupdate domainoverrides ".
"dyndns earlyshellcmd element encryption-algorithm-option field ".
"fieldname hash-algorithm-option gateway_item gateway_group gif gre ".
"group hosts member interface_array item key lagg lbaction lbpool ".
"group hosts member interface_array item key lagg lbaction lbpool l7rules ".
"lbprotocol member menu tab mobilekey monitor_type mount ntpserver onetoone ".
"openvpn-server openvpn-client openvpn-csc " .
"option ppp package passthrumac phase1 phase2 priv proxyarpnet queue ".

130
usr/local/www/diag_patterns.php Executable file
View File

@ -0,0 +1,130 @@
<?php
/* $Id$ */
/*
Exec+ v1.02-000 - Copyright 2001-2003, All rights reserved
Created by André Ribeiro and Hélder Pereira
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
##|+PRIV
##|*IDENT=page-diagnostics-patters
##|*NAME=Diagnostics: Patterns page
##|*DESCR=Allow access to the 'Diagnostics: Patterns' page.
##|*MATCH=patterns.php*
##|-PRIV
require("guiconfig.inc");
//Move the upload file to /usr/local/share/protocols (is_uploaded_file must use tmp_name as argument)
if (($_POST['submit'] == "Upload") && is_uploaded_file($_FILES['ulfile']['tmp_name'])) {
if(fileExtension($_FILES['ulfile']['name'])) {
move_uploaded_file($_FILES['ulfile']['tmp_name'], "/usr/local/share/protocols/" . $_FILES['ulfile']['name']);
$ulmsg = "Uploaded file to /usr/local/share/protocols/" . htmlentities($_FILES['ulfile']['name']);
}
else
$ulmsg = "Warning: You must upload a file with .pat extension.";
}
//Check if file has correct extension (.pat)
function fileExtension($nameFile) {
$format = substr($nameFile, -4);
return ($format == ".pat");
}
$pgtitle = array("Diagnostics","Add layer7 pattern");
include("head.inc");
?>
<style>
<!--
input {
font-family: courier new, courier;
font-weight: normal;
font-size: 9pt;
}
pre {
border: 2px solid #435370;
background: #F0F0F0;
padding: 1em;
font-family: courier new, courier;
white-space: pre;
line-height: 10pt;
font-size: 10pt;
}
.label {
font-family: tahoma, verdana, arial, helvetica;
font-size: 11px;
font-weight: bold;
}
.button {
font-family: tahoma, verdana, arial, helvetica;
font-weight: bold;
font-size: 11px;
}
-->
</style>
</head>
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
<?php include("fbegin.inc"); ?>
<p><strong>You can upload new layer7 patterns to your system!</strong></p>
<?php if ($ulmsg) echo "<p class=\"red\"><strong>" . $ulmsg . "</strong></p>\n"; ?>
<div id="niftyOutter">
<form action="diag_patterns.php" method="POST" enctype="multipart/form-data" name="frmPattern">
<table>
<tr>
<td colspan="2" valign="top" class="vnsepcell">Upload</td>
</tr>
<tr>
<td align="right">File to upload:</td>
<td valign="top" class="label">
<input name="ulfile" type="file" class="formfld file" id="ulfile">
</td></tr>
<tr>
<td valign="top">&nbsp;&nbsp;&nbsp;</td>
<td valign="top" class="label">
<input name="submit" type="submit" class="button" id="upload" value="Upload"></td>
</tr>
<tr>
<td colspan="2" valign="top" height="16"></td>
</tr>
</table>
</div>
<?php include("fend.inc"); ?>
</form>
</body>
</html>
<?php
?>

View File

@ -424,7 +424,8 @@ include("fbegin.inc");
$tab_array[0] = array("By Interface", true, "firewall_shaper.php");
$tab_array[1] = array("By Queue", false, "firewall_shaper_queues.php");
$tab_array[2] = array("Limiter", false, "firewall_shaper_vinterface.php");
$tab_array[3] = array("Wizards", false, "firewall_shaper_wizards.php");
$tab_array[3] = array("Layer7", false, "firewall_shaper_layer7.php");
$tab_array[4] = array("Wizards", false, "firewall_shaper_wizards.php");
display_top_tabs($tab_array);
?>
</td></tr>

View File

@ -0,0 +1,592 @@
<?php
/* $Id$ */
/*
firewall_shaper_layer7.php
Copyright (C) 2008 Helder Pereira, André Ribeiro
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
##|+PRIV
##|*IDENT=page-firewall-trafficshaper-layer7
##|*NAME=Firewall: Traffic Shaper: Layer7 page
##|*DESCR=Allow access to the 'Firewall: Traffic Shaper: Layer7' page.
##|*MATCH=firewall_shaper_layer7.php*
##|-PRIV
require("guiconfig.inc");
// Variables protocols (dynamic) and structures (static)
$avail_protos =& generate_protocols_array();
$avail_structures = array("action","queue","limiter");
// Available behaviours
$avail_behaviours_action = array("allow","block");
read_altq_config();
$avail_behaviours_altq = get_altq_name_list();
read_dummynet_config();
$avail_behaviours_limiter = get_dummynet_name_list();
$show_proto_form = false;
//More variables
$pgtitle = array("Firewall","Traffic Shaper", "Layer7");
$output_form = "";
$default_layer7shaper_msg = "<tr><td colspan=\"4\">";
$default_layer7shaper_msg .= "<p><span class=\"vexpl\"><span class=\"red\"><strong>Note:<br>";
$default_layer7shaper_msg .= "</strong></span>You can add new layer7 protocol patterns by simply uploading the file <a href=\"diag_patterns.php\">here.</a><br>";
$default_layer7shaper_msg .= "</td></tr>";
read_layer7_config();
if($_GET['reset'] <> "") {
mwexec("killall -9 pfctl php");
mwexec("killall -9 ipfw-classifyd"); //kill all ipfw-classifyd processes
exit;
}
if ($_GET) {
if ($_GET['container'])
$name = trim($_GET['container']);
if ($_GET['action'])
$action = $_GET['action'];
}
if($_POST) {
if ($_POST['container']) {
$name = trim($_POST['container']);
}
}
if ($name) {
//Get the object from the 7rules list
$container = $layer7_rules_list[$name];
}
if ($_GET) {
switch ($action) {
case "add":
$show_proto_form = true;
$container = new layer7();
$output_form .= $container->build_form(); //constructs the graphical interface on the right side
unset($container);
break;
case "show":
$show_proto_form = true;
if($container) {
$output_form .= $container->build_form();
}
else {
$show_proto_form = false;
$input_errors[] = "Layer7 Rules Container not found!";
}
break;
default:
echo log_error("Get default");
$show_proto_form = false;
$output_form .= "<p class=\"pgtitle\">" . $dn_default_shaper_msg . $default_layer7shaper_msg . "</p>";
break;
}
}
//add a new l7rules container
else if ($_POST) {
$show_proto_form = true;
unset($input_errors);
if($_POST['submit']) {
$l7r =& new layer7();
$_POST['divert_port'] = $l7r->gen_divert_port();
for($i=0; $i<100; $i++) {
if($_POST['protocol'][$i] <> "") {
$_POST['l7rules'][$i]['protocol'] = $_POST['protocol'][$i];
$_POST['l7rules'][$i]['structure'] = $_POST['structure'][$i];
$_POST['l7rules'][$i]['behaviour'] = $_POST['behaviour'][$i];
}
else {
break;
}
}
$l7r->validate_input($_POST,&$input_errors);
$l7r->ReadConfig($_POST['container'], $_POST);
//Before writing the results, we need to test for repeated protocols
$non_dupes = array();
$dupes = array();
for($j=0; $j<$i; $j++) {
if(!$non_dupes[$_POST['protocol'][$j]])
$non_dupes[$_POST['protocol'][$j]] = true;
else
$dupes[] = $_POST['protocol'][$j];
}
unset($non_dupes);
if(sizeof($dupes) == 0 && !$input_errors) {
$l7r->wconfig();
write_config();
touch($d_shaperconfdirty_path);
read_layer7_config();
}
else {
if(sizeof($dupes) > 0) {
$dupe_error = "Found the following repeated protocol definitions: ";
foreach($dupes as $dupe)
$dupe_error .= "$dupe ";
$input_errors[] .= $dupe_error;
}
}
unset($dupes);
unset($dupe_error);
//Even if there are repeated protocols, we won't loose any previous values
//The user will be able to solve the situation
$output_form .= $l7r->build_form();
//Necessary to correctly build the proto form
$container = $layer7_rules_list[$name];
if($input_errors)
$container =& $l7r;
} else if($_POST['apply']) {
write_config();
$retval = 0;
$savemsg = get_std_save_message($retval);
config_lock();
$retval = filter_configure();
config_unlock();
if(stristr($retval, "error") <> true)
$savemsg = get_std_save_message($retval);
else
$savemsg = $retval;
unlink($d_shaperconfdirty_path);
if($container) {
$output_form .= $container->build_form();
} else {
$show_proto_form = false;
$output_form .= "<p class=\"pgtitle\">" . $dn_default_shaper_msg . $default_layer7shaper_msg . "</p>";
}
} else if ($_POST['delete']) {
$container->delete_l7c();
write_config();
touch($d_shaperconfdirty_path);
unset($container);
header("Location: firewall_shaper_layer7.php");
exit;
}
else {
$show_proto_form = false;
}
}
else {
$show_proto_form = false;
$output_form .= "<p class=\"pgtitle\">" . $dn_default_shaper_msg . $default_layer7shaper_msg . "</p>";
}
// Builds the left tree
$tree = "<ul class=\"tree\" >";
if (is_array($layer7_rules_list)) {
foreach ($layer7_rules_list as $tmpl7) {
$tree .= $tmpl7->build_tree();
}
}
$tree .= "</ul>";
$output = "<div id=\"shaperarea\" style=\"position:relative\">";
$output .= $output_form;
include("head.inc");
?>
<body link="#0000CC" vlink="#0000CC" alink="#0000CC" >
<link rel="stylesheet" type="text/css" media="all" href="./tree/tree.css" />
<script type="text/javascript" src="./tree/tree.js"></script>
<script language="javascript">
var initial_count = new Array();
var rows_limit = 0; // Set to 0 to disable limitation
/* Build the behaviours arrays in javascript */
var js_behaviours_action = ['allow', 'block']; //static
var js_behaviours_altq = new Array();
js_behaviours_altq = array_altq(js_behaviours_altq);
var js_behaviours_limiter = new Array();
js_behaviours_limiter = array_limiter(js_behaviours_limiter);
function array_altq(a_behav) {
var index;
<? if (!empty($avail_behaviours_altq)) {
foreach ($avail_behaviours_altq as $key => $queue) { ?>
name = "<?= $queue; ?>";
index = <? echo $key; ?>;
a_behav[index] = name;
<? }
} ?>
return a_behav;
}
function array_limiter(a_behav) {
var index;
<? if (!empty($avail_behaviours_limiter)) {
foreach ($avail_behaviours_limiter as $key => $limiter) { ?>
name = "<?= $limiter; ?>";
index = <? echo $key; ?>;
a_behav[index] = name;
<? }
} ?>
return a_behav;
}
/* Fill the variables with available protocols, structures and behaviours */
function fillProtocol() {
var protocol = '<select name="protocol[]" id="protocol" style="font-size:8pt">';
var name;
<? foreach ($avail_protos as $key => $proto) { ?>
name = "<?= $proto; ?>";
protocol += "<option value=" + name + ">" + name + "</option>";
<? } ?>
protocol += "</select>";
return protocol;
}
function fillStructure() {
var structure = '<select name="structure[]" id="structure" style="font-size:8pt" onchange="changeBehaviourValues(this.parentNode.parentNode);">';
var name;
<? foreach ($avail_structures as $key => $struct) { ?>
name = "<?= $struct; ?>";
if(name == "queue") {
if(js_behaviours_altq != "") { structure += "<option value=" + name + ">" + name + "</option>";}
}
else {
if(name == "limiter") {
if(js_behaviours_limiter != "") { structure += "<option value=" + name + ">" + name + "</option>";}
}
else structure += "<option value=" + name + ">" + name + "</option>"; //action
}
<? } ?>
structure += "</select>";
return structure;
}
//Used by default to fill the values when inserting a new row.
function fillBehaviour() {
var behaviour = '<select name="behaviour[]" id="behaviour" style="width:80px; font-size:8pt">';
var name;
<? foreach ($avail_behaviours_action as $key => $behav) { ?>
name = "<?= $behav; ?>";
behaviour += "<option value=" + name + ">" + name + "</option>";
<? } ?>
behaviour += "</select>";
return behaviour;
}
/* Change the values on behaviours select when changing the structure row */
function changeBehaviourValues(row) {
var selectedRow = row.rowIndex - 2; //because row.rowIndex returns 2, not 0
var structureSelected = document.getElementsByName("structure[]")[selectedRow].value;
//Select the behaviours values to array a_behav
var a_behav = new Array();
if (structureSelected == "action") {
a_behav = js_behaviours_action; //static
}
else {
if (structureSelected == "queue") {
a_behav = js_behaviours_altq;
}
else {
a_behav = js_behaviours_limiter;
}
}
//Build the html statement with the array values previously selected
var new_behav;
var name;
for(i=0; i<a_behav.length; i++) {
new_behav += "<option value=" + a_behav[i] + ">" + a_behav[i] + "</option>";
}
document.getElementsByName("behaviour[]")[selectedRow].innerHTML = new_behav;
}
/* Add row to the table */
function addRow(table_id) {
var tbl = document.getElementById(table_id);
// counting rows in table
var rows_count = tbl.rows.length;
if (initial_count[table_id] == undefined) {
// if it is first adding in this table setting initial rows count
initial_count[table_id] = rows_count;
}
// determining real count of added fields
var tFielsNum = rows_count - initial_count[table_id];
if (rows_limit!=0 && tFielsNum >= rows_limit) return false;
var remove = '<input type = "image" src = "/themes/<?echo $g['theme'];?>/images/icons/icon_x.gif" onclick="removeRow(\''+table_id+'\',this.parentNode.parentNode)" value = "Delete" />';
try {
var newRow = tbl.insertRow(rows_count);
var newCell = newRow.insertCell(0);
newCell.innerHTML = fillProtocol();
var newCell = newRow.insertCell(1);
newCell.innerHTML = fillStructure();
var newCell = newRow.insertCell(2);
newCell.innerHTML = fillBehaviour();
var newCell = newRow.insertCell(3);
newCell.innerHTML = remove;
}
catch (ex) {
//if exception occurs
alert(ex);
}
}
/* Remove row from the table */
function removeRow(tbl,row) {
var table = document.getElementById(tbl);
try {
table.deleteRow(row.rowIndex);
} catch (ex) {
alert(ex);
}
}
</script>
<?php
include("fbegin.inc");
?>
<div id="inputerrors"></div>
<?php if ($input_errors) print_input_errors($input_errors); ?>
<form action="firewall_shaper_layer7.php" method="post" id="iform" name="iform">
<?php if ($savemsg) print_info_box($savemsg); ?>
<?php if (file_exists($d_shaperconfdirty_path)): ?><p>
<?php print_info_box_np("The traffic shaper configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td>
<?php
$tab_array = array();
$tab_array[0] = array("By Interface", false, "firewall_shaper.php");
$tab_array[1] = array("By Queue", false, "firewall_shaper_queues.php");
$tab_array[2] = array("Limiter", false, "firewall_shaper_vinterface.php");
$tab_array[3] = array("Layer7", true, "firewall_shaper_layer7.php");
$tab_array[4] = array("Wizards", false, "firewall_shaper_wizards.php");
display_top_tabs($tab_array);
?>
</td></tr>
<tr>
<td>
<div id="mainarea">
<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
<?php if (count($layer7_rules_list) > 0): ?>
<tr class="tabcont"><td width="25%" align="left">
</td><td width="75%"> </td></tr>
<? endif; ?>
<tr>
<td width="25%" valign="top" algin="left">
<?php
echo $tree;
?>
<br/><br/>
<a href="firewall_shaper_layer7.php?action=add">
<img src="./themes/<?=$g['theme']; ?>/images/icons/icon_plus.gif" title="Create new l7 rules group" width="17" height="17" border="0"> Create new l7 rules group
</a><br/>
</td>
<td width="75%" valign="top" align="center">
<table>
<?
echo $output;
?>
<!-- Layer 7 rules form -->
<?php if($show_proto_form): ?>
<td width = "22%" valign = "top" class = "vncellreq">
<div id = "addressnetworkport">
Rule(s)
</div>
</td>
<td width = "78%" class = "vtable">
<table width="236" id = "maintable">
<tbody>
<tr>
<td colspan = "4">
<div style = "font-size: 8pt; padding:5px; margin-top: 16px; margin-bottom: 16px; border:1px dashed #000066;"
id = "itemhelp">
Add one or more rules
</div>
</td>
</tr>
<tr>
<td>
<div style = "font-size: 8pt; padding:5px;"
id = "onecolumn">
Protocol
</div>
</td>
<td>
<div style = "font-size: 8pt; padding:5px;"
id = "twocolumn">
Structure
</div>
</td>
<td>
<div style = "font-size: 8pt; padding:5px;"
id = "threecolumn">
Behaviour
</div>
</td>
</tr>
<!-- PHP Code to generate the existing rules -->
<?php
if($container) {
foreach($container->rsets as $l7rule) {
?>
<tr>
<td>
<select name="protocol[]" class="formselect" id="protocol" style="font-size:8pt">
<?php foreach($avail_protos as $proto): ?>
<option value="<?=$proto;?>" <?php if ($proto == $l7rule->GetRProtocol()) echo "selected"; ?>><?=$proto;?></option>
<? endforeach; ?>
</select>
</td>
<td>
<select name="structure[]" class="formselect" id="structure" style="font-size:8pt" onchange="changeBehaviourValues(this.parentNode.parentNode);">
<?php foreach($avail_structures as $struct) {
if($struct == "queue") {
if(!empty($avail_behaviours_altq)) { ?>
<option value="<?=$struct ?>" <?php if ($struct == $l7rule->GetRStructure()) echo "selected"; ?>><?=$struct;?></option>
<?php }
}
else {
if($struct == "limiter") {
if(!empty($avail_behaviours_limiter)) { ?>
<option value="<?=$struct ?>" <?php if ($struct == $l7rule->GetRStructure()) echo "selected"; ?>><?=$struct;?></option>
<?php }
}
else {
if($struct == "action") { ?>
<option value="<?=$struct ?>" <?php if ($struct == $l7rule->GetRStructure()) echo "selected"; ?>><?=$struct;?></option>
<?php }
}
}
} ?>
</select>
</td>
<td>
<select name="behaviour[]" class="formselect" id="behaviour" style="width:80px; font-size:8pt">
<?php if($l7rule->GetRStructure() == "action"): ?>
<?php foreach($avail_behaviours_action as $behaviour): ?>
<option value="<?=$behaviour ?>" <?php if ($behaviour == $l7rule->GetRBehaviour()) echo "selected"; ?>><?=$behaviour;?></option>
<? endforeach; ?>
</select>
<? endif; ?>
<?php if($l7rule->GetRStructure() == "queue"): ?>
<?php foreach($avail_behaviours_altq as $behaviour): ?>
<option value="<?=$behaviour ?>" <?php if ($behaviour == $l7rule->GetRBehaviour()) echo "selected"; ?>><?=$behaviour;?></option>
<? endforeach; ?>
</select>
<? endif; ?>
<?php if($l7rule->GetRStructure() == "limiter"): ?>
<?php foreach($avail_behaviours_limiter as $behaviour): ?>
<option value="<?=$behaviour ?>" <?php if ($behaviour == $l7rule->GetRBehaviour()) echo "selected"; ?>><?=$behaviour;?></option>
<? endforeach; ?>
</select>
<? endif; ?>
</td>
<td>
<input type="image" src="/themes/<? echo $g['theme'];?>/images/icons/icon_x.gif" onclick="removeRow('maintable',this.parentNode.parentNode); return false;" value="Delete" />
</td>
</tr>
<?php
} //end foreach
} //end if
?>
</tbody>
<tfoot>
</tfoot>
</table>
<a onclick = "javascript:addRow('maintable'); return false;" href="#"> <img border = "0"
src = "/themes/<?=$g['theme']; ?>/images/icons/icon_plus.gif"
alt = "" title = "add another entry" /> </a>
</td>
</tr>
<tr>
<td width = "22%" valign = "top">
&nbsp;
</td>
<td width = "78%">
<input id = "submit"
name = "submit" type = "submit" class = "formbtn" value = "Save" />
<a href= "firewall_shaper_layer7.php">
<input id = "cancelbutton"
name = "cancelbutton" type = "button" class = "formbtn" value = "Cancel" /></a>
<?php if($container): ?>
<input id = "delete" type="submit" class="formbtn" name="delete" value="Delete"></a>
<? endif ?>
</td>
</tr>
<? endif; ?>
<!-- End of layer7 rules form -->
</table>
</td></tr>
</table>
</div>
</td>
</tr>
</table>
</form>
<?php include("fend.inc");
?>
</body>
</html>

View File

@ -188,7 +188,8 @@ include("head.inc");
$tab_array[0] = array("By Interface", false, "firewall_shaper.php");
$tab_array[1] = array("By Queue", true, "firewall_shaper_queues.php");
$tab_array[2] = array("Limiter", false, "firewall_shaper_vinterface.php");
$tab_array[3] = array("Wizards", false, "firewall_shaper_wizards.php");
$tab_array[3] = array("Layer7", false, "firewall_shaper_layer7.php");
$tab_array[4] = array("Wizards", false, "firewall_shaper_wizards.php");
display_top_tabs($tab_array);
?>
</td></tr>

View File

@ -367,7 +367,8 @@ include("fbegin.inc");
$tab_array[0] = array("By Interface", false, "firewall_shaper.php");
$tab_array[1] = array("By Queue", false, "firewall_shaper_queues.php");
$tab_array[2] = array("Limiter", true, "firewall_shaper_vinterface.php");
$tab_array[3] = array("Wizards", false, "firewall_shaper_wizards.php");
$tab_array[3] = array("Layer7", false, "firewall_shaper_layer7.php");
$tab_array[4] = array("Wizards", false, "firewall_shaper_wizards.php");
display_top_tabs($tab_array);
?>
</td></tr>

View File

@ -97,7 +97,8 @@ include("fbegin.inc");
$tab_array[0] = array("By Interface", false, "firewall_shaper.php");
$tab_array[1] = array("By Queue", false, "firewall_shaper_queues.php");
$tab_array[2] = array("Limiter", false, "firewall_shaper_vinterface.php");
$tab_array[3] = array("Wizards", true, "firewall_shaper_wizards.php");
$tab_array[3] = array("Layer7", false, "firewall_shaper_layer7.php");
$tab_array[4] = array("Wizards", true, "firewall_shaper_wizards.php");
display_top_tabs($tab_array);
?>
</td></tr>