Files
LibreQoS/src/rust/lqos_node_manager/static/ip_dump.html
Herbert "TheBracket 25801b6445 Issue 291 capture time (#293)
* Make packet capture time user configurable.

* Add `packet_capture_time` to /etc/lqos.conf as a number (seconds)
* Rework the capture logic to obtain the capture time and wait for
  the specified period.
* Rename some functions that specified ten seconds in the name.

Relates to ISSUE #291

* Remove a dangling dashboard link

* Change libpcap download filename to <capture-circuit_id.pcap>

Relates to ISSUE #291

* Pass the circuit_id to the ip_dump page.
* Include the circuit_id in the downloaded packet capture
  filename.

* Add starting timestamp to capture filename

Adds the starting timestamp (in ns) to the capture filename when
you download a libcap dump. Ending timestamp isn't included; the
starting stamp is almost certainly unique.

Relates to ISSUE #291 and fixes the parts that I intend to
touch.
2023-03-23 11:49:36 -07:00

241 lines
9.8 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/vendor/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="/vendor/solid.min.css">
<link rel="stylesheet" href="/lqos.css">
<title>LibreQoS - Local Node Manager</title>
<script src="/lqos.js"></script>
<script src="/vendor/plotly-2.16.1.min.js"></script>
<script src="/vendor/jquery.min.js"></script><script src="/vendor/msgpack.min.js"></script>
<script defer src="/vendor/bootstrap.bundle.min.js"></script>
</head>
<body class="bg-secondary">
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="/"><img src="/vendor/tinylogo.svg" alt="LibreQoS SVG Logo" width="25" height="25" />&nbsp;LibreQoS</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link" href="/tree?parent=0"><i class="fa fa-tree"></i> Tree</a>
</li>
<li class="nav-item">
<a class="nav-link" aria-current="page" href="/shaped"><i class="fa fa-users"></i> Shaped Devices <span id="shapedCount" class="badge badge-pill badge-success green-badge">?</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="/unknown"><i class="fa fa-address-card"></i> Unknown IPs <span id="unshapedCount" class="badge badge-warning orange-badge">?</span></a>
</li>
</ul>
</div>
<ul class="navbar-nav ms-auto">
<li class="nav-item" id="currentLogin"></li>
<li class="nav-item">
<a class="nav-link" href="#" id="startTest"><i class="fa fa-flag-checkered"></i> Run Bandwidth Test</a>
</li>
<li class="nav-item ms-auto">
<a class="nav-link" href="/config"><i class="fa fa-gear"></i> Configuration</a>
</li>
<li>
<a class="nav-link btn btn-small black-txt" href="#" id="btnReload"><i class="fa fa-refresh"></i> Reload LibreQoS</a>
</li>
</ul>
</div>
</nav>
<div id="container" class="pad4">
<div class="row">
<div class="col-sm-12">
<div class="card bg-light">
<div class="card-body">
<h5 class="card-title"><i class="fa fa-users"></i> Packet Dump</h5>
<div id="pages"></div>
<div id="graph"></div>
<div id="dump">Please Wait... this may take a second.</div>
</div>
</div>
</div>
</div>
</div>
<footer>&copy; 2022-2023, LibreQoE LLC</footer>
<script>
var packets = [];
var pages = 0;
var PAGE_SIZE = 1000;
var target = "";
var current_page = 0;
var capacity = [];
function proto(n) {
switch (n) {
case 6: return "TCP"
case 17: return "UDP"
default: return "ICMP"
}
}
/*
Snippet for tcp_flags decoding
if (hdr->fin) flags |= 1;
if (hdr->syn) flags |= 2;
if (hdr->rst) flags |= 4;
if (hdr->psh) flags |= 8;
if (hdr->ack) flags |= 16;
if (hdr->urg) flags |= 32;
if (hdr->ece) flags |= 64;
if (hdr->cwr) flags |= 128;
*/
function tcp_flags(n) {
let result = "";
if (n & 1) result += "FIN-";
if (n & 2) result += "SYN-";
if (n & 4) result += "RST-";
if (n & 8) result += "PSH-";
if (n & 16) result += "ACK-";
if (n & 32) result += "URG-";
if (n & 64) result += "ECE-";
if (n & 128) result += "CWR-";
return result;
}
function zoomIn() {
PAGE_SIZE /= 2;
current_page /= 2;
pages = packets.length / PAGE_SIZE;
viewPage(current_page);
}
function zoomOut() {
PAGE_SIZE *= 2;
current_page *= 2;
pages = packets.length / PAGE_SIZE;
viewPage(current_page);
}
function paginator(active) {
let paginator = "<a href='/api/pcap/" + target + "/capture-" + circuit_id + "-" + starting_timestamp + ".pcap' class='btn btn-warning'>Download PCAP Dump</a> ";
paginator += "<a href='#' class='btn btn-info' onClick='zoomIn();'>Zoom In</a> ";
paginator += "<a href='#' class='btn btn-info' onClick='zoomOut();'>Zoom Out</a> ( Or drag an area of the graph) <br />";
paginator += "<strong>Jump to page</strong>: ";
for (let i=0; i<pages; i++) {
if (i == active) {
paginator += " " + i + " ";
} else {
paginator += "<a href='#' onclick='viewPage(" + i + ");'>" + i + "</a> ";
}
}
$("#pages").html(paginator);
}
function viewPage(n) {
let start = n * PAGE_SIZE;
let end = Math.min(start + PAGE_SIZE, packets.length);
if (start > packets.length) {
console.log("OOps");
}
let html = "<table class='table table-striped'>";
html += "<thead><th>Time (nanos)</th><th>Proto</th><th>TCP Flags</th><th>Sequence</th><th>Window</th><th>Flow</th><th>Bytes</th><th>ECN</th><th>DSCP</th></thead>";
let x_axis = [];
let y1_axis = [];
let y2_axis = [];
for (let i=start; i<end; ++i) {
html += "<tr>";
html += "<td>" + packets[i].timestamp + "</td>";
html += "<td>" + proto(packets[i].ip_protocol) + "</td>";
if (packets[i].ip_protocol == 6) {
html += "<td>" + tcp_flags(packets[i].tcp_flags) + "</td>";
html += "<td>" + packets[i].tcp_tsval + "/" + packets[i].tcp_tsecr + "</td>";
html += "<td>" + packets[i].tcp_window + "</td>";
} else {
html += "<td></td><td></td><td></td>";
}
if (packets[i].ip_protocol != 1) {
html += "<td>" + packets[i].src + ":" + packets[i].src_port + " -> " + packets[i].dst + ":" + packets[i].dst_port + "</td>";
} else {
html += "<td>" + packets[i].src + " -> " + packets[i].dst + "</td>";
}
html += "<td>" + packets[i].size + "</td>";
html += "<td>" + ecn(packets[i].ecn) + "</td>";
html += "<td>0x" + packets[i].dscp.toString(16) + "</td>";
html += "</tr>";
x_axis.push(packets[i].timestamp);
if (packets[i].src == target) {
y1_axis.push(packets[i].size);
y2_axis.push(0);
} else {
y1_axis.push(0);
y2_axis.push(0.0 - packets[i].size);
}
}
html += "</table>";
$("#dump").html(html);
paginator(n);
// Make the graph
let graph = document.getElementById("graph");
let data = [
{x: x_axis, y:y1_axis, name: 'Download', type: 'scatter', mode: 'markers', error_x: { type: 'percent', value: capacity[0], symetric: false, valueminus: 0 }},
{x: x_axis, y:y2_axis, name: 'Upload', type: 'scatter', mode: 'markers', error_x: { type: 'percent', value: capacity[1], symetric: false, valueminus: 0 }},
];
Plotly.newPlot(graph, data, { margin: { l:0,r:0,b:0,t:0,pad:4 }, yaxis: { automargin: true, title: 'Bytes' }, xaxis: {automargin: true, title: "Nanoseconds"} }, { responsive: true });
}
let circuit_id = null;
let starting_timestamp = null;
function start() {
colorReloadButton();
updateHostCounts();
const params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop),
});
circuit_id = params.circuit_id;
capacity = [ params.dn, params.up ]; // Bits per second
capacity = [ capacity[0] / 8, capacity[1] / 8 ]; // Bytes per second
capacity = [ capacity[0] / 1e9, capacity[1] / 1e9 ]; // Bytes per nanosecond
target = params.id;
$.get("/api/packet_dump/" + params.id, (data) => {
data.sort((a,b) => a.timestamp - b.timestamp);
let min_ts = null;
for (let i=0; i<data.length; ++i) {
if (min_ts == null || min_ts > data[i].timestamp) {
min_ts = data[i].timestamp;
}
}
for (let i=0; i<data.length; ++i) {
data[i].timestamp -= min_ts;
}
packets = data;
pages = Math.ceil((packets.length / PAGE_SIZE));
starting_timestamp = min_ts;
paginator(0);
viewPage(0);
});
}
$(document).ready(start);
</script>
</body>
</html>