IPRoute2 App
Code
├── Dockerfile
├── api
│ └── v1
│ ├── index.php
│ └── util.php
├── docker-compose.yml
└── public
├── index.html
├── js
│ ├── index.js
│ └── link.js
└── link.html
version: "3"
services:
web:
container_name: web
image: ifpb/php:7.3-apache-iproute2
build: .
ports:
- 8080:80
volumes:
- ./:/var/www/html/
FROM php:7.3-apache
RUN apt -y update && \
apt install -y \
iproute2
Back-end side
└── api
└── v1
├── index.php
└── util.php
Front-end side
└── public
├── index.html
├── js
│ ├── index.js
│ └── link.js
└── link.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
crossorigin="anonymous"
/>
<title>Interfaces</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Network Manager</a>
<button
class="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
</nav>
<div class="container">
<h1 class="text-center mt-5">Interfaces</h1>
<table class="table mt-4">
<thead>
<th>#</th>
<th>Name</th>
<th>MTU</th>
<th>State</th>
<th>MAC</th>
<th>IP</th>
</thead>
<tbody></tbody>
</table>
</div>
<script
src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
crossorigin="anonymous"
></script>
<script
src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
crossorigin="anonymous"
></script>
<script
src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
crossorigin="anonymous"
></script>
<script src="js/index.js"></script>
</body>
</html>
const table = document.querySelector("table tbody");
function loadInterfaces() {
fetch("/api/v1/")
.then(res => res.json())
.then(json => showInterfaces(json));
}
function showInterfaces(interfaces) {
let rows = "";
for (const interface of interfaces) {
const mask = interface.ipmask ? "/" + interface.ipmask : "";
const link = interface.name.split("@")[0];
rows += `<tr>
<td>${interface.id}</td>
<td>
<a href="link.html?info=link&link=${link}" target="_blank">${
interface.name
}</a>
</td>
<td>${interface.mtu}</td>
<td>${interface.state}</td>
<td>${interface.mac}</td>
<td>${interface.ip || "-"}${mask}</td>
</tr>`;
}
table.innerHTML = rows;
}
loadInterfaces();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
crossorigin="anonymous"
/>
<title>Interface</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Network Manager</a>
<button
class="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
</nav>
<div class="container">
<h1 class="text-center mt-5">Interface X</h1>
<table class="table mt-4">
<thead>
<th>#</th>
<th>bytes</th>
<th>packets</th>
<th>errors</th>
<th>dropped</th>
</thead>
<tbody></tbody>
</table>
</div>
<script
src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
crossorigin="anonymous"
></script>
<script
src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
crossorigin="anonymous"
></script>
<script
src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
crossorigin="anonymous"
></script>
<script src="js/link.js"></script>
</body>
</html>
const url = new URL(location);
const link = url.searchParams.get("link");
const title = document.querySelector("h1");
const table = document.querySelector("table tbody");
function loadInterface() {
title.innerHTML = `Interface ${link}`;
fetch(`/api/v1/?a=link&link=${link}`)
.then(res => res.json())
.then(json => showInterface(json));
}
function showInterface(interface) {
let rows = "";
for (const kind of ["rx", "tx"]) {
rows += `<tr>
<th>${kind.toUpperCase()}</th>
<td>${interface.stats[kind].bytes}</td>
<td>${interface.stats[kind].packets}</td>
<td>${interface.stats[kind].errors}</td>
<td>${interface.stats[kind].dropped}</td>
</tr>`;
}
table.innerHTML = rows;
setTimeout("loadInterface()", 2000);
}
loadInterface();