diff options
Diffstat (limited to 'web/nms.gathering.org/old')
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 & 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); + } +} |