mirror of
https://github.com/LX3JL/xlxd.git
synced 2025-12-06 07:42:01 +01:00
Add files via upload
This commit is contained in:
parent
7176e44386
commit
37a79a95a0
190
dashboard1/css/layout.css
Normal file
190
dashboard1/css/layout.css
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
body {
|
||||
margin : 0px;
|
||||
padding : 0px;
|
||||
background-color : #D3D3D3;
|
||||
font-family : calibri, verdana, arial, comic sans;
|
||||
min-width : 760px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size : 25pt;
|
||||
}
|
||||
|
||||
a img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
a.tip {
|
||||
text-decoration : none;
|
||||
}
|
||||
|
||||
a.tip:hover {
|
||||
position : relative;
|
||||
}
|
||||
|
||||
a.tip span {
|
||||
display : none
|
||||
}
|
||||
|
||||
a.tip:hover span {
|
||||
background : #000000;
|
||||
opacity : 0.8;
|
||||
border : none;
|
||||
border-radius : 5px 5px 5px 5px;
|
||||
font-family : calibri, verdana, arial, comic sans;
|
||||
font-size : 12pt;
|
||||
text-decoration : none;
|
||||
white-space : nowrap;
|
||||
color : #FFFFFF;
|
||||
padding : 6px 6px 6px 6px;
|
||||
margin : 10px;
|
||||
display : block;
|
||||
z-index : 50;
|
||||
position : absolute;
|
||||
top : 10px;
|
||||
}
|
||||
|
||||
#top {
|
||||
height : 115px;
|
||||
background-color : #FFFFFF;
|
||||
width : 100%;
|
||||
background-image : url('../img/dvc.jpg');
|
||||
background-repeat : no-repeat;
|
||||
background-position : 98.5%;
|
||||
position : absolute;
|
||||
left : 0px;
|
||||
top : 0px;
|
||||
min-width : 760px;
|
||||
}
|
||||
|
||||
#menu {
|
||||
margin-top : 5px;
|
||||
height : 34px;
|
||||
float : left;
|
||||
}
|
||||
|
||||
#menubar {
|
||||
height : 40px;
|
||||
width : 100%;
|
||||
background-color : #FEC456;
|
||||
position : absolute;
|
||||
left : 0px;
|
||||
top : 115px;
|
||||
min-width : 760px;
|
||||
}
|
||||
|
||||
#content {
|
||||
width : 100%;
|
||||
position : absolute;
|
||||
left : 0px;
|
||||
top : 175px;
|
||||
}
|
||||
|
||||
.menulink {
|
||||
font-size : 14pt;
|
||||
text-decoration : none;
|
||||
white-space : nowrap;
|
||||
border : 1px #000000 solid;
|
||||
padding-left : 10px;
|
||||
padding-top : 3px;
|
||||
padding-bottom : 3px;
|
||||
padding-right : 10px;
|
||||
margin-left : 10px;
|
||||
background-color : #FFFFC6;
|
||||
color : #000000;
|
||||
}
|
||||
|
||||
.menulinkactive {
|
||||
font-size : 14pt;
|
||||
text-decoration : none;
|
||||
white-space : nowrap;
|
||||
border : 1px #000000 solid;
|
||||
padding-left : 10px;
|
||||
padding-top : 3px;
|
||||
padding-bottom : 3px;
|
||||
padding-right : 10px;
|
||||
margin-left : 10px;
|
||||
background-color : #87dcfc;
|
||||
color : #000000;
|
||||
}
|
||||
|
||||
.pl {
|
||||
font-size : 12pt;
|
||||
text-decoration : none;
|
||||
color : #000000;
|
||||
}
|
||||
|
||||
.listingtable {
|
||||
margin-top : 10px;
|
||||
border : 1px #C1DAD7 solid;
|
||||
font-size : 12pt;
|
||||
}
|
||||
|
||||
.listingtable th {
|
||||
height : 35px;
|
||||
text-align : center;
|
||||
background-color : #D5EBF0;
|
||||
background-image : -webkit-gradient(
|
||||
linear,
|
||||
left top,
|
||||
left bottom,
|
||||
color-stop(0, rgb(201, 231, 233)),
|
||||
color-stop(0.8, rgb(220, 237, 244))
|
||||
);
|
||||
background-image: -o-linear-gradient(bottom, rgb(201, 231, 233) 0%, rgb(220, 237, 244) 80%);
|
||||
background-image: -moz-linear-gradient(bottom, rgb(201, 231, 233) 0%, rgb(220, 237, 244) 80%);
|
||||
background-image: -webkit-linear-gradient(bottom, rgb(201, 231, 233) 0%, rgb(220, 237, 244) 80%);
|
||||
background-image: -ms-linear-gradient(bottom, rgb(201, 231, 233) 0%, rgb(220, 237, 244) 80%);
|
||||
background-image: linear-gradient(to bottom, rgb(201, 231, 233) 0%, rgb(220, 237, 244) 80%);
|
||||
}
|
||||
|
||||
.listingtable td {
|
||||
padding-left : 5px;
|
||||
}
|
||||
|
||||
.listinglink {
|
||||
font-size : 12pt;
|
||||
text-decoration : underline;
|
||||
color : #60A1DE;
|
||||
}
|
||||
|
||||
.error {
|
||||
font-size : 12pt;
|
||||
text-decoration : none,
|
||||
font-weight : bold;
|
||||
color : #FF0000;
|
||||
background-color : #FFFFFF;
|
||||
width : 90%;
|
||||
padding : 15px;
|
||||
margin : 5px;
|
||||
}
|
||||
|
||||
.FilterField {
|
||||
font-size : 10pt;
|
||||
text-decoration : none,
|
||||
color : #000000;
|
||||
background-color : #FFFFFF;
|
||||
width : 150px;
|
||||
height : 20px;
|
||||
padding-left : 5px;
|
||||
padding-top : 3px;
|
||||
border : 1px #60A1DE solid;
|
||||
}
|
||||
|
||||
.FilterSubmit {
|
||||
font-size : 10pt;
|
||||
text-decoration : none,
|
||||
color : #000000;
|
||||
background-color : #FFFFFF;
|
||||
height : 26px;
|
||||
width : 60px;
|
||||
padding-left : 5px;
|
||||
padding-top : 3px;
|
||||
border : 1px #60A1DE solid;
|
||||
}
|
||||
|
||||
.smalllink {
|
||||
font-size : 12pt;
|
||||
text-decoration : none;
|
||||
color : #0E0789;
|
||||
}
|
||||
BIN
dashboard1/favicon.ico
Normal file
BIN
dashboard1/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
227
dashboard1/index.php
Normal file
227
dashboard1/index.php
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
<?php
|
||||
|
||||
// Secure session configuration
|
||||
ini_set('session.cookie_httponly', 1);
|
||||
ini_set('session.cookie_samesite', 'Strict');
|
||||
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
|
||||
ini_set('session.cookie_secure', 1);
|
||||
}
|
||||
|
||||
session_start();
|
||||
|
||||
// Security headers
|
||||
header("X-Content-Type-Options: nosniff");
|
||||
header("X-Frame-Options: SAMEORIGIN");
|
||||
header("X-XSS-Protection: 1; mode=block");
|
||||
header("Referrer-Policy: strict-origin-when-cross-origin");
|
||||
|
||||
if (file_exists("./pgs/functions.php")) { require_once("./pgs/functions.php"); } else { die("functions.php does not exist."); }
|
||||
if (file_exists("./pgs/config.inc.php")) { require_once("./pgs/config.inc.php"); } else { die("config.inc.php does not exist."); }
|
||||
|
||||
if (!class_exists('ParseXML')) require_once("./pgs/class.parsexml.php");
|
||||
if (!class_exists('Node')) require_once("./pgs/class.node.php");
|
||||
if (!class_exists('xReflector')) require_once("./pgs/class.reflector.php");
|
||||
if (!class_exists('Station')) require_once("./pgs/class.station.php");
|
||||
if (!class_exists('Peer')) require_once("./pgs/class.peer.php");
|
||||
if (!class_exists('Interlink')) require_once("./pgs/class.interlink.php");
|
||||
|
||||
// Validate 'show' parameter
|
||||
$allowed_pages = ['users', 'repeaters', 'liveircddb', 'peers', 'modules', 'reflectors', 'traffic'];
|
||||
if (!isset($_GET['show'])) {
|
||||
$_GET['show'] = '';
|
||||
} elseif (!in_array($_GET['show'], $allowed_pages, true)) {
|
||||
$_GET['show'] = '';
|
||||
}
|
||||
|
||||
// Validate 'do' parameter for filter resets
|
||||
if (isset($_GET['do']) && $_GET['do'] !== 'resetfilter') {
|
||||
unset($_GET['do']);
|
||||
}
|
||||
|
||||
// Validate 'callhome' parameter
|
||||
if (isset($_GET['callhome'])) {
|
||||
$_GET['callhome'] = filter_var($_GET['callhome'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
|
||||
if ($_GET['callhome'] === null) {
|
||||
unset($_GET['callhome']);
|
||||
}
|
||||
}
|
||||
|
||||
$Reflector = new xReflector();
|
||||
$Reflector->SetFlagFile("./pgs/country.csv");
|
||||
$Reflector->SetPIDFile($Service['PIDFile']);
|
||||
$Reflector->SetXMLFile($Service['XMLFile']);
|
||||
|
||||
$Reflector->LoadXML();
|
||||
|
||||
if ($CallingHome['Active']) {
|
||||
|
||||
$CallHomeNow = false;
|
||||
$LastSync = 0;
|
||||
$Hash = "";
|
||||
|
||||
if (!file_exists($CallingHome['HashFile'])) {
|
||||
$Ressource = fopen($CallingHome['HashFile'], "w+");
|
||||
if ($Ressource) {
|
||||
$Hash = CreateCode(16);
|
||||
@fwrite($Ressource, "<?php\n");
|
||||
@fwrite($Ressource, "\n".'$Hash = "'.$Hash.'";');
|
||||
@fwrite($Ressource, "\n\n".'?>');
|
||||
@fflush($Ressource);
|
||||
@fclose($Ressource);
|
||||
@chmod($HashFile, 0777);
|
||||
}
|
||||
}
|
||||
else {
|
||||
require_once($CallingHome['HashFile']);
|
||||
}
|
||||
|
||||
if (@file_exists($CallingHome['LastCallHomefile'])) {
|
||||
if (@is_readable($CallingHome['LastCallHomefile'])) {
|
||||
$tmp = @file($CallingHome['LastCallHomefile']);
|
||||
if (isset($tmp[0])) {
|
||||
$LastSync = $tmp[0];
|
||||
}
|
||||
unset($tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if ($LastSync < (time() - $CallingHome['PushDelay'])) {
|
||||
$CallHomeNow = true;
|
||||
$Ressource = @fopen($CallingHome['LastCallHomefile'], "w+");
|
||||
if ($Ressource) {
|
||||
@fwrite($Ressource, time());
|
||||
@fflush($Ressource);
|
||||
@fclose($Ressource);
|
||||
@chmod($HashFile, 0777);
|
||||
}
|
||||
}
|
||||
|
||||
if ($CallHomeNow || isset($_GET['callhome'])) {
|
||||
$Reflector->SetCallingHome($CallingHome, $Hash);
|
||||
$Reflector->ReadInterlinkFile();
|
||||
$Reflector->PrepareInterlinkXML();
|
||||
$Reflector->PrepareReflectorXML();
|
||||
$Reflector->CallHome();
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
$Hash = "";
|
||||
}
|
||||
|
||||
|
||||
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<meta name="description" content="<?php echo sanitize_attribute($PageOptions['MetaDescription']); ?>" />
|
||||
<meta name="keywords" content="<?php echo sanitize_attribute($PageOptions['MetaKeywords']); ?>" />
|
||||
<meta name="author" content="<?php echo sanitize_attribute($PageOptions['MetaAuthor']); ?>" />
|
||||
<meta name="revisit" content="<?php echo sanitize_attribute($PageOptions['MetaRevisit']); ?>" />
|
||||
<meta name="robots" content="<?php echo sanitize_attribute($PageOptions['MetaRobots']); ?>" />
|
||||
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title><?php echo sanitize_output($Reflector->GetReflectorName()); ?> Reflector Dashboard</title>
|
||||
<link rel="stylesheet" type="text/css" href="./css/layout.css">
|
||||
<link rel="icon" href="./favicon.ico" type="image/vnd.microsoft.icon"><?php
|
||||
|
||||
if ($PageOptions['PageRefreshActive']) {
|
||||
echo '
|
||||
<script src="./js/jquery-1.12.4.min.js"></script>
|
||||
<script>
|
||||
var PageRefresh;
|
||||
|
||||
function ReloadPage() {
|
||||
$.get("./index.php'.((!empty($_GET['show'])) ? '?show='.urlencode($_GET['show']) : '').'", function(data) {
|
||||
var BodyStart = data.indexOf("<bo"+"dy");
|
||||
var BodyEnd = data.indexOf("</bo"+"dy>");
|
||||
if ((BodyStart >= 0) && (BodyEnd > BodyStart)) {
|
||||
BodyStart = data.indexOf(">", BodyStart)+1;
|
||||
$("body").html(data.substring(BodyStart, BodyEnd));
|
||||
}
|
||||
})
|
||||
.always(function() {
|
||||
PageRefresh = setTimeout(ReloadPage, '.$PageOptions['PageRefreshDelay'].');
|
||||
});
|
||||
}';
|
||||
|
||||
if (!isset($_GET['show']) || (($_GET['show'] != 'liveircddb') && ($_GET['show'] != 'reflectors') && ($_GET['show'] != 'interlinks'))) {
|
||||
echo '
|
||||
PageRefresh = setTimeout(ReloadPage, '.$PageOptions['PageRefreshDelay'].');';
|
||||
}
|
||||
echo '
|
||||
|
||||
function SuspendPageRefresh() {
|
||||
clearTimeout(PageRefresh);
|
||||
}
|
||||
</script>';
|
||||
}
|
||||
|
||||
if (!isset($_GET['show'])) $_GET['show'] = "";
|
||||
?>
|
||||
</head>
|
||||
<body>
|
||||
<?php if (file_exists("./tracking.php")) { include_once("tracking.php"); }?>
|
||||
<div id="top"><img src="./img/header.jpg" alt="XLX Multiprotocol Gateway Reflector" style="margin-top:15px;" />
|
||||
<br /> <?php echo sanitize_output($Reflector->GetReflectorName()); ?> v<?php echo sanitize_output($Reflector->GetVersion()); ?> - Dashboard v<?php echo sanitize_output($PageOptions['DashboardVersion']); ?> <?php echo sanitize_output($PageOptions['CustomTXT']); ?> / Service uptime: <span id="suptime"><?php echo FormatSeconds($Reflector->GetServiceUptime()); ?></span></div>
|
||||
<div id="menubar">
|
||||
<div id="menu">
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td><a href="./index.php" class="menulink<?php if ($_GET['show'] == '') { echo 'active'; } ?>">Users / Modules</a></td>
|
||||
<td><a href="./index.php?show=repeaters" class="menulink<?php if ($_GET['show'] == 'repeaters') { echo 'active'; } ?>">Repeaters / Nodes (<?php echo intval($Reflector->NodeCount()); ?>)</a></td>
|
||||
<td><a href="./index.php?show=peers" class="menulink<?php if ($_GET['show'] == 'peers') { echo 'active'; } ?>">Peers (<?php echo intval($Reflector->PeerCount()); ?>)</a></td>
|
||||
<td><a href="./index.php?show=modules" class="menulink<?php if ($_GET['show'] == 'modules') { echo 'active'; } ?>">Modules list</a></td>
|
||||
<td><a href="./index.php?show=reflectors" class="menulink<?php if ($_GET['show'] == 'reflectors') { echo 'active'; } ?>">Reflectors list</a></td>
|
||||
<?php
|
||||
|
||||
if ($PageOptions['Traffic']['Show']) {
|
||||
echo '
|
||||
<td><a href="./index.php?show=traffic" class="menulink';
|
||||
if ($_GET['show'] == 'traffic') { echo 'active'; }
|
||||
echo '">Traffic statistics</a></td>';
|
||||
}
|
||||
if ($PageOptions['IRCDDB']['Show']) {
|
||||
echo '
|
||||
<td><a href="./index.php?show=liveircddb" class="menulink';
|
||||
if ($_GET['show'] == 'liveircddb') { echo 'active'; }
|
||||
echo '">D-Star live</a></td>';
|
||||
}
|
||||
|
||||
?>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content" align="center">
|
||||
|
||||
<?php
|
||||
if ($CallingHome['Active']) {
|
||||
if (!is_readable($CallingHome['HashFile']) && (!is_writeable($CallingHome['HashFile']))) {
|
||||
echo '
|
||||
<div class="error">
|
||||
your private hash in '.sanitize_output($CallingHome['HashFile']).' could not be created, please check your config file and the permissions for the defined folder.
|
||||
</div>';
|
||||
}
|
||||
}
|
||||
|
||||
switch ($_GET['show']) {
|
||||
case 'users' : require_once("./pgs/users.php"); break;
|
||||
case 'repeaters' : require_once("./pgs/repeaters.php"); break;
|
||||
case 'liveircddb' : require_once("./pgs/liveircddb.php"); break;
|
||||
case 'peers' : require_once("./pgs/peers.php"); break;
|
||||
case 'modules' : require_once("./pgs/modules.php"); break;
|
||||
case 'reflectors' : require_once("./pgs/reflectors.php"); break;
|
||||
case 'traffic' : require_once("./pgs/traffic.php"); break;
|
||||
default : require_once("./pgs/users.php");
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div style="width:100%;text-align:center;margin-top:50px;"><a href="mailto:<?php echo sanitize_attribute($PageOptions['ContactEmail']); ?>" style="font-family:verdana;color:#000000;font-size:12pt;text-decoration:none;"><?php echo sanitize_output($PageOptions['ContactEmail']); ?></a></div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
5
dashboard1/js/jquery-1.12.4.min.js
vendored
Normal file
5
dashboard1/js/jquery-1.12.4.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
0
dashboard1/log/index.html
Normal file
0
dashboard1/log/index.html
Normal file
81
dashboard1/log/xlxlog.php
Normal file
81
dashboard1/log/xlxlog.php
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
session_start();
|
||||
|
||||
if (isset($_POST['password'])) {
|
||||
$_SESSION['password'] = $_POST['password'];
|
||||
}
|
||||
|
||||
if (isset($_SESSION['password'])) {
|
||||
|
||||
if ($_SESSION['password'] != "-D-Star+") {
|
||||
echo '
|
||||
<form name="frmpass" action="./xlxlog.php" method="post">
|
||||
|
||||
<input type="password" name="password" />
|
||||
<input type="submit" />
|
||||
|
||||
</form>';
|
||||
|
||||
die();
|
||||
}
|
||||
}
|
||||
else {
|
||||
echo '
|
||||
<form name="frmpass" action="./xlxlog.php" method="post">
|
||||
|
||||
<input type="password" name="password" />
|
||||
<input type="submit" />
|
||||
|
||||
</form>';
|
||||
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>XLX Live Log</title>
|
||||
<script>
|
||||
|
||||
function ReloadPage() {
|
||||
document.location.href = "./xlxlog.php";
|
||||
}
|
||||
|
||||
setTimeout(ReloadPage, 1000);
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<pre>
|
||||
|
||||
<?php
|
||||
$a = array();
|
||||
$handle = fopen("/var/log/messages","r");
|
||||
if ($handle) {
|
||||
while(!feof($handle)) {
|
||||
$a[] = fgets($handle, 1024);
|
||||
}
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
$a = array_reverse($a);
|
||||
|
||||
$max = 65;
|
||||
if (count($a) < 65) $max = count($a);
|
||||
|
||||
for ($i=0;$i<$max;$i++) {
|
||||
echo $a[$i];
|
||||
}
|
||||
|
||||
?>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
66
dashboard1/pgs/class.interlink.php
Normal file
66
dashboard1/pgs/class.interlink.php
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
class Interlink {
|
||||
|
||||
private $ReflectorName;
|
||||
private $ReflectorAddress;
|
||||
private $Modules;
|
||||
|
||||
public function __construct() {
|
||||
$this->ReflectorName = null;
|
||||
$this->ReflectorAddress = null;
|
||||
$this->Modules = null;
|
||||
}
|
||||
|
||||
public function SetName($RefName) {
|
||||
$RefName = trim($RefName);
|
||||
// Validate reflector name format (XLX + 3 alphanumeric)
|
||||
if (preg_match('/^[A-Z0-9]{3,10}$/i', $RefName)) {
|
||||
$this->ReflectorName = strtoupper($RefName);
|
||||
}
|
||||
}
|
||||
public function SetAddress($RefAdd) {
|
||||
$RefAdd = trim($RefAdd);
|
||||
// Validate it's a valid hostname or IP
|
||||
if (filter_var($RefAdd, FILTER_VALIDATE_IP) ||
|
||||
filter_var($RefAdd, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) {
|
||||
$this->ReflectorAddress = $RefAdd;
|
||||
}
|
||||
}
|
||||
public function GetName() { return $this->ReflectorName; }
|
||||
public function GetAddress() { return $this->ReflectorAddress; }
|
||||
public function GetModules() { return $this->Modules; }
|
||||
|
||||
|
||||
public function AddModule($Module) {
|
||||
$Module = trim(strtoupper($Module));
|
||||
if (strlen($Module) != 1) return false;
|
||||
if (!preg_match('/^[A-Z]$/', $Module)) return false; // Only A-Z
|
||||
if (strpos($this->Modules, $Module) === false) {
|
||||
$this->Modules .= $Module;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function RemoveModule($Module) {
|
||||
$Module = trim(strtoupper($Module));
|
||||
if (strlen($Module) != 1) return false;
|
||||
if (!preg_match('/^[A-Z]$/', $Module)) return false; // Only A-Z
|
||||
if (strpos($this->Modules, $Module) !== false) {
|
||||
$this->Modules = str_replace($Module, '', $this->Modules);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function HasModuleEnabled($Module) {
|
||||
$Module = trim(strtoupper($Module));
|
||||
if (strlen($Module) != 1 || !preg_match('/^[A-Z]$/', $Module)) {
|
||||
return false;
|
||||
}
|
||||
return (strpos($this->Modules, $Module) !== false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
70
dashboard1/pgs/class.node.php
Normal file
70
dashboard1/pgs/class.node.php
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
class Node {
|
||||
|
||||
private $Callsign;
|
||||
private $IP;
|
||||
private $LinkedModule;
|
||||
private $Protocol;
|
||||
private $ConnectTime;
|
||||
private $LastHeardTime;
|
||||
private $Suffix;
|
||||
private $Prefix;
|
||||
private $RandomID;
|
||||
|
||||
public function __construct($Callsign, $IP, $LinkedModule, $Protocol, $ConnectTime, $LastHeardTime, $RandomID) {
|
||||
|
||||
// Validate and sanitize IP
|
||||
$IP = trim($IP);
|
||||
$this->IP = filter_var($IP, FILTER_VALIDATE_IP) ? $IP : '0.0.0.0';
|
||||
|
||||
// Validate protocol
|
||||
$Protocol = trim($Protocol);
|
||||
$allowed_protocols = ['DPlus', 'DExtra', 'DCS', 'DMR', 'YSF', 'DEXTRA', 'DPLUS', 'DMRMmdvm'];
|
||||
$this->Protocol = in_array($Protocol, $allowed_protocols, true) ? $Protocol : 'Unknown';
|
||||
|
||||
$this->ConnectTime = ParseTime($ConnectTime);
|
||||
$this->LastHeardTime = ParseTime($LastHeardTime);
|
||||
|
||||
// Sanitize callsign (remove excessive spaces, validate format)
|
||||
$Callsign = trim(preg_replace('/\s+/', ' ', $Callsign));
|
||||
|
||||
$this->FullCallsign = str_replace(" ", "-", $Callsign);
|
||||
|
||||
if (strpos($Callsign, " ") !== false) {
|
||||
$this->Callsign = trim(substr($Callsign, 0, strpos($Callsign, " ")));
|
||||
$this->Suffix = trim(substr($Callsign, strpos($Callsign, " ")));
|
||||
$this->Prefix = strtoupper(trim(substr($Callsign, 0, 3)));
|
||||
}
|
||||
else {
|
||||
$this->Callsign = trim($Callsign);
|
||||
$this->Suffix = "";
|
||||
$this->Prefix = "";
|
||||
}
|
||||
|
||||
// Validate callsign format (basic check)
|
||||
if (!preg_match('/^[A-Z0-9]{1,10}$/i', $this->Callsign)) {
|
||||
$this->Callsign = 'INVALID';
|
||||
}
|
||||
|
||||
// Validate LinkedModule (single letter A-Z)
|
||||
$LinkedModule = trim(strtoupper($LinkedModule));
|
||||
$this->LinkedModule = preg_match('/^[A-Z]$/', $LinkedModule) ? $LinkedModule : '';
|
||||
|
||||
$this->RandomID = $RandomID;
|
||||
}
|
||||
|
||||
public function GetFullCallsign() { return $this->FullCallsign; }
|
||||
public function GetCallsign() { return $this->Callsign; }
|
||||
public function GetIP() { return $this->IP; }
|
||||
public function GetLinkedModule() { return $this->LinkedModule; }
|
||||
public function GetProtocol() { return $this->Protocol; }
|
||||
public function GetConnectTime() { return $this->ConnectTime; }
|
||||
public function GetLastHeardTime() { return $this->LastHeardTime; }
|
||||
public function GetSuffix() { return $this->Suffix; }
|
||||
public function GetPrefix() { return $this->Prefix; }
|
||||
public function GetRandomID() { return $this->RandomID; }
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
39
dashboard1/pgs/class.parsexml.php
Normal file
39
dashboard1/pgs/class.parsexml.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
class ParseXML {
|
||||
|
||||
public function __construct() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function GetElement($InputString, $ElementName) {
|
||||
// Sanitize element name to prevent XML injection
|
||||
$ElementName = preg_replace('/[^a-zA-Z0-9_\-\s]/', '', $ElementName);
|
||||
|
||||
if (strpos($InputString, "<".$ElementName.">") === false) return false;
|
||||
if (strpos($InputString, "</".$ElementName.">") === false) return false;
|
||||
|
||||
$Element = substr($InputString, strpos($InputString, "<".$ElementName.">")+strlen($ElementName)+2, strpos($InputString, "</".$ElementName.">")-strpos($InputString, "<".$ElementName.">")-strlen($ElementName)-2);
|
||||
|
||||
// Return raw content - sanitization happens at output time
|
||||
return $Element;
|
||||
}
|
||||
|
||||
public function GetAllElements($InputString, $ElementName) {
|
||||
// Sanitize element name to prevent XML injection
|
||||
$ElementName = preg_replace('/[^a-zA-Z0-9_\-\s]/', '', $ElementName);
|
||||
|
||||
$Elements = array();
|
||||
while (strpos($InputString, $ElementName) !== false) {
|
||||
$element = $this->GetElement($InputString, $ElementName);
|
||||
if ($element !== false) {
|
||||
$Elements[] = $element;
|
||||
}
|
||||
$InputString = substr($InputString, strpos($InputString, "</".$ElementName.">")+strlen($ElementName)+3, strlen($InputString));
|
||||
}
|
||||
return $Elements;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
49
dashboard1/pgs/class.peer.php
Normal file
49
dashboard1/pgs/class.peer.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
class Peer {
|
||||
|
||||
private $Callsign;
|
||||
private $IP;
|
||||
private $LinkedModule;
|
||||
private $Protocol;
|
||||
private $ConnectTime;
|
||||
private $LastHeardTime;
|
||||
|
||||
public function __construct($Callsign, $IP, $LinkedModule, $Protocol, $ConnectTime, $LastHeardTime) {
|
||||
|
||||
// Validate and sanitize IP
|
||||
$IP = trim($IP);
|
||||
$this->IP = filter_var($IP, FILTER_VALIDATE_IP) ? $IP : '0.0.0.0';
|
||||
|
||||
// Validate protocol
|
||||
$Protocol = trim($Protocol);
|
||||
$allowed_protocols = ['DPlus', 'DExtra', 'DCS', 'DMR', 'YSF', 'DEXTRA', 'DPLUS', 'XLX'];
|
||||
$this->Protocol = in_array($Protocol, $allowed_protocols, true) ? $Protocol : 'Unknown';
|
||||
|
||||
$this->ConnectTime = ParseTime($ConnectTime);
|
||||
$this->LastHeardTime = ParseTime($LastHeardTime);
|
||||
|
||||
// Sanitize and validate callsign
|
||||
$Callsign = trim($Callsign);
|
||||
if (preg_match('/^[A-Z0-9]{3,10}$/i', $Callsign)) {
|
||||
$this->Callsign = strtoupper($Callsign);
|
||||
} else {
|
||||
$this->Callsign = 'INVALID';
|
||||
}
|
||||
|
||||
// Validate LinkedModule (single letter A-Z)
|
||||
$LinkedModule = trim(strtoupper($LinkedModule));
|
||||
$this->LinkedModule = preg_match('/^[A-Z]$/', $LinkedModule) ? $LinkedModule : '';
|
||||
}
|
||||
|
||||
|
||||
public function GetCallsign() { return $this->Callsign; }
|
||||
public function GetIP() { return $this->IP; }
|
||||
public function GetLinkedModule() { return $this->LinkedModule; }
|
||||
public function GetProtocol() { return $this->Protocol; }
|
||||
public function GetConnectTime() { return $this->ConnectTime; }
|
||||
public function GetLastHeardTime() { return $this->LastHeardTime; }
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
556
dashboard1/pgs/class.reflector.php
Normal file
556
dashboard1/pgs/class.reflector.php
Normal file
|
|
@ -0,0 +1,556 @@
|
|||
<?php
|
||||
|
||||
class xReflector {
|
||||
|
||||
public $Nodes = null;
|
||||
public $Stations = null;
|
||||
public $Peers = null;
|
||||
private $Flagarray = null;
|
||||
private $Flagarray_DXCC = null;
|
||||
private $Flagfile = null;
|
||||
private $CallingHomeActive = null;
|
||||
private $CallingHomeHash = null;
|
||||
private $CallingHomeDashboardURL = null;
|
||||
private $CallingHomeServerURL = null;
|
||||
private $ReflectorName = null;
|
||||
private $ServiceUptime = null;
|
||||
private $ProcessIDFile = null;
|
||||
private $XMLContent = null;
|
||||
private $XMLFile = null;
|
||||
private $ServiceName = null;
|
||||
private $Version = null;
|
||||
private $CallingHomeCountry = null;
|
||||
private $CallingHomeComment = null;
|
||||
private $CallingHomeOverrideIP = null;
|
||||
private $Transferinterlink = null;
|
||||
private $Interlinkfile = null;
|
||||
public $Interlinks = null;
|
||||
private $InterlinkXML = null;
|
||||
private $ReflectorXML = null;
|
||||
|
||||
public function __construct() {
|
||||
$this->Nodes = array();
|
||||
$this->Stations = array();
|
||||
$this->Peers = array();
|
||||
$this->Interlinks = array();
|
||||
$this->Transferinterlink = false;
|
||||
}
|
||||
|
||||
public function LoadXML() {
|
||||
if ($this->XMLFile != null) {
|
||||
$handle = fopen($this->XMLFile, 'r');
|
||||
$this->XMLContent = fread($handle, filesize($this->XMLFile));
|
||||
fclose($handle);
|
||||
|
||||
# XLX alphanumeric naming...
|
||||
$this->ServiceName = substr($this->XMLContent, strpos($this->XMLContent, "<XLX")+4, 3);
|
||||
|
||||
// Validate service name
|
||||
if (!preg_match('/^[a-zA-Z0-9]{3}$/', $this->ServiceName)) {
|
||||
$this->ServiceName = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->ReflectorName = "XLX".$this->ServiceName;
|
||||
|
||||
$LinkedPeersName = "XLX".$this->ServiceName." linked peers";
|
||||
$LinkedNodesName = "XLX".$this->ServiceName." linked nodes";
|
||||
$LinkedUsersName = "XLX".$this->ServiceName." heard users";
|
||||
|
||||
$XML = new ParseXML();
|
||||
|
||||
$AllNodesString = $XML->GetElement($this->XMLContent, $LinkedNodesName);
|
||||
$tmpNodes = $XML->GetAllElements($AllNodesString, "NODE");
|
||||
|
||||
for ($i=0;$i<count($tmpNodes);$i++) {
|
||||
$Node = new Node(
|
||||
$XML->GetElement($tmpNodes[$i], 'Callsign'),
|
||||
$XML->GetElement($tmpNodes[$i], 'IP'),
|
||||
$XML->GetElement($tmpNodes[$i], 'LinkedModule'),
|
||||
$XML->GetElement($tmpNodes[$i], 'Protocol'),
|
||||
$XML->GetElement($tmpNodes[$i], 'ConnectTime'),
|
||||
$XML->GetElement($tmpNodes[$i], 'LastHeardTime'),
|
||||
CreateCode(16)
|
||||
);
|
||||
$this->AddNode($Node);
|
||||
}
|
||||
|
||||
$AllStationsString = $XML->GetElement($this->XMLContent, $LinkedUsersName);
|
||||
$tmpStations = $XML->GetAllElements($AllStationsString, "STATION");
|
||||
for ($i=0;$i<count($tmpStations);$i++) {
|
||||
$Station = new Station(
|
||||
$XML->GetElement($tmpStations[$i], 'Callsign'),
|
||||
$XML->GetElement($tmpStations[$i], 'Via node'),
|
||||
$XML->GetElement($tmpStations[$i], 'Via peer'),
|
||||
$XML->GetElement($tmpStations[$i], 'LastHeardTime'),
|
||||
$XML->GetElement($tmpStations[$i], 'On module')
|
||||
);
|
||||
$this->AddStation($Station, false);
|
||||
}
|
||||
|
||||
$AllPeersString = $XML->GetElement($this->XMLContent, $LinkedPeersName);
|
||||
$tmpPeers = $XML->GetAllElements($AllPeersString, "PEER");
|
||||
for ($i=0;$i<count($tmpPeers);$i++) {
|
||||
$Peer = new Peer(
|
||||
$XML->GetElement($tmpPeers[$i], 'Callsign'),
|
||||
$XML->GetElement($tmpPeers[$i], 'IP'),
|
||||
$XML->GetElement($tmpPeers[$i], 'LinkedModule'),
|
||||
$XML->GetElement($tmpPeers[$i], 'Protocol'),
|
||||
$XML->GetElement($tmpPeers[$i], 'ConnectTime'),
|
||||
$XML->GetElement($tmpPeers[$i], 'LastHeardTime')
|
||||
);
|
||||
$this->AddPeer($Peer, false);
|
||||
}
|
||||
|
||||
$this->Version = strip_tags($XML->GetElement($this->XMLContent, "Version"));
|
||||
}
|
||||
}
|
||||
|
||||
public function GetVersion() {
|
||||
return $this->Version;
|
||||
}
|
||||
|
||||
public function GetReflectorName() {
|
||||
return $this->ReflectorName;
|
||||
}
|
||||
|
||||
public function SetXMLFile($XMLFile) {
|
||||
// Prevent path traversal
|
||||
$XMLFile = basename($XMLFile);
|
||||
$XMLFile = '/var/log/' . $XMLFile; // Force it to expected directory
|
||||
|
||||
if (file_exists($XMLFile) && is_readable($XMLFile)) {
|
||||
$this->XMLFile = $XMLFile;
|
||||
}
|
||||
else {
|
||||
error_log("XML File ".$XMLFile." does not exist or is not readable");
|
||||
$this->XMLFile = null;
|
||||
$this->XMLContent = null;
|
||||
}
|
||||
}
|
||||
|
||||
public function SetPIDFile($ProcessIDFile) {
|
||||
// Prevent path traversal
|
||||
$ProcessIDFile = basename($ProcessIDFile);
|
||||
$ProcessIDFile = '/var/log/' . $ProcessIDFile;
|
||||
|
||||
if (file_exists($ProcessIDFile)) {
|
||||
$this->ProcessIDFile = $ProcessIDFile;
|
||||
$this->ServiceUptime = time() - filectime($ProcessIDFile);
|
||||
}
|
||||
else {
|
||||
$this->ProcessIDFile = null;
|
||||
$this->ServiceUptime = null;
|
||||
}
|
||||
}
|
||||
|
||||
public function GetServiceUptime() {
|
||||
return $this->ServiceUptime;
|
||||
}
|
||||
|
||||
public function SetFlagFile($Flagfile) {
|
||||
// Security: Only allow country.csv from the pgs directory
|
||||
$expectedFile = dirname(__FILE__) . '/country.csv';
|
||||
$realPath = realpath($Flagfile);
|
||||
|
||||
// Must resolve to the exact expected file
|
||||
if ($realPath !== $expectedFile) {
|
||||
error_log("Flag file must be country.csv in pgs directory. Expected: " . $expectedFile . ", Got: " . $realPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file_exists($realPath) && is_readable($realPath)) {
|
||||
$this->Flagfile = $realPath;
|
||||
return true;
|
||||
}
|
||||
|
||||
error_log("Flag file not readable: " . $realPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
public function LoadFlags() {
|
||||
if ($this->Flagfile != null) {
|
||||
$this->Flagarray = array();
|
||||
$this->Flagarray_DXCC = array();
|
||||
$handle = fopen($this->Flagfile,"r");
|
||||
if ($handle) {
|
||||
$i = 0;
|
||||
while(!feof($handle)) {
|
||||
$row = fgets($handle,1024);
|
||||
$tmp = explode(";", $row);
|
||||
|
||||
if (isset($tmp[0])) { $this->Flagarray[$i]['Country'] = $tmp[0]; } else { $this->Flagarray[$i]['Country'] = 'Undefined'; }
|
||||
if (isset($tmp[1])) { $this->Flagarray[$i]['ISO'] = $tmp[1]; } else { $this->Flagarray[$i]['ISO'] = "Undefined"; }
|
||||
//$this->Flagarray[$i]['DXCC'] = array();
|
||||
if (isset($tmp[2])) {
|
||||
$tmp2 = explode("-", $tmp[2]);
|
||||
for ($j=0;$j<count($tmp2);$j++) {
|
||||
//$this->Flagarray[$i]['DXCC'][] = $tmp2[$j];
|
||||
$this->Flagarray_DXCC[ trim($tmp2[$j]) ] = $i;
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
fclose($handle);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function AddNode($NodeObject) {
|
||||
if (is_object($NodeObject)) {
|
||||
$this->Nodes[] = $NodeObject;
|
||||
}
|
||||
}
|
||||
|
||||
public function NodeCount() {
|
||||
return count($this->Nodes);
|
||||
}
|
||||
|
||||
public function GetNode($ArrayIndex) {
|
||||
if (isset($this->Nodes[$ArrayIndex])) {
|
||||
return $this->Nodes[$ArrayIndex];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function AddPeer($PeerObject) {
|
||||
if (is_object($PeerObject)) {
|
||||
$this->Peers[] = $PeerObject;
|
||||
}
|
||||
}
|
||||
|
||||
public function PeerCount() {
|
||||
return count($this->Peers);
|
||||
}
|
||||
|
||||
public function GetPeer($ArrayIndex) {
|
||||
if (isset($this->Peer[$ArrayIndex])) {
|
||||
return $this->Peer[$ArrayIndex];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function AddStation($StationObject, $AllowDouble = false) {
|
||||
if (is_object($StationObject)) {
|
||||
|
||||
if ($AllowDouble) {
|
||||
$this->Stations[] = $StationObject;
|
||||
}
|
||||
else {
|
||||
$FoundStationInList = false;
|
||||
$i = 0;
|
||||
|
||||
$tmp = explode(" ", $StationObject->GetCallsign());
|
||||
$RealCallsign = trim($tmp[0]);
|
||||
|
||||
while (!$FoundStationInList && $i<$this->StationCount()) {
|
||||
if ($this->Stations[$i]->GetCallsignOnly() == $RealCallsign) {
|
||||
$FoundStationInList = true;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
if (!$FoundStationInList) {
|
||||
if (strlen(trim($RealCallsign)) > 3) {
|
||||
$this->Stations[] = $StationObject;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function GetSuffixOfRepeater($Repeater, $LinkedModul, $StartWithIndex = 0) {
|
||||
$suffix = "";
|
||||
$found = false;
|
||||
$i = $StartWithIndex;
|
||||
while (!$found && $i < $this->NodeCount()) {
|
||||
if ($this->Nodes[$i]->GetLinkedModule() == $LinkedModul) {
|
||||
if (strpos($this->Nodes[$i]->GetCallSign(), $Repeater) !== false) {
|
||||
$suffix = $this->Nodes[$i]->GetSuffix();
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
return $suffix;
|
||||
}
|
||||
|
||||
public function GetCallsignAndSuffixByID($RandomId) {
|
||||
$suffix = "";
|
||||
$callsign = "";
|
||||
$i = 0;
|
||||
while ($i < $this->NodeCount()) {
|
||||
if ($this->Nodes[$i]->GetRandomID() == $RandomId) {
|
||||
if (trim($this->Nodes[$i]->GetSuffix()) == "") {
|
||||
return $this->Nodes[$i]->GetCallSign();
|
||||
}
|
||||
else {
|
||||
return $this->Nodes[$i]->GetCallSign().'-'.$this->Nodes[$i]->GetSuffix();
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
return 'N/A';
|
||||
}
|
||||
|
||||
public function StationCount() {
|
||||
return count($this->Stations);
|
||||
}
|
||||
|
||||
public function GetStation($ArrayIndex) {
|
||||
if (isset($this->Stations[$ArrayIndex])) {
|
||||
return $this->Stations[$ArrayIndex];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function GetFlag($Callsign) {
|
||||
$Image = "";
|
||||
$Letters = 4;
|
||||
$Name = "";
|
||||
while ($Letters >= 2) {
|
||||
$Prefix = substr(trim($Callsign), 0, $Letters);
|
||||
if (isset($this->Flagarray_DXCC[$Prefix])) {
|
||||
$Image = $this->Flagarray[ $this->Flagarray_DXCC[$Prefix] ]['ISO'];
|
||||
$Name = $this->Flagarray[ $this->Flagarray_DXCC[$Prefix] ]['Country'];
|
||||
break;
|
||||
}
|
||||
$Letters--;
|
||||
}
|
||||
return array(strtolower($Image), $Name);
|
||||
}
|
||||
|
||||
public function GetModules() {
|
||||
$out = array();
|
||||
for ($i=0;$i<$this->NodeCount();$i++) {
|
||||
$Found = false;
|
||||
$b = 0;
|
||||
while ($b < count($out) && !$Found) {
|
||||
if ($out[$b] == $this->Nodes[$i]->GetLinkedModule()) {
|
||||
$Found = true;
|
||||
}
|
||||
$b++;
|
||||
}
|
||||
if (!$Found && (trim($this->Nodes[$i]->GetLinkedModule()) != "")) {
|
||||
$out[] = $this->Nodes[$i]->GetLinkedModule();
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function GetModuleOfNode($Node) {
|
||||
die("FUNCTION DEPRECATED...");
|
||||
$Node = trim(str_replace(" ", "-", $Node));
|
||||
$Node = trim(str_replace(" ", "-", $Node));
|
||||
$Node = trim(str_replace(" ", "-", $Node));
|
||||
$found = false;
|
||||
$i = 0;
|
||||
$Module = "";
|
||||
while (!$found && $i<$this->NodeCount()) {
|
||||
if (strpos($Node, $this->Nodes[$i]->GetFullCallsign()) !== false) {
|
||||
$Module = $this->Nodes[$i]->GetLinkedModule();
|
||||
$found = true;
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
return $Module;
|
||||
}
|
||||
|
||||
public function GetCallSignsInModules($Module) {
|
||||
$out = array();
|
||||
for ($i=0;$i<$this->NodeCount();$i++) {
|
||||
if ($this->Nodes[$i]->GetLinkedModule() == $Module) {
|
||||
$out[] = $this->Nodes[$i]->GetCallsign();
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function GetNodesInModulesById($Module) {
|
||||
$out = array();
|
||||
for ($i=0;$i<$this->NodeCount();$i++) {
|
||||
if ($this->Nodes[$i]->GetLinkedModule() == $Module) {
|
||||
$out[] = $this->Nodes[$i]->GetRandomID();
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function SetCallingHome($CallingHomeVariables, $Hash) {
|
||||
|
||||
if (!isset($CallingHomeVariables['Active'])) { $CallingHomeVariables['Active'] = false; }
|
||||
if (!isset($CallingHomeVariables['MyDashBoardURL'])) { $CallingHomeVariables['MyDashBoardURL'] = ''; }
|
||||
if (!isset($CallingHomeVariables['ServerURL'])) { $CallingHomeVariables['ServerURL'] = ''; }
|
||||
if (!isset($CallingHomeVariables['Country'])) { $CallingHomeVariables['Country'] = ''; }
|
||||
if (!isset($CallingHomeVariables['Comment'])) { $CallingHomeVariables['Comment'] = ''; }
|
||||
if (!isset($CallingHomeVariables['OverrideIPAddress'])) { $CallingHomeVariables['OverrideIPAddress'] = false; }
|
||||
if (!isset($CallingHomeVariables['InterlinkFile'])) { $CallingHomeVariables['InterlinkFile'] = ''; }
|
||||
|
||||
// Validate URLs
|
||||
if (!empty($CallingHomeVariables['MyDashBoardURL'])) {
|
||||
if (filter_var($CallingHomeVariables['MyDashBoardURL'], FILTER_VALIDATE_URL) === false) {
|
||||
$CallingHomeVariables['MyDashBoardURL'] = '';
|
||||
}
|
||||
}
|
||||
if (!empty($CallingHomeVariables['ServerURL'])) {
|
||||
if (filter_var($CallingHomeVariables['ServerURL'], FILTER_VALIDATE_URL) === false) {
|
||||
$CallingHomeVariables['ServerURL'] = '';
|
||||
}
|
||||
}
|
||||
|
||||
if (!file_exists($CallingHomeVariables['InterlinkFile'])) {
|
||||
$this->Interlinkfile = '';
|
||||
$this->Transferinterlink = false;
|
||||
}
|
||||
else {
|
||||
$this->Transferinterlink = true;
|
||||
$this->Interlinkfile = $CallingHomeVariables['InterlinkFile'];
|
||||
}
|
||||
|
||||
$this->CallingHomeActive = ($CallingHomeVariables['Active'] === true);
|
||||
$this->CallingHomeHash = $Hash;
|
||||
$this->CallingHomeDashboardURL = $CallingHomeVariables['MyDashBoardURL'];
|
||||
$this->CallingHomeServerURL = $CallingHomeVariables['ServerURL'];
|
||||
$this->CallingHomeCountry = $CallingHomeVariables['Country'];
|
||||
$this->CallingHomeComment = $CallingHomeVariables['Comment'];
|
||||
$this->CallingHomeOverrideIP = $CallingHomeVariables['OverrideIPAddress'];
|
||||
|
||||
}
|
||||
|
||||
public function PushCallingHome() {
|
||||
$CallingHome = @fopen($this->CallingHomeServerURL."?ReflectorName=".$this->ReflectorName."&ReflectorUptime=".$this->ServiceUptime."&ReflectorHash=".$this->CallingHomeHash."&DashboardURL=".$this->CallingHomeDashboardURL."&Country=".urlencode($this->CallingHomeCountry)."&Comment=".urlencode($this->CallingHomeComment)."&OverrideIP=".$this->CallingHomeOverrideIP, "r");
|
||||
}
|
||||
|
||||
public function ReadInterlinkFile() {
|
||||
if (empty($this->Interlinkfile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prevent path traversal
|
||||
$realPath = realpath($this->Interlinkfile);
|
||||
if ($realPath === false || strpos($realPath, '/xlxd/') === false) {
|
||||
error_log("ReadInterlinkFile blocked - invalid path");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file_exists($realPath) && is_readable($realPath)) {
|
||||
$this->Interlinks = array();
|
||||
$this->InterlinkXML = "";
|
||||
$Interlinkfilecontent = file($realPath);
|
||||
for ($i=0;$i<count($Interlinkfilecontent);$i++) {
|
||||
if (substr($Interlinkfilecontent[$i], 0, 1) != '#') {
|
||||
$Interlink = explode(" ", $Interlinkfilecontent[$i]);
|
||||
$this->Interlinks[] = new Interlink();
|
||||
if (isset($Interlink[0])) {
|
||||
$this->Interlinks[count($this->Interlinks)-1]->SetName(trim($Interlink[0]));
|
||||
}
|
||||
if (isset($Interlink[1])) {
|
||||
$this->Interlinks[count($this->Interlinks)-1]->SetAddress(trim($Interlink[1]));
|
||||
}
|
||||
if (isset($Interlink[2])) {
|
||||
$Modules = str_split(trim($Interlink[2]), 1);
|
||||
for ($j=0;$j<count($Modules);$j++) {
|
||||
$this->Interlinks[count($this->Interlinks)-1]->AddModule($Modules[$j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function PrepareInterlinkXML() {
|
||||
$xml = '
|
||||
<interlinks>';
|
||||
for ($i=0;$i<count($this->Interlinks);$i++) {
|
||||
$xml .= '
|
||||
<interlink>
|
||||
<name>'.htmlspecialchars($this->Interlinks[$i]->GetName(), ENT_XML1, 'UTF-8').'</name>
|
||||
<address>'.htmlspecialchars($this->Interlinks[$i]->GetAddress(), ENT_XML1, 'UTF-8').'</address>
|
||||
<modules>'.htmlspecialchars($this->Interlinks[$i]->GetModules(), ENT_XML1, 'UTF-8').'</modules>
|
||||
</interlink>';
|
||||
}
|
||||
$xml .= '
|
||||
</interlinks>';
|
||||
$this->InterlinkXML = $xml;
|
||||
}
|
||||
|
||||
public function PrepareReflectorXML() {
|
||||
$this->ReflectorXML = '
|
||||
<reflector>
|
||||
<name>'.htmlspecialchars($this->ReflectorName, ENT_XML1, 'UTF-8').'</name>
|
||||
<uptime>'.intval($this->ServiceUptime).'</uptime>
|
||||
<hash>'.htmlspecialchars($this->CallingHomeHash, ENT_XML1, 'UTF-8').'</hash>
|
||||
<url>'.htmlspecialchars($this->CallingHomeDashboardURL, ENT_XML1, 'UTF-8').'</url>
|
||||
<country>'.htmlspecialchars($this->CallingHomeCountry, ENT_XML1, 'UTF-8').'</country>
|
||||
<comment>'.htmlspecialchars($this->CallingHomeComment, ENT_XML1, 'UTF-8').'</comment>
|
||||
<ip>'.htmlspecialchars($this->CallingHomeOverrideIP, ENT_XML1, 'UTF-8').'</ip>
|
||||
<reflectorversion>'.htmlspecialchars($this->Version, ENT_XML1, 'UTF-8').'</reflectorversion>
|
||||
</reflector>';
|
||||
}
|
||||
|
||||
public function CallHome() {
|
||||
// Validate ServerURL is not localhost/internal IP
|
||||
$parsed = parse_url($this->CallingHomeServerURL);
|
||||
if (!isset($parsed['host'])) {
|
||||
error_log("CallHome failed - invalid URL");
|
||||
return false;
|
||||
}
|
||||
|
||||
$ip = gethostbyname($parsed['host']);
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) {
|
||||
error_log("CallHome blocked - internal/private IP detected");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sanitize all data being sent
|
||||
$xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<query>CallingHome</query>'.$this->ReflectorXML.$this->InterlinkXML;
|
||||
|
||||
$p = @stream_context_create(array('http' => array(
|
||||
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
|
||||
'method' => 'POST',
|
||||
'content' => http_build_query(array('xml' => $xml)),
|
||||
'timeout' => 10
|
||||
)));
|
||||
|
||||
$result = @file_get_contents($this->CallingHomeServerURL, false, $p);
|
||||
if ($result === false) {
|
||||
error_log("CallHome connection failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function InterlinkCount() {
|
||||
return count($this->Interlinks);
|
||||
}
|
||||
|
||||
public function GetInterlink($Index) {
|
||||
if (isset($this->Interlinks[$Index])) {
|
||||
return $this->Interlinks[$Index];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function IsInterlinked($Reflectorname) {
|
||||
$i = -1;
|
||||
$f = false;
|
||||
while (!$f && $i < $this->InterlinkCount()) {
|
||||
$i++;
|
||||
if (isset($this->Interlinks[$i])) {
|
||||
if ($this->Interlinks[$i]->GetName() == $Reflectorname) {
|
||||
$f = true;
|
||||
return $i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
?>
|
||||
54
dashboard1/pgs/class.station.php
Normal file
54
dashboard1/pgs/class.station.php
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
class Station {
|
||||
|
||||
private $Callsign;
|
||||
private $Via;
|
||||
private $LastHeardTime;
|
||||
private $Suffix;
|
||||
private $CallsignOnly;
|
||||
private $Peer;
|
||||
private $OnModule;
|
||||
|
||||
public function __construct($Callsign, $Via, $Peer, $LastHeardTime, $OnModule) {
|
||||
// Sanitize and validate callsign
|
||||
$Callsign = trim($Callsign);
|
||||
$this->Callsign = $Callsign;
|
||||
|
||||
// Sanitize Via and Peer
|
||||
$this->Via = trim($Via);
|
||||
$this->Peer = trim($Peer);
|
||||
|
||||
$this->LastHeardTime = ParseTime($LastHeardTime);
|
||||
|
||||
if (strpos($Callsign, " / ") !== false) {
|
||||
$this->Suffix = trim(substr($Callsign, strpos($Callsign, " / ")+3));
|
||||
}
|
||||
else {
|
||||
$this->Suffix = "";
|
||||
}
|
||||
|
||||
$tmp = explode(" ", $Callsign);
|
||||
$this->CallsignOnly = isset($tmp[0]) ? trim($tmp[0]) : '';
|
||||
|
||||
// Validate callsign format
|
||||
if (!empty($this->CallsignOnly) && !preg_match('/^[A-Z0-9]{1,10}$/i', $this->CallsignOnly)) {
|
||||
$this->CallsignOnly = 'INVALID';
|
||||
}
|
||||
|
||||
// Validate OnModule (single letter A-Z)
|
||||
$OnModule = trim(strtoupper($OnModule));
|
||||
$this->OnModule = preg_match('/^[A-Z]$/', $OnModule) ? $OnModule : '';
|
||||
}
|
||||
|
||||
public function GetCallsign() { return $this->Callsign; }
|
||||
public function GetVIA() { return $this->Via; }
|
||||
public function GetPeer() { return $this->Peer; }
|
||||
public function GetLastHeardTime() { return $this->LastHeardTime; }
|
||||
public function GetSuffix() { return $this->Suffix; }
|
||||
public function GetCallsignOnly() { return $this->CallsignOnly; }
|
||||
public function GetModule() { return $this->OnModule; }
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
84
dashboard1/pgs/config.inc.php
Normal file
84
dashboard1/pgs/config.inc.php
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
/*
|
||||
Possible values for IPModus
|
||||
|
||||
HideIP
|
||||
ShowFullIP
|
||||
ShowLast1ByteOfIP
|
||||
ShowLast2ByteOfIP
|
||||
ShowLast3ByteOfIP
|
||||
|
||||
*/
|
||||
|
||||
$Service = array();
|
||||
$CallingHome = array();
|
||||
$PageOptions = array();
|
||||
$VNStat = array();
|
||||
|
||||
$PageOptions['ContactEmail'] = 'your_email'; // Support E-Mail address
|
||||
|
||||
$PageOptions['DashboardVersion'] = '2.4.3'; // Dashboard Version
|
||||
|
||||
$PageOptions['PageRefreshActive'] = true; // Activate automatic refresh
|
||||
$PageOptions['PageRefreshDelay'] = '10000'; // Page refresh time in miliseconds
|
||||
|
||||
$PageOptions['NumberOfModules'] = 10; // Number of Modules enabled on reflector
|
||||
|
||||
$PageOptions['RepeatersPage'] = array();
|
||||
$PageOptions['RepeatersPage']['LimitTo'] = 99; // Number of Repeaters to show
|
||||
$PageOptions['RepeatersPage']['IPModus'] = 'ShowFullIP'; // See possible options above
|
||||
$PageOptions['RepeatersPage']['MasqueradeCharacter'] = '*'; // Character used for masquerade
|
||||
|
||||
$PageOptions['PeerPage'] = array();
|
||||
$PageOptions['PeerPage']['LimitTo'] = 99; // Number of peers to show
|
||||
$PageOptions['PeerPage']['IPModus'] = 'ShowFullIP'; // See possible options above
|
||||
$PageOptions['PeerPage']['MasqueradeCharacter'] = '*'; // Character used for masquerade
|
||||
|
||||
$PageOptions['LastHeardPage']['LimitTo'] = 39; // Number of stations to show
|
||||
|
||||
$PageOptions['ModuleNames'] = array(); // Module nomination
|
||||
$PageOptions['ModuleNames']['A'] = 'Int.';
|
||||
$PageOptions['ModuleNames']['B'] = 'Regional';
|
||||
$PageOptions['ModuleNames']['C'] = 'National';
|
||||
$PageOptions['ModuleNames']['D'] = '';
|
||||
|
||||
$PageOptions['MetaDescription'] = 'XLX is a D-Star Reflector System for Ham Radio Operators.'; // Meta Tag Values, usefull for Search Engine
|
||||
$PageOptions['MetaKeywords'] = 'Ham Radio, D-Star, XReflector, XLX, XRF, DCS, REF, '; // Meta Tag Values, usefull forSearch Engine
|
||||
$PageOptions['MetaAuthor'] = 'LX1IQ'; // Meta Tag Values, usefull for Search Engine
|
||||
$PageOptions['MetaRevisit'] = 'After 30 Days'; // Meta Tag Values, usefull for Search Engine
|
||||
$PageOptions['MetaRobots'] = 'index,follow'; // Meta Tag Values, usefull for Search Engine
|
||||
|
||||
$PageOptions['UserPage']['ShowFilter'] = true; // Show Filter on Users page
|
||||
$PageOptions['Traffic']['Show'] = false; // Enable vnstat traffic statistics
|
||||
$PageOptions['IRCDDB']['Show'] = true; // Show liveircddb, set it to false if you are running your db in https
|
||||
|
||||
$PageOptions['CustomTXT'] = ''; // custom text in your header
|
||||
|
||||
$Service['PIDFile'] = '/var/log/xlxd.pid';
|
||||
$Service['XMLFile'] = '/var/log/xlxd.xml';
|
||||
|
||||
$CallingHome['Active'] = false; // xlx phone home, true or false
|
||||
$CallingHome['MyDashBoardURL'] = 'http://your_dashboard'; // dashboard url
|
||||
$CallingHome['ServerURL'] = 'http://xlxapi.rlx.lu/api.php'; // database server, do not change !!!!
|
||||
$CallingHome['PushDelay'] = 600; // push delay in seconds
|
||||
$CallingHome['Country'] = "your_country"; // Country
|
||||
$CallingHome['Comment'] = "your_comment"; // Comment. Max 100 character
|
||||
$CallingHome['HashFile'] = "/tmp/callinghome.php"; // Make sure the apache user has read and write permissions in this folder.
|
||||
$CallingHome['LastCallHomefile'] = "/tmp/lastcallhome.php"; // lastcallhome.php can remain in the tmp folder
|
||||
$CallingHome['OverrideIPAddress'] = ""; // Insert your IP address here. Leave blank for autodetection. No need to enter a fake address.
|
||||
$CallingHome['InterlinkFile'] = "/xlxd/xlxd.interlink"; // Path to interlink file
|
||||
|
||||
$VNStat['Interfaces'] = array();
|
||||
$VNStat['Interfaces'][0]['Name'] = 'eth0';
|
||||
$VNStat['Interfaces'][0]['Address'] = 'eth0';
|
||||
$VNStat['Binary'] = '/usr/bin/vnstat';
|
||||
|
||||
/*
|
||||
include an extra config file for people who dont like to mess with shipped config.ing.php
|
||||
this makes updating dashboard from git a little bit easier
|
||||
*/
|
||||
if (file_exists("../config.inc.php")) {
|
||||
include ("../config.inc.php");
|
||||
}
|
||||
|
||||
?>
|
||||
309
dashboard1/pgs/country.csv
Normal file
309
dashboard1/pgs/country.csv
Normal file
|
|
@ -0,0 +1,309 @@
|
|||
Afghanistan;AF;YA-T6
|
||||
Agalega & St. Brandon Island;MU;3B6-3B7
|
||||
Aland Islands;AX;OH0
|
||||
Alaska;US;AL-KL-NL-WL
|
||||
Albania;AL;ZA
|
||||
Algeria;DZ;7T-7U-7V-7W-7X-7Y
|
||||
American Samoa;AS;KH8
|
||||
Andaman & Nicobar Islands;IN;VU4
|
||||
Andorra;AD;C3
|
||||
Angola;AO;D2-D3
|
||||
Anguilla;AI;VP2E
|
||||
Annobon Island;GQ;3C0
|
||||
Antarctica;AQ;CE9-KC4A-KC4U
|
||||
Antigua and Barbuda;AG;V2
|
||||
Argentina;AR;LO-LP-LQ-LR-LS-LT-LU-LV-LW
|
||||
Armenia;AM;EK
|
||||
Aruba;AW;P4
|
||||
Ascension Island;SH;ZD8
|
||||
Asiatic Russia;RU;UA0-UA8-UA9-UB0-UB8-UB9-UC0-UC8-UC9-UD0-UD8-UD9-UE0-UE8-UE9-UF0-UF8-UF9-UG0-UG8-UG9-UH0-UH8-UH9-UI0-UI8-UI9-RA0-RA8-RA9-RB0-RB8-RB9-RC0-RC8-RC9-RD0-RD8-RD9-RE0-RE8-RE9-RF0-RF8-RF9-RG0-RG8-RG9-RH0-RH8-RH9-RI0-RI8-RI9-RJ0-RJ8-RJ9-RK0-RK8-RK9-RL0-RL8-RL9-RM0-RM8-RM9-RN0-RN8-RN9-RO0-RO8-RO9-RP0-RP8-RP9-RQ0-RQ8-RQ9-RR0-RR8-RR9-RS0-RS8-RS9-RT0-RT8-RT9-RU0-RU8-RU9-RV0-RV8-RV9-RW0-RW8-RW9-RX0-RX8-RX9-RY0-RY8-RY9-RZ0-RZ8-RZ9-R8-R9
|
||||
Australia;AU;VK-AX
|
||||
Austria;AT;OE
|
||||
Azerbaijan;AZ;4J-4K
|
||||
Azores;PT;CU
|
||||
Bahamas;BS;C6
|
||||
Bahrain;BH;A9
|
||||
Baker & Howland Islands;US;KH1
|
||||
Balearic Islands;ES;EA6-EB6-EC6-ED6-EE6-EF6-EG6-EH6
|
||||
Banaba Island (Ocean Island);KI;T33
|
||||
Bangladesh;BD;S2
|
||||
Barbados;BB;8P
|
||||
Belarus;BY;EU-EV-EW
|
||||
Belgium;BE;ON-OO-OP-OQ-OR-OS-OT
|
||||
Belize;BZ;V3
|
||||
Benin;BJ;TY
|
||||
Bermuda;BM;VP9
|
||||
Bhutan;BT;A5
|
||||
Bolivia Plurinational State of;BO;CP
|
||||
Bonaire;NL;PJ4
|
||||
Bosnia and Herzegovina;BA;E7
|
||||
Botswana;BW;A2
|
||||
Bouvet Island;BV;3Y
|
||||
Brazil;BR;PP-PQ-PR-PS-PT-PU-PV-PW-PX-PY-ZV-ZW-ZX-ZY-ZZ
|
||||
British Indian Ocean Territory;IO;VP2V
|
||||
Brunei Darussalam;BN;V8
|
||||
Bulgaria;BG;LZ
|
||||
Burkina Faso;BF;XT
|
||||
Burundi;BI;9U
|
||||
Cambodia;KH;XU
|
||||
Cameroon;CM;TJ
|
||||
Canada;CA;VA-VB-VC-VD-VE-VF-VG-VO-VY
|
||||
Canary Islands;ES;EA8-EB8-EC8-ED8-EE8-EF8-EG8-EH8
|
||||
Cape Verde;CV;D4
|
||||
Cayman Islands;KY;ZF
|
||||
Central African Republic;CF;TL
|
||||
Central Kiribati (British Phoenix Island);KI;T31
|
||||
Ceuta & Melilla;ES;EA9-EB9-EC9-ED9-EE9-EF9-EG9-EH9
|
||||
Chad;TD;TT
|
||||
Chagos Islands;;VQ9
|
||||
Chatham Islands;NZ;ZL7
|
||||
Chile;CL;CA-CB-CC-CD-CE-XQ-XR
|
||||
China;CN;BA-BB-BC-BD-BE-BF-BG-BH-BI-BJ-BK-BL-BN-BP-BQ-BR-BS-BT-BY-BZ
|
||||
Christmas Island;CX;VK9X
|
||||
Cocos Island;;TI9
|
||||
Cocos (Keeling) Islands;CC;VK9C
|
||||
Colombia;CO;HJ-HK-5J-5K
|
||||
Comoros;KM;D6
|
||||
Congo;CG;TN
|
||||
Congo the Democratic Republic of the;CD;9Q-9R-9S-9T
|
||||
Cook Islands;CK;E5
|
||||
Corsica;FR;TK
|
||||
Costa Rica;CR;TI-TE
|
||||
Cote d'Ivoire;CI;TU
|
||||
Crete;GR;SV9-J49
|
||||
Croatia;HR;9A
|
||||
Cuba;CU;CO-CM
|
||||
Curacao;CW;PJ2
|
||||
Cyprus;CY;5B-C4-P3
|
||||
Czech Republic;CZ;OK-OL
|
||||
Denmark;DK;OU-OV-OW-OZ
|
||||
Desecheo Island;US;KP5
|
||||
Djibouti;DJ;J2
|
||||
Dodecanese;GR;SV5-J45
|
||||
Dominica;DM;J7
|
||||
Dominican Republic;DO;HI
|
||||
East Malaysia;MY;9M6-9M8-9W6-9W8
|
||||
Easter Island;CL;CE0
|
||||
Eastern Kiribati (Line Island);KI;T32
|
||||
Ecuador;EC;HC-HD
|
||||
Egypt;EG;SU
|
||||
El Salvador;SV;YS-HU
|
||||
England;EN;2E-M0-M1-M2-M3-M4-M5-M6-M7-M8-M9-MB-MX-G0-G1-G2-G3-G4-G5-G6-G7-G8-G9-GB-GX
|
||||
Equatorial Guinea;GQ;3C
|
||||
Eritrea;ER;E3
|
||||
Estonia;EE;ES
|
||||
Ethiopia;ET;ET
|
||||
European Russia;RU;UA1-UA3-UA4-UA5-UA6-UA7-UB1-UB2-UB3-UB4-UB5-UB6-UB7-UC1-UC2-UC3-UC4-UC5-UC6-UC7-UD1-UD2-UD3-UD4-UD5-UD6-UD7-UE1-UE2-UE3-UE4-UE5-UE6-UE7-UF1-UF2-UF3-UF4-UF5-UF6-UF7-UG1-UG2-UG3-UG4-UG5-UG6-UG7-UH1-UH2-UH3-UH4-UH5-UH6-UH7-UI1-UI2-UI3-UI4-UI5-UI6-UI7-RA1-RA3-RA4-RA5-RA6-RA7-RB1-RB2-RB3-RB4-RB5-RB6-RB7-RC1-RC2-RC3-RC4-RC5-RC6-RC7-RD1-RD2-RD3-RD4-RD5-RD6-RD7-RE1-RE2-RE3-RE4-RE5-RE6-RE7-RF1-RF2-RF3-RF4-RF5-RF6-RF7-RG1-RG2-RG3-RG4-RG5-RG6-RG7-RH1-RH2-RH3-RH4-RH5-RH6-RH7-RI1-RI2-RI3-RI4-RI5-RI6-RI7-RJ1-RJ2-RJ3-RJ4-RJ5-RJ6-RJ7-RK1-RK2-RK3-RK4-RK5-RK6-RK7-RL1-RL2-RL3-RL4-RL5-RL6-RL7-RM1-RM2-RM3-RM4-RM5-RM6-RM7-RN1-RN2-RN3-RN4-RN5-RN6-RN7-RO1-RO2-RO3-RO4-RO5-RO6-RO7-RP1-RP2-RP3-RP4-RP5-RP6-RP7-RQ1-RQ2-RQ3-RQ4-RQ5-RQ6-RQ7-RR1-RR2-RR3-RR4-RR5-RR6-RR7-RS1-RS2-RS3-RS4-RS5-RS6-RS7-RT1-RT2-RT3-RT4-RT5-RT6-RT7-RU1-RU2-RU3-RU4-RU5-RU6-RU7-RV1-RV2-RV3-RV4-RV5-RV6-RV7-RW1-RW2-RW3-RW4-RW5-RW6-RW7-RX1-RX2-RX3-RX4-RX5-RX6-RX7-RY1-RY2-RY3-RY4-RY5-RY6-RY7-RZ1-RZ2-RZ3-RZ4-RZ5-RZ6-RZ7-R1-R2-R3-R4-R5-R6-R7
|
||||
Falkland Islands (Malvinas);FK;VP8
|
||||
Faroe Islands;FO;OY
|
||||
Fiji;FJ;3D2
|
||||
Finland;FI;OF-OG-OH-OI
|
||||
France;FR;F0-F1-F2-F3-F4-F5-F6-F7-F8-F9
|
||||
Franz Josef Land;RU;R1
|
||||
French Guiana;GF;FY
|
||||
French Southern and Antarctic Lands;FR;FT
|
||||
French Polynesia;PF;FO-TX
|
||||
Gabon;GA;TR
|
||||
Galapagos Islands;EC;HC8-HD8
|
||||
Gambia;GM;C5
|
||||
Georgia;GE;4L
|
||||
Germany;DE;DA-DB-DC-DD-DE-DF-DG-DH-DI-DJ-DK-DL-DM-DN-DO-DP-DQ-DR
|
||||
Ghana;GH;9G
|
||||
Gibraltar;GI;ZB2
|
||||
Greece;GR;SV-SW-SX-SY-SZ-J4
|
||||
Greenland;GL;OX
|
||||
Grenada;GD;J3
|
||||
Guadeloupe;GP;FG
|
||||
Guam;GU;KH2
|
||||
Guantanamo Bay;US;KG4
|
||||
Guatemala;GT;TG-TD
|
||||
Guernsey;GG;2U-MU-MP-GU-GP
|
||||
Guinea;GN;3X
|
||||
Guinea-Bissau;GW;J5
|
||||
Guyana;GY;8R
|
||||
Haiti;HT;HH
|
||||
Hawaii;US;KH6-KH7
|
||||
Heard Island and McDonald Islands;HM;VK0
|
||||
Holy See (Vatican City State);VA;HV
|
||||
Honduras;HN;HQ-HR
|
||||
Hong Kong;HK;VR
|
||||
Hungary;HU;HA-HG
|
||||
Iceland;IS;TF
|
||||
India;IN;VU
|
||||
Indonesia;ID;YB-YC-YD-YE-YF-YG-YH
|
||||
Iran Islamic Republic of;IR;EP-EQ
|
||||
Iraq;IQ;YI
|
||||
Ireland;IE;EI-EJ
|
||||
Isle of Man;IM;2D-MD-MT-GD-GT
|
||||
Israel;IL;4X-4Z
|
||||
Italy;IT;I0-I1-I2-I3-I4-I5-I6-I7-I8-I9-IK-IN-IQ-IR-IS-IT-IU-IV-IW-IZ
|
||||
Jamaica;JM;6Y
|
||||
Jan Mayen;NO;JX
|
||||
Japan;JP;JA-JB-JC-JD-JE-JF-JG-JH-JI-JJ-JK-JL-JM-JN-JO-JP-JQ-JR-JS-7J-7K-7L-7M-7N-8J-8N
|
||||
Jersey;JE;2J-MJ-MH-GJ-GH
|
||||
Johnston Island;US;KH3
|
||||
Jordan;JO;JY
|
||||
Kaliningrad;RU;UA2-RA2
|
||||
Kazakhstan;KZ;UN-UO-UP-UQ
|
||||
Kenya;KE;5Y-5Z
|
||||
Kermadec Islands;NZ;ZL8
|
||||
Korea Democratic People's Republic of;KP;P5
|
||||
Korea Republic of;KR;HL-6K-6L-6M-6N-DS
|
||||
Kure Island;US;KH7K
|
||||
Kuwait;KW;9K
|
||||
Kyrgyzstan;KG;EX
|
||||
Lakshadweep Islands;IN;VU7
|
||||
Lao People's Democratic Republic;LA;XW
|
||||
Latvia;LV;YL
|
||||
Lebanon;LB;OD
|
||||
Lesotho;LS;7P
|
||||
Liberia;LR;EL
|
||||
Libya;LY;5A
|
||||
Liechtenstein;LI;HB0
|
||||
Lithuania;LT;LY
|
||||
Lord Howe Island;AU;VK9L
|
||||
Luxembourg;LU;LX
|
||||
Macao;MO;XX9
|
||||
Macedonia;MK;Z3
|
||||
Madagascar;MG;5R
|
||||
Madeira Island;PT;CT3
|
||||
Malawi;MW;7Q
|
||||
Maldives;MV;8Q
|
||||
Mali;ML;TZ
|
||||
Malta;MT;9H
|
||||
Mariana Islands;US;KH0
|
||||
Market Reef;;OJ0
|
||||
Marshall Islands;MH;V7
|
||||
Martinique;MQ;FM
|
||||
Mauritania;MR;5T
|
||||
Mauritius;MU;3B8
|
||||
Mayotte;YT;FH-FO
|
||||
Mellish Reef;AU;VK9M
|
||||
Mexico;MX;XA-XB-XC-XD-XE-XF-XG-XH-XI
|
||||
Micronesia Federated States of;FM;V6
|
||||
Midway Island;US;KH4
|
||||
Moldova Republic of;MD;ER
|
||||
Monaco;MC;3A
|
||||
Mongolia;MN;JT-JU-JV
|
||||
Montenegro;ME;4O
|
||||
Montserrat;MS;VP2M
|
||||
Morocco;MA;CN
|
||||
Mozambique;MZ;C8-C9
|
||||
Myanmar;MM;XY-XZ
|
||||
Namibia;NA;V5
|
||||
Nauru;NR;C2
|
||||
Navassa Island;;KP1
|
||||
Nepal;NP;9N
|
||||
Netherlands;NL;PA-PB-PC-PD-PE-PF-PG-PH-PI
|
||||
New Caledonia;NC;FK
|
||||
New Zealand;NZ;ZL-ZM
|
||||
New Zealand Subantarctic Islands;NZ;ZL9
|
||||
Nicaragua;NI;YN-H6-H7-HT
|
||||
Niger;NE;5U
|
||||
Nigeria;NG;5N
|
||||
Niue;NU;ZK2
|
||||
Norfolk Island;NF;VK9N
|
||||
Northern Ireland;NIE;2I-MI-MN-GI-GN
|
||||
Northern Mariana Islands;MP;KH0
|
||||
Norway;NO;LA-LB-LC-LD-LE-LF-LG-LH-LI-LJ-LK-LL-LM-LN
|
||||
Oman;OM;A4-YP-YQ-YR
|
||||
Pakistan;PK;AP
|
||||
Palau;PW;T8
|
||||
Palestine State of;PS;E4
|
||||
Palmyra & Jarvis Island;UM;KH5
|
||||
Panama;PA;HO-HP
|
||||
Papua New Guinea;PG;P2
|
||||
Paraguay;PY;ZP
|
||||
Peru;PE;OA-OB-OC
|
||||
Philippines;PH;DU-DV-DW-DX-DY-DZ
|
||||
Pitcairn;PN;VP6
|
||||
Poland;PL;3Z6-SN-SO-SP-SQ-SR
|
||||
Portugal;PT;CQ0-CQ1-CQ2-CQ3-CQ7-CQ8-CR1-CR2-CR3-CR5-CR6-CR7-CR8-CR9-CS2-CS3-CS4-CS5-CS7-CS8-CT1-CT2-CT3-CT4-CT5-CT6-CT7-CT8-CT9-CU0-CU1-CU2-CU3-CU4-CU5-CU6-CU7-CU8-CU
|
||||
Pratas Islands;;BV9P
|
||||
Prince Edward & Marion Islands;ZA;ZS8
|
||||
Puerto Rico;PR;KP3-KP4
|
||||
Qatar;QA;A7
|
||||
Reunion;RE;FR
|
||||
Revillagigedo Islands;MX;XA4-XB4-XC4-XD4-XE4-XF4-XG4-XH4-XI4
|
||||
Rodriguez Island;MU;3B9
|
||||
Romania;RO;YO-YP-YQ-YR
|
||||
Rwanda;RW;9X
|
||||
Sable Island;CA;CY0
|
||||
Saint Barthelemy;BL;FJ
|
||||
Saint Helena;SH;ZD7
|
||||
Saint Kitts and Nevis;KN;V4
|
||||
Saint Lucia;LC;J6
|
||||
Saint Martin (French part);MF;FS
|
||||
Saint Pierre and Miquelon;PM;FP
|
||||
Saint Vincent and the Grenadines;VC;J8
|
||||
Samoa;WS;5W
|
||||
San Marino;SM;T7
|
||||
Sao Tome and Principe;ST;S9
|
||||
Sardinia;IT;IS0-IM0
|
||||
Saudi Arabia;SA;HZ
|
||||
Scarborough Reef;;BS7
|
||||
Scotland;SH;2M-MM-MS-GM-GS
|
||||
Senegal;SN;6V-6W
|
||||
Serbia;RS;YT-YU
|
||||
Seychelles;SC;S7
|
||||
Sierra Leone;SL;9L
|
||||
Singapore;SG;9V
|
||||
Sint Eustatius and Saba;NL;PJ5-PJ6
|
||||
Sint Maarten (Dutch part);SX;PJ7
|
||||
Slovakia;SK;OM
|
||||
Slovenia;SI;S5
|
||||
Solomon Islands;SB;H4
|
||||
Somalia;SO;T5-6O
|
||||
South Africa;ZA;ZR-ZS-ZT-ZU
|
||||
South Georgia and the South Sandwich Islands;GS;VP8S
|
||||
South Sudan;SS;Z8
|
||||
Spain;ES;EA-EB-EC-ED-EE-EF-EG-EH
|
||||
Sri Lanka;LK;4S
|
||||
St. Paul Island;US;CY9
|
||||
Sudan;SD;ST
|
||||
Suriname;SR;PZ
|
||||
Svalbard;NO;JW
|
||||
Swaziland;SZ;3DA
|
||||
Sweden;SE;SA-SB-SC-SD-SE-SF-SG-SH-SI-SJ-SK-SL-SM-7S-8S
|
||||
Switzerland;CH;HB
|
||||
Syrian Arab Republic;SY;YK
|
||||
Taiwan Province of China;TW;BM-BO-BU-BV-BW-BX
|
||||
Tajikistan;TJ;EY
|
||||
Tanzania United Republic of;TZ;5H-5I
|
||||
Temotu Province;SB;H40
|
||||
Thailand;TH;HS-E2
|
||||
Timor-Leste;TL;4W
|
||||
Togo;TG;5V
|
||||
Tokelau;TK;ZK3
|
||||
Tonga;TO;A3
|
||||
Trinidad and Tobago;TT;9Y-9Z
|
||||
Tristan da Cunha & Gough Island;SH;ZD9
|
||||
Tunisia;TN;3V
|
||||
Turkey;TR;TA-TB-TC
|
||||
Turkmenistan;TM;EZ
|
||||
Turks and Caicos Islands;TC;VP5
|
||||
Tuvalu;TV;T2
|
||||
Uganda;UG;5X
|
||||
UK Sov. Base Areas on Cyprus;CY;ZC4
|
||||
Ukraine;UA;UR-US-UT-UU-UV-UW-UX-UY-UZ-EM-EN-EO
|
||||
United Arab Emirates;AE;A6
|
||||
United States;US;AA-AB-AC-AD-AE-AF-AG-AH-AI-AJ-AK-K0-K1-K2-K3-K4-K5-K6-K7-K8-K9-KA-KB-KC-KD-KE-KF-KG-KH-KI-KJ-KK-KM-KN-KO-KP-KQ-KR-KS-KT-KU-KV-KW-KX-KY-KZ-N0-N1-N2-N3-N4-N5-N6-N7-N8-N9-NA-NB-NC-ND-NE-NF-NG-NH-NI-NJ-NK-NM-NN-NO-NP-NQ-NR-NS-NT-NU-NV-NW-NX-NY-NZ-W0-W1-W2-W3-W4-W5-W6-W7-W8-W9-WA-WB-WC-WD-WE-WF-WG-WH-WI-WJ-WK-WM-WN-WO-WP-WQ-WR-WS-WT-WU-WV-WW-WX-WY-WZ
|
||||
Uruguay;UY;CV-CW-CX
|
||||
Uzbekistan;UZ;UJ-UK-UL-UM
|
||||
Vanuatu;VU;YJ
|
||||
Venezuela Bolivarian Republic of;VE;YV-YW-YX-YY-4M
|
||||
Aves Island;VE;YV0
|
||||
Viet Nam;VN;3W-XV
|
||||
Virgin Islands British;VG;VP2V
|
||||
Virgin Islands U.S.;VI;KP2
|
||||
Wake Island;US;KH9
|
||||
Wales;WL;2W-MW-MC-GW-GC
|
||||
Wallis and Futuna;WF;FW
|
||||
West Malaysia;MY;9M2-9M4-9W2-9W4
|
||||
Western Kiribati (Gilbert Island);KI;T30
|
||||
Western Sahara;EH;S0
|
||||
Willis Island;AU;VK9W
|
||||
Yemen;YE;7O
|
||||
Zambia;ZM;9I-9J
|
||||
Zimbabwe;ZW;Z2
|
||||
GATE;GATE;REF-XRF
|
||||
|
228
dashboard1/pgs/functions.php
Normal file
228
dashboard1/pgs/functions.php
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
<?php
|
||||
function sanitize_output($string) {
|
||||
if ($string === null) return '';
|
||||
return htmlspecialchars($string, ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
||||
}
|
||||
|
||||
function sanitize_attribute($string) {
|
||||
if ($string === null) return '';
|
||||
return htmlspecialchars($string, ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
||||
}
|
||||
|
||||
function validate_callsign($callsign) {
|
||||
$callsign = trim($callsign);
|
||||
if (preg_match('/^[A-Z0-9\-\/\s]{3,20}$/i', $callsign)) {
|
||||
return strtoupper($callsign);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function validate_module($module) {
|
||||
$module = trim(strtoupper($module));
|
||||
if (preg_match('/^[A-Z]$/', $module)) {
|
||||
return $module;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function validate_protocol($protocol) {
|
||||
$allowed = ['DPlus', 'DExtra', 'DCS', 'DMR', 'YSF', 'DEXTRA', 'DPLUS', 'DMRMmdvm', 'XLX'];
|
||||
return in_array(trim($protocol), $allowed, true) ? trim($protocol) : '';
|
||||
}
|
||||
|
||||
function GetSystemUptime() {
|
||||
if (file_exists('/proc/uptime')) {
|
||||
$uptime = @file_get_contents('/proc/uptime');
|
||||
if ($uptime !== false) {
|
||||
$parts = explode(' ', $uptime);
|
||||
return isset($parts[0]) ? (int)$parts[0] : 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function Debug($message) {
|
||||
if (defined('DEBUG_MODE') && DEBUG_MODE === true) {
|
||||
echo '<br><hr><pre>';
|
||||
print_r($message); // Don't sanitize here as it's debug only
|
||||
echo '</pre><hr><br>';
|
||||
}
|
||||
}
|
||||
|
||||
function ParseTime($Input) {
|
||||
if (empty($Input) || !is_string($Input)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$Input = strip_tags($Input); // Remove any HTML tags
|
||||
|
||||
if (strpos($Input, "<") !== false) {
|
||||
$Input = substr($Input, 0, strpos($Input, "<"));
|
||||
}
|
||||
|
||||
// Tuesday Tue Nov 17 14:23:22 2015
|
||||
$tmp = explode(" ", $Input);
|
||||
|
||||
// Add bounds checking
|
||||
if (count($tmp) < 6) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen(trim($tmp[3])) == 0) {
|
||||
unset($tmp[3]);
|
||||
$tmp = array_values($tmp);
|
||||
}
|
||||
|
||||
// Check array indices exist after potential unset
|
||||
if (!isset($tmp[4]) || !isset($tmp[2]) || !isset($tmp[3]) || !isset($tmp[5])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$tmp1 = explode(":", $tmp[4]);
|
||||
|
||||
// Check time parts exist
|
||||
if (count($tmp1) < 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$month = "";
|
||||
switch (strtolower($tmp[2])) {
|
||||
case 'jan' : $month = 1; break;
|
||||
case 'feb' : $month = 2; break;
|
||||
case 'mar' : $month = 3; break;
|
||||
case 'apr' : $month = 4; break;
|
||||
case 'may' : $month = 5; break;
|
||||
case 'jun' : $month = 6; break;
|
||||
case 'jul' : $month = 7; break;
|
||||
case 'aug' : $month = 8; break;
|
||||
case 'sep' : $month = 9; break;
|
||||
case 'oct' : $month = 10; break;
|
||||
case 'nov' : $month = 11; break;
|
||||
case 'dec' : $month = 12; break;
|
||||
default : $month = 1;
|
||||
}
|
||||
return @mktime($tmp1[0], $tmp1[1], $tmp1[2], $month, $tmp[3], $tmp[5]);
|
||||
}
|
||||
|
||||
function FormatSeconds($seconds) {
|
||||
$seconds = abs($seconds);
|
||||
return sprintf("%d days %02d:%02d:%02d", $seconds/60/60/24,($seconds/60/60)%24,($seconds/60)%60,$seconds%60);
|
||||
}
|
||||
|
||||
function CreateCode ($laenge) {
|
||||
$zeichen = "1234567890abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNAOPQRSTUVWYXZ";
|
||||
$out = "";
|
||||
for ($i=1;$i<=$laenge;$i++){
|
||||
$out .= $zeichen[mt_rand(0,(strlen($zeichen)-1))];
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
function VNStatLocalize($str) {
|
||||
global $L;
|
||||
if (isset($L[$str])) {
|
||||
return $L[$str];
|
||||
}
|
||||
else {
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
function VNStatGetData($iface, $vnstat_bin) {
|
||||
// Validate interface name (only allow alphanumeric, dash, underscore)
|
||||
if (!preg_match('/^[a-zA-Z0-9_-]+$/', $iface)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Validate vnstat binary path
|
||||
if (!file_exists($vnstat_bin) || !is_executable($vnstat_bin)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Escape shell arguments
|
||||
$iface_escaped = escapeshellarg($iface);
|
||||
$vnstat_bin_escaped = escapeshellarg($vnstat_bin);
|
||||
|
||||
$vnstat_data = array();
|
||||
|
||||
$fd = @popen("$vnstat_bin_escaped --dumpdb -i $iface_escaped", "r");
|
||||
if (is_resource($fd)) {
|
||||
$buffer = '';
|
||||
while (!feof($fd)) {
|
||||
$buffer .= fgets($fd);
|
||||
}
|
||||
$vnstat_data = explode("\n", $buffer);
|
||||
pclose($fd);
|
||||
}
|
||||
|
||||
$day = array();
|
||||
$hour = array();
|
||||
$month = array();
|
||||
$top = array();
|
||||
|
||||
if (isset($vnstat_data[0]) && strpos($vnstat_data[0], 'Error') !== false) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($vnstat_data as $line) {
|
||||
$d = explode(';', trim($line));
|
||||
if ($d[0] == 'd') {
|
||||
$day[$d[1]]['time'] = $d[2];
|
||||
$day[$d[1]]['rx'] = $d[3] * 1024 + $d[5];
|
||||
$day[$d[1]]['tx'] = $d[4] * 1024 + $d[6];
|
||||
$day[$d[1]]['act'] = $d[7];
|
||||
$day[$d[1]]['rx2'] = $d[5];
|
||||
$day[$d[1]]['tx2'] = $d[6];
|
||||
}
|
||||
else if ($d[0] == 'm') {
|
||||
$month[$d[1]]['time'] = $d[2];
|
||||
$month[$d[1]]['rx'] = $d[3] * 1024 + $d[5];
|
||||
$month[$d[1]]['tx'] = $d[4] * 1024 + $d[6];
|
||||
$month[$d[1]]['act'] = $d[7];
|
||||
$month[$d[1]]['rx2'] = $d[5];
|
||||
$month[$d[1]]['tx2'] = $d[6];
|
||||
}
|
||||
else if ($d[0] == 'h') {
|
||||
$hour[$d[1]]['time'] = $d[2];
|
||||
$hour[$d[1]]['rx'] = $d[3];
|
||||
$hour[$d[1]]['tx'] = $d[4];
|
||||
$hour[$d[1]]['act'] = 1;
|
||||
}
|
||||
else if ($d[0] == 't') {
|
||||
$top[$d[1]]['time'] = $d[2];
|
||||
$top[$d[1]]['rx'] = $d[3] * 1024 + $d[5];
|
||||
$top[$d[1]]['tx'] = $d[4] * 1024 + $d[6];
|
||||
$top[$d[1]]['act'] = $d[7];
|
||||
}
|
||||
else {
|
||||
$summary[$d[0]] = isset($d[1]) ? $d[1] : '';
|
||||
}
|
||||
}
|
||||
|
||||
rsort($day);
|
||||
rsort($month);
|
||||
rsort($hour);
|
||||
|
||||
return array($day, $month, $hour, $day, $month, $top, $summary);
|
||||
}
|
||||
|
||||
|
||||
function kbytes_to_string($kb) {
|
||||
$byte_notation = null;
|
||||
$units = array('TB','GB','MB','KB');
|
||||
$scale = 1024*1024*1024;
|
||||
$ui = 0;
|
||||
$custom_size = isset($byte_notation) && in_array($byte_notation, $units);
|
||||
|
||||
while ((($kb < $scale) && ($scale > 1)) || $custom_size) {
|
||||
$ui++;
|
||||
$scale = $scale / 1024;
|
||||
if ($custom_size && $units[$ui] == $byte_notation) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sprintf("%0.2f %s", ($kb/$scale),$units[$ui]);
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
4
dashboard1/pgs/liveccs.php
Normal file
4
dashboard1/pgs/liveccs.php
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<div width="100%" style="text-align:center;">
|
||||
<iframe width="1050" height="800" src="http://ccs001.xreflector.net/live_seite/bndex.html" style="border:0px #000000 solid; margin-top:30px;" align="center"></iframe>
|
||||
</div>
|
||||
|
||||
4
dashboard1/pgs/liveircddb.php
Normal file
4
dashboard1/pgs/liveircddb.php
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<div width="100%" style="text-align:center;">
|
||||
<iframe width="1250" height="800" src="http://live.ircddb.net:8080/ircddblive5.html" style="border:0px #000000 solid; margin-top:30px;" align="center"></iframe>
|
||||
</div>
|
||||
|
||||
51
dashboard1/pgs/modules.php
Normal file
51
dashboard1/pgs/modules.php
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<table class="listingtable">
|
||||
<tr>
|
||||
<th width="80" rowspan="2">Module</th>
|
||||
<th width="130" rowspan="2">Name</th>
|
||||
<th width="65" rowspan="2">Users</th>
|
||||
<th colspan="2">DPlus</th>
|
||||
<th colspan="2">DExtra</th>
|
||||
<th colspan="2">DCS</th>
|
||||
<th width="65" rowspan="2">DMR</th>
|
||||
<th width="65" rowspan="2">YSF<br />DG-ID</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th width="100">URCALL</th>
|
||||
<th width="100">DTMF</th>
|
||||
<th width="100">URCALL</th>
|
||||
<th width="100">DTMF</th>
|
||||
<th width="100">URCALL</th>
|
||||
<th width="100">DTMF</th>
|
||||
</tr>
|
||||
<?php
|
||||
|
||||
$ReflectorNumber = substr($Reflector->GetReflectorName(), 3, 3);
|
||||
$NumberOfModules = isset($PageOptions['NumberOfModules']) ? min(max($PageOptions['NumberOfModules'],0),26) : 26;
|
||||
|
||||
$odd = "";
|
||||
|
||||
for ($i = 1; $i <= $NumberOfModules; $i++) {
|
||||
|
||||
$module = chr(ord('A')+($i-1));
|
||||
|
||||
if ($odd == "#FFFFFF") { $odd = "#F1FAFA"; } else { $odd = "#FFFFFF"; }
|
||||
|
||||
echo '
|
||||
<tr height="30" bgcolor="'.$odd.'" onMouseOver="this.bgColor=\'#FFFFCA\';" onMouseOut="this.bgColor=\''.$odd.'\';">
|
||||
<td align="center">'. sanitize_output($module) .'</td>
|
||||
<td align="center">'. sanitize_output(empty($PageOptions['ModuleNames'][$module]) ? '-' : $PageOptions['ModuleNames'][$module]) .'</td>
|
||||
<td align="center">'. count($Reflector->GetNodesInModulesByID($module)) .'</td>
|
||||
<td align="center">'. sanitize_output('REF' . $ReflectorNumber . $module . 'L') .'</td>
|
||||
<td align="center">'. sanitize_output(is_numeric($ReflectorNumber) ? '*' . sprintf('%01d',$ReflectorNumber) . (($i<=4)?$module:sprintf('%02d',$i)) : '-') .'</td>
|
||||
<td align="center">'. sanitize_output('XRF' . $ReflectorNumber . $module . 'L') .'</td>
|
||||
<td align="center">'. sanitize_output(is_numeric($ReflectorNumber) ? 'B' . sprintf('%01d',$ReflectorNumber) . (($i<=4)?$module:sprintf('%02d',$i)) : '-') .'</td>
|
||||
<td align="center">'. sanitize_output('DCS' . $ReflectorNumber . $module . 'L') .'</td>
|
||||
<td align="center">'. sanitize_output(is_numeric($ReflectorNumber) ? 'D' . sprintf('%01d',$ReflectorNumber) . (($i<=4)?$module:sprintf('%02d',$i)) : '-') .'</td>
|
||||
<td align="center">'. sanitize_output(4000+$i) .'</td>
|
||||
<td align="center">'. sanitize_output(9+$i) .'</td>
|
||||
</tr>';
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
</table>
|
||||
88
dashboard1/pgs/peers.php
Normal file
88
dashboard1/pgs/peers.php
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
$Result = @fopen($CallingHome['ServerURL']."?do=GetReflectorList", "r");
|
||||
|
||||
$INPUT = "";
|
||||
|
||||
if ($Result) {
|
||||
|
||||
while (!feof ($Result)) {
|
||||
$INPUT .= fgets ($Result, 1024);
|
||||
}
|
||||
|
||||
$XML = new ParseXML();
|
||||
$Reflectorlist = $XML->GetElement($INPUT, "reflectorlist");
|
||||
$Reflectors = $XML->GetAllElements($Reflectorlist, "reflector");
|
||||
}
|
||||
|
||||
fclose($Result);
|
||||
?>
|
||||
<table class="listingtable">
|
||||
<tr>
|
||||
<th width="25">#</th>
|
||||
<th width="100">XLX Peer</th>
|
||||
<th width="154">Last Heard</th>
|
||||
<th width="156">Linked for</th>
|
||||
<th width="90">Protocol</th>
|
||||
<th width="67">Module</th><?php
|
||||
|
||||
if ($PageOptions['PeerPage']['IPModus'] != 'HideIP') {
|
||||
echo '
|
||||
<th width="125">IP</th>';
|
||||
}
|
||||
|
||||
?>
|
||||
</tr>
|
||||
<?php
|
||||
|
||||
$odd = "";
|
||||
$Reflector->LoadFlags();
|
||||
|
||||
for ($i=0;$i<$Reflector->PeerCount();$i++) {
|
||||
|
||||
if ($odd == "#FFFFFF") { $odd = "#F1FAFA"; } else { $odd = "#FFFFFF"; }
|
||||
|
||||
echo '
|
||||
<tr height="30" bgcolor="'.$odd.'" onMouseOver="this.bgColor=\'#FFFFCA\';" onMouseOut="this.bgColor=\''.$odd.'\';">
|
||||
<td align="center">'.($i+1).'</td>';
|
||||
$Name = $Reflector->Peers[$i]->GetCallSign();
|
||||
$URL = '';
|
||||
for ($j=1;$j<count($Reflectors);$j++) {
|
||||
if ($Name === $XML->GetElement($Reflectors[$j], "name")) {
|
||||
$URL = $XML->GetElement($Reflectors[$j], "dashboardurl");
|
||||
}
|
||||
}
|
||||
if ($Result && (trim($URL) != "")) {
|
||||
echo '
|
||||
<td><a href="'.sanitize_attribute($URL).'" target="_blank" class="listinglink" title="Visit the Dashboard of '.sanitize_attribute($Name).'" style="text-decoration:none;color:#000000;">'.sanitize_output($Name).'</a></td>';
|
||||
} else {
|
||||
echo '
|
||||
<td>'.sanitize_output($Name).'</td>';
|
||||
}
|
||||
echo '
|
||||
<td>'.sanitize_output(date("d.m.Y H:i", $Reflector->Peers[$i]->GetLastHeardTime())).'</td>
|
||||
<td>'.sanitize_output(FormatSeconds(time()-$Reflector->Peers[$i]->GetConnectTime())).' s</td>
|
||||
<td align="center">'.sanitize_output($Reflector->Peers[$i]->GetProtocol()).'</td>
|
||||
<td align="center">'.sanitize_output($Reflector->Peers[$i]->GetLinkedModule()).'</td>';
|
||||
if ($PageOptions['PeerPage']['IPModus'] != 'HideIP') {
|
||||
echo '
|
||||
<td>';
|
||||
$Bytes = explode(".", $Reflector->Peers[$i]->GetIP());
|
||||
if ($Bytes !== false && count($Bytes) == 4) {
|
||||
switch ($PageOptions['PeerPage']['IPModus']) {
|
||||
case 'ShowLast1ByteOfIP' : echo sanitize_output($PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$Bytes[3]); break;
|
||||
case 'ShowLast2ByteOfIP' : echo sanitize_output($PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$Bytes[2].'.'.$Bytes[3]); break;
|
||||
case 'ShowLast3ByteOfIP' : echo sanitize_output($PageOptions['PeerPage']['MasqueradeCharacter'].'.'.$Bytes[1].'.'.$Bytes[2].'.'.$Bytes[3]); break;
|
||||
default : echo sanitize_output($Reflector->Peers[$i]->GetIP());
|
||||
}
|
||||
}
|
||||
echo '</td>';
|
||||
}
|
||||
echo '
|
||||
</tr>';
|
||||
if ($i == $PageOptions['PeerPage']['LimitTo']) { $i = $Reflector->PeerCount()+1; }
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
</table>
|
||||
52
dashboard1/pgs/reflectors.php
Normal file
52
dashboard1/pgs/reflectors.php
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
$Result = @fopen($CallingHome['ServerURL']."?do=GetReflectorList", "r");
|
||||
|
||||
if (!$Result) die("HEUTE GIBTS KEIN BROT");
|
||||
|
||||
$INPUT = "";
|
||||
while (!feof ($Result)) {
|
||||
$INPUT .= fgets ($Result, 1024);
|
||||
}
|
||||
fclose($Result);
|
||||
|
||||
$XML = new ParseXML();
|
||||
$Reflectorlist = $XML->GetElement($INPUT, "reflectorlist");
|
||||
$Reflectors = $XML->GetAllElements($Reflectorlist, "reflector");
|
||||
|
||||
?>
|
||||
|
||||
<table class="listingtable">
|
||||
<tr>
|
||||
<th width="40">#</th>
|
||||
<th width="75">Reflector</th>
|
||||
<th width="120">Country</th>
|
||||
<th width="90">Service</th>
|
||||
<th width="400">Comment</th>
|
||||
</tr>
|
||||
<?php
|
||||
|
||||
$odd = "";
|
||||
|
||||
for ($i=0;$i<count($Reflectors);$i++) {
|
||||
|
||||
$NAME = sanitize_output($XML->GetElement($Reflectors[$i], "name"));
|
||||
$COUNTRY = sanitize_output($XML->GetElement($Reflectors[$i], "country"));
|
||||
$LASTCONTACT = intval($XML->GetElement($Reflectors[$i], "lastcontact"));
|
||||
$COMMENT = sanitize_output($XML->GetElement($Reflectors[$i], "comment"));
|
||||
$DASHBOARDURL = sanitize_attribute($XML->GetElement($Reflectors[$i], "dashboardurl"));
|
||||
|
||||
if ($odd == "#FFFFFF") { $odd = "#F1FAFA"; } else { $odd = "#FFFFFF"; }
|
||||
|
||||
echo '
|
||||
<tr height="30" bgcolor="'.$odd.'" onMouseOver="this.bgColor=\'#FFFFCA\';" onMouseOut="this.bgColor=\''.$odd.'\';">
|
||||
<td align="center">'.($i+1).'</td>
|
||||
<td><a href="'.$DASHBOARDURL.'" target="_blank" class="listinglink" title="Visit the Dashboard of '.$NAME.'">'.$NAME.'</a></td>
|
||||
<td>'.$COUNTRY.'</td>
|
||||
<td align="center" valign="middle"><img src="./img/'; if ($LASTCONTACT<(time()-1800)) { echo 'down'; } ELSE { echo 'up'; } echo '.png" height="25" /></td>
|
||||
<td>'.$COMMENT.'</td>
|
||||
</tr>';
|
||||
}
|
||||
|
||||
?>
|
||||
</table>
|
||||
228
dashboard1/pgs/repeaters.php
Normal file
228
dashboard1/pgs/repeaters.php
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
<?php
|
||||
|
||||
// Initialize filter session variables
|
||||
if (!isset($_SESSION['FilterCallSign'])) {
|
||||
$_SESSION['FilterCallSign'] = null;
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['FilterProtocol'])) {
|
||||
$_SESSION['FilterProtocol'] = null;
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['FilterModule'])) {
|
||||
$_SESSION['FilterModule'] = null;
|
||||
}
|
||||
|
||||
// Validate filter inputs
|
||||
if (isset($_SESSION['FilterCallSign']) && $_SESSION['FilterCallSign'] !== null) {
|
||||
$_SESSION['FilterCallSign'] = preg_replace('/[^A-Z0-9\*\-\/\s]/i', '', $_SESSION['FilterCallSign']);
|
||||
}
|
||||
if (isset($_SESSION['FilterProtocol']) && $_SESSION['FilterProtocol'] !== null) {
|
||||
$_SESSION['FilterProtocol'] = validate_protocol($_SESSION['FilterProtocol']);
|
||||
}
|
||||
if (isset($_SESSION['FilterModule']) && $_SESSION['FilterModule'] !== null) {
|
||||
$_SESSION['FilterModule'] = validate_module($_SESSION['FilterModule']);
|
||||
}
|
||||
|
||||
if (isset($_POST['do'])) {
|
||||
if ($_POST['do'] == 'SetFilter') {
|
||||
|
||||
if (isset($_POST['txtSetCallsignFilter'])) {
|
||||
$_POST['txtSetCallsignFilter'] = trim($_POST['txtSetCallsignFilter']);
|
||||
if ($_POST['txtSetCallsignFilter'] == "") {
|
||||
$_SESSION['FilterCallSign'] = null;
|
||||
}
|
||||
else {
|
||||
$_SESSION['FilterCallSign'] = $_POST['txtSetCallsignFilter'];
|
||||
if (strpos($_SESSION['FilterCallSign'], "*") === false) {
|
||||
$_SESSION['FilterCallSign'] = "*".$_SESSION['FilterCallSign']."*";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['txtSetProtocolFilter'])) {
|
||||
$_POST['txtSetProtocolFilter'] = trim($_POST['txtSetProtocolFilter']);
|
||||
if ($_POST['txtSetProtocolFilter'] == "") {
|
||||
$_SESSION['FilterProtocol'] = null;
|
||||
}
|
||||
else {
|
||||
$_SESSION['FilterProtocol'] = $_POST['txtSetProtocolFilter'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['txtSetModuleFilter'])) {
|
||||
$_POST['txtSetModuleFilter'] = trim($_POST['txtSetModuleFilter']);
|
||||
if ($_POST['txtSetModuleFilter'] == "") {
|
||||
$_SESSION['FilterModule'] = null;
|
||||
}
|
||||
else {
|
||||
$_SESSION['FilterModule'] = $_POST['txtSetModuleFilter'];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET['do'])) {
|
||||
if ($_GET['do'] == "resetfilter") {
|
||||
$_SESSION['FilterModule'] = null;
|
||||
$_SESSION['FilterProtocol'] = null;
|
||||
$_SESSION['FilterCallSign'] = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
||||
<table class="listingtable"><?php
|
||||
|
||||
if ($PageOptions['UserPage']['ShowFilter']) {
|
||||
echo '
|
||||
<tr>
|
||||
<th colspan="9">
|
||||
<table width="100%" border="0">
|
||||
<tr>
|
||||
<td align="left">
|
||||
<form name="frmFilterCallSign" method="post" action="./index.php?show=repeaters">
|
||||
<input type="hidden" name="do" value="SetFilter" />
|
||||
<input type="text" class="FilterField" value="'.sanitize_attribute($_SESSION['FilterCallSign']).'" name="txtSetCallsignFilter" placeholder="Callsign" onfocus="SuspendPageRefresh();" onblur="setTimeout(ReloadPage, '.$PageOptions['PageRefreshDelay'].');" />
|
||||
<input type="submit" value="Apply" class="FilterSubmit" />
|
||||
</form>
|
||||
</td>';
|
||||
if (($_SESSION['FilterModule'] != null) || ($_SESSION['FilterCallSign'] != null) || ($_SESSION['FilterProtocol'] != null)) {
|
||||
echo '
|
||||
<td><a href="./index.php?show=repeaters&do=resetfilter" class="smalllink">Disable filters</a></td>';
|
||||
}
|
||||
echo '
|
||||
<td align="right" style="padding-right:3px;">
|
||||
<form name="frmFilterProtocol" method="post" action="./index.php?show=repeaters">
|
||||
<input type="hidden" name="do" value="SetFilter" />
|
||||
<input type="text" class="FilterField" value="'.sanitize_attribute($_SESSION['FilterProtocol']).'" name="txtSetProtocolFilter" placeholder="Protocol" onfocus="SuspendPageRefresh();" onblur="setTimeout(ReloadPage, '.$PageOptions['PageRefreshDelay'].');" />
|
||||
<input type="submit" value="Apply" class="FilterSubmit" />
|
||||
</form>
|
||||
</td>
|
||||
<td align="right" style="padding-right:3px;">
|
||||
<form name="frmFilterModule" method="post" action="./index.php?show=repeaters">
|
||||
<input type="hidden" name="do" value="SetFilter" />
|
||||
<input type="text" class="FilterField" value="'.sanitize_attribute($_SESSION['FilterModule']).'" name="txtSetModuleFilter" placeholder="Module" onfocus="SuspendPageRefresh();" onblur="setTimeout(ReloadPage, '.$PageOptions['PageRefreshDelay'].');" />
|
||||
<input type="submit" value="Apply" class="FilterSubmit" />
|
||||
</form>
|
||||
</td>
|
||||
</table>
|
||||
</th>
|
||||
</tr>';
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<th width="25">#</th>
|
||||
<th width="60">Flag</th>
|
||||
<th width="100">DV Station</th>
|
||||
<th width="75">Band</th>
|
||||
<th width="150">Last Heard</th>
|
||||
<th width="150">Linked for</th>
|
||||
<th width="90">Protocol</th>
|
||||
<th width="65">Module</th><?php
|
||||
|
||||
if ($PageOptions['RepeatersPage']['IPModus'] != 'HideIP') {
|
||||
echo '
|
||||
<th width="125">IP</th>';
|
||||
}
|
||||
|
||||
?>
|
||||
</tr>
|
||||
<?php
|
||||
|
||||
$odd = "";
|
||||
$Reflector->LoadFlags();
|
||||
|
||||
for ($i=0;$i<$Reflector->NodeCount();$i++) {
|
||||
$ShowThisStation = true;
|
||||
if ($PageOptions['UserPage']['ShowFilter']) {
|
||||
$CS = true;
|
||||
if ($_SESSION['FilterCallSign'] != null) {
|
||||
if (!fnmatch($_SESSION['FilterCallSign'], $Reflector->Nodes[$i]->GetCallSign(), FNM_CASEFOLD)) {
|
||||
$CS = false;
|
||||
}
|
||||
}
|
||||
$MO = true;
|
||||
if ($_SESSION['FilterModule'] != null) {
|
||||
if (trim(strtolower($_SESSION['FilterModule'])) != strtolower($Reflector->Nodes[$i]->GetLinkedModule())) {
|
||||
$MO = false;
|
||||
}
|
||||
}
|
||||
$PR = true;
|
||||
if ($_SESSION['FilterProtocol'] != null) {
|
||||
if (trim(strtolower($_SESSION['FilterProtocol'])) != strtolower($Reflector->Nodes[$i]->GetProtocol())) {
|
||||
$PR = false;
|
||||
}
|
||||
}
|
||||
|
||||
$ShowThisStation = ($CS && $MO && $PR);
|
||||
}
|
||||
|
||||
if ($ShowThisStation) {
|
||||
if ($odd == "#FFFFFF") { $odd = "#F1FAFA"; } else { $odd = "#FFFFFF"; }
|
||||
|
||||
echo '
|
||||
<tr height="30" bgcolor="'.$odd.'" onMouseOver="this.bgColor=\'#FFFFCA\';" onMouseOut="this.bgColor=\''.$odd.'\';">
|
||||
<td align="center">'.($i+1).'</td>
|
||||
<td align="center">';
|
||||
list ($Flag, $Name) = $Reflector->GetFlag($Reflector->Nodes[$i]->GetCallSign());
|
||||
if (file_exists("./img/flags/".$Flag.".png")) {
|
||||
echo '<a href="#" class="tip"><img src="./img/flags/'.sanitize_attribute($Flag).'.png" height="15" alt="'.sanitize_attribute($Name).'" /><span>'.sanitize_output($Name).'</span></a>';
|
||||
}
|
||||
echo '</td>
|
||||
<td><a href="http://www.aprs.fi/'.sanitize_attribute($Reflector->Nodes[$i]->GetCallSign());
|
||||
if ($Reflector->Nodes[$i]->GetSuffix() != "") echo '-'.sanitize_attribute($Reflector->Nodes[$i]->GetSuffix());
|
||||
echo '" class="pl" target="_blank">'.sanitize_output($Reflector->Nodes[$i]->GetCallSign());
|
||||
if ($Reflector->Nodes[$i]->GetSuffix() != "") { echo '-'.sanitize_output($Reflector->Nodes[$i]->GetSuffix()); }
|
||||
echo '</a></td>
|
||||
<td>';
|
||||
if (($Reflector->Nodes[$i]->GetPrefix() == 'REF') || ($Reflector->Nodes[$i]->GetPrefix() == 'XRF')) {
|
||||
switch ($Reflector->Nodes[$i]->GetPrefix()) {
|
||||
case 'REF' : echo 'REF-Link'; break;
|
||||
case 'XRF' : echo 'XRF-Link'; break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch ($Reflector->Nodes[$i]->GetSuffix()) {
|
||||
case 'A' : echo '23cm'; break;
|
||||
case 'B' : echo '70cm'; break;
|
||||
case 'C' : echo '2m'; break;
|
||||
case 'D' : echo 'Dongle'; break;
|
||||
case 'G' : echo 'Internet-Gateway'; break;
|
||||
default : echo '';
|
||||
}
|
||||
}
|
||||
echo '</td>
|
||||
<td>'.sanitize_output(date("d.m.Y H:i", $Reflector->Nodes[$i]->GetLastHeardTime())).'</td>
|
||||
<td>'.sanitize_output(FormatSeconds(time()-$Reflector->Nodes[$i]->GetConnectTime())).' s</td>
|
||||
<td>'.sanitize_output($Reflector->Nodes[$i]->GetProtocol()).'</td>
|
||||
<td align="center">'.sanitize_output($Reflector->Nodes[$i]->GetLinkedModule()).'</td>';
|
||||
if ($PageOptions['RepeatersPage']['IPModus'] != 'HideIP') {
|
||||
echo '
|
||||
<td>';
|
||||
$Bytes = explode(".", $Reflector->Nodes[$i]->GetIP());
|
||||
if ($Bytes !== false && count($Bytes) == 4) {
|
||||
switch ($PageOptions['RepeatersPage']['IPModus']) {
|
||||
case 'ShowLast1ByteOfIP' : echo sanitize_output($PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$Bytes[3]); break;
|
||||
case 'ShowLast2ByteOfIP' : echo sanitize_output($PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$Bytes[2].'.'.$Bytes[3]); break;
|
||||
case 'ShowLast3ByteOfIP' : echo sanitize_output($PageOptions['RepeatersPage']['MasqueradeCharacter'].'.'.$Bytes[1].'.'.$Bytes[2].'.'.$Bytes[3]); break;
|
||||
default : echo sanitize_output($Reflector->Nodes[$i]->GetIP());
|
||||
}
|
||||
}
|
||||
echo '</td>';
|
||||
}
|
||||
echo '
|
||||
</tr>';
|
||||
}
|
||||
if ($i == $PageOptions['RepeatersPage']['LimitTo']) { $i = $Reflector->NodeCount()+1; }
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
</table>
|
||||
103
dashboard1/pgs/traffic.php
Normal file
103
dashboard1/pgs/traffic.php
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
if (!isset($_GET['iface'])) {
|
||||
if (isset($VNStat['Interfaces'][0]['Address'])) {
|
||||
$_GET['iface'] = $VNStat['Interfaces'][0]['Address'];
|
||||
}
|
||||
else {
|
||||
$_GET['iface'] = "";
|
||||
}
|
||||
}
|
||||
|
||||
// Validate interface name against whitelist
|
||||
if (!empty($_GET['iface'])) {
|
||||
$valid = false;
|
||||
for ($i = 0; $i < count($VNStat['Interfaces']); $i++) {
|
||||
if ($_GET['iface'] === $VNStat['Interfaces'][$i]['Address']) {
|
||||
$valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$valid) {
|
||||
$_GET['iface'] = "";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<table class="listingtable">
|
||||
<tr>
|
||||
<th>Network interfaces</th>
|
||||
<th>Statistics</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td bgcolor="#F1FAFA" align="left" valign="top" style="padding-left:5px;"><?php
|
||||
|
||||
for ($i=0;$i<count($VNStat['Interfaces']);$i++) {
|
||||
echo '<a href="./index.php?show=traffic&iface='.sanitize_attribute($VNStat['Interfaces'][$i]['Address']).'" class="listinglink">'.sanitize_output($VNStat['Interfaces'][$i]['Name']).'</a>';
|
||||
if ($i < count($VNStat['Interfaces'])-1) {
|
||||
echo '<br />';
|
||||
}
|
||||
}
|
||||
|
||||
?></td>
|
||||
<td bgcolor="#FFFFFF"><?php
|
||||
|
||||
$Data = VNStatGetData($_GET['iface'], $VNStat['Binary']);
|
||||
|
||||
echo '
|
||||
<table style="margin:10px;">
|
||||
<tr>
|
||||
<td>Day</td>
|
||||
<td>RX</td>
|
||||
<td>TX</td>
|
||||
<td>Avg Rx</td>
|
||||
<td>Avg TX</td>
|
||||
</tr>';
|
||||
|
||||
for ($i=0;$i<count($Data[0]);$i++) {
|
||||
if ($Data[0][$i]['time'] > 0) {
|
||||
echo '
|
||||
<tr>
|
||||
<td width="100">'.date("d.m.Y", $Data[0][$i]['time']).'</td>
|
||||
<td width="100">'.kbytes_to_string($Data[0][$i]['rx']).'</td>
|
||||
<td width="100">'.kbytes_to_string($Data[0][$i]['tx']).'</td>
|
||||
<td width="100">'.kbytes_to_string($Data[0][$i]['rx2']).'</td>
|
||||
<td width="100">'.kbytes_to_string($Data[0][$i]['tx2']).'</td>
|
||||
</tr>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '</table>';
|
||||
|
||||
|
||||
|
||||
|
||||
echo '
|
||||
<table style="margin:10px;">
|
||||
<tr>
|
||||
<td>Month</td>
|
||||
<td>RX</td>
|
||||
<td>TX</td>
|
||||
<td>Avg Rx</td>
|
||||
<td>Avg TX</td>
|
||||
</tr>';
|
||||
|
||||
for ($i=0;$i<count($Data[1]);$i++) {
|
||||
if ($Data[1][$i]['time'] > 0) {
|
||||
echo '
|
||||
<tr>
|
||||
<td width="100">'.date("F", $Data[1][$i]['time']).'</td>
|
||||
<td width="100">'.kbytes_to_string($Data[1][$i]['rx']).'</td>
|
||||
<td width="100">'.kbytes_to_string($Data[1][$i]['tx']).'</td>
|
||||
<td width="100">'.kbytes_to_string($Data[1][$i]['rx2']).'</td>
|
||||
<td width="100">'.kbytes_to_string($Data[1][$i]['tx2']).'</td>
|
||||
</tr>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '</table>';
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
240
dashboard1/pgs/users.php
Normal file
240
dashboard1/pgs/users.php
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
<?php
|
||||
|
||||
if (!isset($_SESSION['FilterCallSign'])) {
|
||||
$_SESSION['FilterCallSign'] = null;
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['FilterModule'])) {
|
||||
$_SESSION['FilterModule'] = null;
|
||||
}
|
||||
|
||||
if (isset($_POST['do'])) {
|
||||
if ($_POST['do'] == 'SetFilter') {
|
||||
|
||||
if (isset($_POST['txtSetCallsignFilter'])) {
|
||||
$_POST['txtSetCallsignFilter'] = trim($_POST['txtSetCallsignFilter']);
|
||||
if ($_POST['txtSetCallsignFilter'] == "") {
|
||||
$_SESSION['FilterCallSign'] = null;
|
||||
}
|
||||
else {
|
||||
$_SESSION['FilterCallSign'] = $_POST['txtSetCallsignFilter'];
|
||||
if (strpos($_SESSION['FilterCallSign'], "*") === false) {
|
||||
$_SESSION['FilterCallSign'] = "*".$_SESSION['FilterCallSign']."*";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['txtSetModuleFilter'])) {
|
||||
$_POST['txtSetModuleFilter'] = trim($_POST['txtSetModuleFilter']);
|
||||
if ($_POST['txtSetModuleFilter'] == "") {
|
||||
$_SESSION['FilterModule'] = null;
|
||||
}
|
||||
else {
|
||||
$_SESSION['FilterModule'] = $_POST['txtSetModuleFilter'];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET['do'])) {
|
||||
if ($_GET['do'] == "resetfilter") {
|
||||
$_SESSION['FilterModule'] = null;
|
||||
$_SESSION['FilterCallSign'] = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate filter inputs
|
||||
if (isset($_SESSION['FilterCallSign']) && $_SESSION['FilterCallSign'] !== null) {
|
||||
$_SESSION['FilterCallSign'] = preg_replace('/[^A-Z0-9\*\-\/\s]/i', '', $_SESSION['FilterCallSign']);
|
||||
}
|
||||
if (isset($_SESSION['FilterModule']) && $_SESSION['FilterModule'] !== null) {
|
||||
$_SESSION['FilterModule'] = validate_module($_SESSION['FilterModule']);
|
||||
}
|
||||
|
||||
?>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td valign="top">
|
||||
|
||||
|
||||
<table class="listingtable"><?php
|
||||
|
||||
if ($PageOptions['UserPage']['ShowFilter']) {
|
||||
echo '
|
||||
<tr>
|
||||
<th colspan="8">
|
||||
<table width="100%" border="0">
|
||||
<tr>
|
||||
<td align="left">
|
||||
<form name="frmFilterCallSign" method="post" action="./index.php">
|
||||
<input type="hidden" name="do" value="SetFilter" />
|
||||
<input type="text" class="FilterField" value="'.sanitize_attribute($_SESSION['FilterCallSign']).'" name="txtSetCallsignFilter" placeholder="Callsign" onfocus="SuspendPageRefresh();" onblur="setTimeout(ReloadPage, '.$PageOptions['PageRefreshDelay'].');" />
|
||||
<input type="submit" value="Apply" class="FilterSubmit" />
|
||||
</form>
|
||||
</td>';
|
||||
if (($_SESSION['FilterModule'] != null) || ($_SESSION['FilterCallSign'] != null)) {
|
||||
echo '
|
||||
<td><a href="./index.php?do=resetfilter" class="smalllink">Disable filters</a></td>';
|
||||
}
|
||||
echo '
|
||||
<td align="right" style="padding-right:3px;">
|
||||
<form name="frmFilterModule" method="post" action="./index.php">
|
||||
<input type="hidden" name="do" value="SetFilter" />
|
||||
<input type="text" class="FilterField" value="'.sanitize_attribute($_SESSION['FilterModule']).'" name="txtSetModuleFilter" placeholder="Module" onfocus="SuspendPageRefresh();" onblur="setTimeout(ReloadPage, '.$PageOptions['PageRefreshDelay'].');" />
|
||||
<input type="submit" value="Apply" class="FilterSubmit" />
|
||||
</form>
|
||||
</td>
|
||||
</table>
|
||||
</th>
|
||||
</tr>';
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Flag</th>
|
||||
<th>Callsign</th>
|
||||
<th>Suffix</th>
|
||||
<th>DPRS</th>
|
||||
<th>Via / Peer</th>
|
||||
<th>Last heard</th>
|
||||
<th align="center" valign="middle"><img src="./img/ear.png" alt="Listening on" /></th>
|
||||
</tr><?php
|
||||
|
||||
$Reflector->LoadFlags();
|
||||
$odd = "";
|
||||
for ($i=0;$i<$Reflector->StationCount();$i++) {
|
||||
$ShowThisStation = true;
|
||||
if ($PageOptions['UserPage']['ShowFilter']) {
|
||||
$CS = true;
|
||||
if ($_SESSION['FilterCallSign'] != null) {
|
||||
if (!fnmatch($_SESSION['FilterCallSign'], $Reflector->Stations[$i]->GetCallSign(), FNM_CASEFOLD)) {
|
||||
$CS = false;
|
||||
}
|
||||
}
|
||||
$MO = true;
|
||||
if ($_SESSION['FilterModule'] != null) {
|
||||
if (trim(strtolower($_SESSION['FilterModule'])) != strtolower($Reflector->Stations[$i]->GetModule())) {
|
||||
$MO = false;
|
||||
}
|
||||
}
|
||||
|
||||
$ShowThisStation = ($CS && $MO);
|
||||
}
|
||||
|
||||
|
||||
if ($ShowThisStation) {
|
||||
if ($odd == "#FFFFFF") { $odd = "#F1FAFA"; } else { $odd = "#FFFFFF"; }
|
||||
echo '
|
||||
<tr height="30" bgcolor="'.$odd.'" onMouseOver="this.bgColor=\'#FFFFCA\';" onMouseOut="this.bgColor=\''.$odd.'\';">
|
||||
<td align="center" valign="middle" width="35">';
|
||||
if ($i==0 && $Reflector->Stations[$i]->GetLastHeardTime() > (time() - 60)) {
|
||||
echo '<img src="./img/tx.gif" style="margin-top:3px;" height="20"/>';
|
||||
}
|
||||
else {
|
||||
echo ($i+1);
|
||||
}
|
||||
|
||||
echo '</td>
|
||||
<td align="center" width="60">';
|
||||
|
||||
list ($Flag, $Name) = $Reflector->GetFlag($Reflector->Stations[$i]->GetCallSign());
|
||||
if (file_exists("./img/flags/".$Flag.".png")) {
|
||||
echo '<a href="#" class="tip"><img src="./img/flags/'.sanitize_attribute($Flag).'.png" height="15" alt="'.sanitize_attribute($Name).'" /><span>'.sanitize_output($Name).'</span></a>';
|
||||
}
|
||||
echo '</td>
|
||||
<td width="75"><a href="https://www.qrz.com/db/'.sanitize_attribute($Reflector->Stations[$i]->GetCallsignOnly()).'" class="pl" target="_blank">'.sanitize_output($Reflector->Stations[$i]->GetCallsignOnly()).'</a></td>
|
||||
<td width="60">'.sanitize_output($Reflector->Stations[$i]->GetSuffix()).'</td>
|
||||
<td width="50" align="center"><a href="http://www.aprs.fi/'.sanitize_attribute($Reflector->Stations[$i]->GetCallsignOnly()).'" class="pl" target="_blank"><img src="./img/sat.png" /></a></td>
|
||||
<td width="150">'.sanitize_output($Reflector->Stations[$i]->GetVia());
|
||||
if ($Reflector->Stations[$i]->GetPeer() != $Reflector->GetReflectorName()) {
|
||||
echo ' / '.sanitize_output($Reflector->Stations[$i]->GetPeer());
|
||||
}
|
||||
echo '</td>
|
||||
<td width="150">'.sanitize_output(@date("d.m.Y H:i", $Reflector->Stations[$i]->GetLastHeardTime())).'</td>
|
||||
<td align="center" width="30">'.sanitize_output($Reflector->Stations[$i]->GetModule()).'</td>
|
||||
</tr>';
|
||||
}
|
||||
if ($i == $PageOptions['LastHeardPage']['LimitTo']) { $i = $Reflector->StationCount()+1; }
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
</td>
|
||||
<td style="padding-left:50px;" align="center" valign="top">
|
||||
|
||||
|
||||
|
||||
|
||||
<table class="listingtable">
|
||||
<?php
|
||||
|
||||
$Modules = $Reflector->GetModules();
|
||||
sort($Modules, SORT_STRING);
|
||||
echo '
|
||||
<tr>';
|
||||
for ($i=0;$i<count($Modules);$i++) {
|
||||
|
||||
if (isset($PageOptions['ModuleNames'][$Modules[$i]])) {
|
||||
echo '
|
||||
<th>'.sanitize_output($PageOptions['ModuleNames'][$Modules[$i]]);
|
||||
if (trim($PageOptions['ModuleNames'][$Modules[$i]]) != "") {
|
||||
echo '<br />';
|
||||
}
|
||||
echo sanitize_output($Modules[$i]).'</th>';
|
||||
}
|
||||
else {
|
||||
echo '
|
||||
<th>'.sanitize_output($Modules[$i]).'</th>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '
|
||||
</tr>
|
||||
<tr bgcolor="#FFFFFF" style="padding:0px;">';
|
||||
|
||||
$GlobalPositions = array();
|
||||
|
||||
for ($i=0;$i<count($Modules);$i++) {
|
||||
|
||||
$Users = $Reflector->GetNodesInModulesByID($Modules[$i]);
|
||||
echo '
|
||||
<td valign="top" style="border:0px;padding:0px;">
|
||||
|
||||
<table width="100" border="0" style="padding:0px;margin:0px;">';
|
||||
$odd = "";
|
||||
|
||||
$UserCheckedArray = array();
|
||||
|
||||
for ($j=0;$j<count($Users);$j++) {
|
||||
|
||||
if ($odd == "#FFFFFF") { $odd = "#F1FAFA"; } else { $odd = "#FFFFFF"; }
|
||||
$Displayname = $Reflector->GetCallsignAndSuffixByID($Users[$j]);
|
||||
echo '
|
||||
<tr height="25" bgcolor="'.$odd.'" onMouseOver="this.bgColor=\'#FFFFCA\';" onMouseOut="this.bgColor=\''.$odd.'\';">
|
||||
<td valign="top" style="border-bottom:1px #C1DAD7 solid;"><a href="http://www.aprs.fi/'.sanitize_attribute($Displayname).'" class="pl" target="_blank">'.sanitize_output($Displayname).'</a> </td>
|
||||
</tr>';
|
||||
$UserCheckedArray[] = $Users[$j];
|
||||
}
|
||||
echo '
|
||||
</table>
|
||||
|
||||
</td>';
|
||||
}
|
||||
|
||||
echo '
|
||||
</tr>';
|
||||
|
||||
?>
|
||||
</table>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
Loading…
Reference in a new issue