diff options
Diffstat (limited to 'src/usr/local/www/widgets/widgets')
22 files changed, 4083 insertions, 0 deletions
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..21c44e3 --- /dev/null +++ b/src/usr/local/www/widgets/widgets/captive_portal_status.widget.php @@ -0,0 +1,146 @@ +<?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="sortable" id="sortabletable" width="100%" border="0" cellpadding="0" cellspacing="0" summary="captive portal status"> + <tr> + <td class="listhdrr"><a href="?order=ip&showact=<?=$showact;?>">IP address</a></td> + <td class="listhdrr"><a href="?order=mac&showact=<?=$showact;?>">MAC address</a></td> + <td class="listhdrr"><a href="?order=user&showact=<?=$showact;?>"><?=gettext("Username");?></a></td> +<?php + if ($showact == 1): +?> + <td class="listhdrr"><a href="?order=start&showact=<?=$showact;?>"><?=gettext("Session start");?></a></td> + <td class="listhdrr"><a href="?order=start&showact=<?=$showact;?>"><?=gettext("Last activity");?></a></td> +<?php + endif; +?> + </tr> +<?php +foreach ($cpdb_all as $cpent): +?> + <tr> + <td class="listlr"><?=$cpent[2];?></td> + <td class="listr"><?=$cpent[3];?> </td> + <td class="listr"><?=$cpent[4];?> </td> +<?php + if ($showact == 1): +?> + <td class="listr"><?=htmlspecialchars(date("m/d/Y H:i:s", $cpent[0]));?></td> + <td class="listr"><?php if ($cpent[11] && ($cpent[11] > 0)) echo htmlspecialchars(date("m/d/Y H:i:s", $cpent[11]));?></td> +<?php + endif; +?> + <td valign="middle" class="list nowrap"> + <a href="?order=<?=htmlspecialchars($_GET['order']);?>&showact=<?=$showact;?>&act=del&zone=<?=$cpent[10];?>&id=<?=$cpent[5];?>" onclick="return confirm('Do you really want to disconnect this client?')"> + <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0" alt="x" /> + </a> + </td> + </tr> +<?php +endforeach; +?> +</table> 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..bb68dbd --- /dev/null +++ b/src/usr/local/www/widgets/widgets/carp_status.widget.php @@ -0,0 +1,85 @@ +<?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 bgcolor="#990000" width="100%" border="0" cellspacing="0" cellpadding="0" summary="carp status"> +<?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 class="vncellt" width="35%"> + <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_cablenic.gif" alt="cablenic" /> + <strong><a href="/system_hasync.php"> + <span style="color:#000000"><?=htmlspecialchars(convert_friendly_interface_to_friendly_descr($carp['interface']) . "@{$vhid}");?></span></a></strong> + </td> + <td width="65%" class="listr"> +<?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){ ?> + <?=htmlspecialchars($status);?> + <?=htmlspecialchars($ipaddress);}?> +</td></tr><?php } + } else { ?> + <tr><td class="listr">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..c2eee76 --- /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 width="100%" border="0" cellpadding="0" cellspacing="0"> + <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<?php echo $i; ?>'><?php echo 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..26a6f4d --- /dev/null +++ b/src/usr/local/www/widgets/widgets/gateways.widget.php @@ -0,0 +1,227 @@ +<?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); + +$counter = 1; + +?> + +<input type="hidden" id="gateways-config" name="gateways-config" value="" /> + +<div id="gateways-settings" class="widgetconfigdiv" style="display:none;"> +<form action="/widgets/widgets/gateways.widget.php" method="post" name="gateways_widget_iform" id="gateways_widget_iform"> + Display: + <?php + $display_type_gw_ip="checked=\"checked\""; + $display_type_monitor_ip=""; + $display_type_both_ip=""; + if (isset($config["widgets"]["gateways_widget"]["display_type"])) { + $selected_radio = $config["widgets"]["gateways_widget"]["display_type"]; + if ($selected_radio == "gw_ip") { + $display_type_gw_ip = "checked=\"checked\""; + $display_type_monitor_ip=""; + $display_type_both_ip=""; + } else if ($selected_radio == "monitor_ip") { + $display_type_gw_ip = ""; + $display_type_monitor_ip="checked=\"checked\""; + $display_type_both_ip=""; + } else if ($selected_radio == "both_ip") { + $display_type_gw_ip = ""; + $display_type_monitor_ip=""; + $display_type_both_ip="checked=\"checked\""; + } + } + ?> + <input name="display_type" class="radio" type="radio" id="display_type_gw_ip" value="gw_ip" <?php echo $display_type_gw_ip; ?> onchange="updateGatewayDisplays();" /> <span>Gateway IP</span> + <input name="display_type" class="radio" type="radio" id="display_type_monitor_ip" value="monitor_ip" <?php echo $display_type_monitor_ip; ?> onchange="updateGatewayDisplays();" /> <span>Monitor IP</span> + <input name="display_type" class="radio" type="radio" id="display_type_both_ip" value="both_ip" <?php echo $display_type_both_ip; ?> onchange="updateGatewayDisplays();" /> <span>Both</span> + <br /><br /> + <input id="submit_settings" name="submit_settings" type="submit" onclick="return updatePref();" class="formbtn" value="Save Settings" /> +</form> +</div> + +<script type="text/javascript"> +//<![CDATA[ + d = document; + selectIntLink = "gateways-configure"; + textlink = d.getElementById(selectIntLink); + textlink.style.display = "inline"; +//]]> +</script> + +<table bgcolor="#990000" width="100%" border="0" cellspacing="0" cellpadding="0" summary="gateway status"> + <tr> + <td class="listhdrr" id="gatewayname" align="center">Name</td> + <td class="listhdrr" align="center">RTT</td> + <td class="listhdrr" align="center">Loss</td> + <td class="listhdrr" align="center">Status</td> + </tr> + <?php foreach ($a_gateways as $gname => $gateway) { ?> + <tr> + <td class="listhdrr" id="gateway<?php echo $counter; ?>" rowspan="2" align="center"> + <strong> + <?php echo htmlspecialchars($gateway['name']); ?> + </strong> + <?php $counter++; ?> + </td> + <td colspan="3" class="listr ellipsis" align="center"> + <div id="gateway<?php echo $counter; ?>" style="display:inline"><b> + <?php + $monitor_address = ""; + $monitor_address_disp = ""; + if ($display_type == "monitor_ip" || $display_type == "both_ip") { + $monitor_address = $gateway['monitor']; + if ($monitor_address != "" && $display_type == "both_ip") { + $monitor_address_disp = " (" . $monitor_address . ")"; + } else { + $monitor_address_disp = $monitor_address; + } + } + $if_gw = ''; + // If the user asked to display Gateway IP or both IPs, or asked for just monitor IP but the monitor IP is blank + // then find the gateway IP (which is also the monitor IP if the monitor IP was not explicitly set). + if ($display_type == "gw_ip" || $display_type == "both_ip" || ($display_type == "monitor_ip" && $monitor_address == "")) { + if (is_ipaddr($gateway['gateway'])) { + $if_gw = htmlspecialchars($gateway['gateway']); + } else { + if ($gateway['ipprotocol'] == "inet") { + $if_gw = htmlspecialchars(get_interface_gateway($gateway['friendlyiface'])); + } + if ($gateway['ipprotocol'] == "inet6") { + $if_gw = htmlspecialchars(get_interface_gateway_v6($gateway['friendlyiface'])); + } + } + if ($if_gw == "") { + $if_gw = "~"; + } + } + if ($monitor_address == $if_gw) { + $monitor_address_disp = ""; + } + echo $if_gw . $monitor_address_disp; + unset ($if_gw); + unset ($monitor_address); + unset ($monitor_address_disp); + $counter++; + ?> + </b></div> + </td> + </tr> + <tr> + <td class="listr ellipsis" align="center" id="gateway<?php echo $counter; ?>"> + <?php + if ($gateways_status[$gname]) { + echo htmlspecialchars($gateways_status[$gname]['delay']); + } else { + echo gettext("Pending"); + } + ?> + <?php $counter++; ?> + </td> + <td class="listr ellipsis" align="center" id="gateway<?php echo $counter; ?>"> + <?php + if ($gateways_status[$gname]) { + echo htmlspecialchars($gateways_status[$gname]['loss']); + } else { + echo gettext("Pending"); + } + ?> + <?php $counter++; ?> + </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 + } + echo "<td class=\"listr ellipsis\" align=\"center\" id=\"gateway$counter\">$online</td>\n"; + ?> + <td style="display:none;"> + <script type="text/javascript"> + //<![CDATA[ + jQuery('#gateway<?php echo $counter;?>').css('background-color',"<?php echo $bgcolor;?>"); + //]]> + </script> + </td> + <?php + $counter++; + ?> + </tr> + <?php } // foreach ?> +</table> 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..59e7f16 --- /dev/null +++ b/src/usr/local/www/widgets/widgets/gmirror_status.widget.php @@ -0,0 +1,52 @@ +<?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"); + +if ($_GET['textonly'] == "true") { + header("Cache-Control: no-cache"); + echo gmirror_html_status(); + exit; +} +?> +<table width="100%" border="0" cellspacing="0" cellpadding="0" summary="gmirror status"> + <tbody id="gmirror_status_table"> + <?php echo gmirror_html_status(); ?> + </tbody> +</table> + +<script type="text/javascript"> +//<![CDATA[ + var gmirrorupdater = new Ajax.PeriodicalUpdater('gmirror_status_table', '/widgets/widgets/gmirror_status.widget.php?textonly=true', + { method: 'get', frequency: 5 } ); +//]]> +</script> 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..3190e1b --- /dev/null +++ b/src/usr/local/www/widgets/widgets/installed_packages.widget.php @@ -0,0 +1,126 @@ +<?php +/* + installed_packages.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/installed_packages.inc"); +require_once("pkg-utils.inc"); + +if (is_array($config['installedpackages']['package'])) { + foreach ($config['installedpackages']['package'] as $instpkg) { + $tocheck[] = $instpkg['name']; + } + $currentvers = get_pkg_info($tocheck, array('version', 'xmlver')); +} + +$updateavailable = false; +?> + +<table width="100%" border="0" cellpadding="6" cellspacing="0" summary="installed packages"> + <tr> + <td width="15%" class="listhdrr">Package Name</td> + <td width="15%" class="listhdrr">Category</td> + <td width="30%" class="listhdrr">Package Version</td> + </tr> + <?php + if ($config['installedpackages']['package'] != "") { + $instpkgs = array(); + foreach ($config['installedpackages']['package'] as $instpkg) { + $instpkgs[] = $instpkg['name']; + } + natcasesort($instpkgs); + $y=1; + foreach ($instpkgs as $index => $pkgname){ + + $pkg = $config['installedpackages']['package'][$index]; + if ($pkg['name'] <> "") { ?> + <tr valign="top"> + <td class="listlr"> + <?= $pkg['name'] ?> + </td> + <td class="listr"> + <?= $pkg['category'] ?> + </td> + <td class="listr"> + <?php + $latest_package = $currentvers[$pkg['name']]['version']; + if ($latest_package == false) { + // We can't determine this package's version status. + echo "Current: Unknown.<br />Installed: " . $pkg['version']; + } elseif (strcmp($pkg['version'], $latest_package) > 0) { + /* we're running a newer version of the package */ + echo "Current: {$latest_package}"; + echo "<br />Installed: {$pkg['version']}"; + } elseif (strcmp($pkg['version'], $latest_package) < 0) { + /* our package is out of date */ + $updateavailable = true; + ?> + <div id="updatediv-<?php echo $y; ?>" style="color:red"> + <b>Update Available!</b></div><div style="float:left"> + Current: <?php echo $latest_package; ?><br /> + Installed: <?php echo $pkg['version']; ?></div><div style="float:right"> + <a href="pkg_mgr_install.php?mode=reinstallpkg&pkg=<?= $pkg['name']; ?>"><img title="Update this package." src="./themes/<?= $g['theme']; ?>/images/icons/icon_reinstall_pkg.gif" width="17" height="17" border="0" alt="reinstall" /></a> + </div> + <?php + $y++; + } else { + echo $pkg['version']; + } ?> + </td> + </tr> + <?php } + } + } else { + echo "<tr><td colspan=\"5\" align=\"center\">There are no packages currently installed.</td></tr>"; + } + ?> +</table> + +<?php if ($updateavailable): ?> +<script type="text/javascript"> +//<![CDATA[ + window.onload = function(in_event) + { + for (y=1; y<=<?php echo $y;?>; y++) { + textID = "#updatediv-" + y; + jQuery(textID).effect('pulsate'); + } + } +//]]> +</script> +<?php endif; ?> 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..a124ea3 --- /dev/null +++ b/src/usr/local/www/widgets/widgets/interface_statistics.widget.php @@ -0,0 +1,216 @@ +<?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"); + +$ifdescrs = get_configured_interface_with_descr(); + +$array_in_packets = array(); +$array_out_packets = array(); +$array_in_bytes = array(); +$array_out_bytes = array(); +$array_in_errors = array(); +$array_out_errors = array(); +$array_collisions = array(); +$array_interrupt = array(); +$interfacecounter = 0; + +//build data arrays +foreach ($ifdescrs as $ifdescr => $ifname) { + $ifinfo = get_interface_info($ifdescr); + $interfacecounter++; + if ($ifinfo['status'] != "down") { + $array_in_packets[] = $ifinfo['inpkts']; + $array_out_packets[] = $ifinfo['outpkts']; + $array_in_bytes[] = format_bytes($ifinfo['inbytes']); + $array_out_bytes[] = format_bytes($ifinfo['outbytes']); + if (isset($ifinfo['inerrs'])) { + $array_in_errors[] = $ifinfo['inerrs']; + $array_out_errors[] = $ifinfo['outerrs']; + } else { + $array_in_errors[] = "n/a"; + $array_out_errors[] = "n/a"; + } + if (isset($ifinfo['collisions'])) { + $array_collisions[] = htmlspecialchars($ifinfo['collisions']); + } else { + $array_collisions[] = "n/a"; + } + } +} //end for + + + + +?> + <div id="int_labels" style="float:left;width:32%"> + <table width="100%" border="0" cellspacing="0" cellpadding="0" summary="interfaces statistics"> + <tr> + <td class="widgetsubheader" style="height:25px"> </td> + </tr> + <tr> + <td class="vncellt" style="height:25px">Packets In</td> + </tr> + <tr> + <td class="vncellt" style="height:25px">Packets Out</td> + </tr> + <tr> + <td class="vncellt" style="height:25px">Bytes In</td> + </tr> + <tr> + <td class="vncellt" style="height:25px">Bytes Out</td> + </tr> + <tr> + <td class="vncellt" style="height:25px">Errors In</td> + </tr> + <tr> + <td class="vncellt" style="height:25px">Errors Out</td> + </tr> + <tr> + <td class="vncellt" style="height:25px">Collisions</td> + </tr> + </table> + </div> + <div id="interfacestats" style="float:right;overflow: auto; width:68%"> + <table width="100%" border="0" cellspacing="0" cellpadding="0" summary="the stats"> + <tr> + <?php + $interface_names = array(); + foreach ($ifdescrs as $ifdescr => $ifname): + $ifinfo = get_interface_info($ifdescr); + if ($ifinfo['status'] != "down") { ?> + <td class="widgetsubheader nowrap" style="height:25px"> + <?=htmlspecialchars($ifname);?> + </td> + <?php + //build array of interface names + $interface_names[] = $ifname; + } + endforeach; + ?> + </tr> + + <tr> + <?php + $counter = 1; + foreach ($array_in_packets as $data): + ?> + <td class="listr nowrap" id="stat<?php echo $counter?>" style="height:25px"> + <?=htmlspecialchars($data);?> + </td> + <?php + $counter = $counter + 7; + endforeach; + ?> + </tr> + + <tr> + <?php + $counter = 2; + foreach ($array_out_packets as $data): ?> + <td class="listr nowrap" id="stat<?php echo $counter;?>" style="height:25px"> + <?=htmlspecialchars($data);?> + </td> + <?php + $counter = $counter + 7; + endforeach; ?> + </tr> + + <tr> + <?php + $counter = 3; + foreach ($array_in_bytes as $data): ?> + <td class="listr nowrap" id="stat<?php echo $counter;?>" style="height:25px"> + <?=htmlspecialchars($data);?> + </td> + <?php + $counter = $counter + 7; + endforeach; ?> + </tr> + + <tr> + <?php + $counter = 4; + foreach ($array_out_bytes as $data): ?> + <td class="listr nowrap" id="stat<?php echo $counter;?>" style="height:25px"> + <?=htmlspecialchars($data);?> + </td> + <?php + $counter = $counter + 7; + endforeach; ?> + </tr> + + <tr> + <?php + $counter = 5; + foreach ($array_in_errors as $data): ?> + <td class="listr nowrap" id="stat<?php echo $counter;?>" style="height:25px"> + <?=htmlspecialchars($data);?> + </td> + <?php + $counter = $counter + 7; + endforeach; ?> + </tr> + + <tr> + <?php + $counter = 6; + foreach ($array_out_errors as $data): ?> + <td class="listr nowrap" id="stat<?php echo $counter;?>" style="height:25px"> + <?=htmlspecialchars($data);?> + </td> + <?php + $counter = $counter + 7; + endforeach; ?> + </tr> + + <tr> + <?php + $counter = 7; + foreach ($array_collisions as $data): ?> + <td class="listr nowrap" id="stat<?php echo $counter;?>" style="height:25px"> + <?=htmlspecialchars($data);?> + </td> + <?php + $counter = $counter + 7; + endforeach; ?> + </tr> + </table> + </div> 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..e49a030 --- /dev/null +++ b/src/usr/local/www/widgets/widgets/interfaces.widget.php @@ -0,0 +1,126 @@ +<?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 bgcolor="#990000" width="100%" border="0" cellspacing="0" cellpadding="0" summary="interfaces"> +<?php +foreach ($ifdescrs as $ifdescr => $ifname): + $ifinfo = get_interface_info($ifdescr); + + if ($ifinfo['ppplink']) { + $icon = '3g'; + } 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 class="vncellt" rowspan="2"> + <span onclick="location.href='/interfaces.php?if=<?=$ifdescr; ?>'" style="cursor:pointer; white-space:nowrap"> + <img src="./themes/<?=$g['theme'];?>/images/icons/icon_<?=$icon;?>.gif" alt="<?=$icon;?>" /> + <u><?=htmlspecialchars($ifname);?></u> + </span> +<?php + if ($ifinfo['dhcplink']) { + echo "<br />(DHCP)"; + } +?> + </td> +<?php + if ($known_status): +?> + <td rowspan="2" class="listr" align="center"> + <div id="<?php echo $ifname . "-up";?>" style="display:<?=$up_display;?>" > + <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_interface_up.gif" title="<?=$ifname;?> is up" alt="up" /> + </div> + <div id="<?php echo $ifname . "-down";?>" style="display:<?=$down_display;?>" > + <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_interface_down.gif" title="<?=$ifname;?> is down" alt="down" /> + </div> + <div id="<?php echo $ifname . "-block";?>" style="display:<?=$block_display;?>" > + <img src="./themes/<?= $g['theme']; ?>/images/icons/icon_block.gif" title="<?=$ifname;?> is disabled" alt="block" /> + </div> + </td> +<?php + else: + echo htmlspecialchars($ifinfo['status']); + endif; +?> + <td class="listr"> + <div id="<?php echo $ifname;?>-media" style="display:inline"><?=htmlspecialchars($ifinfo['media']);?></div> + </td> + </tr> + <tr> + <td class="listr"> + <div id="<?php echo $ifname;?>-ip" style="display:inline"><strong><?=htmlspecialchars($ifinfo['ipaddr']);?> </strong><?php if ($ifinfo['ipaddr']) echo "<br />";?></div> + <div id="<?php echo $ifname;?>-ipv6" style="display:inline"><strong><?=htmlspecialchars($ifinfo['ipaddrv6']);?> </strong></div> + </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..49250ce --- /dev/null +++ b/src/usr/local/www/widgets/widgets/ipsec.widget.php @@ -0,0 +1,265 @@ +<?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'])) { +?> + <div> </div> +<?php + $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'])) { +?> + +<div id="ipsec-Overview" style="display:block;background-color:#EEEEEE;"> + <div> + <table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0" summary="heading"> + <tr> + <td class="listhdrr nowrap">Active Tunnels</td> + <td class="listhdrr nowrap">Inactive Tunnels</td> + <td class="listhdrr nowrap">Mobile Users</td> + </tr> + <tr> + <td class="listlr"><?php echo $activecounter; ?></td> + <td class="listr"><?php echo $inactivecounter; ?></td> + <td class="listr"><?php if (is_array($mobile['pool'])) echo htmlspecialchars($mobile['pool'][0]['usage']); else echo 0; ?></td> + </tr> + </table> + </div> +</div> + +<div id="ipsec-tunnel" style="display:none;background-color:#EEEEEE;"> + <div style="padding: 10px"> + <div style="display:table-row;"> + <div class="widgetsubheader" style="display:table-cell;width:40px">Source</div> + <div class="widgetsubheader" style="display:table-cell;width:100px">Destination</div> + <div class="widgetsubheader" style="display:table-cell;width:90px">Description</div> + <div class="widgetsubheader" style="display:table-cell;width:30px">Status</div> + </div> + <div style="max-height:105px;overflow:auto;"> + + <?php + foreach ($ipsec_detail_array as $ipsec) : + ?> + + <div style="display:table-row;"> + <div class="listlr" style="display:table-cell;width:39px"> + <?php echo htmlspecialchars($ipsec['src']);?> + </div> + <div class="listr" style="display:table-cell;width:100px"> + <?php echo $ipsec['remote-subnet'];?> + <br /> + (<?php echo htmlspecialchars($ipsec['dest']);?>) + </div> + <div class="listr" style="display:table-cell;width:90px"> + <?php echo htmlspecialchars($ipsec['descr']);?> + </div> + <div class="listr" style="display:table-cell;width:37px" align="center"> + <?php + if ($ipsec['status'] == "true") { + /* 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='Tunnel status' width='11' height='11' />"; + ?> + </div> + </div> + <?php + endforeach; + ?> + </div> + </div> +</div> +<div id="ipsec-mobile" style="display:none;background-color:#EEEEEE;"> + <div style="padding: 10px"> + <div style="display:table-row;"> + <div class="widgetsubheader" style="display:table-cell;width:140px">User</div> + <div class="widgetsubheader" style="display:table-cell;width:130px">IP</div> + <div class="widgetsubheader" style="display:table-cell;width:30px">Status</div> + </div> + <div style="max-height:105px;overflow:auto;"> +<?php + if (is_array($mobile['pool'])): + foreach ($mobile['pool'] as $pool): + if (is_array($pool['lease'])): + foreach ($pool['lease'] as $muser) : +?> + <div style="display:table-row;"> + <div class="listlr" style="display:table-cell;width:139px"> + <?php echo htmlspecialchars($muser['id']);?><br /> + </div> + <div class="listr" style="display:table-cell;width:130px"> + <?php echo htmlspecialchars($muser['host']);?><br /> + </div> + <div class="listr" style="display:table-cell;width:30px"> + <?php echo htmlspecialchars($muser['status']);?><br/> + </div> + </div> +<?php + endforeach; + endif; + endforeach; + endif; +?> + </div> + </div> +</div> +<?php // end if tunnels are configured, else show code below +} else { +?> +<div style="display:block"> + <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0" summary="note"> + <tr> + <td colspan="4"> + <span class="vexpl"> + <span class="red"> + <strong> + Note: There are no configured IPsec Tunnels<br /> + </strong> + </span> + You can configure your IPsec <a href="vpn_ipsec.php">here</a>. + </span> + </td> + </tr> + </table> +</div> +<?php +} +?> 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..f5ddda9 --- /dev/null +++ b/src/usr/local/www/widgets/widgets/load_balancer_status.widget.php @@ -0,0 +1,155 @@ +<?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 bgcolor="#990000" width="100%" border="0" cellspacing="0" cellpadding="0" summary="load balancer"> + <tr> + <td width="10%" class="listhdrr">Server</td> + <td width="10%" class="listhdrr">Pool</td> + <td width="30%" class="listhdr">Description</td> + </tr> +<?php +$i = 0; +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 class="listlr"> + <?=$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 class="listr" align="center" > + <table border="0" cellpadding="0" cellspacing="2" summary="status"> + <?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 ($server['ip']['addr']!="") { + 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"; + } + echo "<tr>"; + echo "<td bgcolor=\"{$bgcolor}\"> {$server['ip']['addr']}:{$pool['port']} </td><td bgcolor=\"{$bgcolor}\"> "; + if ($server['ip']['avail']) { + echo " ({$server['ip']['avail']}) "; + } + echo " </td></tr>"; + } + } + } + } + ?> + </table> + </td> + <td class="listbg" > + <font color="#FFFFFF"><?=$vsent['descr'];?></font> + </td> + </tr> +<?php + $i++; +endforeach; +?> +</table> 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..45205a4 --- /dev/null +++ b/src/usr/local/www/widgets/widgets/log.widget.php @@ -0,0 +1,281 @@ +<?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"; +$filterlog = conv_log_filter($filter_logfile, $nentries, 50, $filterfieldsarray); //Get log entries + +/* AJAX related routines */ +handle_ajax($nentries, $nentries + 20); + +?> + +<script type="text/javascript"> +//<![CDATA[ +lastsawtime = '<?php echo time(); ?>'; +var lines = Array(); +var timer; +var updateDelay = 30000; +var isBusy = false; +var isPaused = false; +var nentries = <?php echo $nentries; ?>; + +<?php +if (isset($config['syslog']['reverse'])) { + echo "var isReverse = true;\n"; +} else { + echo "var isReverse = false;\n"; +} +?> + +/* Called by the AJAX updater */ +function format_log_line(row) { + var rrText = "<?php echo gettext("Reverse Resolve with DNS"); ?>"; + + if (row[8] == '6') { + srcIP = '[' + row[3] + ']'; + dstIP = '[' + row[5] + ']'; + } else { + srcIP = row[3]; + dstIP = row[5]; + } + + if (row[4] == '') { + srcPort = ''; + } else { + srcPort = ':' + row[4]; + } + if (row[6] == '') { + dstPort = ''; + } else { + dstPort = ':' + row[6]; + } + + var line = '<td class="listMRlr" align="center">' + row[0] + '</td>' + + '<td class="listMRr ellipsis" title="' + row[1] + '">' + row[1].slice(0,-3) + '</td>' + + '<td class="listMRr ellipsis" title="' + row[2] + '">' + row[2] + '</td>' + + '<td class="listMRr ellipsis" title="' + srcIP + srcPort + '"><a href="diag_dns.php?host=' + row[3] + '" title="' + rrText + '">' + srcIP + '</a></td>' + + '<td class="listMRr ellipsis" title="' + dstIP + dstPort + '"><a href="diag_dns.php?host=' + row[5] + '" title="' + rrText + '">' + dstIP + '</a>' + dstPort + '</td>'; + + var nentriesacts = "<?php echo $nentriesacts; ?>"; + var nentriesinterfaces = "<?php echo $nentriesinterfaces; ?>"; + + var Action = row[0].match(/alt=.*?(pass|block|reject)/i).join("").match(/pass|block|reject/i).join(""); + var Interface = row[2]; + + if (!(in_arrayi(Action, nentriesacts.replace (/\s+/g, ',').split(','))) && (nentriesacts != 'All')) { + return false; + } + if (!(in_arrayi(Interface, nentriesinterfaces.replace(/\s+/g, ',').split(','))) && (nentriesinterfaces != 'All')) { + return false; + } + + return line; +} +//]]> +</script> +<script src="/javascript/filter_log.js" type="text/javascript"></script> +<input type="hidden" id="log-config" name="log-config" value="" /> + +<div id="log-settings" class="widgetconfigdiv" style="display:none;"> + <form action="/widgets/widgets/log.widget.php" method="post" name="log_widget_iform"> + Number of lines to display: + <select name="filterlogentries" class="formfld unknown" id="filterlogentries"> + <?php for ($i = 1; $i <= 20; $i++) { ?> + <option value="<?php echo $i;?>" <?php if ($nentries == $i) echo "selected=\"selected\"";?>><?php echo $i;?></option> + <?php } ?> + </select> + +<?php + $Include_Act = explode(" ", $nentriesacts); + if ($nentriesinterfaces == "All") { + $nentriesinterfaces = ""; + } +?> + <input id="actpass" name="actpass" type="checkbox" value="Pass" <?php if (in_arrayi('Pass', $Include_Act)) echo "checked=\"checked\""; ?> /> Pass + <input id="actblock" name="actblock" type="checkbox" value="Block" <?php if (in_arrayi('Block', $Include_Act)) echo "checked=\"checked\""; ?> /> Block + <input id="actreject" name="actreject" type="checkbox" value="Reject" <?php if (in_arrayi('Reject', $Include_Act)) echo "checked=\"checked\""; ?> /> Reject + <br /> + Interfaces: + <select id="filterlogentriesinterfaces" name="filterlogentriesinterfaces" class="formselect"> + <option value="All">ALL</option> +<?php + $interfaces = get_configured_interface_with_descr(); + foreach ($interfaces as $iface => $ifacename): +?> + <option value="<?=$iface;?>" <?php if ($nentriesinterfaces == $iface) echo "selected=\"selected\"";?>> + <?=htmlspecialchars($ifacename);?> + </option> +<?php + endforeach; + unset($interfaces); + unset($Include_Act); +?> + </select> + + <input id="log_widget_submit" name="log_widget_submit" type="submit" class="formbtn" value="Save" /> + </form> +</div> + +<table width="100%" border="0" cellpadding="0" cellspacing="0" style="table-layout: fixed;" summary="logs"> + <colgroup> + <col style='width: 7%;' /> + <col style='width: 23%;' /> + <col style='width: 11%;' /> + <col style='width: 28%;' /> + <col style='width: 31%;' /> + </colgroup> + <thead> + <tr> + <td class="listhdrr"><?=gettext("Act");?></td> + <td class="listhdrr"><?=gettext("Time");?></td> + <td class="listhdrr"><?=gettext("IF");?></td> + <td class="listhdrr"><?=gettext("Source");?></td> + <td class="listhdrr"><?=gettext("Destination");?></td> + </tr> + </thead> + <tbody id='filter-log-entries'> + <?php + $rowIndex = 0; + foreach ($filterlog as $filterent): + $evenRowClass = $rowIndex % 2 ? " listMReven" : " listMRodd"; + $rowIndex++; + if ($filterent['version'] == '6') { + $srcIP = "[" . htmlspecialchars($filterent['srcip']) . "]"; + $dstIP = "[" . htmlspecialchars($filterent['dstip']) . "]"; + } else { + $srcIP = htmlspecialchars($filterent['srcip']); + $dstIP = htmlspecialchars($filterent['dstip']); + } + + if ($filterent['srcport']) { + $srcPort = ":" . htmlspecialchars($filterent['srcport']); + } else { + $srcPort = ""; + } + + if ($filterent['dstport']) { + $dstPort = ":" . htmlspecialchars($filterent['dstport']); + } else { + $dstPort = ""; + } + + ?> + <tr class="<?=$evenRowClass?>"> + <td class="listMRlr nowrap" align="center"> + <a href="#" onclick="javascript:getURL('diag_logs_filter.php?getrulenum=<?php echo "{$filterent['rulenum']},{$filterent['tracker']},{$filterent['act']}"; ?>', outputrule);"> + <img border="0" src="<?php echo find_action_image($filterent['act']);?>" width="11" height="11" alt="<?php echo $filterent['act'];?>" title="<?php echo $filterent['act'];?>" /> + </a> + </td> + <td class="listMRr ellipsis nowrap" title="<?php echo htmlspecialchars($filterent['time']);?>"><?php echo substr(htmlspecialchars($filterent['time']),0,-3);?></td> + <td class="listMRr ellipsis nowrap" title="<?php echo htmlspecialchars($filterent['interface']);?>"><?php echo htmlspecialchars($filterent['interface']);?></td> + <td class="listMRr ellipsis nowrap" title="<?php echo $srcIP . $srcPort;?>"> + <a href="diag_dns.php?host=<?php echo "{$filterent['srcip']}"; ?>" title="<?=gettext("Reverse Resolve with DNS");?>"> + <?php echo $srcIP;?></a></td> + <td class="listMRr ellipsis nowrap" title="<?php echo $dstIP . $dstPort;?>"> + <a href="diag_dns.php?host=<?php echo "{$filterent['dstip']}"; ?>" title="<?=gettext("Reverse Resolve with DNS");?>"> + <?php echo $dstIP;?></a><?php echo $dstPort;?></td> + <?php + if ($filterent['proto'] == "TCP") { + $filterent['proto'] .= ":{$filterent['tcpflags']}"; + } + ?> + </tr> + <?php + endforeach; + ?> + </tbody> +</table> + +<!-- needed to display the widget settings menu --> +<script type="text/javascript"> +//<![CDATA[ + selectIntLink = "log-configure"; + textlink = document.getElementById(selectIntLink); + textlink.style.display = "inline"; +//]]> +</script> 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..64522be --- /dev/null +++ b/src/usr/local/www/widgets/widgets/ntp_status.widget.php @@ -0,0 +1,515 @@ +<?php +/* + ntp_status.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/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 width="100%" border="0" cellspacing="0" cellpadding="0" summary="clock"> + <tbody> + <tr> + <td width="40%" class="vncellt">Sync Source</td> + <td width="60%" class="listr"> + <?php if ($ntpq_counter == 0): ?> + No active peers available + <?php else: ?> + <?php echo $syncsource; ?> + <?php endif; ?> + </td> + </tr> + <?php if (($gps_ok) && ($gps_lat) && ($gps_lon)): ?> + <tr> + <td width="40%" class="vncellt">Clock location</td> + <td width="60%" class="listr"> + <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> + <td width="40%" class="vncellt">Satellites</td> + <td width="60%" class="listr"> + <?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; ?> + </tbody> +</table> +<?php + exit; +} + +/*** Clock -- beginning of server-side support code +by Andrew Shearer, http://www.shearersoftware.com/ +v2.1.2-PHP, 2003-08-07. For updates and explanations, see +<http://www.shearersoftware.com/software/web-tools/clock/>. ***/ + +/* Prevent this page from being cached (though some browsers still + cache the page anyway, which is why we use cookies). This is + only important if the cookie is deleted while the page is still + cached (and for ancient browsers that don't know about Cache-Control). + If that's not an issue, you may be able to get away with + "Cache-Control: private" instead. */ + +/* Grab the current server time. */ +$gDate = time(); +/* Are the seconds shown by default? When changing this, also change the + JavaScript client code's definition of clockShowsSeconds below to match. */ +$gClockShowsSeconds = true; + +function getServerDateItems($inDate) { + return date('Y,n,j,G,',$inDate).intval(date('i',$inDate)).','.intval(date('s',$inDate)); + // year (4-digit),month,day,hours (0-23),minutes,seconds + // use intval to strip leading zero from minutes and seconds + // so JavaScript won't try to interpret them in octal + // (use intval instead of ltrim, which translates '00' to '') +} + +function clockDateString($inDate) { + return date('Y. F j l',$inDate); // eg "Monday, January 1, 2002" +} + +function clockTimeString($inDate, $showSeconds) { + return date($showSeconds ? 'G:i:s' : 'g:i',$inDate).' '; +} +/*** Clock -- end of server-side support code ***/ +?> + +<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..6f813c5 --- /dev/null +++ b/src/usr/local/www/widgets/widgets/openvpn.widget.php @@ -0,0 +1,290 @@ +<?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; + $errstr; + + /* 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 style="padding-top:0px; padding-bottom:0px; padding-left:0px; padding-right:0px" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td colspan="6" class="listtopic"> + <?=$server['name'];?> Client connections + </td> + </tr> + <tr> + <td> + <table style="padding-top:0px; padding-bottom:0px; padding-left:0px; padding-right:0px" class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0" sortableMultirow="2"> + <tr> + <td class="listhdrr">Name/Time</td> + <td class="listhdrr">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 style="padding-top:0px; padding-bottom:0px; padding-left:0px; padding-right:0px" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td colspan="6" class="listtopic"> + Peer to Peer Server Instance Statistics + </td> + </tr> + <tr> + <table style="padding-top:0px; padding-bottom:0px; padding-left:0px; padding-right:0px" class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td class="listhdrr">Name/Time</td> + <td class="listhdrr">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 style="padding-top:0px; padding-bottom:0px; padding-left:0px; padding-right:0px" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td colspan="6" class="listtopic"> + Client Instance Statistics + </td> + </tr> + <tr> + <table style="padding-top:0px; padding-bottom:0px; padding-left:0px; padding-right:0px" class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td class="listhdrr">Name/Time</td> + <td class="listhdrr">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..02a002a --- /dev/null +++ b/src/usr/local/www/widgets/widgets/picture.widget.php @@ -0,0 +1,96 @@ +<?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; + } + } +} + +?> + +<input type="hidden" id="picture-config" name="picture-config" value="" /> + +<div id="picture-settings" class="widgetconfigdiv" style="display:none;"> + <form action="/widgets/widgets/picture.widget.php" method="post" name="picture_widget_iform" enctype="multipart/form-data"> + <input name="pictfile" type="file" class="formbtn" id="pictfile" size="20" /> + <input id="picture_widget_submit" name="picture_widget_submit" type="submit" class="formbtn" value="Upload" /> + </form> +</div> + +<div id="picture-widgets" style="padding: 5px"> + <a href='/widgets/widgets/picture.widget.php?getpic=true' target='_blank'> + <img border="0" width="100%" height="100%" src="/widgets/widgets/picture.widget.php?getpic=true" alt="picture" /> + </a> +</div> + +<!-- needed to show the settings widget icon --> +<script type="text/javascript"> +//<![CDATA[ + selectIntLink = "picture-configure"; + textlink = document.getElementById(selectIntLink); + textlink.style.display = "inline"; +//]]> +</script> 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..0850039 --- /dev/null +++ b/src/usr/local/www/widgets/widgets/rss.widget.php @@ -0,0 +1,198 @@ +<?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 = ""; +} + +?> + +<input type="hidden" id="rss-config" name="rss-config" value="" /> + +<div id="rss-settings" class="widgetconfigdiv" style="display:none;"> + <form action="/widgets/widgets/rss.widget.php" method="post" name="rss_widget_iform"> + <textarea name="rssfeed" class="formfld unknown textarea_widget" id="rssfeed" cols="40" rows="3"><?=$textarea_txt;?></textarea> + <br /> + <table summary="rss widget"> + <tr> + <td align="right"> + Display number of items: + </td> + <td> + <select name='rssmaxitems' id='rssmaxitems'> + <option value='<?= $max_items ?>'><?= $max_items ?></option> + <?php + for ($x=100; $x<5100; $x=$x+100) { + echo "<option value='{$x}'>{$x}</option>\n"; + } + ?> + </select> + </td> + </tr> + <tr> + <td align="right"> + Widget height: + </td> + <td> + <select name='rsswidgetheight' id='rsswidgetheight'> + <option value='<?= $rsswidgetheight ?>'><?= $rsswidgetheight ?>px</option> + <?php + for ($x=100; $x<5100; $x=$x+100) { + echo "<option value='{$x}'>{$x}px</option>\n"; + } + ?> + </select> + </td> + </tr> + <tr> + <td align="right"> + Show how many characters from story: + </td> + <td> + <select name='rsswidgettextlength' id='rsswidgettextlength'> + <option value='<?= $rsswidgettextlength ?>'><?= $rsswidgettextlength ?></option> + <?php + for ($x=10; $x<5100; $x=$x+10) { + echo "<option value='{$x}'>{$x}</option>\n"; + } + ?> + </select> + </td> + </tr> + <tr> + <td> + + </td> + <td> + <input id="rss_widget_submit" name="rss_widget_submit" type="submit" class="formbtn" value="Save" /> + </td> + </tr> + </table> + </form> +</div> + +<div id="rss-widgets" style="padding: 5px; 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() as $item) { + $feed = $item->get_feed(); + $feed->strip_htmltags(); + echo "<a target='blank' href='" . $item->get_permalink() . "'>" . $item->get_title() . "</a><br />"; + $content = $item->get_content(); + $content = strip_tags($content); + echo textLimit($content, $rsswidgettextlength) . "<br />"; + echo "Source: <a target='_blank' href='" . $item->get_permalink() . "'><img src='" . $feed->get_favicon() . "' alt='" . $feed->get_title() . "' title='" . $feed->get_title() . "' border='0' width='16' height='16' /></a><br />"; + $counter++; + if ($counter > $max_items) { + break; + } + echo "<hr/>"; + } +?> +</div> + +<!-- needed to display the widget settings menu --> +<script type="text/javascript"> +//<![CDATA[ + selectIntLink = "rss-configure"; + textlink = document.getElementById(selectIntLink); + textlink.style.display = "inline"; +//]]> +</script> 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..f4c3542 --- /dev/null +++ b/src/usr/local/www/widgets/widgets/services_status.widget.php @@ -0,0 +1,105 @@ +<?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'])) { + $config['widgets']['servicestatusfilter'] = htmlspecialchars($_POST['servicestatusfilter'], ENT_QUOTES | ENT_HTML401); + write_config("Saved Service Status Filter via Dashboard"); + header("Location: ../../index.php"); +} +?> +<input type="hidden" id="services_status-config" name="services_status-config" value="" /> +<div id="services_status-settings" class="widgetconfigdiv" style="display:none;"> + <form action="/widgets/widgets/services_status.widget.php" method="post" name="services_status_widget_iform"> + Comma separated list of services to NOT display in the widget<br /> + <input type="text" size="30" name="servicestatusfilter" class="formfld unknown" id="servicestatusfilter" value="<?= $config['widgets']['servicestatusfilter'] ?>" /> + <input id="services_status_widget_submit" name="services_status_widget_submit" type="submit" class="formbtn" value="Save" /> + </form> +</div> + +<table width="100%" border="0" cellpadding="0" cellspacing="0" summary="services"> + <tr> + <td class="widgetsubheader" align="center"><b>Service</b></td> + <td class="widgetsubheader" align="center"><b>Description</b></td> + <td class="widgetsubheader" align="center"><b>Status</b></td> + <td class="widgetsubheader"> </td> + </tr> +<?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']); + echo "<tr><td class=\"listlr\">" . $service['name'] . "</td>\n"; + echo "<td class=\"listr\">" . $service_desc[0] . "</td>\n"; + // if service is running then listr else listbg + $bgclass = null; + if (get_service_status($service)) { + $bgclass = "listr"; + } else { + $bgclass = "listbg"; + } + echo "<td class=\"" . $bgclass . "\" align=\"center\">" . get_service_status_icon($service, false, true) . "</td>\n"; + echo "<td valign=\"middle\" class=\"list nowrap\">" . get_service_control_links($service) . "</td></tr>\n"; + } +} else { + echo "<tr><td colspan=\"3\" align=\"center\">" . gettext("No services found") . " . </td></tr>\n"; +} +?> +</table> + +<!-- needed to display the widget settings menu --> +<script type="text/javascript"> +//<![CDATA[ + selectIntLink = "services_status-configure"; + textlink = document.getElementById(selectIntLink); + textlink.style.display = "inline"; +//]]> +</script> 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..87f0605 --- /dev/null +++ b/src/usr/local/www/widgets/widgets/smart_status.widget.php @@ -0,0 +1,76 @@ +<?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 width="100%" border="0" cellpadding="0" cellspacing="0" summary="smart status"> + <tr> + <td class="widgetsubheader" align="center"><b><?php echo gettext("Drive") ?></b></td> + <td class="widgetsubheader" align="center"><b><?php echo gettext("Ident") ?></b></td> + <td class="widgetsubheader" align="center"><b><?php echo gettext("SMART Status") ?></b></td> + </tr> + +<?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 class="listlr"><?php echo $dev; ?></td> + <td class="listr" align="center"><?php echo $dev_ident; ?></td> + <td class="listr" align="center"><span style="background-color:<?php echo $color; ?>"> <?php echo $dev_state; ?> </span></td> + </tr> +<?php } +} +?> +</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..231f2ee --- /dev/null +++ b/src/usr/local/www/widgets/widgets/system_information.widget.php @@ -0,0 +1,322 @@ +<?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 "<br /><br />Unable to check for updates."; + } else { + $current_installed_buildtime = trim(file_get_contents("/etc/version.buildtime")); + + if (!$remote_version) { + echo "<br /><br />Unable to check for updates."; + } else { + $needs_system_upgrade = false; + if (pfs_version_compare($current_installed_buildtime, $g['product_version'], $remote_version) == -1) { + echo "<br /><span class=\"red\" id=\"updatealert\"><b>Update available. </b></span><a href=\"/system_firmware_check.php\">Click Here</a> to view update."; + echo "\n<script type=\"text/javascript\">\n"; + echo "//<![CDATA[\n"; + echo "jQuery('#updatealert').effect('pulsate',{times: 30},10000);\n"; + echo "//]]>\n"; + echo "</script>\n"; + } else { + echo "<br />You are on the latest version."; + } + } + } + exit; +} + +$curcfg = $config['system']['firmware']; + +$filesystems = get_mounted_filesystems(); + +?> +<script type="text/javascript"> +//<![CDATA[ + jQuery(function() { + jQuery("#statePB").progressbar( { value: <?php echo get_pfstate(true); ?> } ); + jQuery("#mbufPB").progressbar( { value: <?php echo get_mbuf(true); ?> } ); + jQuery("#cpuPB").progressbar( { value:false } ); + jQuery("#memUsagePB").progressbar( { value: <?php echo mem_usage(); ?> } ); + +<?PHP $d = 0; ?> +<?PHP foreach ($filesystems as $fs): ?> + jQuery("#diskUsagePB<?php echo $d++; ?>").progressbar( { value: <?php echo $fs['percent_used']; ?> } ); +<?PHP endforeach; ?> + + <?php if ($showswap == true): ?> + jQuery("#swapUsagePB").progressbar( { value: <?php echo swap_usage(); ?> } ); + <?php endif; ?> + <?php if (get_temp() != ""): ?> + jQuery("#tempPB").progressbar( { value: <?php echo get_temp(); ?> } ); + <?php endif; ?> + }); +//]]> +</script> + +<table width="100%" border="0" cellspacing="0" cellpadding="0" summary="system information"> + <tbody> + <tr> + <td width="25%" class="vncellt"><?=gettext("Name");?></td> + <td width="75%" class="listr"><?php echo $config['system']['hostname'] . "." . $config['system']['domain']; ?></td> + </tr> + <tr> + <td width="25%" valign="top" class="vncellt"><?=gettext("Version");?></td> + <td width="75%" class="listr"> + <strong><?=$g['product_version']?></strong> + (<?php echo php_uname("m"); ?>) + <br /> + built on <?php readfile("/etc/version.buildtime"); ?> + <?php if (!$g['hideuname']): ?> + <br /> + <div id="uname"><a href="#" onclick='swapuname(); return false;'><?php echo php_uname("s") . " " . php_uname("r"); ?></a></div> + <?php endif; ?> + <?php if (!isset($config['system']['firmware']['disablecheck'])): ?> + <div id='updatestatus'><br /><?php echo gettext("Obtaining update status"); ?> ...</div> + <?php endif; ?> + </td> + </tr> + <?php if (!$g['hideplatform']): ?> + <tr> + <td width="25%" class="vncellt"><?=gettext("Platform");?></td> + <td width="75%" class="listr"> + <?=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> + <td width="25%" class="vncellt"><?=gettext("NanoBSD Boot Slice");?></td> + <td width="75%" class="listr"> + <?=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> + <td width="25%" class="vncellt"><?=gettext("CPU Type");?></td> + <td width="75%" class="listr"> + <?php + echo (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> + <td width="25%" class="vncellt"><?=gettext("Hardware crypto");?></td> + <td width="75%" class="listr"><?=htmlspecialchars($hwcrypto);?></td> + </tr> + <?php endif; ?> + <tr> + <td width="25%" class="vncellt"><?=gettext("Uptime");?></td> + <td width="75%" class="listr" id="uptime"><?= htmlspecialchars(get_uptime()); ?></td> + </tr> + <tr> + <td width="25%" class="vncellt"><?=gettext("Current date/time");?></td> + <td width="75%" class="listr"> + <div id="datetime"><?= date("D M j G:i:s T Y"); ?></div> + </td> + </tr> + <tr> + <td width="30%" class="vncellt"><?=gettext("DNS server(s)");?></td> + <td width="70%" class="listr"> + <?php + $dns_servers = get_dns_servers(); + foreach ($dns_servers as $dns) { + echo "{$dns}<br />"; + } + ?> + </td> + </tr> + <?php if ($config['revision']): ?> + <tr> + <td width="25%" class="vncellt"><?=gettext("Last config change");?></td> + <td width="75%" class="listr"><?= htmlspecialchars(date("D M j G:i:s T Y", intval($config['revision']['time'])));?></td> + </tr> + <?php endif; ?> + <tr> + <td width="25%" class="vncellt"><?=gettext("State table size");?></td> + <td width="75%" class="listr"> + <?php + $pfstatetext = get_pfstate(); + $pfstateusage = get_pfstate(true); + ?> + <div id="statePB"></div> + <span id="pfstateusagemeter"><?= $pfstateusage.'%'; ?></span> (<span id="pfstate"><?= htmlspecialchars($pfstatetext); ?></span>) + <br /> + <a href="diag_dump_states.php"><?=gettext("Show states");?></a> + </td> + </tr> + <tr> + <td width="25%" class="vncellt"><?=gettext("MBUF Usage");?></td> + <td width="75%" class="listr"> + <?php + $mbufstext = get_mbuf(); + $mbufusage = get_mbuf(true); + ?> + <div id="mbufPB"></div> + <span id="mbufusagemeter"><?= $mbufusage.'%'; ?></span> (<span id="mbuf"><?= $mbufstext ?></span>) + </td> + </tr> + <?php if (get_temp() != ""): ?> + <tr> + <td width="25%" class="vncellt"><?=gettext("Temperature");?></td> + <td width="75%" class="listr"> + <?php $TempMeter = $temp = get_temp(); ?> + <div id="tempPB"></div> + <span id="tempmeter"><?= $temp."°C"; ?></span> + </td> + </tr> + <?php endif; ?> + <tr> + <td width="25%" class="vncellt"><?=gettext("Load average");?></td> + <td width="75%" class="listr"> + <div id="load_average" title="Last 1, 5 and 15 minutes"><?= get_load_average(); ?></div> + </td> + </tr> + <tr> + <td width="25%" class="vncellt"><?=gettext("CPU usage");?></td> + <td width="75%" class="listr"> + <div id="cpuPB"></div> + <span id="cpumeter">(Updating in 10 seconds)</span> + </td> + </tr> + <tr> + <td width="25%" class="vncellt"><?=gettext("Memory usage");?></td> + <td width="75%" class="listr"> + <?php $memUsage = mem_usage(); ?> + <div id="memUsagePB"></div> + <span id="memusagemeter"><?= $memUsage.'%'; ?></span> of <?= sprintf("%.0f", get_single_sysctl('hw.physmem') / (1024*1024)) ?> MB + </td> + </tr> + <?php if ($showswap == true): ?> + <tr> + <td width="25%" class="vncellt"><?=gettext("SWAP usage");?></td> + <td width="75%" class="listr"> + <?php $swapusage = swap_usage(); ?> + <div id="swapUsagePB"></div> + <span id="swapusagemeter"><?= $swapusage.'%'; ?></span> of <?= sprintf("%.0f", `/usr/sbin/swapinfo -m | /usr/bin/grep -v Device | /usr/bin/awk '{ print $2;}'`) ?> MB + </td> + </tr> + <?php endif; ?> + <tr> + <td width="25%" class="vncellt"><?=gettext("Disk usage");?></td> + <td width="75%" class="listr"> + <?php $d = 0; ?> + <?php foreach ($filesystems as $fs): ?> + <div id="diskUsagePB<?php echo $d; ?>"></div> + <?php if (substr(basename($fs['device']), 0, 2) == "md") $fs['type'] .= " in RAM"; ?> + <?php echo "{$fs['mountpoint']} ({$fs['type']})";?>: <span id="diskusagemeter<?php echo $d++ ?>"><?= $fs['percent_used'].'%'; ?></span> of <?PHP echo $fs['total_size'];?> + <br /> + <?php endforeach; ?> + </td> + </tr> + </tbody> +</table> +<script type="text/javascript"> +//<![CDATA[ + function swapuname() { + jQuery('#uname').html("<?php echo php_uname("a"); ?>"); + } + <?php if (!isset($config['system']['firmware']['disablecheck'])): ?> + function getstatus() { + scroll(0,0); + var url = "/widgets/widgets/system_information.widget.php"; + var pars = 'getupdatestatus=yes'; + jQuery.ajax( + url, + { + type: 'get', + data: pars, + complete: activitycallback + }); + } + function activitycallback(transport) { + // .html() method process all script tags contained in responseText, + // to avoid this we set the innerHTML property + jQuery('#updatestatus').prop('innerHTML',transport.responseText); + } + setTimeout('getstatus()', 4000); + <?php endif; ?> +//]]> +</script> 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..0dac0cb --- /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="thermal_sensors_widget_iform" name="thermal_sensors_widget_iform"> + <table width="100%" border="0" summary="thermal sensors widget"> + <tr> + <td align="left" colspan="2"> + <span style="font-weight: bold" >Thresholds in °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 /> + <a href="system_advanced_misc.php">System > Advanced > 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..c5f6286 --- /dev/null +++ b/src/usr/local/www/widgets/widgets/traffic_graphs.widget.php @@ -0,0 +1,193 @@ +<?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"; +} + +?> +<input type="hidden" id="traffic_graphs-config" name="traffic_graphs-config" value="" /> + +<div id="traffic_graphs-settings" class="widgetconfigdiv" style="display:none;"> +<form action="/widgets/widgets/traffic_graphs.widget.php" method="post" name="traffic_graphs_widget_iform" id="traffic_graphs_widget_iform"> + <?php foreach ($ifdescrs as $ifname => $ifdescr) { ?> + <input type="hidden" name="shown[<?= $ifname ?>]" value="<?= $shown[$ifname] ? "show" : "hide" ?>" /> + <?php } ?> + Default AutoScale: + <?php + $scale_type_up="checked=\"checked\""; + $scale_type_follow=""; + if (isset($config["widgets"]["trafficgraphs"]["scale_type"])) { + $selected_radio = $config["widgets"]["trafficgraphs"]["scale_type"]; + if ($selected_radio == "up") { + $scale_type_up = "checked=\"checked\""; + $scale_type_follow=""; + } else if ($selected_radio == "follow") { + $scale_type_up=""; + $scale_type_follow = "checked=\"checked\""; + } + } + ?> + <input name="scale_type" class="radio" type="radio" id="scale_type_up" value="up" <?php echo $scale_type_up; ?> onchange="updateGraphDisplays();" /> <span>up</span> + <input name="scale_type" class="radio" type="radio" id="scale_type_follow" value="follow" <?php echo $scale_type_follow; ?> onchange="updateGraphDisplays();" /> <span>follow</span><br /><br /> + Refresh Interval: + <select name="refreshinterval" class="formfld" id="refreshinterval" onchange="updateGraphDisplays();"> + <?php for ($i = 1; $i <= 10; $i += 1) { ?> + <option value="<?= $i ?>" <?php if ($refreshinterval == $i) echo "selected=\"selected\"";?>><?= $i ?></option> + <?php } ?> + </select> Seconds<br /> <b>Note:</b> changing this setting will increase CPU utilization<br /><br /> + <input id="traffic_graphs_widget_submit" name="traffic_graphs_widget_submit" type="submit" onclick="return updatePref();" class="formbtn" value="Save Settings" /> +</form> +</div> + +<script type="text/javascript"> +//<![CDATA[ + d = document; + selectIntLink = "traffic_graphs-configure"; + textlink = d.getElementById(selectIntLink); + textlink.style.display = "inline"; +//]]> +</script> + +<?php +$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 id="<?=$ifname;?>trafficdiv" style="padding: 5px"> + <div id="<?=$ifname;?>topic" class="widgetsubheader"> + <div style="float:left;width:49%"> + <span onclick="location.href='/status_graph.php?if=<?=$ifname;?>'" style="cursor:pointer">Current <?=$ifdescr;?> Traffic</span> + </div> + <div align="right" style="float:right;width:49%"> + <div id="<?=$ifname;?>graphdiv-min" onclick='return trafficminimizeDiv("<?= $ifname ?>", true);' + style="display:<?php echo $mingraphbutton;?>; cursor:pointer" ><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_minus.gif" alt="Minimize <?=$ifname;?> traffic graph" /></div> + <div id="<?=$ifname;?>graphdiv-open" onclick='return trafficshowDiv("<?= $ifname ?>", "<?= rawurlencode($ifdescr); ?>", "<?= $refreshinterval ?>", true);' + style="display:<?php echo $showgraphbutton;?>; cursor:pointer" ><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_open.gif" alt="Show <?=$ifname;?> traffic graph" /></div> + </div> + <div style="clear:both;"></div> + </div> + <div id="<?=$ifname;?>graphdiv" style="display:<?php echo $graphdisplay;?>"> +<?php + // If the graph is already enabled by the config then put the object inside the div now. + // Otherwise the graph object is inserted by trafficshowDiv JS when the user opens it. + if ($graphdisplay == "inline") { +?> + <object data="graph.php?ifnum=<?=$ifname;?>&ifname=<?=rawurlencode($ifdescr);?>&timeint=<?=$refreshinterval;?>&initdelay=<?=$graphcounter * 2;?>" 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> +<?php + } +?> + </div> + </div> + <?php } +} +?> 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..9cb760a --- /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 width="100%" border="0" cellpadding="0" cellspacing="0" summary="wol status"> + <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"> </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\" /> <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']}&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> |