mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-29 18:08:26 -05:00
421 lines
13 KiB
PHP
Executable File
421 lines
13 KiB
PHP
Executable File
<?php
|
|
//------------------------------------------------------------------------------
|
|
// check if authenticated
|
|
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
|
|
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/server/db.php';
|
|
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/language/lang.php';
|
|
?>
|
|
|
|
|
|
<?php
|
|
|
|
function getExternalIp() {
|
|
$ch = curl_init('https://api64.ipify.org?format=json');
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
|
$response = curl_exec($ch);
|
|
if (curl_errno($ch)) {
|
|
curl_close($ch);
|
|
return 'ERROR: ' . curl_error($ch);
|
|
}
|
|
curl_close($ch);
|
|
|
|
$data = json_decode($response, true);
|
|
if (isset($data['ip'])) {
|
|
return htmlspecialchars($data['ip']);
|
|
}
|
|
return 'ERROR: Invalid response';
|
|
}
|
|
|
|
// ----------------------------------------------------------
|
|
// Network
|
|
// ----------------------------------------------------------
|
|
|
|
// External IP
|
|
$externalIp = getExternalIp();
|
|
|
|
// Server Name
|
|
$network_NAME = gethostname() ?: lang('Systeminfo_Network_Server_Name_String');
|
|
|
|
// HTTPS Check
|
|
$network_HTTPS = isset($_SERVER['HTTPS']) ? 'Yes (HTTPS)' : lang('Systeminfo_Network_Secure_Connection_String');
|
|
|
|
// Query String
|
|
$network_QueryString = !empty($_SERVER['QUERY_STRING'])
|
|
? $_SERVER['QUERY_STRING']
|
|
: lang('Systeminfo_Network_Server_Query_String');
|
|
|
|
// Referer
|
|
$network_referer = !empty($_SERVER['HTTP_REFERER'])
|
|
? $_SERVER['HTTP_REFERER']
|
|
: lang('Systeminfo_Network_HTTP_Referer_String');
|
|
|
|
|
|
// ----------------------------------------------------
|
|
// Network Hardware Stats
|
|
// ----------------------------------------------------
|
|
|
|
|
|
// External IP
|
|
$externalIp = getExternalIp();
|
|
|
|
// Server Name
|
|
$network_NAME = gethostname() ?: lang('Systeminfo_Network_Server_Name_String');
|
|
|
|
// HTTPS Check
|
|
$network_HTTPS = isset($_SERVER['HTTPS']) ? 'Yes (HTTPS)' : lang('Systeminfo_Network_Secure_Connection_String');
|
|
|
|
// Query String
|
|
$network_QueryString = !empty($_SERVER['QUERY_STRING'])
|
|
? $_SERVER['QUERY_STRING']
|
|
: lang('Systeminfo_Network_Server_Query_String');
|
|
|
|
// Referer
|
|
$network_referer = !empty($_SERVER['HTTP_REFERER'])
|
|
? $_SERVER['HTTP_REFERER']
|
|
: lang('Systeminfo_Network_HTTP_Referer_String');
|
|
|
|
|
|
|
|
// ----------------------------------------------------
|
|
// Network Stats (General)
|
|
// ----------------------------------------------------
|
|
|
|
// External IP
|
|
$externalIp = getExternalIp();
|
|
|
|
// Server Name
|
|
$network_NAME = gethostname() ?: lang('Systeminfo_Network_Server_Name_String');
|
|
|
|
// HTTPS Check
|
|
$network_HTTPS = isset($_SERVER['HTTPS']) ? 'Yes (HTTPS)' : lang('Systeminfo_Network_Secure_Connection_String');
|
|
|
|
// Query String
|
|
$network_QueryString = !empty($_SERVER['QUERY_STRING'])
|
|
? $_SERVER['QUERY_STRING']
|
|
: lang('Systeminfo_Network_Server_Query_String');
|
|
|
|
// Referer
|
|
$network_referer = !empty($_SERVER['HTTP_REFERER'])
|
|
? $_SERVER['HTTP_REFERER']
|
|
: lang('Systeminfo_Network_HTTP_Referer_String');
|
|
|
|
echo '
|
|
<div class="box box-solid">
|
|
<div class="box-header">
|
|
<h3 class="box-title sysinfo_headline">
|
|
<i class="fa fa-sitemap fa-rotate-270"></i>' . lang('Systeminfo_Network_Hardware') .'
|
|
</h3>
|
|
</div>
|
|
<div class="box-body">
|
|
<table id="networkTable" class="table table-bordered table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th>' . lang('Systeminfo_Network_Hardware_Interface_Name') . '</th>
|
|
<th>' . lang('Systeminfo_Network_Hardware_Interface_Mask') . '</th>
|
|
<th>' . lang('Systeminfo_Network_Hardware_Interface_RX') . '</th>
|
|
<th>' . lang('Systeminfo_Network_Hardware_Interface_TX') . '</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr><td colspan="4">Loading...</td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>';
|
|
|
|
// Available IPs ----------------------------------------------------------
|
|
echo '<div class="box box-solid">
|
|
<div class="box-header">
|
|
<h3 class="box-title availableips_headline"><i class="fa fa-list"></i> ' . lang('Systeminfo_AvailableIps') . '</h3>
|
|
</div>
|
|
<div class="box-body">
|
|
<table id="availableIpsTable" class="display table table-bordered table-hover dataTable no-footer" style="width:100%"></table>
|
|
</div>
|
|
</div>';
|
|
|
|
|
|
|
|
// Network ----------------------------------------------------------
|
|
echo '<div class="box box-solid">
|
|
<div class="box-header">
|
|
<h3 class="box-title sysinfo_headline"><i class="fas fa-ethernet"></i> ' . lang('Systeminfo_Network') . '</h3>
|
|
</div>
|
|
<div class="box-body">
|
|
<div class="row">
|
|
<div class="col-sm-3 sysinfo_network_a">' . lang('Systeminfo_Network_IP') . '</div>
|
|
<div class="col-sm-9 sysinfo_network_b" id="external-ip">' .$externalIp. '</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-3 sysinfo_network_a">' . lang('Systeminfo_Network_IP_Connection') . '</div>
|
|
<div class="col-sm-9 sysinfo_network_b">' . $_SERVER['REMOTE_ADDR'] . '</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-3 sysinfo_network_a">' . lang('Systeminfo_Network_IP_Server') . '</div>
|
|
<div class="col-sm-9 sysinfo_network_b">' . $_SERVER['SERVER_ADDR'] . '</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-3 sysinfo_network_a">' . lang('Systeminfo_Network_Server_Name') . '</div>
|
|
<div class="col-sm-9 sysinfo_network_b">' . $network_NAME . '</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-3 sysinfo_network_a">' . lang('Systeminfo_Network_Connection_Port') . '</div>
|
|
<div class="col-sm-9 sysinfo_network_b">' . $_SERVER['REMOTE_PORT'] . '</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-3 sysinfo_network_a">' . lang('Systeminfo_Network_Secure_Connection') . '</div>
|
|
<div class="col-sm-9 sysinfo_network_b">' . $network_HTTPS . '</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-3 sysinfo_network_a">' . lang('Systeminfo_Network_Server_Version') . '</div>
|
|
<div class="col-sm-9 sysinfo_network_b">' . $_SERVER['SERVER_SOFTWARE'] . '</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-3 sysinfo_gerneral_a">' . lang('Systeminfo_Network_Request_URI') . '</div>
|
|
<div class="col-sm-9 sysinfo_gerneral_b">' . $_SERVER['REQUEST_URI'] . '</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-3 sysinfo_network_a">' . lang('Systeminfo_Network_Server_Query') . '</div>
|
|
<div class="col-sm-9 sysinfo_network_b">' . $network_QueryString . '</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-3 sysinfo_network_a">' . lang('Systeminfo_Network_HTTP_Host') . '</div>
|
|
<div class="col-sm-9 sysinfo_network_b">' . $_SERVER['HTTP_HOST'] . '</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-3 sysinfo_network_a">' . lang('Systeminfo_Network_HTTP_Referer') . '</div>
|
|
<div class="col-sm-9 sysinfo_network_b">' . $network_referer . '</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-3 sysinfo_network_a">' . lang('Systeminfo_Network_MIME') . '</div>
|
|
<div class="col-sm-9 sysinfo_network_b">' . $_SERVER['HTTP_ACCEPT'] . '</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-3 sysinfo_network_a">' . lang('Systeminfo_Network_Accept_Language') . '</div>
|
|
<div class="col-sm-9 sysinfo_network_b">' . $_SERVER['HTTP_ACCEPT_LANGUAGE'] . '</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-3 sysinfo_network_a">' . lang('Systeminfo_Network_Accept_Encoding') . '</div>
|
|
<div class="col-sm-9 sysinfo_network_b">' . $_SERVER['HTTP_ACCEPT_ENCODING'] . '</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-3 sysinfo_network_a">' . lang('Systeminfo_Network_Request_Method') . '</div>
|
|
<div class="col-sm-9 sysinfo_network_b">' . $_SERVER['REQUEST_METHOD'] . '</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-3 sysinfo_network_a">' . lang('Systeminfo_Network_Request_Time') . '</div>
|
|
<div class="col-sm-9 sysinfo_network_b">' . $_SERVER['REQUEST_TIME'] . '</div>
|
|
</div>
|
|
</div>
|
|
</div>';
|
|
|
|
|
|
?>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
// --------------------------------------------------------
|
|
// Available free IPS functionality
|
|
function inferNetworkRange(usedIps) {
|
|
if (!usedIps || usedIps.length === 0) return [];
|
|
|
|
const subnetMap = {};
|
|
|
|
// Group IPs by /24 subnet
|
|
for (const ip of usedIps) {
|
|
const parts = ip.split('.');
|
|
if (parts.length !== 4) continue;
|
|
const subnet = `${parts[0]}.${parts[1]}.${parts[2]}`;
|
|
if (!subnetMap[subnet]) subnetMap[subnet] = [];
|
|
subnetMap[subnet].push(ip);
|
|
}
|
|
|
|
const result = [];
|
|
|
|
for (const [subnet, ips] of Object.entries(subnetMap)) {
|
|
if (ips.length > 5) {
|
|
for (let i = 2; i < 255; i++) {
|
|
const ip = `${subnet}.${i}`;
|
|
result.push({ subnet, ip });
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function fetchUsedIps(callback) {
|
|
$.ajax({
|
|
url: 'php/server/query_graphql.php',
|
|
type: 'POST',
|
|
contentType: 'application/json',
|
|
data: JSON.stringify({
|
|
query: `
|
|
query devices($options: PageQueryOptionsInput) {
|
|
devices(options: $options) {
|
|
devices {
|
|
devLastIP
|
|
}
|
|
}
|
|
}
|
|
`,
|
|
variables: {
|
|
options: {
|
|
status: "all_devices"
|
|
}
|
|
}
|
|
}),
|
|
success: function(response) {
|
|
|
|
console.log(response);
|
|
|
|
const usedIps = (response?.data?.devices?.devices || [])
|
|
.map(d => d.devLastIP)
|
|
.filter(ip => ip && ip.includes('.'));
|
|
callback(usedIps);
|
|
},
|
|
error: function(err) {
|
|
console.error("Error fetching IPs:", err);
|
|
callback([]);
|
|
}
|
|
});
|
|
}
|
|
|
|
function renderAvailableIpsTable(allIps, usedIps) {
|
|
const availableIps = allIps.filter(row => !usedIps.includes(row.ip));
|
|
|
|
console.log(availableIps);
|
|
|
|
$('#availableIpsTable').DataTable({
|
|
destroy: true,
|
|
data: availableIps,
|
|
columns: [
|
|
{
|
|
title: getString("Gen_Subnet"),
|
|
data: "subnet"
|
|
},
|
|
{
|
|
title: getString("Systeminfo_AvailableIps"),
|
|
data: "ip",
|
|
render: function (data, type, row, meta) {
|
|
return `
|
|
<span>${data}</span>
|
|
<button class="copy-btn btn btn-sm btn-info ml-2 alignRight" data-text="${data}" title="${getString("Gen_CopyToClipboard")}" onclick="copyToClipboard(this)">
|
|
<i class="fa-solid fa-copy"></i>
|
|
</button>
|
|
`;
|
|
}
|
|
}
|
|
],
|
|
pageLength: 10
|
|
});
|
|
|
|
}
|
|
|
|
|
|
// Helper: Convert CIDR to subnet mask
|
|
function cidrToMask(cidr) {
|
|
return ((0xFFFFFFFF << (32 - cidr)) >>> 0)
|
|
.toString(16)
|
|
.match(/.{1,2}/g)
|
|
.map(h => parseInt(h, 16))
|
|
.join('.');
|
|
}
|
|
|
|
function formatDataSize(bytes) {
|
|
if (!bytes) bytes = 0; // ensure it's a number
|
|
|
|
const mb = bytes / 1024 / 1024; // convert bytes to MB
|
|
|
|
// Format number with 2 decimals and thousands separators
|
|
return mb.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + " MB";
|
|
}
|
|
|
|
|
|
|
|
function loadInterfaces() {
|
|
const apiToken = getSetting("API_TOKEN");
|
|
const host = window.location.hostname;
|
|
const protocol = window.location.protocol;
|
|
const port = getSetting("GRAPHQL_PORT");
|
|
|
|
$.ajax({
|
|
url: `${protocol}//${host}:${port}/nettools/interfaces`,
|
|
type: "GET",
|
|
headers: {
|
|
"Authorization": "Bearer " + apiToken,
|
|
"Content-Type": "application/json"
|
|
},
|
|
success: function(data) {
|
|
const tbody = $("#networkTable tbody");
|
|
tbody.empty();
|
|
|
|
console.log(data);
|
|
|
|
|
|
if (!data.success || !data.interfaces || Object.keys(data.interfaces).length === 0) {
|
|
tbody.append('<tr><td colspan="4">No interfaces found</td></tr>');
|
|
return;
|
|
}
|
|
|
|
$.each(data.interfaces, function(iface_name, iface) {
|
|
|
|
const rx_mb = formatDataSize(iface.rx_bytes);
|
|
const tx_mb = formatDataSize(iface.tx_bytes);
|
|
|
|
// const rx_mb = (iface.rx_bytes ?? 0) / 1024 / 1024;
|
|
// const tx_mb = (iface.tx_bytes ?? 0) / 1024 / 1024;
|
|
|
|
let cidr_display = "";
|
|
if (iface.ipv4 && iface.ipv4.length > 0) {
|
|
const ip_info = iface.ipv4[0];
|
|
const ip = ip_info.ip || "--";
|
|
const mask = cidrToMask(ip_info.cidr || 24);
|
|
cidr_display = mask + " / " + iface.ipv4;
|
|
}
|
|
|
|
tbody.append(`
|
|
<tr>
|
|
<td>${iface_name}</td>
|
|
<td>${cidr_display}</td>
|
|
<td>${rx_mb}</td>
|
|
<td>${tx_mb}</td>
|
|
</tr>
|
|
`);
|
|
});
|
|
},
|
|
error: function(xhr) {
|
|
const tbody = $("#networkTable tbody");
|
|
tbody.empty();
|
|
tbody.append('<tr><td colspan="4">Failed to fetch interfaces</td></tr>');
|
|
console.error("Error fetching interfaces:", xhr.responseText);
|
|
}
|
|
});
|
|
}
|
|
|
|
// INIT
|
|
$(document).ready(function() {
|
|
|
|
// available IPs
|
|
fetchUsedIps(usedIps => {
|
|
const allIps = inferNetworkRange(usedIps);
|
|
renderAvailableIpsTable(allIps, usedIps);
|
|
});
|
|
|
|
loadInterfaces();
|
|
|
|
setTimeout(() => {
|
|
// Available IPs datatable
|
|
$('#networkTable').DataTable({
|
|
searching: true,
|
|
order: [[0, "desc"]],
|
|
initComplete: function(settings, json) {
|
|
hideSpinner(); // Called after the DataTable is fully initialized
|
|
}
|
|
});
|
|
}, 200);
|
|
});
|
|
|
|
</script>
|