summaryrefslogtreecommitdiffstats
path: root/src/usr/local/www/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/local/www/widgets')
-rw-r--r--src/usr/local/www/widgets/include/captiveportal.inc4
-rw-r--r--src/usr/local/www/widgets/include/carp_status.inc7
-rw-r--r--src/usr/local/www/widgets/include/dyn_dns_status.inc7
-rw-r--r--src/usr/local/www/widgets/include/gateways.inc5
-rw-r--r--src/usr/local/www/widgets/include/gmirror_status.inc4
-rw-r--r--src/usr/local/www/widgets/include/installed_packages.inc7
-rw-r--r--src/usr/local/www/widgets/include/interface_statistics.inc5
-rw-r--r--src/usr/local/www/widgets/include/interfaces.inc6
-rw-r--r--src/usr/local/www/widgets/include/ipsec.inc4
-rw-r--r--src/usr/local/www/widgets/include/load_balancer.inc4
-rw-r--r--src/usr/local/www/widgets/include/log.inc6
-rw-r--r--src/usr/local/www/widgets/include/ntp_status.inc5
-rw-r--r--src/usr/local/www/widgets/include/openvpn.inc4
-rw-r--r--src/usr/local/www/widgets/include/services_status.inc7
-rw-r--r--src/usr/local/www/widgets/include/smart_status.inc5
-rw-r--r--src/usr/local/www/widgets/include/thermal_sensors.inc27
-rw-r--r--src/usr/local/www/widgets/include/traffic_graph.inc4
-rw-r--r--src/usr/local/www/widgets/include/wake_on_lan.inc7
-rw-r--r--src/usr/local/www/widgets/javascript/cpu_graphs.js245
-rw-r--r--src/usr/local/www/widgets/javascript/ipsec.js9
-rw-r--r--src/usr/local/www/widgets/javascript/thermal_sensors.js296
-rw-r--r--src/usr/local/www/widgets/javascript/traffic_graph.js41
-rw-r--r--src/usr/local/www/widgets/widgets/captive_portal_status.widget.php140
-rw-r--r--src/usr/local/www/widgets/widgets/carp_status.widget.php86
-rw-r--r--src/usr/local/www/widgets/widgets/deactivated/cpu_graphs.widget.php76
-rw-r--r--src/usr/local/www/widgets/widgets/dyn_dns_status.widget.php174
-rw-r--r--src/usr/local/www/widgets/widgets/gateways.widget.php122
-rw-r--r--src/usr/local/www/widgets/widgets/gmirror_status.widget.php59
-rw-r--r--src/usr/local/www/widgets/widgets/installed_packages.widget.php107
-rw-r--r--src/usr/local/www/widgets/widgets/interface_statistics.widget.php82
-rw-r--r--src/usr/local/www/widgets/widgets/interfaces.widget.php110
-rw-r--r--src/usr/local/www/widgets/widgets/ipsec.widget.php215
-rw-r--r--src/usr/local/www/widgets/widgets/load_balancer_status.widget.php156
-rw-r--r--src/usr/local/www/widgets/widgets/log.widget.php234
-rw-r--r--src/usr/local/www/widgets/widgets/ntp_status.widget.php499
-rw-r--r--src/usr/local/www/widgets/widgets/openvpn.widget.php289
-rw-r--r--src/usr/local/www/widgets/widgets/picture.widget.php84
-rw-r--r--src/usr/local/www/widgets/widgets/rss.widget.php167
-rw-r--r--src/usr/local/www/widgets/widgets/services_status.widget.php114
-rw-r--r--src/usr/local/www/widgets/widgets/smart_status.widget.php82
-rw-r--r--src/usr/local/www/widgets/widgets/system_information.widget.php311
-rw-r--r--src/usr/local/www/widgets/widgets/thermal_sensors.widget.php279
-rw-r--r--src/usr/local/www/widgets/widgets/traffic_graphs.widget.php161
-rw-r--r--src/usr/local/www/widgets/widgets/wake_on_lan.widget.php80
44 files changed, 4336 insertions, 0 deletions
diff --git a/src/usr/local/www/widgets/include/captiveportal.inc b/src/usr/local/www/widgets/include/captiveportal.inc
new file mode 100644
index 0000000..3714209
--- /dev/null
+++ b/src/usr/local/www/widgets/include/captiveportal.inc
@@ -0,0 +1,4 @@
+<?php
+$captive_portal_status_title = "Captive Portal Status";
+$captive_portal_status_title_link = "status_captiveportal.php";
+?>
diff --git a/src/usr/local/www/widgets/include/carp_status.inc b/src/usr/local/www/widgets/include/carp_status.inc
new file mode 100644
index 0000000..79d3c03
--- /dev/null
+++ b/src/usr/local/www/widgets/include/carp_status.inc
@@ -0,0 +1,7 @@
+<?php
+
+//set variable for custom title
+$carp_status_title = "Carp Status";
+$carp_status_title_link = "carp_status.php";
+
+?>
diff --git a/src/usr/local/www/widgets/include/dyn_dns_status.inc b/src/usr/local/www/widgets/include/dyn_dns_status.inc
new file mode 100644
index 0000000..8116fe7
--- /dev/null
+++ b/src/usr/local/www/widgets/include/dyn_dns_status.inc
@@ -0,0 +1,7 @@
+<?php
+
+//set variable for custom title
+$dyn_dns_status_title = "Dyn DNS Status";
+$dyn_dns_status_title_link = "services_dyndns.php";
+
+?>
diff --git a/src/usr/local/www/widgets/include/gateways.inc b/src/usr/local/www/widgets/include/gateways.inc
new file mode 100644
index 0000000..4666689
--- /dev/null
+++ b/src/usr/local/www/widgets/include/gateways.inc
@@ -0,0 +1,5 @@
+<?php
+//set variable for custom title
+$gateways_title = "Gateways";
+$gateways_title_link = "status_gateways.php";
+?>
diff --git a/src/usr/local/www/widgets/include/gmirror_status.inc b/src/usr/local/www/widgets/include/gmirror_status.inc
new file mode 100644
index 0000000..6547d4d
--- /dev/null
+++ b/src/usr/local/www/widgets/include/gmirror_status.inc
@@ -0,0 +1,4 @@
+<?php
+$gmirror_status_title = "GEOM Mirror Status";
+$gmirror_status_title_link = "diag_gmirror.php";
+?> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/include/installed_packages.inc b/src/usr/local/www/widgets/include/installed_packages.inc
new file mode 100644
index 0000000..a978191
--- /dev/null
+++ b/src/usr/local/www/widgets/include/installed_packages.inc
@@ -0,0 +1,7 @@
+<?php
+
+//set variable for custom title
+$installed_packages_title = "Installed Packages";
+$installed_packages_title_link = "pkg_mgr_installed.php";
+
+?> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/include/interface_statistics.inc b/src/usr/local/www/widgets/include/interface_statistics.inc
new file mode 100644
index 0000000..c789418
--- /dev/null
+++ b/src/usr/local/www/widgets/include/interface_statistics.inc
@@ -0,0 +1,5 @@
+<?php
+//set variable for custom title
+$interface_statistics_title = "Interface Statistics";
+$interface_statistics_title_link = "status_interfaces.php";
+?> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/include/interfaces.inc b/src/usr/local/www/widgets/include/interfaces.inc
new file mode 100644
index 0000000..6c19a6b
--- /dev/null
+++ b/src/usr/local/www/widgets/include/interfaces.inc
@@ -0,0 +1,6 @@
+<?php
+//set variable for custom title
+$interfaces_title = "Interfaces";
+$interfaces_title_link = "status_interfaces.php";
+
+?> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/include/ipsec.inc b/src/usr/local/www/widgets/include/ipsec.inc
new file mode 100644
index 0000000..6df0a7c
--- /dev/null
+++ b/src/usr/local/www/widgets/include/ipsec.inc
@@ -0,0 +1,4 @@
+<?php
+$ipsec_title = "IPsec";
+$ipsec_title_link = "diag_ipsec.php";
+?>
diff --git a/src/usr/local/www/widgets/include/load_balancer.inc b/src/usr/local/www/widgets/include/load_balancer.inc
new file mode 100644
index 0000000..367ea46
--- /dev/null
+++ b/src/usr/local/www/widgets/include/load_balancer.inc
@@ -0,0 +1,4 @@
+<?php
+$load_balancer_status_title = "Load Balancer Status";
+$load_balancer_status_title_link = "status_lb_pool.php";
+?>
diff --git a/src/usr/local/www/widgets/include/log.inc b/src/usr/local/www/widgets/include/log.inc
new file mode 100644
index 0000000..7ad453a
--- /dev/null
+++ b/src/usr/local/www/widgets/include/log.inc
@@ -0,0 +1,6 @@
+<?php
+//set variable for custom title
+$log_title = "Firewall Logs";
+$log_title_link = "diag_logs_filter.php";
+
+?> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/include/ntp_status.inc b/src/usr/local/www/widgets/include/ntp_status.inc
new file mode 100644
index 0000000..1115095
--- /dev/null
+++ b/src/usr/local/www/widgets/include/ntp_status.inc
@@ -0,0 +1,5 @@
+<?php
+//set variable for custom title
+$ntp_status_title = "NTP Status";
+$ntp_status_title_link = "status_ntpd.php";
+?>
diff --git a/src/usr/local/www/widgets/include/openvpn.inc b/src/usr/local/www/widgets/include/openvpn.inc
new file mode 100644
index 0000000..075d0e5
--- /dev/null
+++ b/src/usr/local/www/widgets/include/openvpn.inc
@@ -0,0 +1,4 @@
+<?php
+$openvpn_title = "OpenVPN";
+$openvpn_title_link = "status_openvpn.php";
+?> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/include/services_status.inc b/src/usr/local/www/widgets/include/services_status.inc
new file mode 100644
index 0000000..685aee4
--- /dev/null
+++ b/src/usr/local/www/widgets/include/services_status.inc
@@ -0,0 +1,7 @@
+<?php
+
+//set variable for custom title
+$services_status_title = "Services Status";
+$services_status_title_link = "status_services.php";
+
+?> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/include/smart_status.inc b/src/usr/local/www/widgets/include/smart_status.inc
new file mode 100644
index 0000000..bbfa274
--- /dev/null
+++ b/src/usr/local/www/widgets/include/smart_status.inc
@@ -0,0 +1,5 @@
+<?php
+//set variable for custom title
+$smart_status_title = "SMART Status";
+$smart_status_title_link = "diag_smart.php";
+?>
diff --git a/src/usr/local/www/widgets/include/thermal_sensors.inc b/src/usr/local/www/widgets/include/thermal_sensors.inc
new file mode 100644
index 0000000..a6e727a
--- /dev/null
+++ b/src/usr/local/www/widgets/include/thermal_sensors.inc
@@ -0,0 +1,27 @@
+<?php
+/*
+ $Id: thermal_sensors.inc
+ File location:
+ \usr\local\www\widgets\include\
+
+ Used by:
+ \usr\local\www\widgets\widgets\thermal_sensors.widget.php
+
+
+*/
+
+//set variable for custom title
+$thermal_sensors_widget_title = "Thermal Sensors";
+//$thermal_sensors_widget_link = "thermal_sensors.php";
+
+
+//returns core temp data (from coretemp.ko or amdtemp.ko driver) as "|"-delimited string.
+//NOTE: depends on proper config in System >> Advanced >> Miscellaneous tab >> Thermal Sensors section.
+function getThermalSensorsData() {
+
+ $_gb = exec("/sbin/sysctl -a | grep temperature", $dfout);
+ $thermalSensorsData = join("|", $dfout);
+ return $thermalSensorsData;
+
+}
+?>
diff --git a/src/usr/local/www/widgets/include/traffic_graph.inc b/src/usr/local/www/widgets/include/traffic_graph.inc
new file mode 100644
index 0000000..3901db6
--- /dev/null
+++ b/src/usr/local/www/widgets/include/traffic_graph.inc
@@ -0,0 +1,4 @@
+<?php
+$traffic_graphs_title = "Traffic Graphs";
+$traffic_graphs_title_link = "status_graph.php";
+?>
diff --git a/src/usr/local/www/widgets/include/wake_on_lan.inc b/src/usr/local/www/widgets/include/wake_on_lan.inc
new file mode 100644
index 0000000..af3229c
--- /dev/null
+++ b/src/usr/local/www/widgets/include/wake_on_lan.inc
@@ -0,0 +1,7 @@
+<?php
+
+//set variable for custom title
+$wake_on_lan_title = "Wake On Lan";
+$wake_on_lan_title_link = "services_wol.php";
+
+?> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/javascript/cpu_graphs.js b/src/usr/local/www/widgets/javascript/cpu_graphs.js
new file mode 100644
index 0000000..1fc690a
--- /dev/null
+++ b/src/usr/local/www/widgets/javascript/cpu_graphs.js
@@ -0,0 +1,245 @@
+/******************************************************************************
+ $Id: graphlink.js,v 1.1 2006/12/21 17:10:25 dberlin Exp $
+
+ This file is part of the GraphLink software.
+ GraphLink is distributed under the MIT License.
+ Copyright (C) 2005-2006 Max Khitrov <max@mxsoft.org>
+ ******************************************************************************/
+
+/***** Global data ************************************************************/
+
+var gl_graphCount = 0; // Number of graphs on the current page
+
+/***** Constants **************************************************************/
+
+var GL_START = 0;
+var GL_END = 1;
+var GL_STATIC = 0;
+var GL_DYNAMIC = 1;
+
+/***** Public functions *******************************************************/
+
+/**
+ * Creates a graph and returns the graph data structure which can later be
+ * manipulated using the other graph functions.
+ *
+ * element_id - DOM element id (should be a DIV) that will contain the graph.
+ * width - The width of the graph in pixels.
+ * height - Height of the graph in pixels.
+ * bar_width - Width of each bar on the graph. This number should divide width
+ * evenly, or else width will be adjusted to meet this requirement.
+ * General formula to keep in mind:
+ * Smaller bar width = more bars = higher CPU usage on client-side.
+ *
+ * Returns graph data structure on success, false on error.
+ */
+function GraphInitialize(element_id, width, height, bar_width) {
+ // Find the page element which will contain the graph
+ var owner;
+ if((owner = jQuery('#' + element_id)) == null) {
+ alert("GraphLink Error: Element ID '" + element_id + "' not found.");
+ return false;
+ }
+
+ // Make sure width is divisible by bar_width
+ if(width / bar_width != Math.floor(width / bar_width))
+ width = Math.floor(width / bar_width) * bar_width;
+
+ var bar_count = width / bar_width;
+
+ // Create the graph data structure
+ var graph = new Array();
+ graph['id'] = gl_graphCount; // ID used to separate elements of one graph from those of another
+ graph['width'] = width; // Graph width
+ graph['height'] = height; // Graph height
+ graph['bar_count'] = bar_count; // Number of bars on the graph
+ graph['scale_type'] = GL_STATIC; // How the graph is scaled
+ graph['scale'] = 1; // Multiplier for the bar height
+ graph['max'] = 0; // Largest value currently on the graph
+ graph['vmax'] = height; // Virtual graph maximum
+ graph['spans'] = new Array(bar_count); // References to all the spans for each graph
+ graph['vals'] = new Array(bar_count); // The height of each bar on the graph, actually it's (graph height - bar height)
+ gl_graphCount++;
+
+ // Build the graph (x)html
+ var graph_html = '';
+ graph_html += '<div id="GraphLinkData' + graph['id'] + '" class="GraphLinkData">';
+
+ for(var i = 0; i < bar_count; i++) {
+ graph['vals'][i] = height;
+ graph_html += '<span id="GraphLinkBar' + graph['id'] + '_' + i + '" class="GraphLinkBar"></span>';
+ }
+
+ graph_html += '</div>';
+ owner.html(graph_html);
+ graph['element_id'] = jQuery('#GraphLinkData' + graph['id']);
+
+ for(i = 0; i < bar_count; i++) {
+ graph['spans'][i] = jQuery('#GraphLinkBar' + graph['id'] + '_' + i);
+ graph['spans'][i].css('width',bar_width + 'px');
+ graph['spans'][i].css('margin-top',height + 'px');
+ }
+
+ return graph;
+}
+
+/**
+ * Adds a new value to a graph.
+ *
+ * graph - Graph object to which to add the new value.
+ * value - Value to add.
+ * where - (optional) GL_START (0) or GL_END (1), depending on where you want
+ * the new value to appear. GL_START will add the value on the left
+ * of the graph, GL_END will add it on the right (default).
+ */
+function GraphValue(graph, value, where) {
+ if(typeof(where) == 'undefined')
+ where = GL_END;
+
+ var rescale = false;
+ var lost = 0;
+
+ if(value < 0)
+ value = 0;
+
+ if(graph['scale_type'] == GL_DYNAMIC && value > graph['max'])
+ rescale = true;
+
+ if(graph['scale_type'] == GL_STATIC) {
+ if(value > graph['vmax'])
+ value = graph['vmax'];
+ value = Math.round(value * graph['scale']);
+ }
+
+ if(where == GL_START) {
+ graph['vals'].unshift(graph['height'] - value);
+ lost = graph['vals'].pop();
+ }
+ else {
+ graph['vals'].push(graph['height'] - value);
+ lost = graph['vals'].shift();
+ }
+
+ if(graph['scale_type'] == GL_DYNAMIC && (graph['height'] - lost) == graph['max'])
+ rescale = true;
+
+ if(rescale)
+ GraphAdjustScale(graph)
+
+ GraphDraw(graph);
+}
+
+/**
+ * Sets a virtual maximum for the graph allowing you to have non-scaled graphs
+ * that can show a value greater then the graph height. This function will
+ * automatically set the graph to a static scale mode, meaning that no values
+ * above the maximum will be permitted. If you need to have a graph with no
+ * pre-defined maximum, make it dynamic. Also note that if you set a vmax on a
+ * graph that has data larger than vmax, that data will be reduced.
+ *
+ * graph - Graph object for which to set virtual max.
+ * vmax - The virtual maximum value for the graph.
+ */
+function GraphSetVMax(graph, vmax) {
+ graph['scale_type'] = GL_STATIC;
+ graph['vmax'] = vmax;
+
+ GraphAdjustScale(graph);
+ GraphDraw(graph);
+}
+
+/**
+ * This function instructs the graph to be scaled according to what the maximum
+ * value is. That value is used as the graph maximum and is reevaluated whenever
+ * a new value is added, or the current maximum is removed. Dynamic scaling is a
+ * good way of showing data for which you don't know what the maximum will be,
+ * but it also is a bit more resource-intensive then statically scaled graphs.
+ *
+ * graph - Graph object for which to enable dynamic scaling.
+ */
+function GraphDynamicScale(graph) {
+ graph['scale_type'] = GL_DYNAMIC;
+
+ GraphAdjustScale(graph);
+ GraphDraw(graph);
+}
+
+/***** Private functions ******************************************************/
+
+/**
+ * Checks if the current scale of the graph is still valid, or needs to be
+ * adjusted.
+ *
+ * graph - Graph object for which to check the scale.
+ */
+function GraphAdjustScale(graph) {
+ var limit = graph['bar_count'];
+ var new_max = 0;
+ var new_scale = 0;
+ var val = 0;
+
+ if(graph['scale_type'] == GL_STATIC) {
+ new_max = graph['vmax'];
+ new_scale = graph['height'] / new_max;
+
+ if(new_scale == graph['scale'])
+ return;
+ }
+
+ for(var i = 0; i < limit; i++) {
+ if(graph['scale_type'] == GL_STATIC) {
+ val = (graph['height'] - graph['vals'][i]) * graph['scale'];
+ val = val * new_scale;
+
+ if(val > new_max)
+ val = new_max;
+
+ graph['vals'][i] = graph['height'] - Math.round(val * new_scale);
+
+ }
+ else if((graph['height'] - graph['vals'][i]) > new_max) {
+ new_max = graph['height'] - graph['vals'][i];
+ }
+ }
+
+
+ if(graph['scale_type'] == GL_STATIC) {
+ graph['scale'] = new_scale;
+ }
+ else {
+ if(new_max == 0)
+ graph['scale'] = 1;
+ else
+ graph['scale'] = graph['height'] / new_max;
+
+ graph['max'] = new_max;
+ }
+}
+
+/**
+ * Redraws the graph on the screen.
+ *
+ * graph - Graph object which needs to be re-drawn.
+ */
+function GraphDraw(graph) {
+ var count = graph['bar_count'];
+
+ if(graph['scale_type'] == GL_STATIC)
+ var getMargin = function(i) {
+ return graph['vals'][i] + 'px';
+ };
+ else
+ var getMargin = function(i) {
+ var h = graph['height'];
+ var s = graph['scale'];
+ var v = graph['vals'][i];
+ return (h - Math.round((h - v) * s)) + 'px';
+ };
+
+ graph['spans'][count - 1].css("display", "none");
+
+ for(var i = 0; i < count; i++)
+ graph['spans'][i].css("marginTop", getMargin(i));
+
+// jQuery('#' + graph['spans'][count - 1]).fadeIn(500);
+}
diff --git a/src/usr/local/www/widgets/javascript/ipsec.js b/src/usr/local/www/widgets/javascript/ipsec.js
new file mode 100644
index 0000000..d38f6cd
--- /dev/null
+++ b/src/usr/local/www/widgets/javascript/ipsec.js
@@ -0,0 +1,9 @@
+function updateIpsec() {
+ selectIntLink = "ipsecDetailed";
+ ipsecsettings = "ipsecDetail=";
+ ipsecsettings += d.getElementById(selectIntLink).checked;
+
+ selectIntLink = "ipsec-config";
+ textlink = d.getElementById(selectIntLink);
+ textlink.value = ipsecsettings;
+} \ No newline at end of file
diff --git a/src/usr/local/www/widgets/javascript/thermal_sensors.js b/src/usr/local/www/widgets/javascript/thermal_sensors.js
new file mode 100644
index 0000000..7415b01
--- /dev/null
+++ b/src/usr/local/www/widgets/javascript/thermal_sensors.js
@@ -0,0 +1,296 @@
+/*
+ $Id: thermal_sensors.js
+ Description:
+ Javascript functions to get and show thermal sensors data in thermal_sensors.widget.php.
+ NOTE: depends on proper config in System >> Advanced >> Miscellaneous tab >> Thermal Sensors section.
+ File location:
+ \usr\local\www\widgets\javascript\
+ Used by:
+ \usr\local\www\widgets\widgets\thermal_sensors.widget.php
+
+ 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.
+*/
+
+
+
+//should be called from "thermal_sensors.widget.php"
+function showThermalSensorsData() {
+
+ //get data from thermal_sensors.widget.php
+ url = "/widgets/widgets/thermal_sensors.widget.php?getThermalSensorsData=1"
+ //IE fix to disable cache when using http:// , just append timespan
+ + new Date().getTime();
+
+ jQuery.ajax(url, {
+ type: 'get',
+ success: function(data) {
+ var thermalSensorsData = data || "";
+ buildThermalSensorsData(thermalSensorsData);
+ },
+ error: function(jqXHR, status, error) {
+ buildThermalSensorsDataRaw(
+ "Error getting data from [thermal_sensors.widget.php] - |" +
+ "status: [" + (status || "") + "]|" +
+ "error: [" + (error || "") + "]");
+ }
+ });
+
+ //call itself in 11 seconds
+ window.setTimeout(showThermalSensorsData, 11000);
+}
+
+function buildThermalSensorsData(thermalSensorsData) {
+ //NOTE: variable thermal_sensors_widget_showRawOutput is declared/set in "thermal_sensors.widget.php"
+ if (thermal_sensors_widget_showRawOutput) {
+ buildThermalSensorsDataRaw(thermalSensorsData);
+ } else {
+ buildThermalSensorsDataGraph(thermalSensorsData);
+ }
+}
+
+function buildThermalSensorsDataRaw(thermalSensorsData) {
+
+ var thermalSensorsContent = "";
+
+ if (thermalSensorsData && thermalSensorsData != "") {
+ thermalSensorsContent = thermalSensorsData.replace(/\|/g, "<br />");
+ //rawData = thermalSensorsData.split("|").join("<br />");
+ }
+
+ loadThermalSensorsContainer(thermalSensorsContent);
+}
+
+function loadThermalSensorsContainer (thermalSensorsContent) {
+
+ if (thermalSensorsContent && thermalSensorsContent != "") {
+ //load generated graph (or raw data) into thermalSensorsContainer (thermalSensorsContainer DIV defined in "thermal_sensors.widget.php")
+ jQuery('#thermalSensorsContainer').html(thermalSensorsContent);
+ } else {
+ jQuery('#thermalSensorsContainer').html("No Thermal Sensors data available.<br /><br />");
+ jQuery('<div/>').html(
+ "<span>* You can configure a proper Thermal Sensor / Module under <br />" +
+ "&nbsp;&nbsp;&nbsp;<a href='system_advanced_misc.php'>System &gt; Advanced &gt; Miscellaneous : Thermal Sensors section</a>.</span>"
+ ).appendTo('#thermalSensorsContainer');
+ }
+}
+
+function buildThermalSensorsDataGraph(thermalSensorsData) {
+
+ //local constants
+ var normalColor = "LimeGreen";
+ var normalColorShadowTop = "Lime";
+ var normalColorShadowBottom = "Green";
+
+ var warningColor = "Orange";
+ var warningColorShadowBottom = "Chocolate";
+
+ var criticalColor = "Red";
+ var criticalColorShadowBottom = "DarkRed";
+
+ //local variables
+ var barBgColor = normalColor; //green/normal as default
+ var barBgColorShadowTop = normalColorShadowTop; //green/normal as default
+ var barBgColorShadowBottom = normalColorShadowBottom; //green/normal as default
+
+ var thermalSensorsArray = new Array();
+
+ if (thermalSensorsData && thermalSensorsData != "") {
+ thermalSensorsArray = thermalSensorsData.split("|");
+ }
+
+ var thermalSensorsHTMLContent = "";
+ var itemsToPulsate = new Array();
+
+ //generate graph for each temperature sensor and append to thermalSensorsHTMLContent string
+ for (var i = 0; i < thermalSensorsArray.length; i++) {
+
+ var sensorDataArray = thermalSensorsArray[i].split(":");
+ var sensorName = sensorDataArray[0].trim();
+ var thermalSensorValue = getThermalSensorValue(sensorDataArray[1]);
+
+ var pulsateTimes = 0;
+ var pulsateDuration = 0;
+
+ var warningTempThresholdPosition = 0;
+ var criticalTempThresholdPosition = 0;
+
+ //NOTE: the following variables are declared/set in "thermal_sensors.widget.php":
+ // thermal_sensors_widget_coreWarningTempThreshold, thermal_sensors_widget_coreCriticalTempThreshold,
+ // thermal_sensors_widget_zoneWarningTempThreshold, thermal_sensors_widget_zoneCriticalTempThreshold
+ // thermal_sensors_widget_pulsateWarning, thermal_sensors_widget_pulsateCritical
+
+ //set graph color and pulsate parameters
+ if (sensorName.indexOf("cpu") > -1) { //check CPU Threshold config settings
+
+ warningTempThresholdPosition = thermal_sensors_widget_coreWarningTempThreshold;
+ criticalTempThresholdPosition = thermal_sensors_widget_coreCriticalTempThreshold;
+
+ if (thermalSensorValue < thermal_sensors_widget_coreWarningTempThreshold) {
+ barBgColor = normalColor;
+ barBgColorShadowTop = normalColorShadowTop;
+ barBgColorShadowBottom = normalColorShadowBottom;
+ pulsateTimes = 0;
+ pulsateDuration = 0;
+ } else if (thermalSensorValue >= thermal_sensors_widget_coreWarningTempThreshold && thermalSensorValue < thermal_sensors_widget_coreCriticalTempThreshold) {
+ barBgColor = warningColor;
+ barBgColorShadowTop = warningColor;
+ barBgColorShadowBottom = warningColorShadowBottom;
+ pulsateTimes = thermal_sensors_widget_pulsateWarning ? 4 : 0;
+ pulsateDuration = thermal_sensors_widget_pulsateWarning ? 900 : 0;
+ } else { // thermalSensorValue > thermal_sensors_widget_coreCriticalTempThreshold
+ barBgColor = criticalColor;
+ barBgColorShadowTop = criticalColor;
+ barBgColorShadowBottom = criticalColorShadowBottom;
+ pulsateTimes = thermal_sensors_widget_pulsateCritical ? 7 : 0;
+ pulsateDuration = thermal_sensors_widget_pulsateCritical ? 900 : 0;
+ }
+ } else { //assuming sensor is for a zone, check Zone Threshold config settings
+
+ warningTempThresholdPosition = thermal_sensors_widget_zoneWarningTempThreshold;
+ criticalTempThresholdPosition = thermal_sensors_widget_zoneCriticalTempThreshold;
+
+ if (thermalSensorValue < thermal_sensors_widget_zoneWarningTempThreshold) {
+
+ barBgColor = normalColor;
+ barBgColorShadowTop = normalColorShadowTop;
+ barBgColorShadowBottom = normalColorShadowBottom;
+ pulsateTimes = 0;
+ pulsateDuration = 0;
+
+ } else if (thermalSensorValue >= thermal_sensors_widget_zoneWarningTempThreshold &&
+ thermalSensorValue < thermal_sensors_widget_zoneCriticalTempThreshold) {
+
+ barBgColor = warningColor;
+ barBgColorShadowTop = warningColor;
+ barBgColorShadowBottom = warningColorShadowBottom;
+ pulsateTimes = thermal_sensors_widget_pulsateWarning ? 4 : 0;
+ pulsateDuration = thermal_sensors_widget_pulsateWarning ? 900 : 0;
+
+ } else { // thermalSensorValue > thermal_sensors_widget_zoneCriticalTempThreshold
+
+ barBgColor = criticalColor;
+ barBgColorShadowTop = criticalColor;
+ barBgColorShadowBottom = criticalColorShadowBottom;
+ pulsateTimes = thermal_sensors_widget_pulsateCritical ? 7 : 0;
+ pulsateDuration = thermal_sensors_widget_pulsateCritical ? 900 : 0;
+ }
+ }
+
+ //NOTE: variable thermal_sensors_widget_showFullSensorName is declared/set in "thermal_sensors.widget.php"
+ if (!thermal_sensors_widget_showFullSensorName) {
+ sensorName = getSensorFriendlyName(sensorName);
+ }
+
+ //build temperature item/row for a sensor
+ //NOTE: additional styles are set in 'thermal_sensors.widget.php'
+ var thermalSensorRow = "<div class='thermalSensorRow' id='thermalSensorRow" + i + "' >" +
+ //sensor name and temperature value
+ " <div class='thermalSensorTextShell'><div class='thermalSensorText' id='thermalSensorText" + i + "'>" + sensorName + ": </div><div class='thermalSensorValue' id='thermalSensorValue" + i + "'>" + thermalSensorValue + " &deg;C</div></div>" +
+ //temperature bar
+ " <div class='thermalSensorBarShell' id='thermalSensorBarShell" + i + "' >" +
+ " <div class='thermalSensorBar' id='thermalSensorBar" + i + "' style='background-color: " + barBgColor + "; border-top-color: " + barBgColorShadowTop + "; border-bottom-color: " + barBgColorShadowBottom + "; width:" + thermalSensorValue + "%;' ></div>" +
+ //threshold targets (warning and critical)
+ " <div class='thermalSensorWarnThresh' id='thermalSensorWarnThresh" + i + "' style='left:" + warningTempThresholdPosition + "%;' ></div>" +
+ " <div class='thermalSensorCritThresh' id='thermalSensorCritThresh" + i + "' style='left:" + criticalTempThresholdPosition + "%;' ></div>" +
+ //temperature scale (max 100 C)
+ " <div class='thermal_sensors_widget_scale000'></div>" +
+ " <div class='thermal_sensors_widget_scale010'></div>" +
+ " <div class='thermal_sensors_widget_scale020'></div>" +
+ " <div class='thermal_sensors_widget_scale030'></div>" +
+ " <div class='thermal_sensors_widget_scale040'></div>" +
+ " <div class='thermal_sensors_widget_scale050'></div>" +
+ " <div class='thermal_sensors_widget_scale060'></div>" +
+ " <div class='thermal_sensors_widget_scale070'></div>" +
+ " <div class='thermal_sensors_widget_scale080'></div>" +
+ " <div class='thermal_sensors_widget_scale090'></div>" +
+ " <div class='thermal_sensors_widget_scale100'></div>" +
+ " <div class='thermal_sensors_widget_mark100'>100&deg;</div>" +
+ " </div>" +
+ "</div>";
+
+ //collect parameters for warning/critical items we need to pulsate
+ if (pulsateTimes > 0) {
+ var params = i + "|" + barBgColor + "|" + pulsateTimes + "|" + pulsateDuration;
+ itemsToPulsate.push(params);
+ }
+
+ //append HTML item
+ thermalSensorsHTMLContent = thermalSensorsHTMLContent + thermalSensorRow;
+ }
+
+ //load generated graph into thermalSensorsContainer (DIV defined in "thermal_sensors.widget.php")
+ loadThermalSensorsContainer(thermalSensorsHTMLContent);
+
+ if (itemsToPulsate.length > 0) {
+ //pulsate/flash warning/critical items we collected
+ pulsateThermalSensorsItems(itemsToPulsate);
+ }
+}
+
+function pulsateThermalSensorsItems(itemsToPulsate) {
+
+ //pulsate/flash warning/critical items we collected
+ for (var i = 0; i < itemsToPulsate.length; i++) {
+
+ var pulsateParams = itemsToPulsate[i].split("|");
+ var rowNum = parseInt(pulsateParams[0]);
+ //var textColor = pulsateParams[1];
+ var pulsateTimes = parseInt(pulsateParams[2]);
+ var pulsateDuration = parseInt(pulsateParams[3]);
+
+ //pulsate temp Value
+ var divThermalSensorValue = jQuery("#thermalSensorValue" + rowNum); //get temp value by id
+ divThermalSensorValue.effect("pulsate", {
+ times: pulsateTimes,
+ easing: 'linear' //'easeInExpo'
+ }, pulsateDuration);
+ ////set Temp Value color
+ //divThermalSensorValue.css({ color: textColor });
+
+ //pulsate temp Bar
+ var divThermalSensorBar = jQuery("#thermalSensorBar" + rowNum); //get temp bar by id
+ divThermalSensorBar.effect("pulsate", {
+ times: pulsateTimes,
+ easing: 'linear' //'easeInExpo'
+ }, pulsateDuration);
+
+ }
+}
+
+function getSensorFriendlyName(sensorFullName) {
+ var rzone = /^hw\.acpi\.thermal\.tz([0-9]+)\.temperature$/;
+ var rcore = /^dev\.cpu\.([0-9]+)\.temperature$/;
+
+ if (rzone.test(sensorFullName)) {
+ return "Zone " + rzone.exec(sensorFullName)[1];
+ }
+
+ if (rcore.test(sensorFullName)) {
+ return "Core " + rcore.exec(sensorFullName)[1];
+ }
+
+ return sensorFullName;
+}
+
+function getThermalSensorValue(stringValue) {
+ return (+parseFloat(stringValue) || 0).toFixed(1);
+}
diff --git a/src/usr/local/www/widgets/javascript/traffic_graph.js b/src/usr/local/www/widgets/javascript/traffic_graph.js
new file mode 100644
index 0000000..383a549
--- /dev/null
+++ b/src/usr/local/www/widgets/javascript/traffic_graph.js
@@ -0,0 +1,41 @@
+function trafficshowDiv(incDiv,ifDescription,refreshIntervalSec,swapButtons) {
+ // put the graph object HTML in the element and make it appear
+ selectedDiv = incDiv + "graphdiv";
+ jQuery('#' + selectedDiv).html(
+ '<object data="graph.php?ifnum=' + incDiv + '&amp;ifname=' + ifDescription + '&amp;timeint=' + refreshIntervalSec + '&amp;initdelay=0" height="100%" width="100%">' +
+ '<param name="id" value="graph" />' +
+ '<param name="type" value="image/svg+xml" />' +
+ '<param name="pluginspage" value="http://www.adobe.com/svg/viewer/install/auto" />' +
+ '</object>');
+ jQuery('#' + selectedDiv).effect('blind',{mode:'show'},1000);
+ d = document;
+ if (swapButtons) {
+ selectIntLink = selectedDiv + "-min";
+ textlink = d.getElementById(selectIntLink);
+ textlink.style.display = "inline";
+
+ selectIntLink = selectedDiv + "-open";
+ textlink = d.getElementById(selectIntLink);
+ textlink.style.display = "none";
+ }
+ document.traffic_graphs_widget_iform["shown[" + incDiv + "]"].value = "show";
+}
+
+function trafficminimizeDiv(incDiv,swapButtons) {
+ // remove the graph object HTML from the element (so it does not keep using CPU) and fade
+ selectedDiv = incDiv + "graphdiv";
+ jQuery('#' + selectedDiv).html('');
+ jQuery('#' + selectedDiv).effect('blind',{mode:'hide'},1000);
+ d = document;
+ if (swapButtons) {
+ selectIntLink = selectedDiv + "-open";
+ textlink = d.getElementById(selectIntLink);
+ textlink.style.display = "inline";
+
+ selectIntLink = selectedDiv + "-min";
+ textlink = d.getElementById(selectIntLink);
+ textlink.style.display = "none";
+ }
+ document.traffic_graphs_widget_iform["shown[" + incDiv + "]"].value = "hide";
+}
+
diff --git a/src/usr/local/www/widgets/widgets/captive_portal_status.widget.php b/src/usr/local/www/widgets/widgets/captive_portal_status.widget.php
new file mode 100644
index 0000000..4f067a0
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/captive_portal_status.widget.php
@@ -0,0 +1,140 @@
+<?php
+/*
+ captive_portal_status.widget.php
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+ All rights reserved.
+
+ Copyright (C) 2007 Sam Wenham
+ All rights reserved.
+
+ status_captiveportal.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+ 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.
+*/
+
+$nocsrf = true;
+
+require_once("globals.inc");
+require_once("guiconfig.inc");
+require_once("pfsense-utils.inc");
+require_once("functions.inc");
+require_once("captiveportal.inc");
+
+?>
+
+<?php
+
+if (!is_array($config['captiveportal'])) {
+ $config['captiveportal'] = array();
+}
+$a_cp =& $config['captiveportal'];
+
+$cpzone = $_GET['zone'];
+if (isset($_POST['zone'])) {
+ $cpzone = $_POST['zone'];
+}
+
+if (isset($cpzone) && !empty($cpzone) && isset($a_cp[$cpzone]['zoneid'])) {
+ $cpzoneid = $a_cp[$cpzone]['zoneid'];
+}
+
+if (($_GET['act'] == "del") && !empty($cpzone) && isset($cpzoneid)) {
+ captiveportal_disconnect_client($_GET['id']);
+}
+unset($cpzone);
+
+flush();
+
+function clientcmp($a, $b) {
+ global $order;
+ return strcmp($a[$order], $b[$order]);
+}
+
+$cpdb_all = array();
+
+$showact = isset($_GET['showact']) ? 1 : 0;
+
+foreach ($a_cp as $cpzone => $cp) {
+ $cpdb = captiveportal_read_db();
+ foreach ($cpdb as $cpent) {
+ $cpent[10] = $cpzone;
+ if ($showact == 1) {
+ $cpent[11] = captiveportal_get_last_activity($cpent[2], $cpentry[3]);
+ }
+ $cpdb_all[] = $cpent;
+ }
+}
+
+if ($_GET['order']) {
+ if ($_GET['order'] == "ip") {
+ $order = 2;
+ } else if ($_GET['order'] == "mac") {
+ $order = 3;
+ } else if ($_GET['order'] == "user") {
+ $order = 4;
+ } else if ($_GET['order'] == "lastact") {
+ $order = 5;
+ } else if ($_GET['order'] == "zone") {
+ $order = 10;
+ } else {
+ $order = 0;
+ }
+ usort($cpdb_all, "clientcmp");
+}
+?>
+<table class="table">
+ <thead>
+ <tr>
+ <th><a href="?order=ip&amp;showact=<?=$showact;?>">IP address</a></td>
+ <th><a href="?order=mac&amp;showact=<?=$showact;?>">MAC address</a></td>
+ <th><a href="?order=user&amp;showact=<?=$showact;?>"><?=gettext("Username");?></a></td>
+<?php if ($showact == 1): ?>
+ <th><a href="?order=start&amp;showact=<?=$showact;?>"><?=gettext("Session start");?></a></td>
+ <th><a href="?order=start&amp;showact=<?=$showact;?>"><?=gettext("Last activity");?></a></td>
+<?php endif; ?>
+ </tr>
+ </thead>
+ <tbody>
+<?php foreach ($cpdb_all as $cpent): ?>
+ <tr>
+ <td><?=$cpent[2];?></td>
+ <td><?=$cpent[3];?></td>
+ <td><?=$cpent[4];?></td>
+<?php if ($showact == 1): ?>
+ <td><?=date("m/d/Y H:i:s", $cpent[0]);?></td>
+ <td><?php if ($cpent[11] && ($cpent[11] > 0)) echo date("m/d/Y H:i:s", $cpent[11]);?></td>
+<?php endif; ?>
+ <td>
+ <a href="?order=<?=htmlspecialchars($_GET['order']);?>&amp;showact=<?=$showact;?>&amp;act=del&amp;zone=<?=$cpent[10];?>&amp;id=<?=$cpent[5];?>" class="btn btn-xs btn-danger">
+ delete
+ </a>
+ </td>
+ </tr>
+<?php
+endforeach;
+?>
+ </tbody>
+</table> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/widgets/carp_status.widget.php b/src/usr/local/www/widgets/widgets/carp_status.widget.php
new file mode 100644
index 0000000..a44ddd8
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/carp_status.widget.php
@@ -0,0 +1,86 @@
+<?php
+/*
+ $Id$
+ carp_status.widget.php
+ Copyright (C) 2007 Sam Wenham
+ All rights reserved.
+
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+ 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.
+*/
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("pfsense-utils.inc");
+require_once("functions.inc");
+require_once("/usr/local/www/widgets/include/carp_status.inc");
+
+$carp_enabled = get_carp_status();
+
+?>
+<table>
+<?php
+ if (is_array($config['virtualip']['vip'])) {
+ $carpint=0;
+ foreach ($config['virtualip']['vip'] as $carp) {
+ if ($carp['mode'] != "carp") {
+ continue;
+ }
+ $ipaddress = $carp['subnet'];
+ $password = $carp['password'];
+ $netmask = $carp['subnet_bits'];
+ $vhid = $carp['vhid'];
+ $advskew = $carp['advskew'];
+ $status = get_carp_interface_status("_vip{$carp['uniqid']}");
+?>
+<tr>
+ <td>
+ <i class="icon icon-inbox"></i>
+ <a href="/system_hasync.php">
+ <?=htmlspecialchars(convert_friendly_interface_to_friendly_descr($carp['interface']) . "@{$vhid}");?>
+ </a>
+ </td>
+ <td>
+<?php
+ if ($carp_enabled == false) {
+ $status = "DISABLED";
+ echo "<img src='/themes/".$g['theme']."/images/icons/icon_block.gif' title=\"$status\" alt=\"$status\" />";
+ } else {
+ if($status == "MASTER") {
+ echo "<img src='/themes/".$g['theme']."/images/icons/icon_pass.gif' title=\"$status\" alt=\"$status\" />";
+ } else if($status == "BACKUP") {
+ echo "<img src='/themes/".$g['theme']."/images/icons/icon_pass_d.gif' title=\"$status\" alt=\"$status\" />";
+ } else if($status == "INIT") {
+ echo "<img src='/themes/".$g['theme']."/images/icons/icon_log.gif' title=\"$status\" alt=\"$status\" />";
+ }
+ }
+ if ($ipaddress){ ?> &nbsp;
+ <?=htmlspecialchars($status);?> &nbsp;
+ <?=htmlspecialchars($ipaddress);}?>
+</td></tr><?php }
+ } else { ?>
+ <tr><td>No CARP Interfaces Defined. Click <a href="carp_status.php">here</a> to configure CARP.</td></tr>
+<?php } ?>
+</table>
diff --git a/src/usr/local/www/widgets/widgets/deactivated/cpu_graphs.widget.php b/src/usr/local/www/widgets/widgets/deactivated/cpu_graphs.widget.php
new file mode 100644
index 0000000..09723d7
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/deactivated/cpu_graphs.widget.php
@@ -0,0 +1,76 @@
+<?php
+/*
+ $Id$
+
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+ All rights reserved.
+
+ Copyright 2007 Scott Dale
+ Part of pfSense widgets (https://www.pfsense.org)
+ originally based on m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004-2005 T. Lechat <dev@lechat.org>, Manuel Kasper <mk@neon1.net>
+ and Jonathan Watt <jwatt@jwatt.org>.
+ 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.
+*/
+
+require_once("guiconfig.inc");
+require_once("pfsense-utils.inc");
+require_once("functions.inc");
+?>
+<link href="/themes/<?=$g['theme'];?>/graphlink.css" rel="stylesheet" type="text/css" />
+<script src="/widgets/javascript/cpu_graphs.js" type="text/javascript"></script>
+<script type="text/javascript">
+ /* initialize the graph */
+ // --- Global Data --- //
+ var graphs; // An array that stores all created graphs
+ var graph_dir; // The direction in which each graph moves
+ var last_val; // An array of values for each graph
+ var last_val_span; // References to Last Value span tags for each graph
+ var pause; // Controls execution
+
+ var ajaxStarted = false;
+
+ /**
+ * Launches the GraphLink demo. It initializes the graph along with the ajax
+ * engine and starts the main execution loop.
+ */
+ graph = new Array();
+ graph_dir = new Array();
+ last_val = new Array();
+ last_val_span = new Array();
+</script>
+<div style='display: block; margin-left: auto; margin-right: auto' class="GraphLink" id="GraphOutput"></div>
+<script type="text/javascript">
+
+ // Graph 1
+ graph[0] = GraphInitialize('GraphOutput', 200, 50, 4);
+ graph_dir[0] = GL_END;
+ last_val[0] = Math.floor(Math.random() * 50);
+ last_val_span[0] = document.getElementById('LastValue0');
+
+ GraphSetVMax(graph[0], 100);
+ GraphDynamicScale(graph[0]);
+
+</script>
diff --git a/src/usr/local/www/widgets/widgets/dyn_dns_status.widget.php b/src/usr/local/www/widgets/widgets/dyn_dns_status.widget.php
new file mode 100644
index 0000000..7839e6e
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/dyn_dns_status.widget.php
@@ -0,0 +1,174 @@
+<?php
+/*
+ Original status page code from: services_dyndns.php
+ Copyright (C) 2008 Ermal Luçi
+ Edits to convert it to a widget: dyn_dns_status.widget.php
+ Copyright (C) 2013 Stanley P. Miller \ stan-qaz
+ All rights reserved.
+
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+ 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.
+*/
+/*
+ pfSense_BUILDER_BINARIES: /usr/bin/host
+ pfSense_MODULE: dyndns
+*/
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("pfsense-utils.inc");
+require_once("functions.inc");
+require_once("/usr/local/www/widgets/include/dyn_dns_status.inc");
+
+if (!is_array($config['dyndnses']['dyndns'])) {
+ $config['dyndnses']['dyndns'] = array();
+}
+
+$a_dyndns = &$config['dyndnses']['dyndns'];
+
+if($_REQUEST['getdyndnsstatus']) {
+ $first_entry = true;
+ foreach ($a_dyndns as $dyndns) {
+ if ($first_entry) {
+ $first_entry = false;
+ } else {
+ // Put a vertical bar delimiter between the echoed HTML for each entry processed.
+ echo "|";
+ }
+
+ $filename = "{$g['conf_path']}/dyndns_{$dyndns['interface']}{$dyndns['type']}" . escapeshellarg($dyndns['host']) . "{$dyndns['id']}.cache";
+ if (file_exists($filename)) {
+ $ipaddr = dyndnsCheckIP($dyndns['interface']);
+ $cached_ip_s = explode(':', file_get_contents($filename));
+ $cached_ip = $cached_ip_s[0];
+ if ($ipaddr <> $cached_ip) {
+ echo "<font color='red'>";
+ } else {
+ echo "<font color='green'>";
+ }
+ echo htmlspecialchars($cached_ip);
+ echo "</font>";
+ } else {
+ echo "N/A " . date("H:i:s");
+ }
+ }
+ exit;
+}
+
+?>
+
+<table>
+ <tr>
+ <td width="5%" class="listhdrr"><?=gettext("Int.");?></td>
+ <td width="15%" class="listhdrr"><?=gettext("Service");?></td>
+ <td width="20%" class="listhdrr"><?=gettext("Hostname");?></td>
+ <td width="20%" class="listhdrr"><?=gettext("Cached IP");?></td>
+ </tr>
+ <?php $i = 0; foreach ($a_dyndns as $dyndns): ?>
+ <tr ondblclick="document.location='services_dyndns_edit.php?id=<?=$i;?>'">
+ <td class="listlr">
+ <?php $iflist = get_configured_interface_with_descr();
+ foreach ($iflist as $if => $ifdesc) {
+ if ($dyndns['interface'] == $if) {
+ if (!isset($dyndns['enable'])) {
+ echo "<span class=\"gray\">{$ifdesc}</span>";
+ } else {
+ echo "{$ifdesc}";
+ }
+ break;
+ }
+ }
+ $groupslist = return_gateway_groups_array();
+ foreach ($groupslist as $if => $group) {
+ if ($dyndns['interface'] == $if) {
+ if (!isset($dyndns['enable'])) {
+ echo "<span class=\"gray\">{$if}</span>";
+ } else {
+ echo "{$if}";
+ }
+ break;
+ }
+ }
+ ?>
+ </td>
+ <td class="listr">
+ <?php
+ $types = explode(",", DYNDNS_PROVIDER_DESCRIPTIONS);
+ $vals = explode(" ", DYNDNS_PROVIDER_VALUES);
+ for ($j = 0; $j < count($vals); $j++) {
+ if ($vals[$j] == $dyndns['type']) {
+ if (!isset($dyndns['enable'])) {
+ echo "<span class=\"gray\">".htmlspecialchars($types[$j])."</span>";
+ } else {
+ echo htmlspecialchars($types[$j]);
+ }
+ break;
+ }
+ }
+ ?>
+ </td>
+ <td class="listr">
+ <?php
+ if (!isset($dyndns['enable'])) {
+ echo "<span class=\"gray\">".htmlspecialchars($dyndns['host'])."</span>";
+ } else {
+ echo htmlspecialchars($dyndns['host']);
+ }
+ ?>
+ </td>
+ <td class="listr">
+ <div id='dyndnsstatus<?= $i;?>'><?= gettext("Checking ...");?></div>
+ </td>
+ </tr>
+ <?php $i++; endforeach;?>
+</table>
+<script type="text/javascript">
+//<![CDATA[
+ function dyndns_getstatus() {
+ scroll(0,0);
+ var url = "/widgets/widgets/dyn_dns_status.widget.php";
+ var pars = 'getdyndnsstatus=yes';
+ jQuery.ajax(
+ url,
+ {
+ type: 'get',
+ data: pars,
+ complete: dyndnscallback
+ });
+ // Refresh the status every 5 minutes
+ setTimeout('dyndns_getstatus()', 5*60*1000);
+ }
+ function dyndnscallback(transport) {
+ // The server returns a string of statuses separated by vertical bars
+ var responseStrings = transport.responseText.split("|");
+ for (var count=0; count<responseStrings.length; count++) {
+ var divlabel = '#dyndnsstatus' + count;
+ jQuery(divlabel).prop('innerHTML',responseStrings[count]);
+ }
+ }
+ // Do the first status check 2 seconds after the dashboard opens
+ setTimeout('dyndns_getstatus()', 2000);
+//]]>
+</script>
diff --git a/src/usr/local/www/widgets/widgets/gateways.widget.php b/src/usr/local/www/widgets/widgets/gateways.widget.php
new file mode 100644
index 0000000..7087cf2
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/gateways.widget.php
@@ -0,0 +1,122 @@
+<?php
+/*
+ gateways.widget.php
+ Copyright 2008 Seth Mos
+ Part of pfSense widgets (https://www.pfsense.org)
+ originally based on m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+ 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.
+*/
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("pfsense-utils.inc");
+require_once("functions.inc");
+require_once("/usr/local/www/widgets/include/gateways.inc");
+
+if ($_POST) {
+ if (!is_array($config["widgets"]["gateways_widget"])) {
+ $config["widgets"]["gateways_widget"] = array();
+ }
+ if (isset($_POST["display_type"])) {
+ $config["widgets"]["gateways_widget"]["display_type"] = $_POST["display_type"];
+ }
+ write_config("Updated gateways widget settings via dashboard.");
+ header("Location: /");
+ exit(0);
+}
+
+if (isset($config["widgets"]["gateways_widget"]["display_type"])) {
+ $display_type = $config["widgets"]["gateways_widget"]["display_type"];
+} else {
+ $display_type = "gw_ip";
+}
+
+$a_gateways = return_gateways_array();
+$gateways_status = array();
+$gateways_status = return_gateways_status(true);
+
+?>
+<table class="table table-striped table-hover">
+<thead>
+<tr>
+ <th>Name</td>
+ <th>RTT</td>
+ <th>Loss</td>
+ <th>Status</td>
+</tr>
+</thead>
+<tbody>
+<?php foreach ($a_gateways as $gname => $gateway): ?>
+ <tr>
+ <td>
+<?php
+ $if_gw = '';
+ if (is_ipaddr($gateway['gateway']))
+ $if_gw = $gateway['gateway'];
+ else {
+ if($gateway['ipprotocol'] == "inet")
+ $if_gw = get_interface_gateway($gateway['friendlyiface']);
+ if($gateway['ipprotocol'] == "inet6")
+ $if_gw = get_interface_gateway_v6($gateway['friendlyiface']);
+ }
+?>
+ <?=htmlspecialchars($gateway['name'])?><br />
+ <i><?=($if_gw == '' ? '~' : htmlspecialchars($if_gw));?></i>
+ </td>
+<?php
+ if ($gateways_status[$gname]) {
+ if (stristr($gateways_status[$gname]['status'], "force_down")) {
+ $online = "Offline (forced)";
+ $bgcolor = "#F08080"; // lightcoral
+ } elseif (stristr($gateways_status[$gname]['status'], "down")) {
+ $online = "Offline";
+ $bgcolor = "#F08080"; // lightcoral
+ } elseif (stristr($gateways_status[$gname]['status'], "loss")) {
+ $online = "Packetloss";
+ $bgcolor = "#F0E68C"; // khaki
+ } elseif (stristr($gateways_status[$gname]['status'], "delay")) {
+ $online = "Latency";
+ $bgcolor = "#F0E68C"; // khaki
+ } elseif ($gateways_status[$gname]['status'] == "none") {
+ $online = "Online";
+ $bgcolor = "#90EE90"; // lightgreen
+ } elseif ($gateways_status[$gname]['status'] == "") {
+ $online = "Pending";
+ $bgcolor = "#D3D3D3"; // lightgray
+ }
+ } else {
+ $online = gettext("Unknown");
+ $bgcolor = "#ADD8E6"; // lightblue
+ }
+?>
+ <td><?=($gateways_status[$gname] ? htmlspecialchars($gateways_status[$gname]['delay']) : gettext("Pending"))?></td>
+ <td><?=($gateways_status[$gname] ? htmlspecialchars($gateways_status[$gname]['loss']) : gettext("Pending"))?></td>
+ <td style="background-color: <?=$bgcolor?>"><?=$online?></td>
+ </tr>
+<?php endforeach; ?>
+</tbody>
+</table> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/widgets/gmirror_status.widget.php b/src/usr/local/www/widgets/widgets/gmirror_status.widget.php
new file mode 100644
index 0000000..c8dad84
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/gmirror_status.widget.php
@@ -0,0 +1,59 @@
+<?php
+/*
+ gmirror_status.widget.php
+ Copyright (C) 2009-2010 Jim Pingle
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+ 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.
+*/
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("gmirror.inc");
+
+?>
+<div id="gmirror_status">
+ <?=gmirror_html_status()?>
+</div>
+
+<script>
+function gmirrorStatusUpdateFromServer(){
+ $.ajax({
+ type: 'get',
+ url: '/widgets/widgets/gmirror_status.widget.php',
+ dataType: 'html',
+ dataFilter: function(raw){
+ // We reload the entire widget, strip this block of javascript from it
+ return raw.replace(/<script>([\s\S]*)<\/script>/gi, '');
+ },
+ success: function(data){
+ $('#gmirror_status').html(data);
+ }
+ });
+}
+
+events.push(function(){
+ setInterval('gmirrorStatusUpdateFromServer()', 60*1000);
+});
+</script> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/widgets/installed_packages.widget.php b/src/usr/local/www/widgets/widgets/installed_packages.widget.php
new file mode 100644
index 0000000..b6e01bc
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/installed_packages.widget.php
@@ -0,0 +1,107 @@
+<?php
+/*
+ installed_packages.widget.php
+
+ Copyright (C) 2013-2014 Electric Sheep Fencing, LP
+ Copyright 2007 Scott Dale
+ Part of pfSense widgets (https://www.pfsense.org)
+ originally based on m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004-2005 T. Lechat <dev@lechat.org>, Manuel Kasper <mk@neon1.net>
+ and Jonathan Watt <jwatt@jwatt.org>.
+ 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.
+*/
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("pfsense-utils.inc");
+require_once("functions.inc");
+require_once("/usr/local/www/widgets/include/installed_packages.inc");
+require_once("pkg-utils.inc");
+
+if(is_array($config['installedpackages']['package'])) {
+ $instpkgs = array();
+ foreach ($config['installedpackages']['package'] as $instpkg)
+ $instpkgs[ $instpkg['name'] ] = $instpkg;
+ ksort($instpkgs);
+ $currentvers = get_pkg_info(array_keys($instpkgs), array('version', 'xmlver'));
+}
+?>
+
+<?php if (empty($config['installedpackages']['package'])): ?>
+ <div class="alert alert-warning" role="alert">
+ <strong>No packages installed.</strong>
+ You can install packages <a href="pkg_mgr.php" class="alert-link">here</a>.
+ </div>
+<?php else: ?>
+ <table class="table table-striped table-hover">
+ <thead>
+ <tr>
+ <th>Package Name</th>
+ <th>Category</th>
+ <th>Package Version</th>
+ </tr>
+ </thead>
+ <tbody>
+<?php
+foreach ($instpkgs as $pkgname => $pkg):
+ if (empty($pkgname))
+ continue;
+
+ $latest_package = $currentvers[$pkg['name']]['version'];
+ if ($latest_package) {
+ // we're running a newer version of the package
+ if(strcmp($pkg['version'], $latest_package) > 0) {
+ $status = 'Newer then available ('. $latest_package .')';
+ $statusicon = 'exclamation';
+ }
+ // we're running an older version of the package
+ if(strcmp($pkg['version'], $latest_package) < 0) {
+ $status = 'Upgrade available to '.$latest_package;
+ $statusicon = 'plus';
+ }
+ // we're running the current version
+ if(!strcmp($pkg['version'], $latest_package)) {
+ $status = 'Up-to-date';
+ $statusicon = 'ok';
+ }
+ } else {
+ // unknown available package version
+ $status = 'Unknown';
+ $statusicon = 'question';
+ }
+?>
+ <tr>
+ <td><?=$pkg['name']?></td>
+ <td><?=$pkg['category']?></td>
+ <td>
+ <i title="<?=$status?>" class="icon icon-<?=$statusicon?>-sign"></i>
+ <?=$pkg['version']?>
+ </td>
+ </tr>
+<?php endforeach; ?>
+ </tbody>
+ </table>
+<?php endif; ?> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/widgets/interface_statistics.widget.php b/src/usr/local/www/widgets/widgets/interface_statistics.widget.php
new file mode 100644
index 0000000..166aa80
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/interface_statistics.widget.php
@@ -0,0 +1,82 @@
+<?php
+/*
+ $Id: interface_statistics.widget.php
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+
+ Copyright 2007 Scott Dale
+ Part of pfSense widgets (https://www.pfsense.org)
+ originally based on m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004-2005 T. Lechat <dev@lechat.org>, Manuel Kasper <mk@neon1.net>
+ and Jonathan Watt <jwatt@jwatt.org>.
+ 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.
+*/
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("pfsense-utils.inc");
+require_once("functions.inc");
+require_once("/usr/local/www/widgets/include/interface_statistics.inc");
+
+$rows = array(
+ 'inpkts' => 'Packets In',
+ 'outpkts' => 'Packets Out',
+ 'inbytes' => 'Bytes In',
+ 'outbytes' => 'Bytes Out',
+ 'inerrs' => 'Errors In',
+ 'outerrs' => 'Errors Out',
+ 'collisions' => 'Collisions',
+);
+$ifdescrs = get_configured_interface_with_descr();
+
+?>
+<table class="table table-striped table-hover">
+<thead>
+ <tr>
+ <td></td>
+<?php foreach ($ifdescrs as $ifname): ?>
+ <th><?=$ifname?></th>
+<?php endforeach; ?>
+ </tr>
+</thead>
+<tbody>
+<?php foreach ($rows as $key => $name): ?>
+ <tr>
+ <th><?=$name?></th>
+<?php foreach ($ifdescrs as $ifdescr => $ifname):
+ $ifinfo = get_interface_info($ifdescr);
+
+ if ($ifinfo['status'] == "down")
+ continue;
+
+ $ifinfo['inbytes'] = format_bytes($ifinfo['inbytes']);
+ $ifinfo['outbytes'] = format_bytes($ifinfo['outbytes']);
+ ?>
+ <td><?=(isset($ifinfo[$key]) ? htmlspecialchars($ifinfo[$key]) : 'n/a')?></td>
+<?php endforeach; ?>
+ </tr>
+<?php endforeach; ?>
+ </tbody>
+</table> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/widgets/interfaces.widget.php b/src/usr/local/www/widgets/widgets/interfaces.widget.php
new file mode 100644
index 0000000..85cfda1
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/interfaces.widget.php
@@ -0,0 +1,110 @@
+<?php
+/*
+ interfaces.widget.php
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+
+ Copyright 2007 Scott Dale
+ Part of pfSense widgets (https://www.pfsense.org)
+ originally based on m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004-2005 T. Lechat <dev@lechat.org>, Manuel Kasper <mk@neon1.net>
+ and Jonathan Watt <jwatt@jwatt.org>.
+ 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.
+*/
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("pfsense-utils.inc");
+require_once("functions.inc");
+require_once("/usr/local/www/widgets/include/interfaces.inc");
+
+$ifdescrs = get_configured_interface_with_descr();
+?>
+
+<table class="table table-striped table-hover">
+<?php
+foreach ($ifdescrs as $ifdescr => $ifname):
+ $ifinfo = get_interface_info($ifdescr);
+
+ if ($ifinfo['ppplink']) {
+ $icon = 'headphones';
+ } else if (is_interface_wireless($ifdescr)) {
+ if ($ifinfo['status'] == "associated") {
+ $icon = 'wlan';
+ } else {
+ $icon = 'wlan_d';
+ }
+ } else {
+ $icon = 'cablenic';
+ }
+
+ if ($ifinfo['status'] == "up" || $ifinfo['status'] == "associated") {
+ $known_status = true;
+ $up_display = "inline";
+ $down_display = "none";
+ $block_display = "none";
+ } elseif ($ifinfo['status'] == "no carrier") {
+ $known_status = true;
+ $up_display = "none";
+ $down_display = "inline";
+ $block_display = "none";
+ } elseif ($ifinfo['status'] == "down") {
+ $known_status = true;
+ $up_display = "none";
+ $down_display = "none";
+ $block_display = "inline";
+ } else {
+ $known_status = false;
+ }
+?>
+ <tr>
+ <td title="<?=htmlspecialchars($ifinfo['macaddr'])?>">
+ <i class="icon icon-<?=$icon?>"></i>
+ <a href="/interfaces.php?if=<?=$ifdescr?>">
+ <?=htmlspecialchars($ifname);?>
+ </a>
+ </td>
+ <td>
+ <?php if (isset($status)):?>
+ <i class="icon icon-<?=status?>-circle" alt="<?=htmlspecialchars($ifinfo['status'])?>"></i>
+ <?php else: ?>
+ <?=htmlspecialchars($ifinfo['status'])?>
+ <?php endif; ?>
+ </td>
+ <td>
+ <?=htmlspecialchars($ifinfo['media']);?>
+ </td>
+ <td<?=($ifinfo['dhcplink'] ? ' title="via dhcp"':'')?>>
+ <?php if (empty($addresses)): ?>
+ n/a
+ <?php else: ?>
+ <?= implode('<br />', $addresses)?>
+ <?php endif; ?>
+ </td>
+ </tr>
+<?php
+endforeach;
+?>
+</table>
diff --git a/src/usr/local/www/widgets/widgets/ipsec.widget.php b/src/usr/local/www/widgets/widgets/ipsec.widget.php
new file mode 100644
index 0000000..76ed282
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/ipsec.widget.php
@@ -0,0 +1,215 @@
+<?php
+/*
+ ipsec.widget.php
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+
+ Copyright 2007 Scott Dale
+ Part of pfSense widgets (https://www.pfsense.org)
+ originally based on m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004-2005 T. Lechat <dev@lechat.org>, Manuel Kasper <mk@neon1.net>
+ and Jonathan Watt <jwatt@jwatt.org>.
+ 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.
+*/
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("functions.inc");
+require_once("ipsec.inc");
+
+if (isset($config['ipsec']['phase1'])) {
+ $tab_array = array();
+ $tab_array[0] = array("Overview", true, "ipsec-Overview");
+ $tab_array[1] = array("Tunnels", false, "ipsec-tunnel");
+ $tab_array[2] = array("Mobile", false, "ipsec-mobile");
+
+ display_widget_tabs($tab_array);
+
+ $spd = ipsec_dump_spd();
+ $sad = ipsec_dump_sad();
+ $mobile = ipsec_dump_mobile();
+ $ipsec_status = ipsec_smp_dump_status();
+
+ $activecounter = 0;
+ $inactivecounter = 0;
+
+ if (!is_array($ipsec_status['query'])) {
+ $ipsec_status['query'] = array();
+ $ipsec_status['query']['ikesalist'] = array();
+ $ipsec_status['query']['ikesalist']['ikesa'] = array();
+ } else if (!is_array($ipsec_status['query']['ikesalist'])) {
+ $ipsec_status['query']['ikesalist'] = array();
+ $ipsec_status['query']['ikesalist']['ikesa'] = array();
+ } else if (!is_array($ipsec_status['query']['ikesalist']['ikesa'])) {
+ $ipsec_status['query']['ikesalist']['ikesa'] = array();
+ }
+
+ $ipsec_detail_array = array();
+ $ikenum = array();
+ if (isset($config['ipsec']['phase2'])) {
+ foreach ($config['ipsec']['phase2'] as $ph2ent) {
+ if (!ipsec_lookup_phase1($ph2ent,$ph1ent)) {
+ continue;
+ }
+
+ if ($ph2ent['remoteid']['type'] == "mobile" || isset($ph1ent['mobile'])) {
+ continue;
+ }
+ if (isset($ph1ent['disabled']) || isset($ph2ent['disabled'])) {
+ continue;
+ }
+
+ if (empty($ph1ent['iketype']) || $ph1ent['iketype'] == 'ikev1') {
+ if (!isset($ikenum[$ph1ent['ikeid']])) {
+ $ikenum[$ph1ent['ikeid']] = 0;
+ } else {
+ $ikenum[$ph1ent['ikeid']]++;
+ }
+ $ikeid = "con{$ph1ent['ikeid']}00" . $ikenum[$ph1ent['ikeid']];
+ } else {
+ if (isset($ikenum[$ph1ent['ikeid']])) {
+ continue;
+ }
+ $ikeid = "con{$ph1ent['ikeid']}";
+ $ikenum[$ph1ent['ikeid']] = true;
+ }
+
+ $found = false;
+ foreach ($ipsec_status['query']['ikesalist']['ikesa'] as $ikesa) {
+ if (isset($ikesa['childsalist']) && isset($ikesa['childsalist']['childsa'])) {
+ foreach ($ikesa['childsalist']['childsa'] as $childsa) {
+ if ($ikeid == $childsa['childconfig']) {
+ $found = true;
+ break;
+ }
+ }
+ } else if ($ikeid == $ikesa['peerconfig']) {
+ $found = true;
+ }
+
+ if ($found === true) {
+ if ($ikesa['status'] == 'established') {
+ /* tunnel is up */
+ $iconfn = "true";
+ $activecounter++;
+ } else {
+ /* tunnel is down */
+ $iconfn = "false";
+ $inactivecounter++;
+ }
+ break;
+ }
+ }
+
+ if ($found === false) {
+ /* tunnel is down */
+ $iconfn = "false";
+ $inactivecounter++;
+ }
+
+ $ipsec_detail_array[] = array('src' => convert_friendly_interface_to_friendly_descr($ph1ent['interface']),
+ 'dest' => $ph1ent['remote-gateway'],
+ 'remote-subnet' => ipsec_idinfo_to_text($ph2ent['remoteid']),
+ 'descr' => $ph2ent['descr'],
+ 'status' => $iconfn);
+ }
+ }
+ unset($ikenum);
+}
+
+if (isset($config['ipsec']['phase2'])): ?>
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Active Tunnels</td>
+ <th>Inactive Tunnels</td>
+ <th>Mobile Users</td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><?=$activecounter; ?></td>
+ <td><?=$inactivecounter; ?></td>
+ <td><?=(is_array($mobile['pool']) ? htmlspecialchars($mobile['pool'][0]['usage']) : '0'); ?></td>
+ </tr>
+ </tbody>
+ </table>
+
+ <table class="table table-striped table-hover">
+ <thead>
+ <th>Source</th>
+ <th>Destination</th>
+ <th>Description</th>
+ <th>Status</th>
+ </thead>
+ <tbody>
+ <?php foreach ($ipsec_detail_array as $ipsec) : ?>
+ <tr>
+ <td><?php echo htmlspecialchars($ipsec['src']);?></td>
+ <td><?php echo $ipsec['remote-subnet'];?><br />(<?php echo htmlspecialchars($ipsec['dest']);?>)</td>
+ <td><?php echo htmlspecialchars($ipsec['descr']);?></td>
+ <td>
+ <?php if ($ipsec['status'] == "true"): ?>
+ <i class="icon icon-chevron-up"></i>
+ <?php else: ?>
+ <i class="icon icon-chevron-down"></i>
+ <?php endif; ?>
+ </td>
+ </tr>
+ <?php endforeach; ?>
+ </tbody>
+ </table>
+
+ <?php if (is_array($mobile['pool'])): ?>
+ <table class="table table-striped table-hover">
+ <thead>
+ <th>User</th>
+ <th>IP</th>
+ <th>Status</th>
+ </thead>
+ <tbody>
+
+ <?php foreach ($mobile['pool'] as $pool):
+ if (!is_array($pool['lease']))
+ continue;
+
+ foreach ($pool['lease'] as $muser) : ?>
+ <tr>
+ <td><?php echo htmlspecialchars($muser['id']);?></td>
+ <td><?php echo htmlspecialchars($muser['host']);?></td>
+ <td><?php echo htmlspecialchars($muser['status']);?></td>
+ </tr>
+ <?php
+ endforeach;
+ endforeach; ?>
+ </tbody>
+ </table>
+ <?php endif;?>
+<?php else: ?>
+ <div class="alert alert-warning">
+ <h3>There are no configured IPsec Tunnels</h3>
+ <p>You can configure your IPsec <a href="vpn_ipsec.php">here</a>.</p>
+ </div>
+<?php endif; ?> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/widgets/load_balancer_status.widget.php b/src/usr/local/www/widgets/widgets/load_balancer_status.widget.php
new file mode 100644
index 0000000..0613713
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/load_balancer_status.widget.php
@@ -0,0 +1,156 @@
+<?php
+/*
+ load_balancer_status.widget.php
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+
+ Copyright 2010 Jim Pingle
+ Portions copied from status_lb_pool.php, status_lb_vs.php, and vslb.inc:
+ Copyright (C) 2010 Seth Mos <seth.mos@dds.nl>.
+ Copyright (C) 2005-2008 Bill Marquette
+
+ Part of pfSense widgets (https://www.pfsense.org)
+ originally based on m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004-2005 T. Lechat <dev@lechat.org>, Manuel Kasper <mk@neon1.net>
+ and Jonathan Watt <jwatt@jwatt.org>.
+ 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.
+*/
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("pfsense-utils.inc");
+require_once("functions.inc");
+require_once("vslb.inc");
+
+$now = time();
+$year = date("Y");
+
+if (!is_array($config['load_balancer']['lbpool'])) {
+ $config['load_balancer']['lbpool'] = array();
+}
+if (!is_array($config['load_balancer']['virtual_server'])) {
+ $config['load_balancer']['virtual_server'] = array();
+}
+$a_vs = &$config['load_balancer']['virtual_server'];
+$a_pool = &$config['load_balancer']['lbpool'];
+$rdr_a = get_lb_redirects();
+$relay_hosts = get_lb_summary();
+
+$lb_logfile = "{$g['varlog_path']}/relayd.log";
+$nentries = $config['syslog']['nentries'];
+if (!$nentries) {
+ $nentries = 50;
+}
+
+?>
+
+<table class="table">
+<thead>
+ <tr>
+ <th>Server</th>
+ <th>Pool</th>
+ <th>Description</th>
+ </tr>
+</thead>
+<tbody>
+ <?php foreach ($a_vs as $vsent): ?>
+ <tr>
+ <?php
+ switch (trim($rdr_a[$vsent['name']]['status'])) {
+ case 'active':
+ $bgcolor = "#90EE90"; // lightgreen
+ $rdr_a[$vsent['name']]['status'] = "Active";
+ break;
+ case 'down':
+ $bgcolor = "#F08080"; // lightcoral
+ $rdr_a[$vsent['name']]['status'] = "Down";
+ break;
+ default:
+ $bgcolor = "#D3D3D3"; // lightgray
+ $rdr_a[$vsent['name']]['status'] = 'Unknown - relayd not running?';
+ }
+ ?>
+ <td>
+ <?=$vsent['name'];?><br />
+ <span style="background-color: <?=$bgcolor?>; display: block"><i><?=$rdr_a[$vsent['name']]['status']?></i></span>
+ <?=$vsent['ipaddr'].":".$vsent['port'];?><br />
+ </td>
+ <td>
+ <table>
+ <?php
+ foreach ($a_pool as $pool) {
+ if ($pool['name'] == $vsent['poolname']) {
+ $pool_hosts=array();
+ foreach ((array) $pool['servers'] as $server) {
+ $svr['ip']['addr']=$server;
+ $svr['ip']['state']=$relay_hosts[$pool['name'].":".$pool['port']][$server]['state'];
+ $svr['ip']['avail']=$relay_hosts[$pool['name'].":".$pool['port']][$server]['avail'];
+ $pool_hosts[]=$svr;
+ }
+ foreach ((array) $pool['serversdisabled'] as $server) {
+ $svr['ip']['addr']="$server";
+ $svr['ip']['state']='disabled';
+ $svr['ip']['avail']='disabled';
+ $pool_hosts[]=$svr;
+ }
+ asort($pool_hosts);
+ foreach ((array) $pool_hosts as $server) {
+ if(empty($server['ip']['addr']))
+ continue;
+
+ switch ($server['ip']['state']) {
+ case 'up':
+ $bgcolor = "#90EE90"; // lightgreen
+ $checked = "checked";
+ break;
+ case 'disabled':
+ $bgcolor = "#FFFFFF"; // white
+ $checked = "";
+ break;
+ default:
+ $bgcolor = "#F08080"; // lightcoral
+ $checked = "checked";
+ }
+?>
+ <tr style="background-color: <?=$bgcolor?>">
+ <td><?=$server['ip']['addr']?>:<?=$pool['port']?></td>
+ <td>
+ <?php if($server['ip']['avail']): ?>
+ ({$server['ip']['avail']})
+ <?php endif; ?>
+ </td>
+ </tr>
+<?php
+ }
+ }
+ }
+?>
+ </table>
+ </td>
+ <td><?=$vsent['descr'];?></td>
+ </tr>
+ <?php endforeach; ?>
+</tbody>
+</table> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/widgets/log.widget.php b/src/usr/local/www/widgets/widgets/log.widget.php
new file mode 100644
index 0000000..00b668a
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/log.widget.php
@@ -0,0 +1,234 @@
+<?php
+/*
+ log.widget.php
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+
+ Copyright 2007 Scott Dale
+ Part of pfSense widgets (https://www.pfsense.org)
+ originally based on m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004-2005 T. Lechat <dev@lechat.org>, Manuel Kasper <mk@neon1.net>
+ and Jonathan Watt <jwatt@jwatt.org>.
+ 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.
+*/
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("pfsense-utils.inc");
+require_once("functions.inc");
+
+/* In an effort to reduce duplicate code, many shared functions have been moved here. */
+require_once("filter_log.inc");
+
+if (is_numeric($_POST['filterlogentries'])) {
+ $config['widgets']['filterlogentries'] = $_POST['filterlogentries'];
+
+ $acts = array();
+ if ($_POST['actpass']) {
+ $acts[] = "Pass";
+ }
+ if ($_POST['actblock']) {
+ $acts[] = "Block";
+ }
+ if ($_POST['actreject']) {
+ $acts[] = "Reject";
+ }
+
+ if (!empty($acts)) {
+ $config['widgets']['filterlogentriesacts'] = implode(" ", $acts);
+ } else {
+ unset($config['widgets']['filterlogentriesacts']);
+ }
+ unset($acts);
+
+ if (($_POST['filterlogentriesinterfaces']) and ($_POST['filterlogentriesinterfaces'] != "All")) {
+ $config['widgets']['filterlogentriesinterfaces'] = trim($_POST['filterlogentriesinterfaces']);
+ } else {
+ unset($config['widgets']['filterlogentriesinterfaces']);
+ }
+
+ write_config("Saved Filter Log Entries via Dashboard");
+ Header("Location: /");
+ exit(0);
+}
+
+$nentries = isset($config['widgets']['filterlogentries']) ? $config['widgets']['filterlogentries'] : 5;
+
+//set variables for log
+$nentriesacts = isset($config['widgets']['filterlogentriesacts']) ? $config['widgets']['filterlogentriesacts'] : 'All';
+$nentriesinterfaces = isset($config['widgets']['filterlogentriesinterfaces']) ? $config['widgets']['filterlogentriesinterfaces'] : 'All';
+
+$filterfieldsarray = array(
+ "act" => $nentriesacts,
+ "interface" => $nentriesinterfaces
+);
+
+$filter_logfile = "{$g['varlog_path']}/filter.log";
+
+/* AJAX related routines */
+if (isset($_POST['lastsawtime'])) {
+ $filterlog = conv_log_filter($filter_logfile, $nentries, $nentries + 20);
+
+ foreach ($filterlog as $idx => $row) {
+ if (strtotime($log_row['time']) <= $_POST['lastsawtime'])
+ unset($filterlog[$idx]);
+ }
+}
+else
+ $filterlog = conv_log_filter($filter_logfile, $nentries, 50, $filterfieldsarray);
+?>
+<script>
+ var logWidgetLastRefresh = <?=time()?>;
+</script>
+
+<table class="table table-striped table-hover">
+ <thead>
+ <tr>
+ <th><?=gettext("Act");?></th>
+ <th><?=gettext("Time");?></th>
+ <th><?=gettext("IF");?></th>
+ <th><?=gettext("Source");?></th>
+ <th><?=gettext("Destination");?></th>
+ </tr>
+ </thead>
+ <tbody>
+<?php
+ foreach ($filterlog as $filterent):
+ if ($filterent['version'] == '6') {
+ $srcIP = "[" . htmlspecialchars($filterent['srcip']) . "]";
+ $dstIP = "[" . htmlspecialchars($filterent['dstip']) . "]";
+ } else {
+ $srcIP = htmlspecialchars($filterent['srcip']);
+ $dstIP = htmlspecialchars($filterent['dstip']);
+ }
+
+ if ($filterent['act'] == "block")
+ $iconfn = "remove";
+ else if ($filterent['act'] == "reject")
+ $iconfn = "fire";
+ else if ($filterent['act'] == "match")
+ $iconfn = "filter";
+ else
+ $iconfn = "ok";
+
+ $rule = find_rule_by_number($filterent['rulenum'], $filterent['tracker'], $filterent['act']);
+?>
+ <tr>
+ <td><a role="button" data-toggle="popover" data-trigger="hover"
+ data-title="Rule that triggered this action"
+ data-content="<?=htmlspecialchars($rule)?>"> <i
+ class="icon icon-<?=$iconfn?>"></i>
+ </a></td>
+ <td title="<?=htmlspecialchars($filterent['time'])?>"><?=substr(htmlspecialchars($filterent['time']),0,-3)?></td>
+ <td><?=htmlspecialchars($filterent['interface']);?></td>
+ <td><a href="diag_dns.php?host=<?=$filterent['srcip']?>"
+ title="<?=gettext("Reverse Resolve with DNS")?>"><?=$srcIP?></a>:<?=htmlspecialchars($filterent['srcport'])?>
+ </td>
+ <td><a href="diag_dns.php?host=<?=$filterent['dstip']?>"
+ title="<?=gettext("Reverse Resolve with DNS");?>"><?=$dstIP?></a>:<?=htmlspecialchars($filterent['dstport'])?>
+ </td>
+ </tr>
+ <?php
+ endforeach;
+ ?>
+ </tbody>
+</table>
+
+<?php
+
+/* for AJAX response, we only need the panel-body */
+if (isset($_GET['lastsawtime']))
+ exit;
+?>
+
+<script>
+function logWidgetUpdateFromServer(){
+ $.ajax({
+ type: 'get',
+ url: '/widgets/widgets/log.widget.php',
+ data: 'lastsawtime='+logWidgetLastRefresh,
+ dataFilter: function(raw){
+ // We reload the entire widget, strip this block of javascript from it
+ return raw.replace(/<script>([\s\S]*)<\/script>/gi, '');
+ },
+ dataType: 'html',
+ success: function(data){
+ $('#widget-log .panel-body').html(data);
+ }
+ });
+}
+
+events.push(function(){
+ setInterval('logWidgetUpdateFromServer()', 60*1000);
+});
+</script>
+
+<!-- close the body we're wrapped in and add a configuration-panel -->
+</div>
+<div class="panel-footer collapse">
+
+ <form action="/widgets/widgets/log.widget.php" method="post"
+ class="form-horizontal">
+ <div class="form-group">
+ <label for="filterlogentries" class="col-sm-4 control-label">Number
+ of entries</label>
+ <div class="col-sm-6">
+ <input type="number" name="filterlogentries" value="<?=$nentries?>"
+ min="1" max="20" class="form-control" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label class="col-sm-4 control-label">Filter actions</label>
+ <div class="col-sm-6 checkbox">
+ <?php $include_acts = explode(" ", strtolower($nentriesacts)); ?>
+ <label><input name="actpass" type="checkbox" value="Pass"
+ <?=(in_array('pass', $include_acts) ? 'checked="checked"':'')?> />Pass</label>
+ <label><input name="actblock" type="checkbox" value="Block"
+ <?=(in_array('block', $include_acts) ? 'checked="checked"':'')?> />Block</label>
+ <label><input name="actreject" type="checkbox" value="Reject"
+ <?=(in_array('reject', $include_acts) ? 'checked="checked"':'')?> />Reject</label>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="filterlogentriesinterfaces"
+ class="col-sm-4 control-label">Filter interface</label>
+ <div class="col-sm-6 checkbox">
+ <select name="filterlogentriesinterfaces" class="form-control">
+ <?php foreach (array("All" => "ALL") + get_configured_interface_with_descr() as $iface => $ifacename):?>
+ <option value="<?=$iface?>"
+ <?=($nentriesinterfaces==$iface?'selected="selected"':'')?>><?=htmlspecialchars($ifacename)?></option>
+ <?php endforeach;?>
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="col-sm-offset-4 col-sm-6">
+ <button type="submit" class="btn btn-default">Save</button>
+ </div>
+ </div>
+ </form>
diff --git a/src/usr/local/www/widgets/widgets/ntp_status.widget.php b/src/usr/local/www/widgets/widgets/ntp_status.widget.php
new file mode 100644
index 0000000..48d3755
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/ntp_status.widget.php
@@ -0,0 +1,499 @@
+<?php
+/*
+ ntp_status.widget.php
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+X
+ Copyright 2007 Scott Dale
+ Part of pfSense widgets (https://www.pfsense.org)
+ originally based on m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004-2005 T. Lechat <dev@lechat.org>, Manuel Kasper <mk@neon1.net>
+ and Jonathan Watt <jwatt@jwatt.org>.
+ 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.
+*/
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("pfsense-utils.inc");
+require_once("functions.inc");
+
+require_once("/usr/local/www/widgets/include/ntp_status.inc");
+
+if ($_REQUEST['updateme']) {
+//this block displays only on ajax refresh
+ if (isset($config['system']['ipv6allow'])) {
+ $inet_version = "";
+ } else {
+ $inet_version = " -4";
+ }
+
+ exec("/usr/local/sbin/ntpq -pn $inet_version | /usr/bin/tail +3", $ntpq_output);
+ $ntpq_counter = 0;
+ foreach ($ntpq_output as $line) {
+ if (substr($line, 0, 1) == "*") {
+ //Active NTP Peer
+ $line = substr($line, 1);
+ $peerinfo = preg_split("/[\s\t]+/", $line);
+ if ($peerinfo[2] == "1") {
+ $syncsource = $peerinfo[0] . " (stratum " . $peerinfo[2] . ", " . $peerinfo[1] . ")";
+ } else {
+ $syncsource = $peerinfo[0] . " (stratum " . $peerinfo[2] . ")";
+ }
+ $ntpq_counter++;
+ } elseif (substr($line, 0, 1) == "o") {
+ //Local PPS Peer
+ $line = substr($line, 1);
+ $peerinfo = preg_split("/[\s\t]+/", $line);
+ $syncsource = $peerinfo[1] . " (stratum " . $peerinfo[2] . ", PPS)";
+ $ntpq_counter++;
+ }
+ }
+
+ exec("/usr/local/sbin/ntpq -c clockvar $inet_version", $ntpq_clockvar_output);
+ foreach ($ntpq_clockvar_output as $line) {
+ if (substr($line, 0, 9) == "timecode=") {
+ $tmp = explode('"', $line);
+ $tmp = $tmp[1];
+ if (substr($tmp, 0, 6) == '$GPRMC') {
+ $gps_vars = explode(",", $tmp);
+ $gps_ok = ($gps_vars[2] == "A");
+ $gps_lat_deg = substr($gps_vars[3], 0, 2);
+ $gps_lat_min = substr($gps_vars[3], 2) / 60.0;
+ $gps_lon_deg = substr($gps_vars[5], 0, 3);
+ $gps_lon_min = substr($gps_vars[5], 3) / 60.0;
+ $gps_lat = $gps_lat_deg + $gps_lat_min;
+ $gps_lat = $gps_lat * (($gps_vars[4] == "N") ? 1 : -1);
+ $gps_lon = $gps_lon_deg + $gps_lon_min;
+ $gps_lon = $gps_lon * (($gps_vars[6] == "E") ? 1 : -1);
+ $gps_la = $gps_vars[4];
+ $gps_lo = $gps_vars[6];
+ }elseif (substr($tmp, 0, 6) == '$GPGGA') {
+ $gps_vars = explode(",", $tmp);
+ $gps_ok = $gps_vars[6];
+ $gps_lat_deg = substr($gps_vars[2], 0, 2);
+ $gps_lat_min = substr($gps_vars[2], 2) / 60.0;
+ $gps_lon_deg = substr($gps_vars[4], 0, 3);
+ $gps_lon_min = substr($gps_vars[4], 3) / 60.0;
+ $gps_lat = $gps_lat_deg + $gps_lat_min;
+ $gps_lat = $gps_lat * (($gps_vars[3] == "N") ? 1 : -1);
+ $gps_lon = $gps_lon_deg + $gps_lon_min;
+ $gps_lon = $gps_lon * (($gps_vars[5] == "E") ? 1 : -1);
+ $gps_alt = $gps_vars[9];
+ $gps_alt_unit = $gps_vars[10];
+ $gps_sat = $gps_vars[7];
+ $gps_la = $gps_vars[3];
+ $gps_lo = $gps_vars[5];
+ }elseif (substr($tmp, 0, 6) == '$GPGLL') {
+ $gps_vars = explode(",", $tmp);
+ $gps_ok = ($gps_vars[6] == "A");
+ $gps_lat_deg = substr($gps_vars[1], 0, 2);
+ $gps_lat_min = substr($gps_vars[1], 2) / 60.0;
+ $gps_lon_deg = substr($gps_vars[3], 0, 3);
+ $gps_lon_min = substr($gps_vars[3], 3) / 60.0;
+ $gps_lat = $gps_lat_deg + $gps_lat_min;
+ $gps_lat = $gps_lat * (($gps_vars[2] == "N") ? 1 : -1);
+ $gps_lon = $gps_lon_deg + $gps_lon_min;
+ $gps_lon = $gps_lon * (($gps_vars[4] == "E") ? 1 : -1);
+ $gps_la = $gps_vars[2];
+ $gps_lo = $gps_vars[4];
+ }
+ }
+ }
+
+ if (isset($config['ntpd']['gps']['type']) && ($config['ntpd']['gps']['type'] == 'SureGPS') && (isset($gps_ok))) {
+ //GSV message is only enabled by init commands in services_ntpd_gps.php for SureGPS board
+ $gpsport = fopen("/dev/gps0", "r+");
+ while($gpsport){
+ $buffer = fgets($gpsport);
+ if(substr($buffer, 0, 6)=='$GPGSV'){
+ //echo $buffer."\n";
+ $gpgsv = explode(',',$buffer);
+ $gps_satview = $gpgsv[3];
+ break;
+ }
+ }
+ }
+?>
+
+<table class="table" id="ntp_status_widget">
+ <tr>
+ <th>Server Time</th>
+ <td id="ntpStatusClock">
+ <script>var ntpServerTime = new Date('<?=date_format(date_create(), 'c')?>');</script>
+ <!-- display initial value before javascript takes over -->
+ <?=gmdate('D j Y H:i:s \G\M\T O (T)');?>
+ </td>
+ </tr>
+ <tr>
+ <th>Sync Source</th>
+ <td>
+ <?php if ($ntpq_counter == 0): ?>
+ <i>No active peers available</i>
+ <?php else: ?>
+ <?php echo $syncsource; ?>
+ <?php endif; ?>
+ </td>
+ </tr>
+ <?php if (($gps_ok) && ($gps_lat) && ($gps_lon)): ?>
+ <tr>
+ <th>Clock location</th>
+ <td>
+ <a target="_gmaps" href="http://maps.google.com/?q=<?php echo $gps_lat; ?>,<?php echo $gps_lon; ?>">
+ <?php
+ echo sprintf("%.5f", $gps_lat) . " " . $gps_la . ", " . sprintf("%.5f", $gps_lon) . " " . $gps_lo; ?>
+ </a>
+ <?php if (isset($gps_alt)) {echo " (" . $gps_alt . " " . $gps_alt_unit . " alt.)";} ?>
+ </td>
+ </tr>
+ <?php if (isset($gps_sat) || isset($gps_satview)): ?>
+ <tr>
+ <th>Satellites</th>
+ <td>
+ <?php
+ if (isset($gps_satview)) {echo 'in view ' . intval($gps_satview);}
+ if (isset($gps_sat) && isset($gps_satview)) {echo ', ';}
+ if (isset($gps_sat)) {echo 'in use ' . $gps_sat;}
+ ?>
+ </td>
+ </tr>
+ <?php endif; ?>
+ <?php endif; ?>
+</table>
+
+<?php
+ exit;
+}
+?>
+<script>
+function ntpWidgetUpdateFromServer(){
+ $.ajax({
+ type: 'get',
+ url: '/widgets/widgets/ntp_status.widget.php',
+ dataFilter: function(raw){
+ // We reload the entire widget, strip this block of javascript from it
+ return raw.replace(/<script>([\s\S]*)<\/script>/gi, '');
+ },
+ dataType: 'html',
+ success: function(data){
+ console.log(data);
+ $('#ntp_status_widget').html(data);
+ }
+ });
+}
+
+function ntpWidgetUpdateDisplay(){
+ // Javascript handles overflowing
+ ntpServerTime.setSeconds(ntpServerTime.getSeconds()+1);
+
+ $('#ntpStatusClock').html(ntpServerTime.toString());
+}
+
+<script type="text/javascript">
+//<![CDATA[
+/* set up variables used to init clock in BODY's onLoad handler;
+ should be done as early as possible */
+var clockLocalStartTime = new Date();
+var clockServerStartTime = new Date(<?php echo(getServerDateItems($gDate))?>);
+
+/* stub functions for older browsers;
+ will be overridden by next JavaScript1.2 block */
+function clockInit() {
+}
+//]]>
+</script>
+
+
+<script type="text/javascript">
+//<![CDATA[
+/*** simpleFindObj, by Andrew Shearer
+
+Efficiently finds an object by name/id, using whichever of the IE,
+classic Netscape, or Netscape 6/W3C DOM methods is available.
+The optional inLayer argument helps Netscape 4 find objects in
+the named layer or floating DIV. */
+function simpleFindObj(name, inLayer) {
+ return document[name] || (document.all && document.all[name])
+ || (document.getElementById && document.getElementById(name))
+ || (document.layers && inLayer && document.layers[inLayer].document[name]);
+}
+
+/*** Beginning of Clock 2.1.2, by Andrew Shearer
+See: http://www.shearersoftware.com/software/web-tools/clock/
+Redistribution is permitted with the above notice intact.
+
+Client-side clock, based on computed time differential between browser &
+server. The server time is inserted by server-side JavaScript, and local
+time is subtracted from it by client-side JavaScript while the page is
+loading.
+
+Cookies: The local and remote times are saved in cookies named
+localClock and remoteClock, so that when the page is loaded from local
+cache (e.g. by the Back button) the clock will know that the embedded
+server time is stale compared to the local time, since it already
+matches its cookie. It can then base the calculations on both cookies,
+without reloading the page from the server. (IE 4 & 5 for Windows didn't
+respect Response.Expires = 0, so if cookies weren't used, the clock
+would be wrong after going to another page then clicking Back. Netscape
+& Mac IE were OK.)
+
+Every so often (by default, one hour) the clock will reload the page, to
+make sure the clock is in sync (as well as to update the rest of the
+page content).
+
+Compatibility: IE 4.x and 5.0, Netscape 4.x and 6.0, Mozilla 1.0. Mac & Windows.
+
+History: 1.0 2000-05-09 GIF-image digits
+ 2.0 2000-06-29 Uses text DIV layers (so 4.0 browsers req'd), &
+ cookies to work around Win IE stale-time bug
+ 2.1 2002-10-12 Noted Mozilla 1.0 compatibility; released PHP version.
+ 2.1.1 2002-10-20 Fixed octal bug in the PHP translation; the number of
+ minutes & seconds were misinterpreted when less than 10
+ 2.1.2 2003-08-07 The previous fix had introduced a bug when the
+ minutes or seconds were exactly 0. Thanks to Man Bui
+ for reporting the bug.
+*/
+var clockIncrementMillis = 1000;
+var localTime;
+var clockOffset;
+var clockExpirationLocal;
+var clockShowsSeconds = true;
+var clockTimerID = null;
+
+function clockInit(localDateObject, serverDateObject)
+{
+ var origRemoteClock = parseInt(clockGetCookieData("remoteClock"));
+ var origLocalClock = parseInt(clockGetCookieData("localClock"));
+ var newRemoteClock = serverDateObject.getTime();
+ // May be stale (WinIE); will check against cookie later
+ // Can't use the millisec. ctor here because of client inconsistencies.
+ var newLocalClock = localDateObject.getTime();
+ var maxClockAge = 60 * 60 * 1000; // get new time from server every 1hr
+
+ if (newRemoteClock != origRemoteClock) {
+ // new clocks are up-to-date (newer than any cookies)
+ document.cookie = "remoteClock=" + newRemoteClock;
+ document.cookie = "localClock=" + newLocalClock;
+ clockOffset = newRemoteClock - newLocalClock;
+ clockExpirationLocal = newLocalClock + maxClockAge;
+ localTime = newLocalClock; // to keep clockUpdate() happy
+ } else if (origLocalClock != origLocalClock) {
+ // error; localClock cookie is invalid (parsed as NaN)
+ clockOffset = null;
+ clockExpirationLocal = null;
+ } else {
+ // fall back to clocks in cookies
+ clockOffset = origRemoteClock - origLocalClock;
+ clockExpirationLocal = origLocalClock + maxClockAge;
+ localTime = origLocalClock;
+ // so clockUpdate() will reload if newLocalClock
+ // is earlier (clock was reset)
+ }
+ /* Reload page at server midnight to display the new date,
+ by expiring the clock then */
+ var nextDayLocal = (new Date(serverDateObject.getFullYear(),
+ serverDateObject.getMonth(),
+ serverDateObject.getDate() + 1)).getTime() - clockOffset;
+ if (nextDayLocal < clockExpirationLocal) {
+ clockExpirationLocal = nextDayLocal;
+ }
+}
+
+function clockOnLoad()
+{
+ clockUpdate();
+}
+
+function clockOnUnload() {
+ clockClearTimeout();
+}
+
+function clockClearTimeout() {
+ if (clockTimerID) {
+ clearTimeout(clockTimerID);
+ clockTimerID = null;
+ }
+}
+
+function clockToggleSeconds()
+{
+ clockClearTimeout();
+ if (clockShowsSeconds) {
+ clockShowsSeconds = false;
+ clockIncrementMillis = 60000;
+ } else {
+ clockShowsSeconds = true;
+ clockIncrementMillis = 1000;
+ }
+ clockUpdate();
+}
+
+function clockTimeString(inHours, inMinutes, inSeconds) {
+ return inHours
+ + (inMinutes < 10 ? ":0" : ":") + inMinutes
+ + (inSeconds < 10 ? ":0" : ":") + inSeconds;
+}
+
+function clockDisplayTime(inHours, inMinutes, inSeconds) {
+ clockWriteToDiv("ClockTime", clockTimeString(inHours, inMinutes, inSeconds));
+}
+
+function clockWriteToDiv(divName, newValue) // APS 6/29/00
+{
+ var divObject = simpleFindObj(divName);
+ newValue = '<b>' + newValue + '<' + '/b>';
+ if (divObject && divObject.innerHTML) {
+ divObject.innerHTML = newValue;
+ } else if (divObject && divObject.document) {
+ divObject.document.writeln(newValue);
+ divObject.document.close();
+ }
+ // else divObject wasn't found; it's only a clock, so don't bother complaining
+}
+
+function clockGetCookieData(label) {
+ /* find the value of the specified cookie in the document's
+ semicolon-delimited collection. For IE Win98 compatibility, search
+ from the end of the string (to find most specific host/path) and
+ don't require "=" between cookie name & empty cookie values. Returns
+ null if cookie not found. One remaining problem: Under IE 5 [Win98],
+ setting a cookie with no equals sign creates a cookie with no name,
+ just data, which is indistinguishable from a cookie with that name
+ but no data but can't be overwritten by any cookie with an equals
+ sign. */
+ var c = document.cookie;
+ if (c) {
+ var labelLen = label.length, cEnd = c.length;
+ while (cEnd > 0) {
+ var cStart = c.lastIndexOf(';',cEnd-1) + 1;
+ /* bug fix to Danny Goodman's code: calculate cEnd, to
+ prevent walking the string char-by-char & finding cookie
+ labels that contained the desired label as suffixes */
+ // skip leading spaces
+ while (cStart < cEnd && c.charAt(cStart)==" ") {
+ cStart++;
+ }
+ if (cStart + labelLen <= cEnd && c.substr(cStart,labelLen) == label) {
+ if (cStart + labelLen == cEnd) {
+ return ""; // empty cookie value, no "="
+ } else if (c.charAt(cStart+labelLen) == "=") {
+ // has "=" after label
+ return unescape(c.substring(cStart + labelLen + 1,cEnd));
+ }
+ }
+ cEnd = cStart - 1; // skip semicolon
+ }
+ }
+ return null;
+}
+
+/* Called regularly to update the clock display as well as onLoad (user
+ may have clicked the Back button to arrive here, so the clock would need
+ an immediate update) */
+function clockUpdate()
+{
+ var lastLocalTime = localTime;
+ localTime = (new Date()).getTime();
+
+ /* Sanity-check the diff. in local time between successive calls;
+ reload if user has reset system clock */
+ if (clockOffset == null) {
+ clockDisplayTime(null, null, null);
+ } else if (localTime < lastLocalTime || clockExpirationLocal < localTime) {
+ /* Clock expired, or time appeared to go backward (user reset
+ the clock). Reset cookies to prevent infinite reload loop if
+ server doesn't give a new time. */
+ document.cookie = 'remoteClock=-';
+ document.cookie = 'localClock=-';
+ location.reload(); // will refresh time values in cookies
+ } else {
+ // Compute what time would be on server
+ var serverTime = new Date(localTime + clockOffset);
+ clockDisplayTime(serverTime.getHours(), serverTime.getMinutes(),
+ serverTime.getSeconds());
+
+ // Reschedule this func to run on next even clockIncrementMillis boundary
+ clockTimerID = setTimeout("clockUpdate()",
+ clockIncrementMillis - (serverTime.getTime() % clockIncrementMillis));
+ }
+}
+
+/*** End of Clock ***/
+window.onload=clockInit(clockLocalStartTime, clockServerStartTime);clockOnLoad();
+window.onunload=clockOnUnload()
+clockUpdate();
+//]]>
+</script>
+
+
+<table width="100%" border="0" cellspacing="0" cellpadding="0" summary="clock">
+ <tbody>
+ <tr>
+ <td width="40%" class="vncellt">Server Time</td>
+ <td width="60%" class="listr">
+ <div id="ClockTime">
+ <b><?php echo(clockTimeString($gDate,$gClockShowsSeconds));?></b>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<div id='ntpstatus'>
+<table width="100%" border="0" cellspacing="0" cellpadding="0" summary="clock">
+ <tbody>
+ <tr>
+ <td width="100%" class="listr">
+ Updating...
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+
+<script type="text/javascript">
+//<![CDATA[
+ function ntp_getstatus() {
+ scroll(0,0);
+ var url = "/widgets/widgets/ntp_status.widget.php";
+ var pars = 'updateme=yes';
+ jQuery.ajax(
+ url,
+ {
+ type: 'get',
+ data: pars,
+ complete: ntpstatuscallback
+ });
+ // Refresh the status every 1 minute
+ setTimeout('ntp_getstatus()', 1*60*1000);
+ }
+ function ntpstatuscallback(transport) {
+ // The server returns formatted html code
+ var responseStringNtp = transport.responseText
+ jQuery('#ntpstatus').prop('innerHTML',responseStringNtp);
+ }
+ // Do the first status check 1 second after the dashboard opens
+ setTimeout('ntp_getstatus()', 1000);
+//]]>
+</script>
diff --git a/src/usr/local/www/widgets/widgets/openvpn.widget.php b/src/usr/local/www/widgets/widgets/openvpn.widget.php
new file mode 100644
index 0000000..4dc386c
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/openvpn.widget.php
@@ -0,0 +1,289 @@
+<?php
+
+/*
+ openvpn.widget.php
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+ Part of pfSense widgets (https://www.pfsense.org)
+
+ 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.
+*/
+
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("openvpn.inc");
+
+/* Handle AJAX */
+if ($_GET['action']) {
+ if ($_GET['action'] == "kill") {
+ $port = $_GET['port'];
+ $remipp = $_GET['remipp'];
+ if (!empty($port) and !empty($remipp)) {
+ $retval = kill_client($port, $remipp);
+ echo htmlentities("|{$port}|{$remipp}|{$retval}|");
+ } else {
+ echo gettext("invalid input");
+ }
+ exit;
+ }
+}
+
+
+function kill_client($port, $remipp) {
+ global $g;
+
+ //$tcpsrv = "tcp://127.0.0.1:{$port}";
+ $tcpsrv = "unix://{$g['varetc_path']}/openvpn/{$port}.sock";
+ $errval = null;
+ $errstr = null;
+
+ /* open a tcp connection to the management port of each server */
+ $fp = @stream_socket_client($tcpsrv, $errval, $errstr, 1);
+ $killed = -1;
+ if ($fp) {
+ stream_set_timeout($fp, 1);
+ fputs($fp, "kill {$remipp}\n");
+ while (!feof($fp)) {
+ $line = fgets($fp, 1024);
+
+ $info = stream_get_meta_data($fp);
+ if ($info['timed_out']) {
+ break;
+ }
+
+ /* parse header list line */
+ if (strpos($line, "INFO:") !== false) {
+ continue;
+ }
+ if (strpos($line, "SUCCESS") !== false) {
+ $killed = 0;
+ }
+ break;
+ }
+ fclose($fp);
+ }
+ return $killed;
+}
+
+$servers = openvpn_get_active_servers();
+$sk_servers = openvpn_get_active_servers("p2p");
+$clients = openvpn_get_active_clients();
+?>
+
+<br />
+<script type="text/javascript">
+//<![CDATA[
+ function killClient(mport, remipp) {
+ var busy = function(index,icon) {
+ jQuery(icon).bind("onclick","");
+ jQuery(icon).attr('src',jQuery(icon).attr('src').replace("\.gif", "_d.gif"));
+ jQuery(icon).css("cursor","wait");
+ }
+
+ jQuery('img[name="i:' + mport + ":" + remipp + '"]').each(busy);
+
+ jQuery.ajax(
+ "<?=$_SERVER['SCRIPT_NAME'];?>" +
+ "?action=kill&port=" + mport + "&remipp=" + remipp,
+ { type: "get", complete: killComplete }
+ );
+ }
+
+ function killComplete(req) {
+ var values = req.responseText.split("|");
+ if (values[3] != "0") {
+ alert('<?=gettext("An error occurred.");?>' + ' (' + values[3] + ')');
+ return;
+ }
+
+ jQuery('tr[name="r:' + values[1] + ":" + values[2] + '"]').each(
+ function(index,row) { jQuery(row).fadeOut(1000); }
+ );
+ }
+//]]>
+</script>
+
+<?php foreach ($servers as $server): ?>
+
+<table>
+ <tr>
+ <td colspan="6" class="listtopic">
+ <?=$server['name'];?> Client connections
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table>
+ <tr>
+ <th>Name/Time</td>
+ <th>Real/Virtual IP</td>
+ </tr>
+ <?php $rowIndex = 0;
+ foreach ($server['conns'] as $conn):
+ $evenRowClass = $rowIndex % 2 ? " listMReven" : " listMRodd";
+ $rowIndex++;
+ ?>
+ <tr name='<?php echo "r:{$server['mgmt']}:{$conn['remote_host']}"; ?>' class="<?=$evenRowClass?>">
+ <td class="listMRlr">
+ <?=$conn['common_name'];?>
+ </td>
+ <td class="listMRr">
+ <?=$conn['remote_host'];?>
+ </td>
+ <td class='listMR' rowspan="2">
+ <img src='/themes/<?php echo $g['theme']; ?>/images/icons/icon_x.gif' height='17' width='17' border='0'
+ onclick="killClient('<?php echo $server['mgmt']; ?>', '<?php echo $conn['remote_host']; ?>');" style='cursor:pointer;'
+ name='<?php echo "i:{$server['mgmt']}:{$conn['remote_host']}"; ?>'
+ title='Kill client connection from <?php echo $conn['remote_host']; ?>' alt='' />
+ </td>
+ </tr>
+ <tr name='<?php echo "r:{$server['mgmt']}:{$conn['remote_host']}"; ?>' class="<?=$evenRowClass?>">
+ <td class="listMRlr">
+ <?=$conn['connect_time'];?>
+ </td>
+ <td class="listMRr">
+ <?=$conn['virtual_addr'];?>
+ </td>
+ </tr>
+
+ <?php endforeach; ?>
+ <tfoot>
+ <tr>
+ <td colspan="6" class="list" height="12"></td>
+ </tr>
+ </tfoot>
+ </table>
+ </td>
+ </tr>
+</table>
+
+<?php endforeach; ?>
+<?php if (!empty($sk_servers)) { ?>
+<table>
+ <tr>
+ <td colspan="6" class="listtopic">
+ Peer to Peer Server Instance Statistics
+ </td>
+ </tr>
+ <tr>
+ <table>
+ <tr>
+ <th>Name/Time</td>
+ <th>Remote/Virtual IP</td>
+ </tr>
+
+<?php foreach ($sk_servers as $sk_server): ?>
+ <tr name='<?php echo "r:{$sk_server['port']}:{$sk_server['remote_host']}"; ?>'>
+ <td class="listlr">
+ <?=$sk_server['name'];?>
+ </td>
+ <td class="listr">
+ <?=$sk_server['remote_host'];?>
+ </td>
+ <td rowspan="2" align="center">
+ <?php
+ if ($sk_server['status'] == "up") {
+ /* tunnel is up */
+ $iconfn = "interface_up";
+ } else {
+ /* tunnel is down */
+ $iconfn = "interface_down";
+ }
+ echo "<img src ='/themes/{$g['theme']}/images/icons/icon_{$iconfn}.gif' alt='' />";
+ ?>
+ </td>
+ </tr>
+ <tr name='<?php echo "r:{$sk_server['port']}:{$sk_server['remote_host']}"; ?>'>
+ <td class="listlr">
+ <?=$sk_server['connect_time'];?>
+ </td>
+ <td class="listr">
+ <?=$sk_server['virtual_addr'];?>
+ </td>
+ </tr>
+<?php endforeach; ?>
+ </table>
+ </tr>
+</table>
+
+<?php
+} ?>
+<?php if (!empty($clients)) { ?>
+<table>
+ <tr>
+ <td colspan="6" class="listtopic">
+ Client Instance Statistics
+ </td>
+ </tr>
+ <tr>
+ <table>
+ <tr>
+ <th>Name/Time</td>
+ <th>Remote/Virtual IP</td>
+ </tr>
+
+ <?php foreach ($clients as $client): ?>
+ <tr name='<?php echo "r:{$client['port']}:{$client['remote_host']}"; ?>'>
+ <td class="listlr">
+ <?=$client['name'];?>
+ </td>
+ <td class="listr">
+ <?=$client['remote_host'];?>
+ </td>
+ <td rowspan="2" align="center">
+ <?php
+ if ($client['status'] == "up") {
+ /* tunnel is up */
+ $iconfn = "interface_up";
+ } else {
+ /* tunnel is down */
+ $iconfn = "interface_down";
+ }
+ echo "<img src ='/themes/{$g['theme']}/images/icons/icon_{$iconfn}.gif' alt='' />";
+ ?>
+ </td>
+ </tr>
+ <tr name='<?php echo "r:{$client['port']}:{$client['remote_host']}"; ?>'>
+ <td class="listlr">
+ <?=$client['connect_time'];?>
+ </td>
+ <td class="listr">
+ <?=$client['virtual_addr'];?>
+ </td>
+ </tr>
+ <?php endforeach; ?>
+ </table>
+ </tr>
+</table>
+
+<?php
+}
+
+if ($DisplayNote) {
+ echo "<br /><b>NOTE:</b> You need to bind each OpenVPN client to enable its management daemon: use 'Local port' setting in the OpenVPN client screen";
+}
+
+if ((empty($clients)) && (empty($servers)) && (empty($sk_servers))) {
+ echo "No OpenVPN instances defined";
+}
+?>
diff --git a/src/usr/local/www/widgets/widgets/picture.widget.php b/src/usr/local/www/widgets/widgets/picture.widget.php
new file mode 100644
index 0000000..6b19ab6
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/picture.widget.php
@@ -0,0 +1,84 @@
+<?php
+/*
+ picture.widget.php
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+ Copyright 2009 Scott Ullrich
+ Part of pfSense widgets (https://www.pfsense.org)
+
+ 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.
+*/
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("pfsense-utils.inc");
+require_once("functions.inc");
+
+if ($_GET['getpic']=="true") {
+ $pic_type_s = explode(".", $config['widgets']['picturewidget_filename']);
+ $pic_type = $pic_type_s[1];
+ if ($config['widgets']['picturewidget']) {
+ $data = base64_decode($config['widgets']['picturewidget']);
+ }
+ header("Content-Disposition: inline; filename=\"{$config['widgets']['picturewidget_filename']}\"");
+ header("Content-Type: image/{$pic_type}");
+ header("Content-Length: " . strlen($data));
+ echo $data;
+ exit;
+}
+
+if ($_POST) {
+ if (is_uploaded_file($_FILES['pictfile']['tmp_name'])) {
+ /* read the file contents */
+ $fd_pic = fopen($_FILES['pictfile']['tmp_name'], "rb");
+ while (($buf=fread($fd_pic, 8192)) != '') {
+ // Here, $buf is guaranteed to contain data
+ $data .= $buf;
+ }
+ fclose($fd_pic);
+ if (!$data) {
+ log_error("Warning, could not read file " . $_FILES['pictfile']['tmp_name']);
+ die("Could not read temporary file");
+ } else {
+ $picname = basename($_FILES['uploadedfile']['name']);
+ $config['widgets']['picturewidget'] = base64_encode($data);
+ $config['widgets']['picturewidget_filename'] = $_FILES['pictfile']['name'];
+ write_config("Picture widget saved via Dashboard.");
+ header("Location: /index.php");
+ exit;
+ }
+ }
+}
+
+?>
+<a href="/widgets/widgets/picture.widget.php?getpic=true" target="_blank">
+ <img width="100%" height="100%" src="/widgets/widgets/picture.widget.php?getpic=true" alt="picture" />
+</a>
+
+<!-- close the body we're wrapped in and add a configuration-panel -->
+</div><div class="panel-footer collapse">
+
+<form action="/widgets/widgets/picture.widget.php" method="post" enctype="multipart/form-data" class="form-inline">
+ <label for="pictfile">New picture: </label>
+ <input name="pictfile" type="file" class="form-control" />
+ <button type="submit" class="btn btn-default">Upload</button>
+</form>
diff --git a/src/usr/local/www/widgets/widgets/rss.widget.php b/src/usr/local/www/widgets/widgets/rss.widget.php
new file mode 100644
index 0000000..e84bae2
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/rss.widget.php
@@ -0,0 +1,167 @@
+<?php
+/*
+ rss.widget.php
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+
+ Copyright 2009 Scott Ullrich
+ Part of pfSense widgets (https://www.pfsense.org)
+
+ 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.
+*/
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("pfsense-utils.inc");
+require_once("functions.inc");
+
+if ($_POST['rssfeed']) {
+ $config['widgets']['rssfeed'] = str_replace("\n", ",", htmlspecialchars($_POST['rssfeed'], ENT_QUOTES | ENT_HTML401));
+ $config['widgets']['rssmaxitems'] = str_replace("\n", ",", htmlspecialchars($_POST['rssmaxitems'], ENT_QUOTES | ENT_HTML401));
+ $config['widgets']['rsswidgetheight'] = htmlspecialchars($_POST['rsswidgetheight'], ENT_QUOTES | ENT_HTML401);
+ $config['widgets']['rsswidgettextlength'] = htmlspecialchars($_POST['rsswidgettextlength'], ENT_QUOTES | ENT_HTML401);
+ write_config("Saved RSS Widget feed via Dashboard");
+ header("Location: /");
+}
+
+// Use saved feed and max items
+if ($config['widgets']['rssfeed']) {
+ $rss_feed_s = explode(",", $config['widgets']['rssfeed']);
+}
+
+if ($config['widgets']['rssmaxitems']) {
+ $max_items = $config['widgets']['rssmaxitems'];
+}
+
+if (is_numeric($config['widgets']['rsswidgetheight'])) {
+ $rsswidgetheight = $config['widgets']['rsswidgetheight'];
+}
+
+if (is_numeric($config['widgets']['rsswidgettextlength'])) {
+ $rsswidgettextlength = $config['widgets']['rsswidgettextlength'];
+}
+
+// Set a default feed if none exists
+if (!$rss_feed_s) {
+ $rss_feed_s = "https://blog.pfsense.org";
+ $config['widgets']['rssfeed'] = "https://blog.pfsense.org";
+}
+
+if (!$max_items) {
+ $max_items = 10;
+}
+
+if (!$rsswidgetheight) {
+ $rsswidgetheight = 300;
+}
+
+if (!$rsswidgettextlength) {
+ $rsswidgettextlength = 140; // oh twitter, how do we love thee?
+}
+
+if ($config['widgets']['rssfeed']) {
+ $textarea_txt = str_replace(",", "\n", $config['widgets']['rssfeed']);
+} else {
+ $textarea_txt = "";
+}
+
+?>
+<div class="list-group" style="height: <?=$rsswidgetheight?>px; overflow:scroll;">
+<?php
+ if (!is_dir("/tmp/simplepie")) {
+ mkdir("/tmp/simplepie");
+ mkdir("/tmp/simplepie/cache");
+ }
+ exec("chmod a+rw /tmp/simplepie/.");
+ exec("chmod a+rw /tmp/simplepie/cache/.");
+ require_once("simplepie/simplepie.inc");
+ function textLimit($string, $length, $replacer = '...') {
+ if(strlen($string) > $length)
+ return (preg_match('/^(.*)\W.*$/', substr($string, 0, $length+1), $matches) ? $matches[1] : substr($string, 0, $length)) . $replacer;
+ return $string;
+ }
+ $feed = new SimplePie();
+ $feed->set_cache_location("/tmp/simplepie/");
+ $feed->set_feed_url($rss_feed_s);
+ $feed->init();
+ $feed->handle_content_type();
+ $counter = 1;
+ foreach($feed->get_items(0, $max_items) as $item) {
+ $feed = $item->get_feed();
+ $feed->strip_htmltags();
+ $content = $item->get_content();
+ $content = strip_tags($content);
+?>
+ <a href="<?=$item->get_permalink()?>" target="_blank" class="list-group-item">
+ <h4 class="list-group-item-heading">
+ <img src="<?=$feed->get_favicon()?>" title="Source: <?=$feed->get_title()?>" width="16" height="16" />
+ <?=$item->get_title()?>
+ </h4>
+ <p class="list-group-item-text">
+ <?=textLimit($content, $rsswidgettextlength)?>
+ <br />
+ </p>
+ </a>
+<?php
+ }
+?>
+
+</div>
+
+<!-- close the body we're wrapped in and add a configuration-panel -->
+</div><div class="panel-footer collapse">
+
+<form action="/widgets/widgets/rss.widget.php" method="post" class="form-horizontal">
+ <div class="form-group">
+ <label for="rssfeed" class="col-sm-3 control-label">Feeds</label>
+ <div class="col-sm-6">
+ <textarea name="rssfeed" class="form-control"><?=$textarea_txt;?></textarea>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="rssmaxitems" class="col-sm-3 control-label"># Stories</label>
+ <div class="col-sm-6">
+ <input type="number" name="rssmaxitems" value="<?=$max_items?>" min="1" max="100" class="form-control" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="rsswidgetheight" class="col-sm-3 control-label">Widget height</label>
+ <div class="col-sm-6">
+ <input type="number" name="rsswidgetheight" value="<?=$rsswidgetheight?>" min="100" max="2500" step="100" class="form-control" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="rsswidgettextlength" class="col-sm-3 control-label">Content limit</label>
+ <div class="col-sm-6">
+ <input type="number" name="rsswidgettextlength" value="<?=$rsswidgettextlength?>" min="100" max="5000" step="100" class="form-control" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="col-sm-offset-3 col-sm-6">
+ <button type="submit" class="btn btn-default">Save</button>
+ </div>
+ </div>
+</form> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/widgets/services_status.widget.php b/src/usr/local/www/widgets/widgets/services_status.widget.php
new file mode 100644
index 0000000..a0f7e54
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/services_status.widget.php
@@ -0,0 +1,114 @@
+<?php
+/*
+ services_status.widget.php
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+
+ Copyright (C) 2004, 2005 Scott Ullrich
+ All rights reserved.
+
+ services_status.widget.php
+ Copyright (C) 2007 Sam Wenham
+
+ 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.
+*/
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("captiveportal.inc");
+require_once("service-utils.inc");
+require_once("ipsec.inc");
+require_once("vpn.inc");
+require_once("/usr/local/www/widgets/include/services_status.inc");
+
+$services = get_services();
+
+if(isset($_POST['servicestatusfilter'])) {
+ $validNames = array();
+ foreach ($services as $service)
+ array_push($validNames, $service['name']);
+
+ $config['widgets']['servicestatusfilter'] = implode(',', array_intersect($validNames, $_POST['servicestatusfilter']));
+ write_config("Saved Service Status Filter via Dashboard");
+ header("Location: /");
+}
+?>
+<table class="table table-striped table-hover">
+<thead>
+ <tr>
+ <th></th>
+ <th>Service</td>
+ <th>Description</td>
+ <th>Action</td>
+ </tr>
+</thead>
+<tbody>
+<?php
+$skipservices = explode(",", $config['widgets']['servicestatusfilter']);
+
+if (count($services) > 0) {
+ uasort($services, "service_name_compare");
+ foreach ($services as $service) {
+ if ((!$service['name']) || (in_array($service['name'], $skipservices)) || (!is_service_enabled($service['name']))) {
+ continue;
+ }
+ if (empty($service['description'])) {
+ $service['description'] = get_pkg_descr($service['name']);
+ }
+ $service_desc = explode(".",$service['description']);
+?>
+ <tr>
+ <td><i class="icon icon-<?=get_service_status($service)? 'ok' : 'remove'?>-sign"></i></td>
+ <td><?=$service['name']?></td>
+ <td><?=$service_desc[0]?></td>
+ <td><?=get_service_control_links($service)?></td>
+ </tr>
+<?php
+ }
+} else {
+ echo "<tr><td colspan=\"3\" align=\"center\">" . gettext("No services found") . " . </td></tr>\n";
+}
+?>
+</tbody>
+</table>
+
+<!-- close the body we're wrapped in and add a configuration-panel -->
+</div><div class="panel-footer collapse">
+
+<form action="/widgets/widgets/services_status.widget.php" method="post" class="form-horizontal">
+ <div class="form-group">
+ <label for="inputPassword3" class="col-sm-3 control-label">Hidden services</label>
+ <div class="col-sm-6">
+ <select multiple="multiple" name="servicestatusfilter" class="form-control" height="5">
+ <?php foreach ($services as $service): ?>
+ <option <?=(in_array($service['name'], $skipservices)?'selected="selected"':'')?>><?=$service['name']?></option>
+ <?php endforeach; ?>
+ </select>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="col-sm-offset-3 col-sm-6">
+ <button type="submit" class="btn btn-default">Save</button>
+ </div>
+ </div>
+</form> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/widgets/smart_status.widget.php b/src/usr/local/www/widgets/widgets/smart_status.widget.php
new file mode 100644
index 0000000..175a185
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/smart_status.widget.php
@@ -0,0 +1,82 @@
+<?php
+/*
+ smart_status.widget.php
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+ Copyright 2012 mkirbst @ pfSense Forum
+ Part of pfSense widgets (https://www.pfsense.org)
+ 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.
+*/
+
+require_once("guiconfig.inc");
+require_once("pfsense-utils.inc");
+require_once("functions.inc");
+require_once("/usr/local/www/widgets/include/smart_status.inc");
+?>
+
+<table class="table table-striped table-hover">
+ <thead>
+ <tr>
+ <th></th>
+ <th><?=gettext("Drive")?></th>
+ <th><?=gettext("Ident")?></th>
+ <th><?=gettext("SMART Status")?></th>
+ </tr>
+ </thead>
+ <tbody>
+<?php
+$devs = array();
+## Get all adX, daX, and adaX (IDE, SCSI, and AHCI) devices currently installed
+$devs = get_smart_drive_list();
+
+if (count($devs) > 0) {
+ foreach ($devs as $dev) { ## for each found drive do
+ $dev_ident = exec("diskinfo -v /dev/$dev | grep ident | awk '{print $1}'"); ## get identifier from drive
+ $dev_state = trim(exec("smartctl -H /dev/$dev | awk -F: '/^SMART overall-health self-assessment test result/ {print $2;exit}
+/^SMART Health Status/ {print $2;exit}'")); ## get SMART state from drive
+ switch ($dev_state) {
+ case "PASSED":
+ case "OK":
+ $color = "#90EE90";
+ break;
+ case "":
+ $dev_state = "Unknown";
+ $color = "#C0B788";
+ break;
+ default:
+ $color = "#F08080";
+ break;
+ }
+?>
+ <tr>
+ <td><i class="icon icon-<?=$icon?>-sign"></i></td>
+ <td><?=$dev?></td>
+ <td><?=$dev_ident?></td>
+ <td><?=ucfirst($dev_state)?></td>
+ </tr>
+<?php
+ }
+}
+?>
+ </tbody>
+</table>
diff --git a/src/usr/local/www/widgets/widgets/system_information.widget.php b/src/usr/local/www/widgets/widgets/system_information.widget.php
new file mode 100644
index 0000000..c9aab04
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/system_information.widget.php
@@ -0,0 +1,311 @@
+<?php
+/*
+ system_information.widget.php
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+ Copyright 2007 Scott Dale
+ Part of pfSense widgets (https://www.pfsense.org)
+ originally based on m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004-2005 T. Lechat <dev@lechat.org>, Manuel Kasper <mk@neon1.net>
+ and Jonathan Watt <jwatt@jwatt.org>.
+ 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.
+*/
+
+require_once("functions.inc");
+require_once("guiconfig.inc");
+require_once('notices.inc');
+include_once("includes/functions.inc.php");
+
+if ($_REQUEST['getupdatestatus']) {
+ if (isset($config['system']['firmware']['disablecheck'])) {
+ exit;
+ }
+ if (isset($config['system']['firmware']['alturl']['enable'])) {
+ $updater_url = "{$config['system']['firmware']['alturl']['firmwareurl']}";
+ } else {
+ $updater_url = $g['update_url'];
+ }
+
+ $nanosize = "";
+ if ($g['platform'] == "nanobsd") {
+ if (file_exists("/etc/nano_use_vga.txt")) {
+ $nanosize = "-nanobsd-vga-";
+ } else {
+ $nanosize = "-nanobsd-";
+ }
+ $nanosize .= strtolower(trim(file_get_contents("/etc/nanosize.txt")));
+ }
+
+ @unlink("/tmp/{$g['product_name']}_version");
+ if (download_file_with_progress_bar("{$updater_url}/version{$nanosize}", "/tmp/{$g['product_name']}_version", 'read_body', 5, 5) === true) {
+ $remote_version = trim(@file_get_contents("/tmp/{$g['product_name']}_version"));
+ }
+
+ if(empty($remote_version))
+ echo "<i>Unable to check for updates</i>";
+ else {
+ $current_installed_buildtime = trim(file_get_contents("/etc/version.buildtime"));
+ $current_installed_version = trim(file_get_contents("/etc/version"));
+
+ if(!$remote_version) {
+ echo "<i>Unable to check for updates</i>";
+ }
+ else {
+ $needs_system_upgrade = false;
+ if (pfs_version_compare($current_installed_buildtime, $current_installed_version, $remote_version) == -1) {
+?>
+<div class="alert alert-warning" role="alert">
+ Version <?=$remote_version?> is available. <a href="/system_firmware_check.php" class="alert-link">Click Here to view.</a>
+</div>
+<?php
+ } else
+ echo "You are on the latest version.";
+ }
+ }
+ exit;
+}
+
+$curcfg = $config['system']['firmware'];
+
+$filesystems = get_mounted_filesystems();
+?>
+
+<table class="table table-striped table-hover">
+ <tbody>
+ <tr>
+ <th><?=gettext("Name");?></td>
+ <td><?php echo $config['system']['hostname'] . "." . $config['system']['domain']; ?></td>
+ </tr>
+ <tr>
+ <th><?=gettext("Version");?></th>
+ <td>
+ <strong><?php readfile("/etc/version"); ?></strong>
+ (<?php echo php_uname("m"); ?>)
+ <br />
+ built on <?php readfile("/etc/version.buildtime"); ?>
+ <?php if(!$g['hideuname']): ?>
+ <br />
+ <span title="<?php echo php_uname("a"); ?>"><?php echo php_uname("s") . " " . php_uname("r"); ?></span>
+ <?php endif; ?>
+ <br/><br/>
+ <?php if(!isset($config['system']['firmware']['disablecheck'])): ?>
+ <div id='updatestatus'><?php echo gettext("Obtaining update status"); ?> ...</div>
+ <?php endif; ?>
+ </td>
+ </tr>
+ <?php if (!$g['hideplatform']): ?>
+ <tr>
+ <th><?=gettext("Platform");?></td>
+ <td>
+ <?=htmlspecialchars($g['platform']);?>
+ <?php if (($g['platform'] == "nanobsd") && (file_exists("/etc/nanosize.txt"))) {
+ echo " (" . htmlspecialchars(trim(file_get_contents("/etc/nanosize.txt"))) . ")";
+ } ?>
+ </td>
+ </tr>
+ <?php endif; ?>
+ <?php if ($g['platform'] == "nanobsd"): ?>
+ <?
+ global $SLICE, $OLDSLICE, $TOFLASH, $COMPLETE_PATH, $COMPLETE_BOOT_PATH;
+ global $GLABEL_SLICE, $UFS_ID, $OLD_UFS_ID, $BOOTFLASH;
+ global $BOOT_DEVICE, $REAL_BOOT_DEVICE, $BOOT_DRIVE, $ACTIVE_SLICE;
+ nanobsd_detect_slice_info();
+ $rw = is_writable("/") ? "(rw)" : "(ro)";
+ ?>
+ <tr>
+ <th><?=gettext("NanoBSD Boot Slice");?></td>
+ <td>
+ <?=htmlspecialchars(nanobsd_friendly_slice_name($BOOT_DEVICE));?> / <?=htmlspecialchars($BOOTFLASH);?><?php echo $rw; ?>
+ <?php if ($BOOTFLASH != $ACTIVE_SLICE): ?>
+ <br /><br />Next Boot:<br />
+ <?=htmlspecialchars(nanobsd_friendly_slice_name($GLABEL_SLICE));?> / <?=htmlspecialchars($ACTIVE_SLICE);?>
+ <?php endif; ?>
+ </td>
+ </tr>
+ <?php endif; ?>
+ <tr>
+ <th><?=gettext("CPU Type");?></td>
+ <td><?=htmlspecialchars(get_single_sysctl("hw.model"))?>
+ <div id="cpufreq"><?= get_cpufreq(); ?></div>
+ <?php
+ $cpucount = get_cpu_count();
+ if ($cpucount > 1): ?>
+ <div id="cpucount">
+ <?= htmlspecialchars($cpucount) ?> CPUs: <?= htmlspecialchars(get_cpu_count(true)); ?></div>
+ <?php endif; ?>
+ </td>
+ </tr>
+ <?php if ($hwcrypto): ?>
+ <tr>
+ <th><?=gettext("Hardware crypto");?></td>
+ <td><?=htmlspecialchars($hwcrypto);?></td>
+ </tr>
+ <?php endif; ?>
+ <tr>
+ <th><?=gettext("Uptime");?></td>
+ <td id="uptime"><?= htmlspecialchars(get_uptime()); ?></td>
+ </tr>
+ <tr>
+ <th><?=gettext("Current date/time");?></td>
+ <td><div id="datetime"><?= date("D M j G:i:s T Y"); ?></div></td>
+ </tr>
+ <tr>
+ <th><?=gettext("DNS server(s)");?></td>
+ <td>
+ <ul>
+ <?php
+ $dns_servers = get_dns_servers();
+ foreach($dns_servers as $dns) {
+ echo "<li>{$dns}</li>";
+ }
+ ?>
+ </ul>
+ </td>
+ </tr>
+ <?php if ($config['revision']): ?>
+ <tr>
+ <th><?=gettext("Last config change");?></td>
+ <td><?= htmlspecialchars(date("D M j G:i:s T Y", intval($config['revision']['time'])));?></td>
+ </tr>
+ <?php endif; ?>
+ <tr>
+ <th><?=gettext("State table size");?></td>
+ <td>
+ <?php $pfstatetext = get_pfstate();
+ $pfstateusage = get_pfstate(true);
+ ?>
+ <div class="progress">
+ <div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="<?=$pfstateusage?>" aria-valuemin="0" aria-valuemax="100" style="width: <?=$pfstateusage?>%">
+ <span><?=$pfstateusage?>% (<?= htmlspecialchars($pfstatetext)?>)</span>
+ </div>
+ </div>
+ <a href="diag_dump_states.php"><?=gettext("Show states");?></a>
+ </td>
+ </tr>
+ <tr>
+ <th><?=gettext("MBUF Usage");?></td>
+ <td>
+ <?php
+ $mbufstext = get_mbuf();
+ $mbufusage = get_mbuf(true);
+ ?>
+ <div class="progress">
+ <div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="<?=$mbufusage?>" aria-valuemin="0" aria-valuemax="100" style="width: <?=$mbufusage?>%">
+ <span><?=$mbufusage?>% (<?= htmlspecialchars($mbufstext)?>)</span>
+ </div>
+ </div>
+ </td>
+ </tr>
+ <?php if (get_temp() != ""): ?>
+ <tr>
+ <th><?=gettext("Temperature");?></td>
+ <td>
+ <?php $TempMeter = $temp = get_temp(); ?>
+ <div id="tempPB"></div>
+ <span id="tempmeter"><?= $temp."&#176;C"; ?></span>
+ </td>
+ </tr>
+ <?php endif; ?>
+ <tr>
+ <th><?=gettext("Load average");?></td>
+ <td>
+ <div id="load_average" title="Last 1, 5 and 15 minutes"><?= get_load_average(); ?></div>
+ </td>
+ </tr>
+ <tr>
+ <th><?=gettext("CPU usage");?></td>
+ <td>
+ <div id="cpuPB"></div>
+ <span id="cpumeter">(Updating in 10 seconds)</span>
+ </td>
+ </tr>
+ <tr>
+ <th><?=gettext("Memory usage");?></td>
+ <td>
+ <?php $memUsage = mem_usage(); ?>
+ <div class="progress">
+ <div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="<?=$memUsage?>" aria-valuemin="0" aria-valuemax="100" style="width: <?=$memUsage?>%">
+ <span><?=$memUsage?>% of <?= sprintf("%.0f", get_single_sysctl('hw.physmem') / (1024*1024)) ?> MB</span>
+ </div>
+ </div>
+ </td>
+ </tr>
+ <?php if ($showswap == true): ?>
+ <tr>
+ <th><?=gettext("SWAP usage");?></td>
+ <td>
+ <?php $swapusage = swap_usage(); ?>
+ <div class="progress">
+ <div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="<?=$swapusage?>" aria-valuemin="0" aria-valuemax="100" style="width: <?=$swapusage?>%">
+ <span><?=$swapusage?>% of <?= sprintf("%.0f", `/usr/sbin/swapinfo -m | /usr/bin/grep -v Device | /usr/bin/awk '{ print $2;}'`) ?> MB</span>
+ </div>
+ </div>
+ </td>
+ </tr>
+ <?php endif; ?>
+ <tr>
+ <th><?=gettext("Disk usage");?></td>
+ <td>
+ <table class="table">
+<?PHP foreach ($filesystems as $fs): ?>
+ <tr>
+ <th><?=$fs['mountpoint']?></th>
+ <td><?=$fs['type'] . ("md" == substr(basename($fs['device']), 0, 2) ? " in RAM" : "")?></td>
+ <td><?=$fs['total_size']?></td>
+ <td>
+ <div class="progress">
+ <div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="<?=$fs['percent_used']?>" aria-valuemin="0" aria-valuemax="100" style="width: <?=$fs['percent_used']?>%">
+ <span><?=$fs['percent_used']?>%</span>
+ </div>
+ </div>
+ </td>
+ </tr>
+<?PHP endforeach; ?>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<script>
+function systemStatusGetUpdateStatus() {
+ $.ajax({
+ type: 'get',
+ url: '/widgets/widgets/system_information.widget.php',
+ data: 'getupdatestatus=1',
+ dataFilter: function(raw){
+ // We reload the entire widget, strip this block of javascript from it
+ return raw.replace(/<script>([\s\S]*)<\/script>/gi, '');
+ },
+ dataType: 'html',
+ success: function(data){
+ $('#widget-system_information #updatestatus').html(data);
+ }
+ });
+}
+
+events.push(function(){
+ setTimeout('systemStatusGetUpdateStatus()', 4000);
+});
+</script> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/widgets/thermal_sensors.widget.php b/src/usr/local/www/widgets/widgets/thermal_sensors.widget.php
new file mode 100644
index 0000000..875ccb2
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/thermal_sensors.widget.php
@@ -0,0 +1,279 @@
+<?php
+/*
+ $Id: thermal_sensors.widget.php
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+
+ Description: Thermal Sensors Widget.
+ NOTE: depends on proper config in System >> Advanced >> Miscellaneous tab >> Thermal Sensors section.
+
+ File location:
+ \usr\local\www\widgets\widgets\
+ Depends on:
+ \usr\local\www\widgets\javascript\thermal_sensors.js
+ \usr\local\www\widgets\include\thermal_sensors.inc
+
+ 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.
+ */
+
+require_once("guiconfig.inc");
+require_once("/usr/local/www/widgets/include/thermal_sensors.inc");
+
+//=========================================================================
+//called by showThermalSensorsData() (jQuery Ajax call) in thermal_sensors.js
+if (isset($_GET["getThermalSensorsData"])) {
+ //get Thermal Sensors data and return
+ echo getThermalSensorsData();
+ return;
+}
+//=========================================================================
+
+
+const WIDGETS_CONFIG_SECTION_KEY = "widgets";
+const THERMAL_SENSORS_WIDGET_SUBSECTION_KEY = "thermal_sensors_widget";
+
+//default constants
+const DEFAULT_WARNING_THRESHOLD = 60; //60 C
+const DEFAULT_CRITICAL_THRESHOLD = 70; //70 C
+const MIN_THRESHOLD_VALUE = 1; //deg C
+const MAX_THRESHOLD_VALUE = 100; //deg C
+
+//NOTE: keys used in $_POST and $config should match text and checkbox inputs' IDs/names in HTML code section
+//=========================================================================
+//save widget config settings on POST
+if ($_POST) {
+ saveThresholdSettings($config, $_POST, "thermal_sensors_widget_zone_warning_threshold", "thermal_sensors_widget_zone_critical_threshold");
+ saveThresholdSettings($config, $_POST, "thermal_sensors_widget_core_warning_threshold", "thermal_sensors_widget_core_critical_threshold");
+
+ //handle checkboxes separately
+ saveGraphDisplaySettings($config, $_POST, "thermal_sensors_widget_show_raw_output");
+ saveGraphDisplaySettings($config, $_POST, "thermal_sensors_widget_show_full_sensor_name");
+ saveGraphDisplaySettings($config, $_POST, "thermal_sensors_widget_pulsate_warning");
+ saveGraphDisplaySettings($config, $_POST, "thermal_sensors_widget_pulsate_critical");
+
+ //write settings to config file
+ write_config("Saved thermal_sensors_widget settings via Dashboard.");
+ header("Location: ../../index.php");
+}
+
+function saveThresholdSettings(&$configArray, &$postArray, $warningValueKey, $criticalValueKey) {
+ $warningValue = 0;
+ $criticalValue = 0;
+
+ if (isset($postArray[$warningValueKey])) {
+ $warningValue = (int) $postArray[$warningValueKey];
+ }
+
+ if (isset($postArray[$criticalValueKey])) {
+ $criticalValue = (int) $postArray[$criticalValueKey];
+ }
+
+ if (($warningValue >= MIN_THRESHOLD_VALUE && $warningValue <= MAX_THRESHOLD_VALUE) &&
+ ($criticalValue >= MIN_THRESHOLD_VALUE && $criticalValue <= MAX_THRESHOLD_VALUE) &&
+ ($warningValue < $criticalValue)) {
+ //all validated ok, save to config array
+ $configArray[WIDGETS_CONFIG_SECTION_KEY][THERMAL_SENSORS_WIDGET_SUBSECTION_KEY][$warningValueKey] = $warningValue;
+ $configArray[WIDGETS_CONFIG_SECTION_KEY][THERMAL_SENSORS_WIDGET_SUBSECTION_KEY][$criticalValueKey] = $criticalValue;
+ }
+}
+
+function saveGraphDisplaySettings(&$configArray, &$postArray, $valueKey) {
+ $configArray[WIDGETS_CONFIG_SECTION_KEY][THERMAL_SENSORS_WIDGET_SUBSECTION_KEY][$valueKey] = isset($postArray[$valueKey]) ? 1 : 0;
+}
+
+//=========================================================================
+//get Threshold settings from config (apply defaults if missing)
+$thermal_sensors_widget_zoneWarningTempThreshold = getThresholdValueFromConfig($config, "thermal_sensors_widget_zone_warning_threshold", DEFAULT_WARNING_THRESHOLD);
+$thermal_sensors_widget_zoneCriticalTempThreshold = getThresholdValueFromConfig($config, "thermal_sensors_widget_zone_critical_threshold", DEFAULT_CRITICAL_THRESHOLD);
+$thermal_sensors_widget_coreWarningTempThreshold = getThresholdValueFromConfig($config, "thermal_sensors_widget_core_warning_threshold", DEFAULT_WARNING_THRESHOLD);
+$thermal_sensors_widget_coreCriticalTempThreshold = getThresholdValueFromConfig($config, "thermal_sensors_widget_core_critical_threshold", DEFAULT_CRITICAL_THRESHOLD);
+
+//get display settings from config (apply defaults if missing)
+$thermal_sensors_widget_showRawOutput = getBoolValueFromConfig($config, "thermal_sensors_widget_show_raw_output", false);
+$thermal_sensors_widget_showFullSensorName = getBoolValueFromConfig($config, "thermal_sensors_widget_show_full_sensor_name", false);
+$thermal_sensors_widget_pulsateWarning = getBoolValueFromConfig($config, "thermal_sensors_widget_pulsate_warning", true);
+$thermal_sensors_widget_pulsateCritical = getBoolValueFromConfig($config, "thermal_sensors_widget_pulsate_critical", true);
+
+function getThresholdValueFromConfig(&$configArray, $valueKey, $defaultValue) {
+
+ $thresholdValue = $defaultValue;
+
+ if (isset($configArray[WIDGETS_CONFIG_SECTION_KEY][THERMAL_SENSORS_WIDGET_SUBSECTION_KEY][$valueKey])) {
+ $thresholdValue = (int) $configArray[WIDGETS_CONFIG_SECTION_KEY][THERMAL_SENSORS_WIDGET_SUBSECTION_KEY][$valueKey];
+ }
+
+ if ($thresholdValue < MIN_THRESHOLD_VALUE || $thresholdValue > MAX_THRESHOLD_VALUE) {
+ //set to default if not in allowed range
+ $thresholdValue = $defaultValue;
+ }
+ return $thresholdValue;
+}
+
+function getBoolValueFromConfig(&$configArray, $valueKey, $defaultValue) {
+
+ $boolValue = false;
+
+ if (isset($configArray[WIDGETS_CONFIG_SECTION_KEY][THERMAL_SENSORS_WIDGET_SUBSECTION_KEY][$valueKey])) {
+ $boolValue = (bool) $configArray[WIDGETS_CONFIG_SECTION_KEY][THERMAL_SENSORS_WIDGET_SUBSECTION_KEY][$valueKey];
+ } else {
+ //set to default if not in allowed range
+ $boolValue = $defaultValue;
+ }
+ return $boolValue;
+}
+
+//=========================================================================
+?>
+
+<script type="text/javascript">
+//<![CDATA[
+ //set Thresholds, to be used in thermal_sensors.js
+ var thermal_sensors_widget_zoneWarningTempThreshold = <?= $thermal_sensors_widget_zoneWarningTempThreshold; ?>;
+ var thermal_sensors_widget_zoneCriticalTempThreshold = <?= $thermal_sensors_widget_zoneCriticalTempThreshold; ?>;
+ var thermal_sensors_widget_coreWarningTempThreshold = <?= $thermal_sensors_widget_coreWarningTempThreshold; ?>;
+ var thermal_sensors_widget_coreCriticalTempThreshold = <?= $thermal_sensors_widget_coreCriticalTempThreshold; ?>;
+
+ //set Graph display settings, to be used in thermal_sensors.js
+ var thermal_sensors_widget_showRawOutput = <?= $thermal_sensors_widget_showRawOutput ? "true" : "false"; ?>;
+ var thermal_sensors_widget_showFullSensorName = <?= $thermal_sensors_widget_showFullSensorName ? "true" : "false"; ?>;
+ var thermal_sensors_widget_pulsateWarning = <?= $thermal_sensors_widget_pulsateWarning ? "true" : "false"; ?>;
+ var thermal_sensors_widget_pulsateCritical = <?= $thermal_sensors_widget_pulsateCritical ? "true" : "false"; ?>;
+
+ //start showing temp data
+ //NOTE: the refresh interval will be reset to a proper value in showThermalSensorsData() (thermal_sensors.js).
+ jQuery(document).ready(function() {
+ showThermalSensorsData();
+ });
+//]]>
+</script>
+
+<input type="hidden" id="thermal_sensors-config" name="thermal_sensors-config" value="" />
+<div id="thermal_sensors-settings" class="widgetconfigdiv" style="display:none;">
+ <form action="/widgets/widgets/thermal_sensors.widget.php" method="post" id="iform_thermal_sensors_settings" name="iform_thermal_sensors_settings">
+ <table>
+ <tr>
+ <td align="left" colspan="2">
+ <span style="font-weight: bold" >Thresholds in &deg;C (1 to 100):</span>
+ </td>
+ <td align="right" colspan="1">
+ <span style="font-weight: bold" >Display settings:</span>
+ </td>
+ </tr>
+ <tr>
+ <td align="right">
+ Zone Warning:
+ </td>
+ <td>
+ <input type="text" maxlength="3" size="3" class="formfld unknown"
+ name="thermal_sensors_widget_zone_warning_threshold"
+ id="thermal_sensors_widget_zone_warning_threshold"
+ value="<?= $thermal_sensors_widget_zoneWarningTempThreshold; ?>" />
+ </td>
+ <td align="right">
+ <label for="thermal_sensors_widget_show_raw_output">Show raw output (no graph): </label>
+ <input type="checkbox"
+ id="thermal_sensors_widget_show_raw_output"
+ name="thermal_sensors_widget_show_raw_output"
+ value="<?= $thermal_sensors_widget_showRawOutput; ?>" <?= ($thermal_sensors_widget_showRawOutput) ? " checked='checked'" : ""; ?> />
+ </td>
+ </tr>
+ <tr>
+ <td align="right">
+ Zone Critical:
+ </td>
+ <td>
+ <input type="text" maxlength="3" size="3" class="formfld unknown"
+ name="thermal_sensors_widget_zone_critical_threshold"
+ id="thermal_sensors_widget_zone_critical_threshold"
+ value="<?= $thermal_sensors_widget_zoneCriticalTempThreshold; ?>" />
+ </td>
+ <td align="right">
+ <label for="thermal_sensors_widget_show_full_sensor_name">Show full sensor name: </label>
+ <input type="checkbox"
+ id="thermal_sensors_widget_show_full_sensor_name"
+ name="thermal_sensors_widget_show_full_sensor_name"
+ value="<?= $thermal_sensors_widget_showFullSensorName; ?>" <?= ($thermal_sensors_widget_showFullSensorName) ? " checked='checked'" : ""; ?> />
+ </td>
+ </tr>
+ <tr>
+ <td align="right">
+ Core Warning:
+ </td>
+ <td>
+ <input type="text" maxlength="3" size="3" class="formfld unknown"
+ name="thermal_sensors_widget_core_warning_threshold"
+ id="thermal_sensors_widget_core_warning_threshold"
+ value="<?= $thermal_sensors_widget_coreWarningTempThreshold ?>" />
+ </td>
+ <td align="right">
+ <label for="thermal_sensors_widget_pulsate_warning">Pulsate Warning: </label>
+ <input type="checkbox"
+ id="thermal_sensors_widget_pulsate_warning"
+ name="thermal_sensors_widget_pulsate_warning"
+ value="<?= $thermal_sensors_widget_pulsateWarning; ?>" <?= ($thermal_sensors_widget_pulsateWarning) ? " checked='checked'" : ""; ?> />
+ </td>
+ </tr>
+ <tr>
+ <td align="right">
+ Core Critical:
+ </td>
+ <td>
+ <input type="text" maxlength="3" size="3" class="formfld unknown"
+ name="thermal_sensors_widget_core_critical_threshold"
+ id="thermal_sensors_widget_core_critical_threshold"
+ value="<?= $thermal_sensors_widget_coreCriticalTempThreshold ?>" />
+ </td>
+ <td align="right">
+ <label for="thermal_sensors_widget_pulsate_critical">Pulsate Critical: </label>
+ <input type="checkbox"
+ id="thermal_sensors_widget_pulsate_critical"
+ name="thermal_sensors_widget_pulsate_critical"
+ value="<?= $thermal_sensors_widget_pulsateCritical; ?>" <?= ($thermal_sensors_widget_pulsateCritical) ? " checked='checked'" : ""; ?> />
+ </td>
+ </tr>
+ <tr>
+ <td align="right" colspan="3">
+ <input type="submit" id="thermal_sensors_widget_submit" name="thermal_sensors_widget_submit" class="formbtn" value="Save" />
+ </td>
+ </tr>
+ <tr>
+ <td align="left" colspan="3">
+ <span>* You can configure a proper Thermal Sensor / Module under <br />
+ &nbsp;&nbsp;&nbsp;<a href="system_advanced_misc.php">System &gt; Advanced &gt; Miscellaneous : Thermal Sensors section</a>.</span>
+ </td>
+ </tr>
+ </table>
+ </form>
+</div>
+
+<div style="padding: 5px">
+ <div id="thermalSensorsContainer" class="listr">
+ (Updating...)<br /><br />
+ </div>
+</div>
+
+<!-- needed to display the widget settings menu -->
+<script type="text/javascript">
+//<![CDATA[
+ textlink = jQuery("#thermal_sensors-configure");
+ textlink.css({display: "inline"});
+//]]>
+</script>
diff --git a/src/usr/local/www/widgets/widgets/traffic_graphs.widget.php b/src/usr/local/www/widgets/widgets/traffic_graphs.widget.php
new file mode 100644
index 0000000..2689e32
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/traffic_graphs.widget.php
@@ -0,0 +1,161 @@
+<?php
+/*
+ traffic_graphs.widget.php
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+
+ Copyright 2007 Scott Dale
+ Part of pfSense widgets (https://www.pfsense.org)
+ originally based on m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004-2005 T. Lechat <dev@lechat.org>, Manuel Kasper <mk@neon1.net>
+ and Jonathan Watt <jwatt@jwatt.org>.
+ 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.
+*/
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("pfsense-utils.inc");
+require_once("functions.inc");
+
+$first_time = false;
+if (!is_array($config["widgets"]["trafficgraphs"])) {
+ $first_time = true;
+ $config["widgets"]["trafficgraphs"] = array();
+}
+$a_config = &$config["widgets"]["trafficgraphs"];
+
+if (!is_array($a_config["shown"])) {
+ $a_config["shown"] = array();
+}
+if (!is_array($a_config["shown"]["item"])) {
+ $a_config["shown"]["item"] = array();
+}
+
+$ifdescrs = get_configured_interface_with_descr();
+if (isset($config['ipsec']['enable'])) {
+ $ifdescrs['enc0'] = "IPsec";
+}
+
+if ($_POST) {
+ if (isset($_POST["refreshinterval"])) {
+ $a_config["refreshinterval"] = $_POST["refreshinterval"];
+ }
+ if (isset($_POST["scale_type"])) {
+ $a_config["scale_type"] = $_POST["scale_type"];
+ }
+ $a_config["shown"]["item"] = array();
+ foreach ($ifdescrs as $ifname => $ifdescr) {
+ $state = $_POST["shown"][$ifname];
+ if ($state === "show") {
+ $a_config["shown"]["item"][] = $ifname;
+ }
+ }
+ write_config("Updated traffic graph settings via dashboard.");
+ header("Location: /");
+ exit(0);
+}
+
+$shown = array();
+foreach ($a_config["shown"]["item"] as $if) {
+ $shown[$if] = true;
+}
+if ($first_time) {
+ $keys = array_keys($ifdescrs);
+ $shown[$keys[0]] = true;
+}
+
+if (isset($a_config["refreshinterval"])) {
+ $refreshinterval = $a_config["refreshinterval"];
+} else {
+ $refreshinterval = 10;
+}
+
+if (isset($a_config["scale_type"])) {
+ $scale_type = $a_config["scale_type"];
+} else {
+ $scale_type = "up";
+}
+
+$graphcounter = 0;
+foreach ($ifdescrs as $ifname => $ifdescr):
+ $ifinfo = get_interface_info($ifname);
+ if ($shown[$ifname]) {
+ $mingraphbutton = "inline";
+ $showgraphbutton = "none";
+ $graphdisplay = "inline";
+ $interfacevalue = "show";
+ $graphcounter++;
+ } else {
+ $mingraphbutton = "none";
+ $showgraphbutton = "inline";
+ $graphdisplay = "none";
+ $interfacevalue = "hide";
+ }
+ if ($ifinfo['status'] != "down"):
+?>
+ <div style="display:<?=$graphdisplay?>">
+ <object data="graph.php?ifnum=<?=$ifname?>&amp;ifname=<?=rawurlencode($ifdescr)?>&amp;timeint=<?=$refreshinterval?>&amp;initdelay=<?=$graphcounter * 2?>">
+ <param name="id" value="graph" />
+ <param name="type" value="image/svg+xml" />
+ <param name="pluginspage" value="http://www.adobe.com/svg/viewer/install/auto" />
+ </object>
+ </div>
+<?php endif; ?>
+<?php endforeach; ?>
+
+<!-- close the body we're wrapped in and add a configuration-panel -->
+</div><div class="panel-footer collapse">
+
+<form action="/widgets/widgets/traffic_graphs.widget.php" method="post" class="form-horizontal">
+ <?php foreach ($ifdescrs as $ifname => $ifdescr): ?>
+ <input type="hidden" name="shown[<?= $ifname?>]" value="<?= $shown[$ifname] ? "show" : "hide"?>" />
+ <?php endforeach; ?>
+ <div class="form-group">
+ <label for="scale_type_up" class="col-sm-3 control-label">Default Autoscale</label>
+ <div class="col-sm-6 checkbox">
+ <label>
+ <input name="scale_type" type="radio" id="scale_type_up" value="up" <?=($config["widgets"]["trafficgraphs"]["scale_type"]=="follow" ? '' : 'checked="checked"')?> />
+ up
+ </label>
+ <label>
+ <input name="scale_type" type="radio" id="scale_type_follow" value="up" <?=($config["widgets"]["trafficgraphs"]["scale_type"]=="follow" ? 'checked="checked"' : '')?> />
+ follow
+ </label>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="refreshinterval" class="col-sm-3 control-label">Refresh Interval</label>
+ <div class="col-sm-6">
+ <input type="number" name="refreshinterval" value="<?=$refreshinterval?>" min="1" max="30" class="form-control" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="col-sm-offset-3 col-sm-6">
+ <button type="submit" class="btn btn-default">Save</button>
+ </div>
+ </div>
+</form> \ No newline at end of file
diff --git a/src/usr/local/www/widgets/widgets/wake_on_lan.widget.php b/src/usr/local/www/widgets/widgets/wake_on_lan.widget.php
new file mode 100644
index 0000000..5715044
--- /dev/null
+++ b/src/usr/local/www/widgets/widgets/wake_on_lan.widget.php
@@ -0,0 +1,80 @@
+<?php
+/*
+ wake_on_lan.widget.php
+ Copyright (C) 2013-2015 Electric Sheep Fencing, LP
+
+ Copyright (C) 2010 Yehuda Katz
+
+ 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.
+*/
+
+$nocsrf = true;
+
+require_once("guiconfig.inc");
+require_once("/usr/local/www/widgets/include/wake_on_lan.inc");
+
+if (is_array($config['wol']['wolentry'])) {
+ $wolcomputers = $config['wol']['wolentry'];
+} else {
+ $wolcomputers = array();
+}
+
+?>
+<table>
+ <tr>
+ <?php
+ echo '<td class="widgetsubheader" align="center">' . gettext("Computer / Device") . '</td>';
+ echo '<td class="widgetsubheader" align="center">' . gettext("Interface") . '</td>';
+ echo '<td class="widgetsubheader" align="center">' . gettext("Status") . '</td>';
+ ?>
+ <td class="widgetsubheader">&nbsp;</td>
+ </tr>
+<?php
+
+if (count($wolcomputers) > 0) {
+ foreach($wolcomputers as $wolent) {
+ echo '<tr><td class="listlr">' . $wolent['descr'] . '<br />' . $wolent['mac'] . '</td>' . "\n";
+ echo '<td class="listr">' . convert_friendly_interface_to_friendly_descr($wolent['interface']) . '</td>' . "\n";
+
+ $is_active = exec("/usr/sbin/arp -an |/usr/bin/grep {$wolent['mac']}| /usr/bin/wc -l|/usr/bin/awk '{print $1;}'");
+ if($is_active == 1) {
+ echo '<td class="listr" align="center">' . "\n";
+ echo "<img src=\"/themes/" . $g["theme"] . "/images/icons/icon_pass.gif\" alt=\"pass\" /> " . gettext("Online") . "</td>\n";
+ } else {
+ echo '<td class="listbg" align="center">' . "\n";
+ echo "<img src=\"/themes/" . $g["theme"] . "/images/icons/icon_block.gif\" alt=\"block\" />&nbsp;<font color=\"white\">" . gettext("Offline") . "</font></td>\n";
+ }
+ echo '<td valign="middle" class="list nowrap">';
+ /*if($is_active) { */
+ /* Will always show wake-up button even if pfsense thinks it is awake */
+ /* } else { */
+ echo "<a href='services_wol.php?mac={$wolent['mac']}&amp;if={$wolent['interface']}'> ";
+ echo "<img title='" . gettext("Wake Up") . "' border='0' src='./themes/".$g['theme']."/images/icons/icon_wol_all.gif' alt='wol' /></a>\n";
+ /* } */
+ echo "</td></tr>\n";
+ }
+} else {
+ echo "<tr><td colspan=\"4\" align=\"center\">" . gettext("No saved WoL addresses") . ".</td></tr>\n";
+}
+?>
+</table>
+<center><a href="status_dhcp_leases.php" class="navlink">DHCP Leases Status</a></center>
OpenPOWER on IntegriCloud