commit 13d293089877888bae4cefdd61b34c0ff668ccb2
Author: adrien <adrien@malingrey.fr>
Date:   Tue Apr 4 20:54:10 2023 +0200

    first commit

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3320f38
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+# Show a HP/3COM switch interfaces vlans in a webpage diagram from its *.cfg configuration file.
+
+* Create a `confs` subdir.
+* Copy *.cfg files in it.
+* Explore index.php.
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..39a3a9f
--- /dev/null
+++ b/index.php
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<html lang='fr'>
+<head>
+<title>Tableau des VLANs</title>
+<style>
+ul {
+    list-style: none;
+}
+</style>
+</head>
+<body>
+<header>
+<h1>Tableau des VLANs</h1>
+</header>
+<main>
+<?php
+    $basedir = __DIR__ . "/confs";
+
+    function recursive_ls($path) {
+        global $basedir;
+        echo "<ul>\n";
+        foreach (scandir($path) as $filename) {
+            if (substr($filename, 0, 1) != '.') {
+                $fullpath = $path ."/". $filename;
+                if (is_dir($fullpath)) {
+                    echo "<li>\n<details>\n<summary>", $filename, "</summary>\n";
+                    recursive_ls($fullpath);
+                    echo "</details>\n</li>\n";
+                } elseif (substr($filename, -4) == ".cfg") {
+                    echo "<li><a href='vlans.php?switch=", str_replace($basedir.'/', "", $fullpath), "'>$filename</a></li>\n";
+                }
+            }
+        }
+        echo "</ul>\n";
+    }
+
+    recursive_ls($basedir);
+?>
+</main>
+</body>
+</html>
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..6c257d2
--- /dev/null
+++ b/style.css
@@ -0,0 +1,34 @@
+body {
+    text-align: center;
+}
+main {
+    display: flex;
+    flex-flow: wrap;
+}
+main > table {
+    margin: auto;
+}
+.member {
+    border-collapse: collapse;
+    border: 4px solid #335;
+}
+.vlans {
+    border-collapse: collapse;
+}
+.member td,
+.vlans td {
+    border: 2px inset;
+}
+.number {
+    text-align: center;
+    min-width: 2em;
+    height: 2em;
+    mix-blend-mode: darken;
+}
+.pvid {
+    background-color: hsl(var(--pvid) 100% 58%);
+}
+.shutdown {
+    background-color: lightgray;
+    color: gray;
+}
diff --git a/vlans.php b/vlans.php
new file mode 100644
index 0000000..8b838de
--- /dev/null
+++ b/vlans.php
@@ -0,0 +1,77 @@
+<?php
+$basedir = __DIR__ . "/confs/";
+$path = realpath($basedir . filter_input(INPUT_GET, "switch", FILTER_SANITIZE_STRING));
+if (strpos($path, $basedir) !== 0 || substr($path, -4) != ".cfg") {
+    header('HTTP/1.1 404 Not Found');
+    die();
+}
+
+$conf = file_get_contents($path);
+
+preg_match("/ sysname ([\w-]+)/", $conf, $sysname);
+preg_match("/ip address ([\d.]+)/", $conf, $address);
+preg_match_all("/\nvlan (?P<pvid>\d+)(?:[\r\n]+ name (?P<name>.+))?(?:[\r\n]+ description (?P<description>.*))?/", $conf, $vlans, PREG_SET_ORDER);
+preg_match_all("/\n(?P<conf>(?P<name>interface [\w-]+(?:[\r\n]+ .*)*(?P<member>\d+)\/0\/(?P<port>\d+))[\r\n]+(?: description (?P<description>.*))?[\r\n]+(?P<shutdown> shutdown[\r\n]+)?(?: port access vlan (?P<pvid>\d+)[\r\n]+| .*[\r\n]+)*)/", $conf, $interfaces, PREG_SET_ORDER);
+
+$stack = array();
+foreach ($interfaces as $interface) {
+    if (!$stack[$interface["member"]]) {
+        $stack[$interface["member"]] = array();
+    }
+    $stack[$interface["member"]][$interface["port"]] = $interface;
+}
+
+?>
+<!DOCTYPE HTML>
+<html lang='fr'>
+<head>
+<title>Tableau des VLANs - <?=$sysname[1]?></title>
+<link href="style.css" rel="stylesheet" />
+</head>
+<body>
+<header>
+<h1>
+<div><?=$sysname[1]?></div>
+<div><small><a href="https://<?=$address[1]?>" target="_blank"><?=$address[1]?></a></small></div>
+</h1>
+</header>
+<main>
+<table>
+<caption><h2>Interfaces</h2></caption>
+<tbody>
+<?php
+foreach ($stack as $member => $interfaces) {
+    echo "<tr>\n<th>$member</th>\n<td>\n<table class='member'>\n<tbody>\n<tr>\n";
+    foreach ($interfaces as $interface) {
+        if ($interface["port"] % 2) {
+            echo "<td class='number ".($interface["shutdown"]? "shutdown" : "pvid")."' title='".$interface["conf"]."' style='--pvid: ".$interface["pvid"]."'>".$interface["port"]."</td>\n";
+        }
+    }
+    echo "</tr>\n<tr>\n";
+    foreach ($interfaces as $interface) {
+        if ($interface["port"] % 2 == 0) {
+            echo "<td class='number ".($interface["shutdown"]? "shutdown" : "pvid")."' title='".$interface["conf"]."' style='--pvid: ".$interface["pvid"]."'>".$interface["port"]."</td>\n";
+        }
+    }
+    echo "</tr>\n</tbody>\n</table>\n</td>\n</tr>\n";
+}
+?>
+</tbody>
+</table>
+<table class='vlans'>
+<caption><h2>VLANs</h2></caption>
+<thead><tr><th>PVID</th><th>Nom</th><th>Description</th></tr></thead>
+<tbody>
+<?php
+foreach ($vlans as $vlan) {
+    if ($vlan["pvid"] != 1) {
+        echo "<tr><td class='number pvid' style='--pvid: ${vlan["pvid"]}'>${vlan["pvid"]}</td><td>${vlan["name"]}</td><td>${vlan["description"]}</td></tr>";
+    }
+}
+?>
+<tr><td class='number shutdown'></td><td colspan='2'>Interface désactivée</td></tr>
+</tbody>
+</table>
+</main>
+</body>
+</html>