aboutsummaryrefslogtreecommitdiffstats
path: root/web/nms.gathering.org/old
diff options
context:
space:
mode:
Diffstat (limited to 'web/nms.gathering.org/old')
-rwxr-xr-xweb/nms.gathering.org/old/change-switch-pos.pl15
-rwxr-xr-xweb/nms.gathering.org/old/dhcp-json.pl19
-rwxr-xr-xweb/nms.gathering.org/old/dhcpkart.pl96
-rwxr-xr-xweb/nms.gathering.org/old/display-rack.html70
-rwxr-xr-xweb/nms.gathering.org/old/display.html64
-rw-r--r--web/nms.gathering.org/old/edit.html21
-rw-r--r--web/nms.gathering.org/old/index.html115
-rwxr-xr-xweb/nms.gathering.org/old/led.pl20
-rwxr-xr-xweb/nms.gathering.org/old/mygraph.pl179
-rw-r--r--web/nms.gathering.org/old/nettkart-continuous.html31
-rwxr-xr-xweb/nms.gathering.org/old/nettkart-json.pl80
-rwxr-xr-xweb/nms.gathering.org/old/nettkart-text.pl63
-rwxr-xr-xweb/nms.gathering.org/old/nettkart-web.pl47
-rwxr-xr-xweb/nms.gathering.org/old/nettkart.pl145
-rwxr-xr-xweb/nms.gathering.org/old/observium.html37
-rwxr-xr-xweb/nms.gathering.org/old/ping-json.pl32
-rw-r--r--web/nms.gathering.org/old/ping.css13
-rw-r--r--web/nms.gathering.org/old/ping.html21
-rw-r--r--web/nms.gathering.org/old/ping.js238
-rw-r--r--web/nms.gathering.org/old/ping2.html21
-rwxr-xr-xweb/nms.gathering.org/old/portkart.pl93
-rwxr-xr-xweb/nms.gathering.org/old/showswitch.pl249
-rw-r--r--web/nms.gathering.org/old/slide.html38
-rwxr-xr-xweb/nms.gathering.org/old/smanagement.pl246
-rwxr-xr-xweb/nms.gathering.org/old/sshow.pl258
-rwxr-xr-xweb/nms.gathering.org/old/stempmap.pl89
-rwxr-xr-xweb/nms.gathering.org/old/stromkart.pl72
-rwxr-xr-xweb/nms.gathering.org/old/switches-json.pl43
-rwxr-xr-xweb/nms.gathering.org/old/uplinkkart-text.pl38
-rwxr-xr-xweb/nms.gathering.org/old/uplinkkart.pl72
-rwxr-xr-xweb/nms.gathering.org/old/uplinktrafikkart.pl92
31 files changed, 2617 insertions, 0 deletions
diff --git a/web/nms.gathering.org/old/change-switch-pos.pl b/web/nms.gathering.org/old/change-switch-pos.pl
new file mode 100755
index 0000000..70d12f4
--- /dev/null
+++ b/web/nms.gathering.org/old/change-switch-pos.pl
@@ -0,0 +1,15 @@
+#! /usr/bin/perl
+use CGI;
+use GD;
+use DBI;
+use lib '../../include';
+use nms;
+my $cgi = CGI->new;
+
+my $dbh = nms::db_connect();
+my $box = sprintf("(%d,%d)", $cgi->param('x'), $cgi->param('y'));
+
+$dbh->do('UPDATE placements SET placement=box(?::point, ?::point + point(width(placement),height(placement))) WHERE switch=?',
+ undef, $box, $box, $cgi->param('switch'));
+print $cgi->header(-type=>'text/plain', -expires=>'now');
+
diff --git a/web/nms.gathering.org/old/dhcp-json.pl b/web/nms.gathering.org/old/dhcp-json.pl
new file mode 100755
index 0000000..210c434
--- /dev/null
+++ b/web/nms.gathering.org/old/dhcp-json.pl
@@ -0,0 +1,19 @@
+#! /usr/bin/perl
+use CGI qw(fatalsToBrowser);
+use DBI;
+use lib '../../include';
+use nms;
+my $cgi = CGI->new;
+
+my $dbh = nms::db_connect();
+
+my $q = $dbh->prepare('select sysname,EXTRACT(EPOCH FROM last_ack) as last_ack from switches natural join dhcp ');
+$q->execute();
+
+my %json = ();
+while (my $ref = $q->fetchrow_hashref()) {
+ $json{'dhcp'}{$ref->{'sysname'}}{'last_ack'} = $ref->{'last_ack'};
+}
+$dbh->disconnect;
+print $cgi->header(-type=>'text/json; charset=utf-8');
+print JSON::XS::encode_json(\%json);
diff --git a/web/nms.gathering.org/old/dhcpkart.pl b/web/nms.gathering.org/old/dhcpkart.pl
new file mode 100755
index 0000000..ace4a4e
--- /dev/null
+++ b/web/nms.gathering.org/old/dhcpkart.pl
@@ -0,0 +1,96 @@
+#! /usr/bin/perl
+use CGI qw(fatalsToBrowser);
+use GD;
+use DBI;
+use lib '../../include';
+use nms;
+use File::Basename;
+my $cgi = CGI->new;
+my $cwd = dirname($0);
+
+#my $greentimeout = 7200;
+my $greentimeout = 15*60;
+my $maxtimeout = $greentimeout*9;
+
+my $dbh = nms::db_connect();
+
+GD::Image->trueColor(1);
+my $map = "$cwd/tg15-salkart.png";
+die "$map does not exist" unless -e $map;
+$img = GD::Image->new($map);
+
+my $blk = $img->colorResolve(0, 0, 0);
+
+$img->string(gdMediumBoldFont,0,0,"DHCP-lease status",$blk);
+$img->string(gdSmallFont,0,20,"Last received DHCP-request",$blk);
+
+# first 1/5: green (<30 min)
+# middle 3/5: yellow -> red (30 min - 6 hours)
+# last 1/5: blue (>6 hours)
+my $grn = $img->colorResolve(0, 255, 0);
+my $blu = $img->colorResolve(0, 0, 255);
+
+my $l1 = 42 + (236 - 42)/5;
+my $l2 = 236 - (236 - 42)/5;
+
+$img->filledRectangle(32, 42, 53, $l1, $grn);
+$img->string(gdSmallFont,56,$l1-8,($greentimeout/60)." min",$blk);
+
+$img->filledRectangle(32, $l2, 53, 237, $blu);
+$img->string(gdSmallFont,56,$l2-5,($maxtimeout/60)." min",$blk);
+
+for my $y ($l1..$l2) {
+ my $i = 1.0 - ($y - $l1) / ($l2 - $l1);
+ my $clr = get_color($i);
+
+ $img->filledRectangle(32,$y,53,$y+1,$clr);
+}
+
+my $q = $dbh->prepare('select switch,sysname,placement,EXTRACT(EPOCH FROM now() - last_ack) as age from switches natural join placements natural join dhcp order by sysname');
+$q->execute();
+while (my $ref = $q->fetchrow_hashref()) {
+ my $age = $ref->{'age'};
+ if (!defined($age) || $age > $maxtimeout) {
+ $clr = $img->colorResolve(0, 0, 255);
+ } elsif ($age < $greentimeout) {
+ $clr = $img->colorResolve(0, 255, 0);
+ } else {
+ # 30 minutes = 0.0
+ # 6 hours = 1.0
+
+ my $intensity = log($age / $greentimeout) / log($maxtimeout/$greentimeout);
+ $clr = get_color(1.0 - $intensity);
+ }
+
+ my $sysname = $ref->{'sysname'};
+ if ($sysname !~ m/d0/i) { # don't draw distro-switches
+ $ref->{'placement'} =~ /\((\d+),(\d+)\),\((\d+),(\d+)\)/;
+ $img->filledRectangle($3,$4,$1,$2,$clr);
+ $img->rectangle($3,$4,$1,$2,$blk);
+
+ my ($x2, $y2, $x1, $y1) = ($1, $2, $3, $4);
+ my $max_textlen = ($x2-$x1) > ($y2-$y1) ? $x2-$x1 : $y2-$y1;
+ while (length($sysname) * 6 > $max_textlen) {
+ # Try to abbreviate sysname if it is too long for the box
+ $sysname =~ s/^(.*)[a-z]~?([0-9]+)$/$1~$2/ or last;
+ }
+ if (($x2-$x1) > ($y2-$y1)) {
+ $img->string(gdSmallFont,$x1+2,$y1,$sysname,$blk);
+ } else {
+ $img->stringUp(gdSmallFont,$x1,$y2-3,$sysname,$blk);
+ }
+ }
+}
+$dbh->disconnect;
+
+if (!defined($ARGV[0])) {
+ print $cgi->header(-type=>'image/png',
+ -refresh=>'10; ' . CGI::url());
+}
+print $img->png;
+
+sub get_color {
+ my $intensity = shift;
+ my $gamma = 1.0/1.90;
+ return $img->colorResolve(255.0, 255.0 * ($intensity ** $gamma), 0);
+}
diff --git a/web/nms.gathering.org/old/display-rack.html b/web/nms.gathering.org/old/display-rack.html
new file mode 100755
index 0000000..694bf11
--- /dev/null
+++ b/web/nms.gathering.org/old/display-rack.html
@@ -0,0 +1,70 @@
+<html>
+ <head>
+ <title>TG15 - The Future Is Back</title>
+ <style type="text/css">
+ body {
+ margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin: 0 auto;
+ }
+
+ #slide {
+ visibility: hidden;
+ position: absolute;
+ bottom: 0px;
+ top: 0px;
+ left: 0px;
+ margin: 0px;
+ overflow-y: hidden;
+ overflow-x: hidden;
+ }
+
+ #subframe {
+ width: 1920px;
+ height: 1080px;
+ }
+ </style>
+ <script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
+ <script type="text/javascript">
+ var page = 0;
+ var iframes = 5;
+ var delay = 10;
+
+ function rotate() {
+ $('body').delay(delay*1000).queue(function(next) {
+ $('div').each(function(i, obj) {
+ if (i == page) {
+ this.style.visibility = 'visible';
+ } else {
+ this.style.visibility = 'hidden';
+ }
+ });
+ next();
+ rotate();
+ });
+ page = (page + 1) % iframes;
+ }
+
+ $(document).ready(function(){
+ rotate();
+ });
+ </script>
+ </head>
+ <body>
+ <div id="slide" style="visibility: visible;">
+ <iframe class="frames" id="subframe" frameborder="0" src="http://funfact.tg15.gathering.org/" scrolling="no"></iframe>
+ </div>
+
+ <div id="slide">
+ <iframe class="frames" id="subframe" frameborder="0" src="http://funfact.tg15.gathering.org/searchwars.html" scrolling="no"></iframe>
+ </div>
+
+ <div id="slide">
+ <iframe class="frames" id="subframe" frameborder="0" src="http://funfact.tg15.gathering.org/social.html" scrolling="no"></iframe>
+ </div>
+ <div id="slide">
+ <iframe class="frames" id="subframe" frameborder="0" src="http://nms.tg15.gathering.org/speedometer/" scrolling="no"></iframe>
+ </div>
+ <div id="slide">
+ <iframe class="frames" id="subframe" frameborder="0" src="http://nms-public.tg15.gathering.org/weathermap.pl" scrolling="no"></iframe>
+ </div>
+ </body>
+</html>
diff --git a/web/nms.gathering.org/old/display.html b/web/nms.gathering.org/old/display.html
new file mode 100755
index 0000000..bb7c174
--- /dev/null
+++ b/web/nms.gathering.org/old/display.html
@@ -0,0 +1,64 @@
+<html>
+ <head>
+ <title>TG15 - The Future Is Back</title>
+ <style type="text/css">
+ body {
+ margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin: 0 auto;
+ }
+
+ #slide {
+ visibility: hidden;
+ position: absolute;
+ bottom: 0px;
+ top: 0px;
+ left: 0px;
+ margin: 0px;
+ overflow-y: hidden;
+ overflow-x: hidden;
+ }
+
+ #subframe {
+ width: 1920px;
+ height: 1080px;
+ }
+ </style>
+ <script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
+ <script type="text/javascript">
+ var page = 0;
+ var iframes = 3;
+ var delay = 10;
+
+ function rotate() {
+ $('body').delay(delay*1000).queue(function(next) {
+ $('div').each(function(i, obj) {
+ if (i == page) {
+ this.style.visibility = 'visible';
+ } else {
+ this.style.visibility = 'hidden';
+ }
+ });
+ next();
+ rotate();
+ });
+ page = (page + 1) % iframes;
+ }
+
+ $(document).ready(function(){
+ rotate();
+ });
+ </script>
+ </head>
+ <body>
+ <div id="slide" style="visibility: visible;">
+ <iframe class="frames" id="subframe" frameborder="0" src="http://nms.tg15.gathering.org/observium.html" scrolling="no"></iframe>
+ </div>
+
+ <div id="slide">
+ <iframe class="frames" id="subframe" frameborder="0" src="http://nms.tg15.gathering.org/ping.html" scrolling="no"></iframe>
+ </div>
+
+ <div id="slide">
+ <iframe class="frames" id="subframe" frameborder="0" src="http://nms.tg15.gathering.org/dhcpkart.pl" scrolling="no"></iframe>
+ </div>
+ </body>
+</html>
diff --git a/web/nms.gathering.org/old/edit.html b/web/nms.gathering.org/old/edit.html
new file mode 100644
index 0000000..dff76c7
--- /dev/null
+++ b/web/nms.gathering.org/old/edit.html
@@ -0,0 +1,21 @@
+<html>
+ <head>
+ <title>Ping? Pong!</title>
+ </head>
+ <body>
+ <link rel="stylesheet" href="/ping.css">
+ <p id="playground">
+ <svg id="lines" width="1920" height="1032" style="position: absolute; top: 0; left: 0; z-index: 1">
+ </svg>
+ <img src="tg15-salkart.png" alt="" id="map" />
+ </p>
+ <script>
+ // These are used by ping.js, below.
+ var switches_url = "/switches-json.pl";
+ var ping_url = "/ping-json.pl";
+ var draw_linknets = true;
+ var can_edit = true;
+ </script>
+ <script type="text/javascript" src="ping.js"></script>
+ </body>
+</html>
diff --git a/web/nms.gathering.org/old/index.html b/web/nms.gathering.org/old/index.html
new file mode 100644
index 0000000..8043c7d
--- /dev/null
+++ b/web/nms.gathering.org/old/index.html
@@ -0,0 +1,115 @@
+<html>
+ <head>
+ <title>snmp</title>
+ </head>
+ <body>
+ <p>tg light &amp; magic. :-)</p>
+
+ <ul>
+ <li><a href="nms2/">NMS 2 NG (Ping, Temp, Uplink, Trafikk, Info)</a>
+ <br /><i>Trykk på svitsjene (Work in progress)</i>
+ </li>
+ <br />
+ <li><a href="dhcpkart.pl">DHCP-kart</a>
+ <br /><i>Oversikt over DHCP-lease etter switch</i>
+ </li>
+
+ <br />
+
+ <li><a href="nettkart-text.pl">Nettkart</a>
+ <br /><i>Trafikkoversikt</i>
+ </li>
+
+ <br />
+<!--
+
+ <li><a href="nettkart-telnet.pl">Nettkart</a>
+ <br /><i>Trafikkoversikt /m telnetlink</i>
+ </li>
+
+ <br />
+-->
+<!-- Kun moderat nyttig når vi har disablet alle webinterfacene...
+ <li><a href="nettkart-web.pl">Nettkart</a>
+ <br /><i>Trafikkoversikt /m weblink</i>
+ </li>
+
+ <br />
+-->
+ <li><a href="portkart.pl">Nettkart, per port</a>
+ <br /><i>Trafikkoversikt per port</i>
+ </li>
+
+ <br />
+
+ <li><a href="uplinkkart.pl">Uplink-kart</a>
+ <br /><i>Hvilke switcher har ikke to uplinker</i>
+ </li>
+
+ <br />
+<!--
+ <li><a href="uplinktrafikkart.pl">Uplink-trafikkart</a>
+ <br /><i>Hvem burde hatt mer enn to uplinker</i>
+ </li>
+
+ <br />
+-->
+ <li><a href="stromkart.pl">Strømkart</a>
+ <br /><i>Hvilke switcher har færre enn fem tilkoblede klienter</i>
+ </li>
+
+ <br />
+<!--
+ <li><a href="apkart.pl">Aksesspunkt-kart</a>
+ <br /><i>Hvilke aksesspunkter er plugget i</i>
+ </li>
+
+ <br />
+-->
+ <!--<li><a href="overlay.pl">Overlay-nettkart</a>
+ <br /><i>Teh magic 3D!</i>
+ </li>
+
+ <br /> -->
+
+ <li><a href="smanagement.pl">Kommander switcher</a>
+ <br /><i>Konfigurer switchene</i>
+ </li>
+
+ <br />
+
+ <li><a href="sshow.pl">Utførte og køede kommandoer</a>
+ <br /><i>Se og håndter kommandoer som er utført og fortsatt i køen</i>
+ </li>
+
+ <br />
+
+ <li><a href="stempmap.pl">Temperaturkart</a>
+ <br /><i>Temperaturkart for switchene</i>
+ </li>
+<!--
+ <br />
+ <li><a href="mbd-status.pl">MBD-status</a>
+ <br /><i>Hva spiller folk mest?</i>
+ </li>
+-->
+ <br />
+
+ <li><a href="ping.html">Ping-kart</a>
+ <br /><i>Pinger alle bokser hvert sekund</i>
+ </li>
+
+ <br />
+
+ <li><a href="ping2.html">Realtime trafikkart</a>
+ <br /><i>Som nettkartet, men oppdateres hele tiden</i>
+ </li>
+
+ <br />
+
+ <li><a href="edit.html">Rediger kartet</a>
+ <br /><i>Dra rundt på switcher. Wheeee!</i>
+ </li>
+ </ul>
+ </body>
+</html>
diff --git a/web/nms.gathering.org/old/led.pl b/web/nms.gathering.org/old/led.pl
new file mode 100755
index 0000000..a05041d
--- /dev/null
+++ b/web/nms.gathering.org/old/led.pl
@@ -0,0 +1,20 @@
+#! /usr/bin/perl
+use CGI;
+use GD;
+use DBI;
+use lib '../../include';
+use nms;
+my $cgi = CGI->new;
+
+my $dbh = nms::db_connect();
+
+print $cgi->header(-type=>'text/plain', -expires=>'now');
+
+my $q = $dbh->prepare('select * from ( SELECT switch,sysname,sum(bytes_in) AS bytes_in,sum(bytes_out) AS bytes_out from switches natural left join get_current_datarate() group by switch,sysname) t1 natural join placements order by zorder;');
+$q->execute();
+while (my $ref = $q->fetchrow_hashref()) {
+ my $sysname = $ref->{'sysname'};
+ next unless $sysname =~ /e\d+-\d+/;
+ printf "%s %s\n", $sysname, (defined($ref->{'bytes_in'}) ? 'on' : 'off');
+}
+$dbh->disconnect;
diff --git a/web/nms.gathering.org/old/mygraph.pl b/web/nms.gathering.org/old/mygraph.pl
new file mode 100755
index 0000000..64104aa
--- /dev/null
+++ b/web/nms.gathering.org/old/mygraph.pl
@@ -0,0 +1,179 @@
+#! /usr/bin/perl -T
+use strict;
+use warnings;
+use GD;
+use POSIX;
+use Time::Zone;
+
+sub blendpx {
+ my ($gd, $x, $y, $r, $g, $b, $frac) = @_;
+ my ($ro, $go, $bo) = $gd->rgb($gd->getPixel($x, $y));
+
+ # workaround for icky 256-color graphs
+ # $frac = int($frac * 32) / 32;
+
+ my $rn = $ro * (1.0 - $frac) + $r * $frac;
+ my $gn = $go * (1.0 - $frac) + $g * $frac;
+ my $bn = $bo * (1.0 - $frac) + $b * $frac;
+
+ $gd->setPixel($x, $y, $gd->colorResolve($rn, $gn, $bn));
+}
+
+# Standard implementation of Wu's antialiased line algorithm.
+sub wuline {
+ my ($gd, $x1, $y1, $x2, $y2, $r, $g, $b, $a) = @_;
+ $x1 = POSIX::floor($x1);
+ $x2 = POSIX::floor($x2);
+ $y1 = POSIX::floor($y1);
+ $y2 = POSIX::floor($y2);
+
+ if (abs($x2 - $x1) > abs($y2 - $y1)) {
+ # x-directional
+ if ($y2 < $y1) {
+ ($x2, $y2, $x1, $y1) = ($x1, $y1, $x2, $y2);
+ }
+
+ my $y = POSIX::floor($y1);
+ my $frac = $y1 - $y;
+ my $dx = ($x2 > $x1) ? 1 : -1;
+ my $dy = ($y2 - $y1) / abs($x2 - $x1);
+
+ for (my $x = $x1; $x != $x2 + $dx; $x += $dx) {
+ blendpx($gd, $x, $y, $r, $g, $b, $a * (1.0 - $frac));
+ blendpx($gd, $x, $y + 1, $r, $g, $b, $a * $frac);
+ $frac += $dy;
+ if ($frac > 1) {
+ $frac -= 1;
+ ++$y;
+ }
+ }
+ } else {
+ # y-directional
+ if ($x2 < $x1) {
+ ($x2, $y2, $x1, $y1) = ($x1, $y1, $x2, $y2);
+ }
+ my $x = POSIX::floor($x1);
+ my $frac = $x1 - $x;
+ my $dy = ($y2 > $y1) ? 1 : -1;
+ my $dx = ($x2 - $x1) / abs($y2 - $y1);
+
+ for (my $y = $y1; $y != $y2 + $dy; $y += $dy) {
+ blendpx($gd, $x, $y, $r, $g, $b, $a * (1.0 - $frac));
+ blendpx($gd, $x + 1, $y, $r, $g, $b, $a * $frac);
+ $frac += $dx;
+ if ($frac > 1) {
+ $frac -= 1;
+ ++$x;
+ }
+ }
+ }
+}
+
+sub makegraph {
+ my $xoffset = 70;
+ my ($width, $height, $min_x, $max_x, $min_y, $max_y, $tickgran) = @_;
+
+ # Create our base graph
+ my $graph = new GD::Image($width, $height, 1);
+ my $white = $graph->colorAllocate(255, 255, 255);
+ my $gray = $graph->colorAllocate(230, 230, 255);
+ my $black = $graph->colorAllocate(0, 0, 0);
+
+# $graph->fill(0, 0, $white);
+ $graph->filledRectangle(0, 0, $width, $height, $white); # seems to work better
+
+ $::xs = ($width - ($xoffset+2)) / ($max_x - $min_x);
+ $::ys = ($height - 33) / ($min_y - $max_y);
+
+ # Hour marks
+ for my $i ($xoffset+1..$width-2) {
+ if (((($i-($xoffset+1)) / $::xs + $min_x) / 3600) % 2 == 1) {
+ $graph->line($i, 0, $i, $height - 1, $gray);
+ }
+ }
+
+ # Hour text
+ for my $i (0..23) {
+ my @bounds = GD::Image::stringFT(undef, $black, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 0, 0, $i);
+ my $w = $bounds[2] - $bounds[0];
+
+ # Determine where the center of this will be
+ my $starthour = POSIX::fmod(($min_x + Time::Zone::tz_local_offset()) / 3600, 24);
+ my $diff = POSIX::fmod($i - $starthour + 24, 24);
+
+ my $center = ($diff * 3600 + 1800) * $::xs;
+
+ next if ($center - $w / 2 < 1 || $center + $w / 2 > $width - ($xoffset+2));
+ $graph->stringFT($black, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, $xoffset + $center - $w / 2, $height - 6, $i);
+ }
+
+ #
+ # Y lines; we want max 11 of them (zero-line, plus five on each side, or
+ # whatever) but we don't want the ticks to be on minimum 50 (or
+ # whatever $tickgran is set to). However, if there would be
+ # really really few lines, go down an order of magnitude and try
+ # again.
+ #
+ my $ytick;
+ do {
+ $ytick = ($max_y - $min_y) / 11;
+ $ytick = POSIX::ceil($ytick / $tickgran) * $tickgran;
+ $tickgran *= 0.1;
+ } while (($max_y - $min_y) / $ytick < 4);
+
+ for my $i (-11..11) {
+ my $y = ($i * $ytick - $max_y) * $::ys + 10;
+ next if ($y < 2 || $y > $height - 18);
+
+ if ($i == 0) {
+ wuline($graph, $xoffset, $y, $width - 1, $y, 0, 0, 0, 1.0);
+ wuline($graph, $xoffset, $y + 1, $width - 1, $y + 1, 0, 0, 0, 1.0);
+ } else {
+ wuline($graph, $xoffset, $y, $width - 1, $y, 0, 0, 0, 0.2);
+ }
+
+ # text
+ my $traf = 8 * ($i * $ytick);
+ my $text;
+ if ($traf >= 500_000_000) {
+ $text = (sprintf "%.1f Gbit", ($traf/1_000_000_000));
+ } elsif ($traf >= 500_000) {
+ $text = (sprintf "%.1f Mbit", ($traf/1_000_000));
+ } else {
+ $text = (sprintf "%.1f kbit", ($traf/1_000));
+ }
+
+ my @bounds = GD::Image::stringFT(undef, $black, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 0, 0, $text);
+ my $w = $bounds[2] - $bounds[0];
+ my $h = $bounds[1] - $bounds[5];
+
+ next if ($y - $h/2 < 2 || $y + $h/2 > $height - 12);
+ $graph->stringFT($black, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, ($xoffset - 4) - $w, $y + $h/2, $text);
+ }
+
+ # Nice border(TM)
+ $graph->rectangle($xoffset, 0, $width - 1, $height - 1, $black);
+
+ return $graph;
+}
+
+sub plotseries {
+ my ($graph, $xvals, $yvals, $r, $g, $b, $min_x, $max_y) = @_;
+ my $xoffset = 70;
+
+ my @xvals = @{$xvals};
+ my @yvals = @{$yvals};
+
+ my $x = $xvals[0];
+ my $y = $yvals[0];
+ for my $i (1..$#xvals) {
+ next if ($::xs * ($xvals[$i] - $x) < 2 && $::ys * ($yvals[$i] - $y) > -2);
+
+ wuline($graph, ($x-$min_x) * $::xs + $xoffset + 1, ($y-$max_y) * $::ys + 10,
+ ($xvals[$i]-$min_x) * $::xs + $xoffset + 1, ($yvals[$i]-$max_y) * $::ys + 10, $r, $g, $b, 1.0);
+ $x = $xvals[$i];
+ $y = $yvals[$i];
+ }
+}
+
+1;
diff --git a/web/nms.gathering.org/old/nettkart-continuous.html b/web/nms.gathering.org/old/nettkart-continuous.html
new file mode 100644
index 0000000..e51eea0
--- /dev/null
+++ b/web/nms.gathering.org/old/nettkart-continuous.html
@@ -0,0 +1,31 @@
+<html>
+ <body>
+ <div id="d"></div>
+ <script type="text/javascript">
+ <!--
+ var existing_img = null;
+
+ function load_new() {
+ var i = document.createElement('img');
+ i.onload = function() { loaded(i); };
+ i.style.display = 'none';
+ i.src = '/nettkart.pl?random=' + (new Date()).getTime();
+ document.getElementById('d').appendChild(i);
+ }
+
+ function loaded(i) {
+ i.style.display = '';
+
+ if (existing_img) {
+ existing_img.parentElement.removeChild(existing_img);
+ }
+ existing_img = i;
+
+ setTimeout(function() { load_new(); }, 10000);
+ }
+
+ load_new();
+ -->
+ </script>
+ </body>
+</html>
diff --git a/web/nms.gathering.org/old/nettkart-json.pl b/web/nms.gathering.org/old/nettkart-json.pl
new file mode 100755
index 0000000..e95920e
--- /dev/null
+++ b/web/nms.gathering.org/old/nettkart-json.pl
@@ -0,0 +1,80 @@
+#! /usr/bin/perl
+use CGI;
+use DBI;
+use POSIX;
+use lib '../../include';
+use strict;
+use warnings;
+use nms;
+use JSON::XS;
+use Digest::MD5;
+
+my $cgi = CGI->new;
+my $secret = $cgi->param('secret');
+my $secret2 = $cgi->param('secret2');
+my $noise = $cgi->param('noise') // 0;
+my $fade_time = 0.0;
+if (defined($secret2)) {
+ my $phase = $cgi->param('phase');
+ my $period = $cgi->param('period');
+ $fade_time = sin((time - $phase) * 2.0 * 3.14159265358 / $period) * 0.5 + 0.5;
+}
+my $dbh = nms::db_connect();
+
+my %json = ();
+my $q = $dbh->prepare("select * from ( SELECT switch,sysname,sum(ifhcinoctets) AS ifhcinoctets,sum(ifhcoutoctets) AS ifhcoutoctets from switches natural left join get_current_datarate() where ip <> inet '127.0.0.1' group by switch,sysname) t1 natural join placements order by zorder;");
+$q->execute();
+while (my $ref = $q->fetchrow_hashref()) {
+
+ # for now:
+ # 10Mbit/switch = green
+ # 100Mbit/switch = yellow
+ # 1Gbit/switch = red
+ # 10Gbit/switch = white
+
+ my $clr;
+
+ if (defined($ref->{'ifhcinoctets'})) {
+ my $intensity = 0.0;
+ my $traffic = 4.0 * ($ref->{'ifhcinoctets'} + $ref->{'ifhcoutoctets'}); # average and convert to bits (should be about the same in practice)
+
+ my $max = 100_000_000_000.0; # 100Gbit
+ my $min = 10_000_000.0; # 10Mbit
+ if ($traffic >= $min) {
+ $intensity = log($traffic / $min) / log(10);
+
+ my $fudge1 = oct('0x'.substr(Digest::MD5::md5_hex($ref->{'sysname'} . $cgi->param('secret')), 0, 8));
+ my $fudge2 = oct('0x'.substr(Digest::MD5::md5_hex($ref->{'sysname'} . $cgi->param('secret2')), 0, 8));
+ $intensity += ($fudge1 + ($fudge2 - $fudge1) * $fade_time) * $noise;
+
+ $intensity = 4.0 if ($intensity > 4.0);
+ }
+ $clr = get_color($intensity);
+ } else {
+ $clr = [ 0, 0, 255 ];
+ }
+
+ $clr = sprintf("#%02x%02x%02x",
+ POSIX::floor($clr->[0] + 0.5),
+ POSIX::floor($clr->[1] + 0.5),
+ POSIX::floor($clr->[2] + 0.5));
+
+ $json{'switches'}{$ref->{'switch'}}{'color'} = $clr;
+}
+$dbh->disconnect;
+print CGI::header(-type=>'text/json; charset=utf-8');
+print JSON::XS::encode_json(\%json);
+
+sub get_color {
+ my $intensity = shift;
+ my $gamma = 1.0/1.90;
+ if ($intensity > 3.0) {
+ return [ 255.0 * ((4.0 - $intensity) ** $gamma), 255.0 * ((4.0 - $intensity) ** $gamma), 255.0 * ((4.0 - $intensity) ** $gamma) ];
+ } elsif ($intensity > 2.0) {
+ return [ 255.0, 255.0 * (($intensity - 2.0) ** $gamma), 255.0 * (($intensity - 2.0) ** $gamma) ];
+ } elsif ($intensity > 1.0) {
+ return [ 255.0, 255.0 * ((2.0 - $intensity) ** $gamma), 0 ];
+ } else {
+ return [ 255.0 * ($intensity ** $gamma), 255, 0 ];
+ }
+}
diff --git a/web/nms.gathering.org/old/nettkart-text.pl b/web/nms.gathering.org/old/nettkart-text.pl
new file mode 100755
index 0000000..673ade5
--- /dev/null
+++ b/web/nms.gathering.org/old/nettkart-text.pl
@@ -0,0 +1,63 @@
+#! /usr/bin/perl
+use CGI;
+use DBI;
+use lib '../../include';
+use nms;
+my $cgi = CGI->new;
+
+my $dbh = nms::db_connect();
+
+my $night = defined($cgi->param('night'));
+
+if ($night) {
+print $cgi->header(-type=>'text/html; charset=utf-8', -refresh=>'10; nettkart-text.pl?night=1');
+} else {
+print $cgi->header(-type=>'text/html; charset=utf-8', -refresh=>'10; ' . CGI::url());
+}
+
+my $tag = "";
+
+$tag = "bgcolor=black" if($night);
+
+print <<"EOF";
+<html>
+ <head>
+ <title>nettkart</title>
+ </head>
+ <body $tag>
+ <map name="switches">
+EOF
+
+my $q = $dbh->prepare("select * from switches natural join placements where ip <> inet '127.0.0.1'");
+$q->execute();
+while (my $ref = $q->fetchrow_hashref()) {
+ $ref->{'placement'} =~ /\((\d+),(\d+)\),\((\d+),(\d+)\)/;
+
+ my $traffic = 4.0 * $ref->{'bytes_in'} + $ref->{'bytes_out'}; # average and convert to bits (should be about the same in practice)
+ my $ttext;
+ if ($traffic >= 1_000_000_000) {
+ $ttext = sprintf "%.2f Gbit/port/sec", $traffic/1_000_000_000;
+ } elsif ($traffic => 1_000_000) {
+ $ttext = sprintf "%.2f Mbit/port/sec", $traffic/1_000_000;
+ } else {
+ $ttext = sprintf "%.2f kbit/port/sec", $traffic/1_000;
+ }
+
+ printf " <area shape=\"rect\" coords=\"%u,%u,%u,%u\" href=\"showswitch.pl?id=%u\" alt=\"%s (%s)\" onmouseover=\"window.status='%s (%s)'; return true\" onmouseout=\"window.status=''\" />\n",
+ $3, $4, $1, $2, $ref->{'switch'}, $ref->{'sysname'},
+ $ttext, $ref->{'sysname'}, $ttext;
+}
+$dbh->disconnect;
+
+my $image = "nettkart.pl";
+
+$image = "nettkart.pl?night=1" if ($night);
+
+
+print <<"EOF";
+ </map>
+
+ <p><img src="$image" usemap="#switches" /></p>
+ </body>
+</html>
+EOF
diff --git a/web/nms.gathering.org/old/nettkart-web.pl b/web/nms.gathering.org/old/nettkart-web.pl
new file mode 100755
index 0000000..ce76c35
--- /dev/null
+++ b/web/nms.gathering.org/old/nettkart-web.pl
@@ -0,0 +1,47 @@
+#! /usr/bin/perl
+use CGI;
+use DBI;
+use lib '../../include';
+use nms;
+my $cgi = CGI->new;
+
+my $dbh = nms::db_connect();
+print $cgi->header(-type=>'text/html; charset=utf-8', -refresh=>'45; ' . CGI::url());
+
+print <<"EOF";
+<html>
+ <head>
+ <title>nettkart - web</title>
+ </head>
+ <body>
+ <map name="switches">
+EOF
+
+my $q = $dbh->prepare("select * from switches natural join placements where ip <> inet '127.0.0.1'");
+$q->execute();
+while (my $ref = $q->fetchrow_hashref()) {
+ $ref->{'placement'} =~ /\((\d+),(\d+)\),\((\d+),(\d+)\)/;
+
+ my $traffic = 4.0 * $ref->{'bytes_in'} + $ref->{'bytes_out'}; # average and convert to bits (should be about the same in practice)
+ my $ttext;
+ if ($traffic >= 1_000_000_000) {
+ $ttext = sprintf "%.2f Gbit/port/sec", $traffic/1_000_000_000;
+ } elsif ($traffic => 1_000_000) {
+ $ttext = sprintf "%.2f Mbit/port/sec", $traffic/1_000_000;
+ } else {
+ $ttext = sprintf "%.2f kbit/port/sec", $traffic/1_000;
+ }
+
+ printf " <area shape=\"rect\" coords=\"%u,%u,%u,%u\" href=\"http://$ref->{'ip'}\" alt=\"%s (%s)\" onmouseover=\"window.status='%s (%s)'; return true\" onmouseout=\"window.status=''\" />\n",
+ $3, $4, $1, $2, $ref->{'switch'}, $ref->{'sysname'},
+ $ttext, $ref->{'sysname'}, $ttext;
+}
+$dbh->disconnect;
+
+print <<"EOF";
+ </map>
+
+ <p><img src="nettkart.pl" usemap="#switches" /></p>
+ </body>
+</html>
+EOF
diff --git a/web/nms.gathering.org/old/nettkart.pl b/web/nms.gathering.org/old/nettkart.pl
new file mode 100755
index 0000000..bf3bf74
--- /dev/null
+++ b/web/nms.gathering.org/old/nettkart.pl
@@ -0,0 +1,145 @@
+#! /usr/bin/perl
+use CGI;
+use GD;
+use Image::Magick;
+use DBI;
+use lib '../../include';
+use strict;
+use warnings;
+use nms;
+use File::Basename;
+my $cgi = CGI->new;
+my $cwd = dirname($0);
+
+# Sekrit night-mode
+my $night = defined($cgi->param('night'));
+
+my $dbh = nms::db_connect();
+
+GD::Image->trueColor(1);
+
+my $text_img;
+our $img = GD::Image->new($cwd.'/tg15-salkart.png');
+if ($night) {
+ my ($width, $height) = ($img->width, $img->height);
+
+ $img = GD::Image->new($width, $height, 1);
+ $img->alphaBlending(0);
+ $img->saveAlpha(1);
+ my $blank = $img->colorAllocateAlpha(0, 0, 0, 127);
+ $img->filledRectangle(0, 0, $img->width - 1, $img->height - 1, $blank);
+
+ $text_img = GD::Image->new($width, $height, 1);
+ $text_img->alphaBlending(0);
+ $text_img->saveAlpha(1);
+ $blank = $text_img->colorAllocateAlpha(0, 0, 0, 127);
+ $text_img->filledRectangle(0, 0, $text_img->width - 1, $text_img->height - 1, $blank);
+} else {
+ $text_img = $img;
+}
+
+my $blk = $img->colorResolve(0, 0, 0);
+
+for my $y (42..236) {
+ my $i = 4.0 * ($y - 236.0) / (42.0 - 237.0);
+ my $clr = get_color($i);
+
+ $img->filledRectangle(12, $y, 33, $y+1, $clr);
+ $text_img->filledRectangle(12, $y, 33, $y+1, $clr);
+}
+
+$text_img->rectangle(12,42,33,236,$blk);
+
+my $tclr = $night ? $text_img->colorResolve(255, 255, 255) : $blk;
+$text_img->stringFT($tclr, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 40, 47 + (236-42)*0.0/4.0, "100 Gbit/sec");
+$text_img->stringFT($tclr, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 40, 47 + (236-42)*1.0/4.0, "10 Gbit/sec");
+$text_img->stringFT($tclr, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 40, 47 + (236-42)*2.0/4.0, "1 Gbit/sec");
+$text_img->stringFT($tclr, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 40, 47 + (236-42)*3.0/4.0, "100 Mbit/sec");
+$text_img->stringFT($tclr, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 40, 47 + (236-42)*4.0/4.0, "10 Mbit/sec");
+$text_img->stringFT($tclr, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 1600, 1000, "NMS (C) 2005-2015 Tech:Server");
+
+my $q = $dbh->prepare("select * from ( SELECT switch,sysname,sum(ifhcinoctets) AS ifhcinoctets,sum(ifhcoutoctets) AS ifhcoutoctets from switches natural left join get_current_datarate() where ip <> inet '127.0.0.1' group by switch,sysname) t1 natural join placements order by zorder;");
+$q->execute();
+while (my $ref = $q->fetchrow_hashref()) {
+
+ # for now:
+ # 10Mbit/switch = green
+ # 100Mbit/switch = yellow
+ # 1Gbit/switch = red
+ # 10Gbit/switch = white
+
+ my $clr;
+
+ if (defined($ref->{'ifhcinoctets'})) {
+ my $intensity = 0.0;
+ my $traffic = 4.0 * ($ref->{'ifhcinoctets'} + $ref->{'ifhcoutoctets'}); # average and convert to bits (should be about the same in practice)
+
+ my $max = 100_000_000_000.0; # 100Gbit
+ my $min = 10_000_000.0; # 10Mbit
+ if ($traffic >= $min) {
+ $intensity = log($traffic / $min) / log(10);
+ $intensity = 4.0 if ($intensity > 4.0);
+ }
+ $clr = get_color($intensity);
+ } else {
+ $clr = $img->colorResolve(0, 0, 255);
+ }
+
+ my $sysname = $ref->{'sysname'};
+ $sysname =~ s/-sekrit//;
+
+ $ref->{'placement'} =~ /\((\d+),(\d+)\),\((\d+),(\d+)\)/;
+ $img->filledRectangle($3,$4,$1,$2,$clr);
+ $text_img->filledRectangle($3,$4,$1,$2,$clr);
+
+ $img->rectangle($3,$4,$1,$2,$blk);
+ $text_img->rectangle($3,$4,$1,$2,$blk);
+ my ($x2, $y2, $x1, $y1) = ($1, $2, $3, $4);
+ my $max_textlen = ($x2-$x1) > ($y2-$y1) ? $x2-$x1 : $y2-$y1;
+ while (length($sysname) * 6 > $max_textlen) {
+ # Try to abbreviate sysname if it is too long for the box
+ $sysname =~ s/^(.*)[a-z]~?([0-9-]+)$/$1~$2/ or last;
+ }
+ if (($x2-$x1) > ($y2-$y1)) {
+ $text_img->string(gdSmallFont,$x1+2,$y1,$sysname,$blk);
+ } else {
+ $text_img->stringUp(gdSmallFont,$x1,$y2-3,$sysname,$blk);
+ }
+}
+$dbh->disconnect;
+
+print $cgi->header(-type=>'image/png', -expires=>'now');
+if ($night) {
+ my $magick = Image::Magick->new;
+ $magick->BlobToImage($img->png);
+ $magick->Blur(sigma=>10.0, channel=>'All');
+ $magick->Gamma(gamma=>1.90);
+
+ my $m2 = Image::Magick->new;
+ $m2->Read($cwd.'/tg15-salkart.png');
+ $m2->Negate();
+ $m2->Composite(image=>$magick, compose=>'Atop');
+
+ my $m3 = Image::Magick->new;
+ $m3->BlobToImage($text_img->png);
+ $m2->Composite(image=>$m3, compose=>'Atop');
+
+ $img = $m2->ImageToBlob();
+ print $img;
+} else {
+ print $img->png;
+}
+
+sub get_color {
+ my $intensity = shift;
+ my $gamma = 1.0/1.90;
+ if ($intensity > 3.0) {
+ return $img->colorResolve(255.0 * ((4.0 - $intensity) ** $gamma), 255.0 * ((4.0 - $intensity) ** $gamma), 255.0 * ((4.0 - $intensity) ** $gamma));
+ } elsif ($intensity > 2.0) {
+ return $img->colorResolve(255.0, 255.0 * (($intensity - 2.0) ** $gamma), 255.0 * (($intensity - 2.0) ** $gamma));
+ } elsif ($intensity > 1.0) {
+ return $img->colorResolve(255.0, 255.0 * ((2.0 - $intensity) ** $gamma), 0);
+ } else {
+ return $img->colorResolve(255.0 * ($intensity ** $gamma), 255, 0);
+ }
+}
diff --git a/web/nms.gathering.org/old/observium.html b/web/nms.gathering.org/old/observium.html
new file mode 100755
index 0000000..a4acd16
--- /dev/null
+++ b/web/nms.gathering.org/old/observium.html
@@ -0,0 +1,37 @@
+<html>
+ <head>
+ <title>TG15 - The Future Is Back</title>
+ <style type="text/css">
+ body {
+ margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin: 0 auto;
+ background-image: url('http://funfact.tg15.gathering.org/background.png');
+ background-size: 1920px 1080px; background-repeat: no-repeat; overflow: hidden;
+ }
+
+ iframe {
+ position: absolute;
+ bottom: 0px;
+ top: 0px;
+ left: 0px;
+ visibility: hidden;
+ margin: 0px;
+ overflow-y: hidden;
+ overflow-x: hidden;
+ //-ms-zoom: 0.75;
+ //-moz-transform: scale(0.75);
+ //-moz-transform-origin: 0 0;
+ //-o-transform: scale(0.75);
+ //-o-transform-origin: 0 0;
+ //-webkit-transform: scale(0.75);
+ //-webkit-transform-origin: 0 0;
+ }
+
+ #observium {
+ padding-top: 300px;
+ }
+ </style>
+ </head>
+ <body>
+ <iframe height="700" class="frames" width="1780" id="observium" frameborder="0" src="http://observium.tg15.gathering.org/graph-realtime.php?type=bits&id=447&interval=30" scrolling="no" style="visibility: visible;"></iframe>
+ </body>
+</html>
diff --git a/web/nms.gathering.org/old/ping-json.pl b/web/nms.gathering.org/old/ping-json.pl
new file mode 100755
index 0000000..e661e8f
--- /dev/null
+++ b/web/nms.gathering.org/old/ping-json.pl
@@ -0,0 +1,32 @@
+#! /usr/bin/perl
+use CGI;
+use DBI;
+use JSON::XS;
+use lib '../../include';
+use nms;
+my $cgi = CGI->new;
+
+my $dbh = nms::db_connect();
+my %json = ();
+
+my $q = $dbh->prepare("SELECT DISTINCT ON (switch) switch, latency_ms FROM ping WHERE updated >= NOW() - INTERVAL '15 secs' ORDER BY switch, updated DESC;");
+$q->execute();
+while (my $ref = $q->fetchrow_hashref()) {
+ $json{'switches'}{$ref->{'switch'}}{'latency'} = $ref->{'latency_ms'};
+}
+
+my $qs = $dbh->prepare("SELECT DISTINCT ON (switch) switch, latency_ms FROM ping_secondary_ip WHERE updated >= NOW() - INTERVAL '15 secs' ORDER BY switch, updated DESC;");
+$qs->execute();
+while (my $ref = $qs->fetchrow_hashref()) {
+ $json{'switches'}{$ref->{'switch'}}{'latency_secondary'} = $ref->{'latency_ms'};
+}
+
+my $lq = $dbh->prepare("SELECT DISTINCT ON (linknet) linknet, latency1_ms, latency2_ms FROM linknet_ping WHERE updated >= NOW() - INTERVAL '15 secs' ORDER BY linknet, updated DESC;");
+$lq->execute();
+while (my $ref = $lq->fetchrow_hashref()) {
+ $json{'linknets'}{$ref->{'linknet'}} = [ $ref->{'latency1_ms'}, $ref->{'latency2_ms'} ];
+}
+
+$q->execute();
+print $cgi->header(-type=>'text/json; charset=utf-8');
+print JSON::XS::encode_json(\%json);
diff --git a/web/nms.gathering.org/old/ping.css b/web/nms.gathering.org/old/ping.css
new file mode 100644
index 0000000..1045a4a
--- /dev/null
+++ b/web/nms.gathering.org/old/ping.css
@@ -0,0 +1,13 @@
+.switchname {
+ position: absolute;
+ font-family: sans-serif;
+ font-size: small;
+ white-space: nowrap;
+}
+.rot {
+ -webkit-transform: rotate(-90deg);
+ -webkit-transform-origin: 0% 0%;
+ transform: rotate(-90deg);
+ transform-origin: 0% 0%;
+ bottom: -14px;
+}
diff --git a/web/nms.gathering.org/old/ping.html b/web/nms.gathering.org/old/ping.html
new file mode 100644
index 0000000..1c3c3e0
--- /dev/null
+++ b/web/nms.gathering.org/old/ping.html
@@ -0,0 +1,21 @@
+<html>
+ <head>
+ <title>Ping? Pong!</title>
+ </head>
+ <body>
+ <link rel="stylesheet" href="/ping.css">
+ <p id="playground">
+ <svg id="lines" width="1920" height="1032" style="position: absolute; top: 0; left: 0; z-index: 1">
+ </svg>
+ <img src="tg15-salkart.png" alt="" id="map" />
+ </p>
+ <script>
+ // These are used by ping.js, below.
+ var switches_url = "/switches-json.pl";
+ var ping_url = "/ping-json.pl";
+ var draw_linknets = true;
+ var can_edit = false;
+ </script>
+ <script type="text/javascript" src="ping.js"></script>
+ </body>
+</html>
diff --git a/web/nms.gathering.org/old/ping.js b/web/nms.gathering.org/old/ping.js
new file mode 100644
index 0000000..7c5de57
--- /dev/null
+++ b/web/nms.gathering.org/old/ping.js
@@ -0,0 +1,238 @@
+var switches = [];
+var linknets = [];
+var last_dataset = [];
+get_switches();
+get_ping();
+
+function json_request(url, func, repeat_ms) {
+ var request = new XMLHttpRequest();
+ request.open('GET', url, true);
+
+ request.onload = function() {
+ if (this.status >= 200 && this.status < 400) {
+ func(JSON.parse(this.response));
+ } else if (this.status != 410) {
+ json_request(url, func, repeat_ms);
+ }
+ };
+ request.onerror = function() {
+ json_request(url, func, repeat_ms);
+ };
+ request.send();
+}
+
+function get_switches() {
+ json_request(switches_url, draw_switches, 1000);
+}
+
+function get_ping() {
+ json_request(ping_url, update_ping, 1000);
+}
+
+function draw_switches(json) {
+ for (var switchnum in switches) {
+ document.body.removeChild(switches[switchnum]);
+ }
+ switches = [];
+ var lines = document.getElementById("lines");
+ for (var linknetnum in linknets) {
+ lines.removeChild(linknets[linknetnum][0]);
+ lines.removeChild(linknets[linknetnum][1]);
+ lines.removeChild(linknets[linknetnum][2]);
+ }
+ linknets = [];
+
+ for (var switchnum in json['switches']) {
+ var s = json['switches'][switchnum];
+ create_switch(switchnum,
+ s['sysname'],
+ parseInt(s['x']),
+ parseInt(s['y']),
+ parseInt(s['zorder']),
+ parseInt(s['width']),
+ parseInt(s['height']));
+ }
+
+ if (draw_linknets) {
+ for (var i = 0; i < json['linknets'].length; ++i) {
+ var linknet = json['linknets'][i];
+ create_linknet(linknet['linknet'], linknet['switch1'], linknet['switch2']);
+ }
+ }
+
+ setTimeout(get_switches, 60000);
+ really_update_ping(last_dataset);
+}
+
+function create_linknet(linknetnum, switch1, switch2) {
+ var s1 = switches[switch1];
+ var s2 = switches[switch2];
+ var s1x = parseInt(s1.style.left.replace("px", "")) + 0.5 * parseInt(s1.style.width.replace("px", ""));
+ var s1y = parseInt(s1.style.top.replace("px", "")) + 0.5 * parseInt(s1.style.height.replace("px", ""));
+ var s2x = parseInt(s2.style.left.replace("px", "")) + 0.5 * parseInt(s2.style.width.replace("px", ""));
+ var s2y = parseInt(s2.style.top.replace("px", "")) + 0.5 * parseInt(s2.style.height.replace("px", ""));
+
+ var midx = 0.5 * (s1x + s2x);
+ var midy = 0.5 * (s1y + s2y);
+
+ var outline = document.createElementNS("http://www.w3.org/2000/svg", "line");
+ outline.setAttribute("x1", s1x);
+ outline.setAttribute("y1", s1y);
+ outline.setAttribute("x2", s2x);
+ outline.setAttribute("y2", s2y);
+ outline.style.stroke = "rgb(0, 0, 0)";
+ outline.style.strokeWidth = 4;
+ document.getElementById("lines").appendChild(outline);
+
+ var line1 = document.createElementNS("http://www.w3.org/2000/svg", "line");
+ line1.setAttribute("x1", s1x);
+ line1.setAttribute("y1", s1y);
+ line1.setAttribute("x2", midx);
+ line1.setAttribute("y2", midy);
+ line1.style.stroke = "rgb(0, 0, 255)";
+ line1.style.strokeWidth = 3;
+ document.getElementById("lines").appendChild(line1);
+
+ var line2 = document.createElementNS("http://www.w3.org/2000/svg", "line");
+ line2.setAttribute("x1", midx);
+ line2.setAttribute("y1", midy);
+ line2.setAttribute("x2", s2x);
+ line2.setAttribute("y2", s2y);
+ line2.style.stroke = "rgb(0, 0, 255)";
+ line2.style.strokeWidth = 3;
+ document.getElementById("lines").appendChild(line2);
+
+ linknets[linknetnum] = [ line1, line2, outline ];
+}
+
+function update_ping(json) {
+ last_dataset = json;
+ really_update_ping(json);
+ setTimeout(get_ping, 1000);
+}
+
+function gradient_from_latency(latency_ms, latency_secondary_ms) {
+ if (latency_secondary_ms === undefined) {
+ return rgb_from_latency(latency_ms);
+ }
+ return 'linear-gradient(' +
+ rgb_from_latency(latency_ms) + ', ' +
+ rgb_from_latency(latency_secondary_ms) + ')';
+}
+
+function rgb_from_latency(latency_ms) {
+ if (latency_ms === null || latency_ms === undefined) {
+ return '#0000ff';
+ }
+
+ // 10ms is max
+ var l = latency_ms / 50.0;
+ if (l >= 2.0) {
+ return 'rgb(255, 0, 0)';
+ } else if (l >= 1.0) {
+ l = 2.0 - l;
+ l = Math.pow(l, 1.0/2.2);
+ l = Math.round(l * 255.0);
+ return 'rgb(255, ' + l + ', 0)';
+ } else {
+ l = Math.pow(l, 1.0/2.2);
+ l = Math.round(l * 255.0);
+ return 'rgb(' + l + ', 255, 0)';
+ }
+}
+
+function really_update_ping(json) {
+ if (json['switches']) {
+ for (var switchnum in switches) {
+ if (json['switches'][switchnum]) {
+ if (json['switches'][switchnum]['color']) {
+ switches[switchnum].style.background = json['switches'][switchnum]['color'];
+ } else {
+ switches[switchnum].style.background =
+ gradient_from_latency(json['switches'][switchnum]['latency'],
+ json['switches'][switchnum]['latency_secondary']);
+ }
+ } else {
+ switches[switchnum].style.background = '#0000ff';
+ }
+ }
+ }
+ if (json['linknets']) {
+ for (var linknetnum in linknets) {
+ linknets[linknetnum][0].style.stroke = rgb_from_latency(json['linknets'][linknetnum][0]);
+ linknets[linknetnum][1].style.stroke = rgb_from_latency(json['linknets'][linknetnum][1]);
+ }
+ }
+}
+
+function create_switch(switchnum, sysname, x, y, zorder, width, height) {
+ var s = document.createElement("div");
+ var map = document.getElementById('map');
+ var top_offset = map.getBoundingClientRect().top;
+ var left_offset = map.getBoundingClientRect().left;
+
+ s.style.position = 'absolute';
+ s.style.left = (left_offset + x) + 'px';
+ s.style.top = (top_offset + y) + 'px';
+ s.style.width = width + 'px';
+ s.style.height = height + 'px';
+ s.style.backgroundColor = '#0000ff';
+ s.style.border = '1px solid black';
+ s.style.padding = "0";
+ s.style.zIndex = zorder + 100;
+ switches[switchnum] = s;
+
+ var span = document.createElement("div");
+ span.className = "switchname";
+ if (width < 1.5 * height) {
+ span.className = "switchname rot";
+ }
+ span.style.border = "0";
+ span.style.padding = "0";
+ s.appendChild(span);
+
+ var text = document.createTextNode(sysname);
+ span.appendChild(text);
+
+ s.setAttribute("data-switchnum", switchnum);
+
+ document.body.appendChild(s);
+}
+
+var dragging_switch = null;
+var delta_x = null, delta_y = null;
+
+if (can_edit) {
+ document.onmousedown = function(e) {
+ var switchnum = e.target.getAttribute("data-switchnum");
+ if (switchnum === null) {
+ return;
+ }
+ dragging_switch = switchnum;
+ delta_x = parseInt(e.target.style.left.replace("px", "")) - e.clientX;
+ delta_y = parseInt(e.target.style.top.replace("px", "")) - e.clientY;
+ }
+
+ document.onmousemove = function(e) {
+ if (dragging_switch === null) {
+ return;
+ }
+ switches[dragging_switch].style.left = (e.clientX + delta_x) + 'px';
+ switches[dragging_switch].style.top = (e.clientY + delta_y) + 'px';
+ }
+
+ document.onmouseup = function(e) {
+ if (dragging_switch === null) {
+ return;
+ }
+ var x = e.clientX + delta_x - map.getBoundingClientRect().top;
+ var y = e.clientY + delta_y - map.getBoundingClientRect().left;
+
+ var request = new XMLHttpRequest();
+ request.open('POST', '/change-switch-pos.pl', true);
+ request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
+ request.send("switch=" + dragging_switch + "&x=" + x + "&y=" + y);
+
+ dragging_switch = null;
+ }
+}
diff --git a/web/nms.gathering.org/old/ping2.html b/web/nms.gathering.org/old/ping2.html
new file mode 100644
index 0000000..05ed129
--- /dev/null
+++ b/web/nms.gathering.org/old/ping2.html
@@ -0,0 +1,21 @@
+<html>
+ <head>
+ <title>Ping? Pong!</title>
+ </head>
+ <body>
+ <link rel="stylesheet" href="/ping.css">
+ <p id="playground">
+ <svg id="lines" width="1280" height="736" style="position: absolute; top: 0; left: 0; z-index: 1">
+ </svg>
+ <img src="tg15-salkart.png" alt="" id="map" />
+ </p>
+ <script>
+ // These are used by ping.js, below.
+ var switches_url = "/switches-json.pl";
+ var ping_url = "/nettkart-json.pl";
+ var draw_linknets = false;
+ var can_edit = false;
+ </script>
+ <script type="text/javascript" src="ping.js"></script>
+ </body>
+</html>
diff --git a/web/nms.gathering.org/old/portkart.pl b/web/nms.gathering.org/old/portkart.pl
new file mode 100755
index 0000000..ce7dcdd
--- /dev/null
+++ b/web/nms.gathering.org/old/portkart.pl
@@ -0,0 +1,93 @@
+#! /usr/bin/perl
+use CGI;
+use GD;
+use DBI;
+use lib '../../include';
+use nms;
+use File::Basename;
+my $cgi = CGI->new;
+my $cwd = dirname($0);
+
+my $dbh = nms::db_connect();
+
+GD::Image->trueColor(1);
+$img = GD::Image->new($cwd.'/tg15-salkart.png');
+
+my $blk = $img->colorResolve(0, 0, 0);
+
+for my $y (42..236) {
+ my $i = 3.0 * ($y - 236.0) / (42.0 - 237.0);
+ my $clr = get_color($i);
+
+ $img->filledRectangle(12,$y,33,$y+1,$clr);
+}
+
+$img->stringFT($blk, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 40, 47 + (236-42)*0.0/3.0, "1 Gbit/sec");
+$img->stringFT($blk, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 40, 47 + (236-42)*1.0/3.0, "100 Mbit/sec");
+$img->stringFT($blk, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 40, 47 + (236-42)*2.0/3.0, "10 Mbit/sec");
+$img->stringFT($blk, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 40, 47 + (236-42)*3.0/3.0, "1 Mbit/sec");
+$img->stringFT($blk, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 1600, 1000, "NMS (C) 2005-2007 Tech:Server");
+
+sub portnum($) {
+ my ($port) = @_;
+ if ($port =~ /(\d+)$/) {
+ return $1;
+ }
+ warn "Unrecognized port name: $port";
+ return undef;
+}
+
+my $q = $dbh->prepare('select switch,ifname,ifhcinoctets,ifhcoutoctets,placement,switchtype from switches natural join placements natural join get_datarate() where switchtype like \'%2200%\' and sysname like \'e%-%\'');
+$q->execute();
+while (my $ref = $q->fetchrow_hashref()) {
+
+ # for now:
+ # 100kbit/port = all green
+ # 1gbit/port = all red
+
+ my $clr;
+
+ if (defined($ref->{'ifhcinoctets'})) {
+ my $intensity = 0.0;
+ my $traffic = 4.0 * ($ref->{'ifhcinoctets'} + $ref->{'ifhcoutoctets'}); # average and convert to bits (should be about the same in practice)
+
+ my $max = 100_000_000_000.0; # 1Gbit
+ my $min = 1_000_000.0; # 1Mbit
+ if ($traffic >= $min) {
+ $intensity = log($traffic / $min) / log(10);
+ $intensity = 4.0 if ($intensity > 4.0);
+ }
+ $clr = get_color($intensity);
+ } else {
+ $clr = $img->colorResolve(0, 0, 255);
+ }
+
+ $ref->{'placement'} =~ /\((\d+),(\d+)\),\((\d+),(\d+)\)/;
+ my $npo = 48;
+ my $f = portnum($ref->{'ifname'}) % 2;
+ my $po = (portnum($ref->{'ifname'}) - $f)/2;
+ my $h = 2*($2-$4)/$npo;
+ my $w = ($1-$3)/2;
+
+ $img->filledRectangle($3+$w*$f,$4+$po*$h,$3+$w+$w*$f,$4+$h*($po+1),$clr);
+# $img->rectangle($3+$w*$f,$4+$po*$h,$3+$w+$w*$f,$4+$h*($po+1),$blk);
+ $img->rectangle($3,$4,$1,$2,$blk);
+}
+$dbh->disconnect;
+
+print $cgi->header(-type=>'image/png');
+print $img->png;
+
+sub get_color {
+ my $intensity = shift;
+ my $gamma = 1.0/1.90;
+ if ($intensity > 3.0) {
+ return $img->colorResolve(255.0 * ((4.0 - $intensity) ** $gamma), 255.0 * ((4.0 - $intensity) ** $gamma), 255.0 * ((4.0 - $intensity) ** $gamma));
+ } elsif ($intensity > 2.0) {
+ return $img->colorResolve(255.0, 255.0 * (($intensity - 2.0) ** $gamma), 255.0 * (($intensity - 2.0) ** $gamma));
+ } elsif ($intensity > 1.0) {
+ return $img->colorResolve(255.0, 255.0 * ((2.0 - $intensity) ** $gamma), 0);
+ } else {
+ return $img->colorResolve(255.0 * ($intensity ** $gamma), 255, 0);
+ }
+}
diff --git a/web/nms.gathering.org/old/showswitch.pl b/web/nms.gathering.org/old/showswitch.pl
new file mode 100755
index 0000000..e585841
--- /dev/null
+++ b/web/nms.gathering.org/old/showswitch.pl
@@ -0,0 +1,249 @@
+#! /usr/bin/perl
+use CGI;
+use DBI;
+use Time::HiRes;
+use POSIX ":sys_wait_h";
+use strict;
+use warnings;
+use lib '../../include';
+use nms;
+use File::Basename;
+my $cgi = CGI->new;
+my $cwd = dirname($0);
+my $switch = $cgi->param('id');
+my $width = $cgi->param('width');
+my $height = $cgi->param('height');
+my @pids = ();
+my $resthtml = "";
+
+$width = 500 unless (defined($width));
+$height = 250 unless (defined($height));
+
+require "$cwd/mygraph.pl";
+
+my $start = [Time::HiRes::gettimeofday];
+my $dbh = nms::db_connect();
+
+sub filename($$$$) {
+ my ($switch, $last_port, $width, $height) = @_;
+ $last_port =~ y,/,_,;
+ return "$switch-$last_port-$width-$height.png";
+}
+
+# Fetch the name
+my $ref = $dbh->selectrow_hashref('SELECT sysname,ip FROM switches WHERE switch=?', undef, $switch);
+
+print $cgi->header(-type=>'text/html; charset=utf-8');
+print <<"EOF";
+<html>
+ <head>
+ <title>snmp</title>
+ </head>
+ <body>
+ <h1>Switch $switch ($ref->{'sysname'} - $ref->{'ip'})</h1>
+EOF
+
+my $q = $dbh->prepare('select ifname,\'Port \' || ifname as description,extract(epoch from time) as time,ifhcinoctets,ifhcoutoctets from switches natural join polls where time between now() - \'1 day\'::interval and now() and switch=? order by switch,ifname,time;') or die $dbh->errstr;
+$q->execute($switch) or die $dbh->errstr;
+
+my (@totx, @toty1, @toty2) = ();
+
+my (@x, @y1, @y2) = ();
+my $last_port;
+my $portname = "";
+my $min_x = time;
+my $max_x = time - 86400;
+my ($min_y, $max_y, $prev_time, $prev_in, $prev_out);
+my ($if,$of,$ifv,$ofv);
+my $idx;
+my ($min_ty,$max_ty) = (0, 10_000_000/8);
+
+$prev_time = -1;
+my $last_totx;
+# Buffer all the rows so we can fancy-sort them
+my @rows;
+while (my $ref = $q->fetchrow_hashref()) {
+ push @rows, $ref;
+}
+sub cmp_ports {
+ my @a = split(/(\d+)/, $_[0]);
+ my @b = split(/(\d+)/, $_[1]);
+ for (my $i = 0; $i < scalar @a; ++$i) {
+ last if $i >= scalar @b;
+ my $a = $a[$i];
+ my $b = $b[$i];
+ if ($a =~ /^\d+$/ && $a =~ /^\d+$/) {
+ return $a <=> $b if ($a != $b);
+ } else {
+ return $a cmp $b if ($a ne $b);
+ }
+ }
+ # None of the N first parts differed, this means the shortest one is first
+ return scalar @a <=> scalar @b;
+}
+sort { cmp_ports($a->{'ifname'}, $b->{'ifname'}) } @rows;
+foreach my $ref (@rows) {
+ my $time = $ref->{'time'};
+ my $in = $ref->{'ifhcinoctets'};
+ my $out = $ref->{'ifhcoutoctets'};
+ next if ($time == $prev_time);
+ if ($ref->{'ifname'} ne $last_port) {
+ if (defined $last_port) {
+ my $filename = filename($switch, $last_port, $width, $height);
+
+ # reap children
+ waitpid(-1, WNOHANG);
+
+ my $pid = fork();
+ if ($pid == 0) {
+# write out the graph
+ my $graph = makegraph($width, $height, $min_x, $max_x, $min_y, $max_y, 5);
+ plotseries($graph, \@x, \@y1, 255, 0, 0, $min_x, $max_y);
+ plotseries($graph, \@x, \@y2, 0, 0, 255, $min_x, $max_y);
+
+ open GRAPH, ">$cwd/img/$filename"
+ or die "$cwd/img/$filename: $!";
+ print GRAPH $graph->png;
+ close GRAPH;
+ exit;
+ }
+
+ push @pids, $pid;
+
+ $resthtml .= "<div style=\"float: left;\"><h2>$portname</h2>\n";
+ $resthtml .= "<p><img src=\"img/$filename\" width=\"$width\" height=\"$height\" /></p></div>\n";
+ }
+
+ # Reset all the variables
+ @x = ();
+ @y1 = ();
+ @y2 = ();
+ ($min_y,$max_y) = (0, 10_000_000/8);
+ $prev_time = $ref->{'time'};
+ $prev_in = $ref->{'ifhcinoctets'};
+ $prev_out = $ref->{'ifhcoutoctets'};
+ $last_port = $ref->{'ifname'};
+ $portname = $ref->{'description'};
+ ($if,$of,$ifv,$ofv) = (0,0,0,0);
+ ($prev_time,$prev_in,$prev_out) = ($time,$in,$out);
+ $idx = 0;
+ $last_totx = undef;
+ next;
+ }
+
+ # Assume overflow (unless the switch has been down for >10 minutes)
+ my ($calc_in, $calc_out) = ($in, $out);
+ if ($in < $prev_in || $out < $prev_out) {
+ if ($prev_in < 4294967296 && $prev_out < 4294967296) {
+ # ick, heuristics
+ if ($prev_time - $time > 600 || ($in + 4294967296 - $prev_in) > 2147483648 || ($out + 4294967296 - $prev_out) > 2147483648) {
+ ($prev_time,$prev_in,$prev_out) = ($time,$in,$out);
+ next;
+ }
+
+ $calc_in += 4294967296 if ($in < $prev_in);
+ $calc_out += 4294967296 if ($out < $prev_out);
+ } else {
+ $prev_in = 0;
+ $prev_out = 0;
+ }
+ }
+
+ # Remove dupes
+ if ($in == $prev_in && $out == $prev_out) {
+ ($prev_time,$prev_in,$prev_out) = ($time,$in,$out);
+ next;
+ }
+
+ # Find the current flow
+ my $if = ($calc_in - $prev_in) / ($time - $prev_time);
+ my $of = ($calc_out - $prev_out) / ($time - $prev_time);
+
+ # Summarize (we don't care about the summed variance for now)
+ $min_x = $time if (!defined($min_x) || $time < $min_x);
+ $max_x = $time if (!defined($max_x) || $time > $max_x);
+ $min_y = $if if (!defined($min_y) || $if < $min_y);
+ $min_y = $of if ($of < $min_y);
+ $max_y = $if if (!defined($max_y) || $if > $max_y);
+ $max_y = $of if ($of > $max_y);
+
+ my $pt = 0.5 * ($time + $prev_time);
+
+ push @x, $pt;
+ push @y1, $if;
+ push @y2, $of;
+
+ while ($idx < $#totx && $pt > $totx[$idx]) {
+ ++$idx;
+ }
+ if ($idx >= $#totx) {
+ push @totx, $pt;
+ push @toty1, $if;
+ push @toty2, $of;
+ ++$idx;
+
+ $min_ty = $if if (!defined($min_ty) || $if < $min_ty);
+ $min_ty = $of if ($of < $min_ty);
+ $max_ty = $if if (!defined($max_ty) || $if > $max_ty);
+ $max_ty = $of if ($of > $max_ty);
+ } else {
+ if (!defined($last_totx) || $last_totx != $idx) {
+ $toty1[$idx] += $if;
+ $toty2[$idx] += $of;
+ }
+ $last_totx = $idx;
+
+ $min_ty = $toty1[$idx] if (!defined($min_ty) || $toty1[$idx] < $min_ty);
+ $min_ty = $toty2[$idx] if ($toty2[$idx] < $min_ty);
+ $max_ty = $toty1[$idx] if (!defined($max_ty) || $toty1[$idx] > $max_ty);
+ $max_ty = $toty2[$idx] if ($toty2[$idx] > $max_ty);
+ }
+
+ ($prev_time,$prev_in,$prev_out) = ($time,$in,$out);
+}
+$dbh->disconnect;
+
+# last graph
+my $filename = filename($switch, $last_port, $width, $height);
+
+my $pid = fork();
+if ($pid == 0) {
+ my $graph = makegraph($width, $height, $min_x, $max_x, $min_y, $max_y, 5);
+ plotseries($graph, \@x, \@y1, 255, 0, 0, $min_x, $max_y);
+ plotseries($graph, \@x, \@y2, 0, 0, 255, $min_x, $max_y);
+
+ open GRAPH, ">$cwd/img/$filename"
+ or die "img/$filename: $!";
+ print GRAPH $graph->png;
+ close GRAPH;
+ exit;
+}
+
+push @pids, $pid;
+
+$resthtml .= "<div style=\"float: left;\"><h2>$portname</h2>\n";
+$resthtml .= "<p><img src=\"img/$filename\" width=\"$width\" height=\"$height\" /></p></div>\n";
+
+# total graph
+my $graph = makegraph($width, $height, $min_x, $max_x, $min_ty, $max_ty, 5);
+plotseries($graph, \@totx, \@toty1, 255, 0, 0, $min_x, $max_ty);
+plotseries($graph, \@totx, \@toty2, 0, 0, 255, $min_x, $max_ty);
+
+$filename = "$switch-$width-$height.png";
+open GRAPH, ">$cwd/img/$filename" or die "img/$filename: $!";
+print GRAPH $graph->png;
+close GRAPH;
+
+# Wait for all the other graphs to be done
+while (waitpid(-1, 0) != -1) {
+ 1;
+}
+
+print $resthtml;
+
+print "<div style=\"float: left;\"><h2>Total</h2>\n";
+print "<p><img src=\"img/$filename\" width=\"$width\" height=\"$height\" /></p></div>\n";
+
+my $elapsed = Time::HiRes::tv_interval($start);
+printf "<p style=\"clear: both;\">Page and all graphs generated in %.2f seconds.</p>\n", $elapsed;
+print "</body>\n</html>\n";
diff --git a/web/nms.gathering.org/old/slide.html b/web/nms.gathering.org/old/slide.html
new file mode 100644
index 0000000..046020d
--- /dev/null
+++ b/web/nms.gathering.org/old/slide.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <body>
+ <iframe id="tgview" style="border: 0; width: 1536px; height: 864px"></iframe>
+
+ <script>
+ (function() {
+ var urls = [
+ 'http://onlineclock.net/',
+ 'http://nms.tg13.gathering.org/dhcpkart.pl',
+ 'http://nms.tg13.gathering.org/nettkart-text.pl',
+ 'http://nms.tg13.gathering.org/nettkart-text.pl',
+ 'http://nms.tg13.gathering.org/uplinkkart.pl',
+ 'http://nms.tg13.gathering.org/uplinktrafikkart.pl',
+ 'http://nms.tg13.gathering.org/apkart.pl',
+ 'http://stats.tg13.gathering.org/'
+ ];
+
+ var view = document.getElementById('tgview');
+ var fload = function( frame, url ) {
+ frame.src = url;
+ };
+
+ var i = 0;
+ (function rotation() {
+ //if ( i != l-1 ) {
+ if ( i != urls.length-1 ) {
+ i++
+ } else {
+ i = 0;
+ }
+ fload( view, urls[i] );
+ setTimeout( arguments.callee, 10000 );
+ })();
+ })();
+ </script>
+ </body>
+</html>
diff --git a/web/nms.gathering.org/old/smanagement.pl b/web/nms.gathering.org/old/smanagement.pl
new file mode 100755
index 0000000..485e2b0
--- /dev/null
+++ b/web/nms.gathering.org/old/smanagement.pl
@@ -0,0 +1,246 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use 5.010;
+use CGI;
+use DBI;
+use Data::Dumper;
+use lib '../../include';
+use nms;
+
+# Grab from .htaccess-authentication
+my $user = $ENV{'REMOTE_USER'};
+
+my $dbh = nms::db_connect();
+$dbh->{AutoCommit} = 0;
+
+# Ugly casting, found no other way
+my $sinsert = $dbh->prepare( "INSERT INTO squeue
+ (gid, added, priority, addr, sysname, cmd, author)
+ VALUES(?::text::int, timeofday()::timestamptz, ?::text::int, ?::text::inet, ?, ?, ?)")
+ or die "Could not prepare sinsert";
+my $sgetip = $dbh->prepare("SELECT ip FROM switches WHERE sysname = ?")
+ or die "Could not prepare sgetip";
+my $sgid = $dbh->prepare("SELECT nextval('squeue_group_sequence') as gid");
+my $all_switches = $dbh->prepare("SELECT sysname FROM switches ORDER BY sysname");
+
+sub parse_range($) {
+ my $switches = $_;
+ my @range;
+
+ my @rangecomma = split(/\s*,\s*/, $switches);
+ foreach (@rangecomma) {
+ my ($first, $last) = $_ =~ /(e\d+\-(?:sw)?[123456])\s*\-\s*(e\d+\-(?:sw)?[123456])?/;
+ if (!defined($first) && $_ =~ /e\d+\-(sw)?[123456]/) {
+ $first = $_;
+ }
+ if (!defined($first)) {
+ print "<font color=\"red\">Parse error in: $_</font><br>\n";
+ next;
+ }
+ my ($rowstart, $placestart) = $first =~ /e(\d+)\-(?:sw)?([123456])/;
+ if (!defined($rowstart) || !defined($placestart)) {
+ print "<font color=\"red\">Parse error in: $_</font><br>\n";
+ next;
+ }
+ my ($rowend, $placeend);
+ if (!defined($last)) {
+ $rowend = $rowstart;
+ $placeend = $placestart;
+ }
+ else {
+ ($rowend, $placeend) = $last =~ /e(\d+)\-(?:sw)?([123456])/;
+ }
+ if (!defined($rowend) || !defined($placeend)) {
+ print "<font color=\"red\">Parse error in: $_</font><br>\n";
+ next;
+ }
+ #print "e $rowstart - $placestart to e $rowend - $placeend <br>\n";
+ for (my $i = $rowstart; $i <= $rowend; $i++) {
+ my $dostart;
+ if ($rowstart != $i) {
+ $dostart = 1;
+ }
+ else {
+ $dostart = $placestart;
+ }
+ for (my $j = $dostart; $j <= 6; $j++) {
+ last if ($i == $rowend && $j > $placeend);
+ push(@range, "e$i-$j");
+ }
+ }
+ }
+# foreach (@range) {
+# print ":: $_<br>\n";
+# }
+ return @range;
+}
+
+sub get_addr_from_switchnum($) {
+ my ($sysname) = @_;
+
+ $sgetip->execute($sysname);
+ if ($sgetip->rows() < 1) {
+ print "Could not get the ip for: ".$sysname;
+ return undef;
+ }
+ my $row = $sgetip->fetchrow_hashref();
+ return $row->{'ip'};
+}
+
+my $cgi = new CGI;
+
+print $cgi->header(-type=>'text/html; charset=utf-8');
+
+print << "EOF";
+<html>
+ <head>
+ <title>Switch managment</title>
+ </head>
+ <body>
+ <p>Du er logget inn som: $user</p>
+ <form method="POST" action="smanagement.pl">
+ <table>
+ <tr>
+ <td>Alle switchene</td>
+ <td><input type="radio" name="rangetype" value="all" /></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>Switch</td>
+ <td><input type="radio" checked name="rangetype" value="switch" /></td>
+ <td><input type="text" name="range" /></td>
+ <td>e1-2, e3-3 - e10-2</td>
+ </tr>
+ <tr>
+ <td>Regexp</td>
+ <td><input type="radio" name="rangetype" value="regexp" /></td>
+ <td><input type="text" name="regexp" /></td>
+ <td>Regulært uttrykk</td>
+ </tr>
+ <tr>
+ <td>Rad</td>
+ <td><input type="radio" name="rangetype" value="row" /></td>
+ <td><input type="text" name="range" /></td>
+ <td>1,3-5 (Disabled)</td>
+ </tr>
+ <tr>
+ <td><hr /></td>
+ <td><hr /></td>
+ <td><hr /></td>
+ <td><hr /></td>
+ </tr>
+ <tr>
+ <td>Prioritet</td>
+ <td></td>
+ <td>
+ <select name="priority">
+ <option value="1">1 (lavest)</option>
+ <option value="2">2</option>
+ <option selected value="3">3</option>
+ <option value="4">4</option>
+ <option value="5">5 (høyest)</option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td>Kommando(er):</td>
+ <td></td>
+ <td><textarea name="cmd" cols="80" rows="24"></textarea></td>
+ <td>
+ <ul>
+ <li>En kommando per linje.</li>
+ <li>Linjer som begynner med ! sørger for at nms ikke venter på normal prompt, men fyrer av gårde neste linje umiddelbart. Kjekt for kommandoer av typen "!save\\nY"</li>
+ <li>%SYSNAME% erstattes med hostnavnet til switchen</li>
+ <li>"#require-version 14.1X53-D15.2" avbryter scriptet om versjonen av JunOS ikke er lik 14.1X53-D15.2</li>
+ </ul>
+ </td>
+ </td>
+ <tr>
+ <td><hr /></td>
+ <td><hr /></td>
+ <td><hr /></td>
+ <td><hr /></td>
+ </tr>
+ </table>
+ <input type="submit" value="Execute!" /><br />
+ </form>
+EOF
+
+print "<br />\n";
+
+my @switches = ();
+given ($cgi->param('rangetype')) {
+ when ('all') {
+ print "Sender `".$cgi->param('cmd')."` til alle switchene<br />";
+ @switches = ();
+ $all_switches->execute();
+ while (my $ref = $all_switches->fetchrow_hashref) {
+ push @switches, $ref->{'sysname'};
+ }
+ }
+ when ('switch') {
+# print "Sender `".$cgi->param('cmd')."` til switchene `"
+# .$cgi->param('range')."`.<br />";
+ $_ = $cgi->param('range');
+ @switches = parse_range($_);
+ }
+ when ('regexp') {
+ @switches = ();
+ $all_switches->execute();
+ while (my $ref = $all_switches->fetchrow_hashref) {
+ push @switches, $ref->{'sysname'} if $ref->{'sysname'} =~ $cgi->param('regexp');
+ }
+ }
+ when ('row') {
+# print "Sender `".$cgi->param('cmd')."` til radene `"
+# .$cgi->param('range')."`.<br />";
+# print "This function does not work yet.";
+# $_ = $cgi->param('range');
+# @switches = &parse_row_range($_);
+# @switches = ();
+ print "<font color=\"red\">Slått av!</font>\n";
+ }
+};
+
+my $gid;
+if (@switches > 0) {
+ $sgid->execute();
+ my $row = $sgid->fetchrow_hashref();
+ $gid = $row->{gid};
+}
+
+my $pri = $cgi->param('priority');
+
+print "<pre>\n";
+foreach my $switch (@switches) {
+ my $addr = get_addr_from_switchnum($switch);
+ if (!defined($addr)) {
+ next;
+ }
+ my $cmd = $cgi->param('cmd');
+ print "$switch got addr $addr <br>\n";
+ print "Queuing commands for $switch:\n";
+ my $result = $sinsert->execute($gid, $pri, $addr, $switch, $cmd, $user);
+ if (!$result) {
+ print "\t<font color=\"red\">"
+ ."Could not execute query."
+ ."</font>\n";
+ print "\t".$dbh->errstr."\n";
+ }
+ else {
+ print "\tQueued: $cmd\n";
+ }
+ print "\n";
+}
+$dbh->commit;
+if (defined($gid)) {
+ print "<a href=\"sshow.pl?action=showgid&gid=".$gid."\">Vis resultat</a>\n";
+}
+print "</pre>\n";
+
+print << "EOF";
+ </body>
+</html>
+EOF
diff --git a/web/nms.gathering.org/old/sshow.pl b/web/nms.gathering.org/old/sshow.pl
new file mode 100755
index 0000000..64663a2
--- /dev/null
+++ b/web/nms.gathering.org/old/sshow.pl
@@ -0,0 +1,258 @@
+#!/usr/bin/perl
+use lib '../../include';
+use nms;
+
+use warnings;
+use strict;
+use Switch;
+use CGI;
+use DBI;
+use HTML::Entities;
+
+# Grab from .htaccess-authentication
+my $user = $ENV{'REMOTE_USER'};
+
+my $dbh = nms::db_connect();
+$dbh->{AutoCommit} = 0;
+
+my $sgetdone = $dbh->prepare(
+"SELECT *
+FROM squeue
+WHERE processed = 't'
+ORDER BY updated DESC, sysname
+LIMIT ?::text::int")
+ or die "Could not prepare sgetdone";
+
+my $sgetdonegid = $dbh->prepare(
+"SELECT *
+FROM squeue
+WHERE processed = 't' AND gid = ?::text::int
+ORDER BY updated DESC, sysname")
+ or die "Could not prepare sgetdonegid";
+
+my $slistdonegid = $dbh->prepare(
+"SELECT DISTINCT gid, cmd, author, added
+FROM squeue
+WHERE processed = 't'
+ORDER BY gid DESC
+LIMIT ?::text::int")
+ or die "Could not prepare slistdonegid";
+
+my $slistprocgid = $dbh->prepare(
+"SELECT DISTINCT gid, cmd, author, added
+FROM squeue
+WHERE processed = 'f'
+ORDER BY gid")
+ or die "Could not prepare slistprocgid";
+
+my $sgetgid = $dbh->prepare(
+"SELECT *
+FROM squeue
+WHERE gid = ?")
+ or die "Could not prepare sgetgid";
+
+my $sgetprocessing = $dbh->prepare(
+"SELECT *
+FROM squeue
+WHERE processed = 'f'
+ORDER BY updated DESC, gid, sysname")
+ or die "Could not prepare sgetprocessing";
+
+my $sgetnoconnect = $dbh->prepare(
+"SELECT *
+FROM squeue
+WHERE result = 'Could not connect to switch, delaying...'")
+ or die "Could not prepare sgetnoconnect";
+
+my $sdisablegid = $dbh->prepare("
+UPDATE squeue SET disabled = 't'
+WHERE gid = ?::text::int")
+ or die "Could not prepare sdisablegid";
+my $senablegid = $dbh->prepare("
+UPDATE squeue SET disabled = 'f'
+WHERE gid = ?::text::int")
+ or die "Could not prepare sdisablegid";
+
+
+my $cgi = new CGI;
+
+print $cgi->header(-type=>'text/html; charset=utf-8');
+
+print << "EOF";
+<html>
+ <head>
+ <title>Switch managment</title>
+ </head>
+ <body>
+ <p>Du er logget inn som: $user</p>
+ <form method="POST" action="sshow.pl">
+ <p>
+ Vis <input type="text" name="count" size="4" value="10" /> siste<br />
+ Vis: <select name="action" />
+ <option value="listgid">Grupper</option>
+ <option value="done">Ferdige</option>
+ <option value="processing">I kø</option>
+ </select>
+ <input type="submit" value="Vis" /><br />
+ </p>
+ </form>
+ <br />
+EOF
+
+my $limit = $cgi->param('count');
+if (!defined($limit)) {
+ $limit = 10;
+}
+my $action = $cgi->param('action');
+if (!defined($action)) {
+ $action = 'listgid';
+}
+
+if (defined($cgi->param('agid'))) {
+ my $gid = $cgi->param('gid');
+ if (!defined($gid)) {
+ print "<font color=\"red\">Du har ikke valgt en gid å slette.</font>\n";
+ print "<p>gid: ".$cgi->param('gid')." har blitt disablet.\n";
+ }
+ else {
+ $senablegid->execute($gid);
+ print "<p>gid: ".$cgi->param('gid')." har blitt enablet.\n";
+ }
+ $dbh->commit();
+}
+
+if ($action eq 'noconnect') {
+ print "<h3>Kunne ikke koble til disse switchene:</h3>\n";
+ $sgetnoconnect->execute();
+ print "<pre>\n";
+ while ((my $row = $sgetnoconnect->fetchrow_hashref())) {
+ print "$row->{'sysname'} : $row->{'cmd'} : Added: $row->{'added'} : Updated: $row->{'updated'}\n";
+ }
+ print "</pre>\n";
+}
+
+if ($action eq 'listgid') {
+ print "<pre>\n";
+ print "<a href=\"sshow.pl?action=noconnect\" />Kunne ikke koble til</a>\n\n\n";
+ print "<b>Ferdige:</b>\n";
+ $slistdonegid->execute($limit);
+ my ($gid, $author);
+ $gid = -1;
+ while ((my $row = $slistdonegid->fetchrow_hashref())) {
+ $author = $row->{author};
+ if ($gid != $row->{gid}) {
+ $gid = $row->{gid};
+ print "GID: <a href=\"sshow.pl?action=showgid&gid=$gid\">$gid</a>\n";
+ print "Author: $author\n";
+ print "Added: ".$row->{added}."\n";
+ }
+ my $cmd = $row->{cmd};
+ print "$cmd\n\n";
+ }
+ print "\n\n";
+ print "<b>I kø:</b>\n";
+ $slistprocgid->execute();
+ $gid = -1;
+ while ((my $row = $slistprocgid->fetchrow_hashref())) {
+ $author = $row->{author};
+ if ($gid != $row->{gid}) {
+ $gid = $row->{gid};
+ print "GID: <a href=\"sshow.pl?action=showgid&gid=$gid\">$gid</a>\n";
+ print "Author: $author\n";
+ print "Added: ".$row->{added}."\n";
+ }
+ my $cmd = $row->{cmd};
+ print "$cmd\n\n";
+ }
+ $dbh->commit();
+ print "</pre>\n";
+}
+
+if ($action eq 'showgid') {
+ print "<pre>\n";
+ $sgetgid->execute($cgi->param('gid'));
+ my $row = $sgetgid->fetchrow_hashref();
+ print "GID: ".$row->{gid}."\n";
+ print "Author: ".$row->{author}."\n";
+ do {
+ print " <b>Name: ".$row->{sysname}." Addr: ".$row->{addr}."</b>\n";
+ print " `<b>".$row->{cmd}."`</b>\n";
+ print " <i>Added: ".$row->{added}." executed ".$row->{updated}."</i>\n";
+ my $data = $row->{result};
+ if (!defined($data)) {
+ $data = "Not executed yet!";
+ }
+ my @lines = split(/[\n\r]+/, $data);
+ foreach my $line (@lines) {
+ print "\t", encode_entities($line), "\n";
+ }
+ } while (($row = $sgetgid->fetchrow_hashref()));
+ print "</pre>\n";
+}
+
+if ($action eq 'done') {
+ print "<h3>Done</h3>\n";
+ print "<pre>\n";
+
+ my $squery;
+ if (defined($cgi->param('gid'))) {
+ my $gid = $cgi->param('gid');
+ $sgetdonegid->execute($gid);
+ $squery = $sgetdonegid;
+ } else {
+ $sgetdone->execute($limit);
+ $squery = $sgetdone;
+ }
+ my $sysname = '';
+ while (my $row = $squery->fetchrow_hashref()) {
+ if ($sysname ne $row->{'sysname'}) {
+ $sysname = $row->{'sysname'};
+ print "$sysname (".$row->{addr}."):\n";
+ }
+ print " Author: ".$row->{author}."\n";
+ print " Cmd: ".$row->{cmd}."\n";
+ print " Added: ".$row->{added}." Updated: ".$row->{updated}."\n";
+ print " GID: ".$row->{gid}."\n";
+ my @result = split(/[\n\r]+/, $row->{result});
+ foreach (@result) {
+ print "\t", encode_entities($_), "\n";
+ }
+ print "\n";
+ }
+ $dbh->commit();
+ print "</pre>\n";
+}
+elsif ($action eq 'processing') {
+ print "<h3>Processing</h3>\n";
+ print "<pre>\n";
+ $sgetprocessing->execute();
+ while (my $row = $sgetprocessing->fetchrow_hashref()) {
+ my $sysname = $row->{'sysname'};
+ print "$sysname (".$row->{addr}."):\n";
+ print " Author: ".$row->{author}."\n";
+ print " Cmd: ".$row->{cmd}."\n";
+ my $updated;
+ if (defined($row->{updated})) { $updated = $row->{updated}; }
+ else { $updated = 'never'; }
+ print " Added: ".$row->{added}." Updated: ".$updated."\n";
+ print " Disabled: ".$row->{disabled}."\n";
+ print " Locked: ".$row->{locked}."\n";
+ print " gID: ".$row->{gid};
+ print " <form action=\"sshow.pl\" methos=\"POST\">";
+ print "<input type=\"hidden\" name=\"gid\" value=\"".$row->{gid}."\">";
+ print "<input type=\"hidden\" name=\"action\" value=\"processing\">";
+ if ($row->{disabled} == 0) {
+ print "<input type=\"submit\" name=\"agid\" value=\"Disable\">\n";
+ }
+ else {
+ print "<input type=\"submit\" name=\"agid\" value=\"Enable\">\n";
+ }
+ }
+ $dbh->commit();
+ print "</pre>\n";
+}
+
+print << "EOF";
+ </body>
+</html>
+EOF
diff --git a/web/nms.gathering.org/old/stempmap.pl b/web/nms.gathering.org/old/stempmap.pl
new file mode 100755
index 0000000..ccd44fd
--- /dev/null
+++ b/web/nms.gathering.org/old/stempmap.pl
@@ -0,0 +1,89 @@
+#!/usr/bin/perl
+#
+#
+use strict;
+use warnings;
+
+use CGI;
+use GD;
+use DBI;
+use File::Basename;
+use lib '../../include';
+use nms;
+
+GD::Image->trueColor(1);
+
+my $cwd = dirname($0);
+my $img = GD::Image->new($cwd.'/tg15-salkart.png');
+my $cgi = CGI->new;
+
+my $dbh = nms::db_connect();
+
+my $max_update_age = '\'8 min\'::interval';
+
+# Henter ut de som er oppdatert for mindre enn $max_update_age siden
+my $sgetpoll = $dbh->prepare('select switch,sysname,(select temp from switch_temp where switches.switch = switch_temp.switch AND temp != 0 order by time desc limit 1) AS temp,placement from switches natural join placements where now()-'.$max_update_age.' < last_updated');
+
+my $black = $img->colorAllocate(0,0,0);
+my $white = $img->colorAllocate(255,255,255);
+my $grey = $img->colorAllocate(192,192,192);
+my $green = $img->colorAllocate(0,255,0);
+my $blue = $img->colorAllocate(0,0,255);
+
+my $mintemp = 10.0;
+my $maxtemp = 55.0;
+my $steps = 100;
+
+for (my $i = 0; $i < $steps; $i++) {
+ my $diff = $maxtemp - $mintemp;
+ my $temp = $mintemp + ($maxtemp - $mintemp) * ((($diff / $steps) * $i)/$diff);
+ $img->line(5, $i, 45, $i, &getcolor($temp));
+}
+
+$img->stringFT($black, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 50, 10, "Freezing!");
+$img->stringFT($black, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 50, 22, "$mintemp C");
+$img->stringFT($black, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 50, $steps - 12, "$maxtemp C");
+$img->stringFT($black, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 50, $steps, "Too hot!");
+
+$sgetpoll->execute();
+while (my $ref = $sgetpoll->fetchrow_hashref()) {
+ next if (!defined($ref->{'temp'}));
+
+ my $sysname = $ref->{'sysname'};
+ $sysname =~ s/sw$//;
+
+ my $temp = $ref->{'temp'};
+ my $color = getcolor($temp);
+
+ $ref->{'placement'} =~ /\((\d+),(\d+)\),\((\d+),(\d+)\)/;
+ my ($x2, $y2, $x1, $y1) = ($1, $2, $3, $4);
+ $img->filledRectangle($x1,$y1,$x2,$y2,$color);
+ $img->rectangle($x1,$y1,$x2,$y2,$black);
+ my $max_textlen = ($x2-$x1) > ($y2-$y1) ? $x2-$x1 : $y2-$y1;
+ while (length($sysname) * 6 > $max_textlen) {
+ # Try to abbreviate sysname if it is too long for the box
+ $sysname =~ s/^(.*)[a-z]~?([0-9-]+)$/$1~$2/ or last;
+ }
+ if (($x2-$x1) > ($y2-$y1)) {
+ $img->string(gdSmallFont,$x1+2,$y1,$sysname,$white);
+ } else {
+ $img->stringUp(gdSmallFont,$x1,$y2-3,$sysname,$white);
+ }
+ $img->string(gdGiantFont, $x2-(length("$temp") * 9), $y1, "$temp", $white);
+}
+
+print $cgi->header(-type=>'image/png');
+print $img->png;
+
+sub getcolor {
+ my ($temp) = @_;
+
+ my $t = ($temp - $mintemp) / ($maxtemp - $mintemp);
+ $t = 0 if ($t < 0);
+ $t = 1 if ($t > 1);
+
+ my $colorred = 65025 * $t;
+ my $colorblue = 65025 - $colorred;
+
+ return $img->colorResolve(sqrt($colorred), 0, sqrt($colorblue) );
+}
diff --git a/web/nms.gathering.org/old/stromkart.pl b/web/nms.gathering.org/old/stromkart.pl
new file mode 100755
index 0000000..c0e4a3d
--- /dev/null
+++ b/web/nms.gathering.org/old/stromkart.pl
@@ -0,0 +1,72 @@
+#! /usr/bin/perl
+use CGI qw(fatalsToBrowser);
+use GD;
+use DBI;
+use lib '../../include';
+use nms;
+use strict;
+use warnings;
+use File::Basename;
+my $cgi = CGI->new;
+my $cwd = dirname($0);
+
+#my $greentimeout = 7200;
+my $greentimeout = 15*60;
+my $maxtimeout = $greentimeout*9;
+
+my $dbh = nms::db_connect();
+
+GD::Image->trueColor(1);
+my $img = GD::Image->new($cwd.'/tg15-salkart.png');
+
+my $blk = $img->colorResolve(0, 0, 0);
+
+$img->string(gdMediumBoldFont,0,0,"Switch uplink status",$blk);
+$img->string(gdSmallFont,0,20,"Number of ports with activity",$blk);
+
+my $red = $img->colorResolve(255, 0, 0);
+my $yel = $img->colorResolve(255, 255, 0);
+my $grn = $img->colorResolve(0, 255, 0);
+my $wht = $img->colorResolve(255, 255, 255);
+my $gry = $img->colorResolve(127, 127, 127);
+
+#my $q = $dbh->prepare('select switch,sysname,(select placement from placements where placements.switch=switches.switch) as placement,count((bytes_in > 0 and bytes_out > 0) or null) as active_ports,(max(last_poll_time) >= current_timestamp - interval \'2 minutes\') as fresh from switches natural left join get_current_datarate() natural join placements where switchtype like \'dlink3100%\' group by switch,sysname');
+my $q = $dbh->prepare(' select switch,sysname,(select placement from placements where placements.switch = switches.switch) as placement,count((ifoperstatus = 1) or null) as active_ports from switches natural left join get_operstatus() natural join placements where ifdescr like \'ge-0/0/%\' group by switch,sysname');
+$q->execute();
+while (my $ref = $q->fetchrow_hashref()) {
+ my $ports = $ref->{'active_ports'};
+ my $sysname = $ref->{'sysname'};
+ my $clr;
+ if ($ports < 5) {
+ $clr = $red;
+ } else {
+ if (!$ref->{'fresh'}) {
+ $clr = $yel;
+ } else {
+ $clr = $grn;
+ }
+ }
+
+ $ref->{'placement'} =~ /\((\d+),(\d+)\),\((\d+),(\d+)\)/;
+ $img->filledRectangle($3,$4,$1,$2,$clr);
+ $img->rectangle($3,$4,$1,$2,$blk);
+
+ my ($x2, $y2, $x1, $y1) = ($1, $2, $3, $4);
+ my $max_textlen = ($x2-$x1) > ($y2-$y1) ? $x2-$x1 : $y2-$y1;
+ while (length($sysname) * 6 > $max_textlen) {
+ # Try to abbreviate sysname if it is too long for the box
+ $sysname =~ s/^(.*)[a-z]~?([0-9]+)$/$1~$2/ or last;
+ }
+ if (($x2-$x1) > ($y2-$y1)) {
+ $img->string(gdSmallFont,$x1+2,$y1,$sysname,$blk);
+ } else {
+ $img->stringUp(gdSmallFont,$x1,$y2-3,$sysname,$blk);
+ }
+}
+$dbh->disconnect;
+
+if (!defined($ARGV[0])) {
+ print $cgi->header(-type=>'image/png',
+ -refresh=>'10; ' . CGI::url());
+}
+print $img->png;
diff --git a/web/nms.gathering.org/old/switches-json.pl b/web/nms.gathering.org/old/switches-json.pl
new file mode 100755
index 0000000..74f4e5f
--- /dev/null
+++ b/web/nms.gathering.org/old/switches-json.pl
@@ -0,0 +1,43 @@
+#! /usr/bin/perl
+use CGI;
+use GD;
+use DBI;
+use JSON::XS;
+use lib '../../include';
+use nms;
+my $cgi = CGI->new;
+
+my $dbh = nms::db_connect();
+my %json = ();
+
+my $q = $dbh->prepare('select switch,sysname,placement,zorder from switches natural join placements WHERE sysname != \'e3-2\''); # FULHACK to remove e3-2 from the maps
+# my $q = $dbh->prepare('select switch,sysname,placement,zorder from switches natural join placements'); # FULHACK to remove e3-2 from the maps
+my $q2 = $dbh->prepare('select distinct on (switch) switch,temp,time,sysname from switch_temp natural join switches order by switch,time desc');
+$q->execute();
+while (my $ref = $q->fetchrow_hashref()) {
+ $ref->{'placement'} =~ /\((-?\d+),(-?\d+)\),\((-?\d+),(-?\d+)\)/;
+ my ($x1, $y1, $x2, $y2) = ($1, $2, $3, $4);
+ my $sysname = $ref->{'sysname'};
+ $json{'switches'}{$ref->{'switch'}} = {
+ sysname => $sysname,
+ x => $x2,
+ y => $y2,
+ width => $x1 - $x2,
+ height => $y1 - $y2,
+ zorder => $ref->{'zorder'}
+ };
+}
+
+$q2->execute();
+while (my $ref = $q2->fetchrow_hashref()) {
+ $json{'switches'}{$ref->{'switch'}}{'temp'} = $ref->{'temp'};
+ $json{'switches'}{$ref->{'switch'}}{'time'} = $ref->{'time'};
+}
+my $q = $dbh->prepare('select linknet,switch1,switch2 from linknets');
+$q->execute();
+while (my $ref = $q->fetchrow_hashref()) {
+ push @{$json{'linknets'}}, $ref;
+}
+
+print $cgi->header(-type=>'text/json; charset=utf-8');
+print JSON::XS::encode_json(\%json);
diff --git a/web/nms.gathering.org/old/uplinkkart-text.pl b/web/nms.gathering.org/old/uplinkkart-text.pl
new file mode 100755
index 0000000..c4b31a9
--- /dev/null
+++ b/web/nms.gathering.org/old/uplinkkart-text.pl
@@ -0,0 +1,38 @@
+#! /usr/bin/perl
+use CGI;
+use DBI;
+use lib '../../include';
+use nms;
+my $cgi = CGI->new;
+
+my $dbh = nms::db_connect();
+print $cgi->header(-type=>'text/html; charset=utf-8', -refresh=>'10; ' . CGI::url());
+
+print <<"EOF";
+<html>
+ <head>
+ <title>Uplinkkart</title>
+ </head>
+ <body>
+ <map name="switches">
+EOF
+
+my $q = $dbh->prepare("SELECT * FROM switches NATURAL JOIN placements WHERE switchtype = 'ex2200'");
+$q->execute();
+while (my $ref = $q->fetchrow_hashref()) {
+ $ref->{'placement'} =~ /\((\d+),(\d+)\),\((\d+),(\d+)\)/;
+
+ my $ttext = 'FIXME: Put something here';
+ printf " <area shape=\"rect\" coords=\"%u,%u,%u,%u\" href=\"switchdiag.pl?id=%u\" alt=\"%s (%s)\" onmouseover=\"window.status='%s (%s)'; return true\" onmouseout=\"window.status=''\" />\n",
+ $3, $4, $1, $2, $ref->{'switch'}, $ref->{'sysname'},
+ $ttext, $ref->{'sysname'}, $ttext;
+}
+$dbh->disconnect;
+
+print <<"EOF";
+ </map>
+
+ <p><img src="uplinkkart.pl" usemap="#switches" /></p>
+ </body>
+</html>
+EOF
diff --git a/web/nms.gathering.org/old/uplinkkart.pl b/web/nms.gathering.org/old/uplinkkart.pl
new file mode 100755
index 0000000..052fe9c
--- /dev/null
+++ b/web/nms.gathering.org/old/uplinkkart.pl
@@ -0,0 +1,72 @@
+#! /usr/bin/perl
+use CGI qw(fatalsToBrowser);
+use GD;
+use DBI;
+use lib '../../include';
+use nms;
+use strict;
+use warnings;
+use File::Basename;
+my $cgi = CGI->new;
+my $cwd = dirname($0);
+
+#my $greentimeout = 7200;
+my $greentimeout = 15*60;
+my $maxtimeout = $greentimeout*9;
+
+my $dbh = nms::db_connect();
+
+GD::Image->trueColor(1);
+my $img = GD::Image->new($cwd.'/tg15-salkart.png');
+
+my $blk = $img->colorResolve(0, 0, 0);
+
+$img->string(gdMediumBoldFont,0,0,"Switch uplink status",$blk);
+$img->string(gdSmallFont,0,20,"Number of ports with activity",$blk);
+
+my $red = $img->colorResolve(255, 0, 0);
+my $yel = $img->colorResolve(255, 255, 0);
+my $grn = $img->colorResolve(0, 255, 0);
+my $blu = $img->colorResolve(0, 0, 255);
+my $wht = $img->colorResolve(255, 255, 255);
+my $gry = $img->colorResolve(127, 127, 127);
+
+my @palette = ( $blu, $red, $yel, $grn, $wht );
+
+for my $ports (0..4) {
+ my $y = 60 + 20 * (4 - $ports);
+ $img->filledRectangle(20, $y, 30, $y + 10, $palette[$ports]);
+ $img->rectangle(20, $y, 30, $y + 10, $blk);
+ $img->stringFT($blk, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 40, $y + 10, $ports);
+}
+
+my $q = $dbh->prepare('select switch,sysname,(select placement from placements where placements.switch=switches.switch) as placement,count((ifhcinoctets > 0 and ifhcoutoctets > 0) or null) as active_ports from switches natural left join get_current_datarate() where (ifname = \'ge-0/0/44\' or ifname = \'ge-0/0/45\' or ifname = \'ge-0/0/46\' or ifname = \'ge-0/0/47\') and switchtype like \'%2200%\' group by switch,sysname');
+$q->execute();
+while (my $ref = $q->fetchrow_hashref()) {
+ my $ports = $ref->{'active_ports'};
+ my $sysname = $ref->{'sysname'};
+ my $clr = $palette[$ports];
+
+ $ref->{'placement'} =~ /\((\d+),(\d+)\),\((\d+),(\d+)\)/;
+ $img->filledRectangle($3,$4,$1,$2,$clr);
+ $img->rectangle($3,$4,$1,$2,$blk);
+
+ my ($x2, $y2, $x1, $y1) = ($1, $2, $3, $4);
+ my $max_textlen = ($x2-$x1) > ($y2-$y1) ? $x2-$x1 : $y2-$y1;
+ while (length($sysname) * 6 > $max_textlen) {
+ # Try to abbreviate sysname if it is too long for the box
+ $sysname =~ s/^(.*)[a-z]~?([0-9]+)$/$1~$2/ or last;
+ }
+ if (($x2-$x1) > ($y2-$y1)) {
+ $img->string(gdSmallFont,$x1+2,$y1,$sysname,$blk);
+ } else {
+ $img->stringUp(gdSmallFont,$x1,$y2-3,$sysname,$blk);
+ }
+}
+$dbh->disconnect;
+
+if (!defined($ARGV[0])) {
+ print $cgi->header(-type=>'image/png',
+ -refresh=>'10; ' . CGI::url());
+}
+print $img->png;
diff --git a/web/nms.gathering.org/old/uplinktrafikkart.pl b/web/nms.gathering.org/old/uplinktrafikkart.pl
new file mode 100755
index 0000000..97000cf
--- /dev/null
+++ b/web/nms.gathering.org/old/uplinktrafikkart.pl
@@ -0,0 +1,92 @@
+#! /usr/bin/perl
+use CGI qw(fatalsToBrowser);
+use GD;
+use DBI;
+use lib '../../include';
+use nms;
+use strict;
+use warnings;
+use File::Basename;
+my $cgi = CGI->new;
+my $cwd = dirname($0);
+
+#my $greentimeout = 7200;
+my $greentimeout = 15*60;
+my $maxtimeout = $greentimeout*9;
+
+my $dbh = nms::db_connect();
+
+GD::Image->trueColor(1);
+my $img = GD::Image->new($cwd.'/tg15-salkart.png');
+
+my $blk = $img->colorResolve(0, 0, 0);
+
+for my $y (42..236) {
+ my $i = 2.0 * ($y - 236.0) / (42.0 - 237.0);
+ my $clr = get_color($i);
+
+ $img->filledRectangle(12, $y, 33, $y+1, $clr);
+}
+
+$img->string(gdMediumBoldFont,0,0,"Switch uplink traffic",$blk);
+$img->string(gdSmallFont,0,20,"max of bytes in/out",$blk);
+
+my $red = $img->colorResolve(255, 0, 0);
+my $yel = $img->colorResolve(255, 255, 0);
+my $grn = $img->colorResolve(0, 255, 0);
+my $wht = $img->colorResolve(255, 255, 255);
+
+$img->rectangle(12,42,33,236,$blk);
+
+$img->stringFT($blk, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 40, 47 + (236-42)*0.0/2.0, "4 Gbit/sec");
+$img->stringFT($blk, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 40, 47 + (236-42)*1.0/2.0, "2 Gbit/sec");
+$img->stringFT($blk, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 40, 47 + (236-42)*2.0/2.0, "1 Gbit/sec");
+$img->stringFT($blk, "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf", 10, 0, 1600, 1000, "NMS (C) 2005-2012 Tech:Server");
+
+my $q = $dbh->prepare('select switch,sysname,(select placement from placements where placements.switch=switches.switch) as placement,greatest(sum(bytes_in),sum(bytes_out)) as traffic from switches natural left join get_current_datarate() natural join placements where port between 45 and 48 and switchtype like \'dlink3100%\' group by switch,sysname');
+$q->execute();
+while (my $ref = $q->fetchrow_hashref()) {
+ my $traffic = $ref->{'traffic'} * 8.0; # convert to bits
+ my $sysname = $ref->{'sysname'};
+
+ my $max = 4_000_000_000.0; # 2Gbit
+ my $min = 1_000_000_000.0; # 1Gbit
+ $traffic = $max if ($traffic > $max);
+ $traffic = $min if ($traffic < $min);
+ my $intensity = log($traffic / $min) / log(2);
+ my $clr = get_color($intensity);
+
+ $ref->{'placement'} =~ /\((\d+),(\d+)\),\((\d+),(\d+)\)/;
+ $img->filledRectangle($3,$4,$1,$2,$clr);
+ $img->rectangle($3,$4,$1,$2,$blk);
+
+ my ($x2, $y2, $x1, $y1) = ($1, $2, $3, $4);
+ my $max_textlen = ($x2-$x1) > ($y2-$y1) ? $x2-$x1 : $y2-$y1;
+ while (length($sysname) * 6 > $max_textlen) {
+ # Try to abbreviate sysname if it is too long for the box
+ $sysname =~ s/^(.*)[a-z]~?([0-9]+)$/$1~$2/ or last;
+ }
+ if (($x2-$x1) > ($y2-$y1)) {
+ $img->string(gdSmallFont,$x1+2,$y1,$sysname,$blk);
+ } else {
+ $img->stringUp(gdSmallFont,$x1,$y2-3,$sysname,$blk);
+ }
+}
+$dbh->disconnect;
+
+if (!defined($ARGV[0])) {
+ print $cgi->header(-type=>'image/png',
+ -refresh=>'10; ' . CGI::url());
+}
+print $img->png;
+
+sub get_color {
+ my $intensity = shift;
+ my $gamma = 1.0/1.90;
+ if ($intensity > 1.0) {
+ $intensity -= 1.0;
+ return $img->colorResolve(255.0, 255.0 * ($intensity ** $gamma), 255.0 * ($intensity ** $gamma));
+ } else {
+ return $img->colorResolve(255.0 * ($intensity ** $gamma), 255.0 * (1.0 - ($intensity ** $gamma)), 0);
+ }
+}