From f63d5b66b49abe5190703d9d251b7e2d462e993b Mon Sep 17 00:00:00 2001
From: Helder Pereira Welcome to the pfSense Traffic Shaper. Welcome to the pfSense Traffic Shaper. You can upload new layer7 patterns to your system! ";
+ $form .= "
";
+ $form .= "Enable/Disable";
+ $form .= "";
+ $form .= " GetREnabled()) {
+ $form .= "checked = \"CHECKED\"";
+ }
+ $form .= " > Enable/Disable layer7 Container";
+ $form .= " ";
+ $form .= " ";
+ $form .= "
Name";
+ $form .= "GetRName()."\">";
+ $form .= " ";
+
+ 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 = "Description ";
+ $form .= "";
+ $form .= "GetRDescription();
+ $form .= "\">";
+ $form .= "
";
+ $form .= "You may enter a description here ";
+ $form .= "for your reference (not parsed).";
+ $form .= " ";
$dn_default_shaper_msg = "";
$default_shaper_msg .= "
";
$default_shaper_msg .= "The tree on the left helps you navigate through the queues
";
$default_shaper_msg .= "buttons at the bottom represent queue actions and are activated accordingly.";
-$default_shaper_ms .= " ";
diff --git a/etc/inc/xmlparse.inc b/etc/inc/xmlparse.inc
index e406f5a..c1caaa7 100644
--- a/etc/inc/xmlparse.inc
+++ b/etc/inc/xmlparse.inc
@@ -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 ".
diff --git a/usr/local/www/diag_patterns.php b/usr/local/www/diag_patterns.php
new file mode 100755
index 0000000..551fc44
--- /dev/null
+++ b/usr/local/www/diag_patterns.php
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+";
$dn_default_shaper_msg .= "
";
$dn_default_shaper_msg .= "The tree on the left helps you navigate through the queues
";
$dn_default_shaper_msg .= "buttons at the bottom represent queue actions and are activated accordingly.";
-$dn_default_shaper_ms .= "