From: Eirik Nygaard Date: Wed, 4 Apr 2007 10:25:19 +0000 (+0200) Subject: Merge with space:/root/nms X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=c82739fc0e65b8eb06787c97795c0101eebca313;hp=01dcc835d2c31911173bcf2e44d7c7f200baee71;p=nms Merge with space:/root/nms --- diff --git a/clients/ciscong.pl b/clients/ciscong.pl index 89ad6d5..76ec475 100644 --- a/clients/ciscong.pl +++ b/clients/ciscong.pl @@ -12,12 +12,14 @@ use Net::Ping; use Data::Dumper; -#my $patchlist = "/root/patchlist.txt"; -#my $switches = "/root/switches.txt"; +my $patchlist = "/root/patchlist.txt"; +my $switches = "/root/switches.txt"; #my $patchlist = "/home/eirikn/patchlist.txt.eirik"; #my $switches = "/home/eirikn/switches.txt.eirik"; -my $patchlist = "/root/patchlist.txt.d01-1-2"; -my $switches = "/root/switches.txt.d01-1-2"; +#my $patchlist = "/root/patchlist.txt.d05"; +#my $switches = "/root/switches.txt.d05"; + +open LOG, ">>/tmp/zyxel.could.not.connect" or die "Could not open log"; BEGIN { @@ -69,7 +71,12 @@ sub do_distro { my $ios = Net::Telnet::Cisco->new(Host => $dip, Errmode => 'return', - Prompt => '/[^\s\(]+(\([^\(]\)){0,1}[#>]/'); + Prompt => '/\S+[#>]/'); +# Prompt => '/[^\s\(]+(\([^\(]\)){0,1}[#>]/'); + if (!defined($ios)) { + print "Could not connect to $dip"; + return; + } $ios->login($nms::config::ios_user, $nms::config::ios_pass); $ios->enable; @@ -100,8 +107,9 @@ sub do_distro { printf "Waiting for zyxel to come up...\n"; my $counter = 0; while (1) { - if ($counter > 180) { - print "Waiting for zyxel on $dip:$vlan timed out, wanted to set ip: $newip"; + if ($counter > 6) { + print "Waiting for zyxel on $dip:$vlan timed out, wanted to set ip: $newip\n"; + print LOG "Could not connect to $switchname\n"; stop_vlan($ios, $vlan); return; } @@ -158,6 +166,9 @@ sub first_run { open(PATCHLIST, $patchlist) or die "Unable to open patchlist"; while () { my ($switch, $distro, $port) = split; + + #print "Testing: ".$ARGV[1]." $switch\n"; + next if (defined($ARGV[1]) and $ARGV[1] ne $switch); print "First run...\n"; my ($row, $place, $ipnet, $vlan, $ip, $dip) = switch_info($switch, $distro, $port); @@ -191,9 +202,15 @@ sub verify_run { printf "Checking if zyxel is up $dip:$vlan $ip...\n"; my $counter = 0; while (1) { - if ($counter > 10) { + if ($counter > 4) { print "No answer from $dip:$vlan $ip, trying to route it up\n"; do_distro($dip, $ip, $vlan, $switch); + my $pid = fork(); + if ($pid == 0) { + sleep 100; + system("perl ./ciscong2.pl $switch"); + exit 0; + } last; } last if $p->ping($ip); @@ -215,5 +232,6 @@ else { verify_run(); } +close(LOG); diff --git a/clients/ciscong2.pl b/clients/ciscong2.pl new file mode 100644 index 0000000..b8c33b2 --- /dev/null +++ b/clients/ciscong2.pl @@ -0,0 +1,146 @@ +#!/usr/bin/perl +# +# + +use warnings; +use strict; + +use lib '../include'; + +use Net::Telnet::Cisco; +use Net::Ping; + +use Data::Dumper; + +my $patchlist = "/root/patchlist.txt"; +my $switches = "/root/switches.txt"; +#my $patchlist = "/home/eirikn/patchlist.txt.eirik"; +#my $switches = "/home/eirikn/switches.txt.eirik"; +#my $patchlist = "/root/patchlist.txt.d05"; +#my $switches = "/root/switches.txt.d05"; + +open LOG, ">>/tmp/zyxel.could.not.connect2" or die "Could not open log"; + + +BEGIN { + require "../include/config.pm"; + eval { + require "../include/config.local.pm"; + }; +} + +sub ios_getroute { + my ($t, $net) = @_; + + $t->cmd("show ip route".($net ? " $net" : '')) or return 0;; + + return 1; +} + +#my $ios_server = "noc-gw.net.tg07.gathering.org"; +#my $vlannumber = 16; + +#my $ios = nms::ios_connect($ios_server, $nms::config::ios_user, $nms::config::ios_pass) +# or die "Unable to connect to cisco"; + + +sub do_distro { + my ($dip, $newip, $net, $switchname) = @_; + + my $ios = Net::Telnet::Cisco->new(Host => $dip, + Errmode => 'return', + Prompt => '/(\S+[#>])|(es-3024>)/'); +# Prompt => '/[^\s\(]+(\([^\(]\)){0,1}[#>]/'); + if (!defined($ios)) { + print "Could not connect to $dip"; + return; + } + $ios->login($nms::config::ios_user, $nms::config::ios_pass); + $ios->enable; + +#nms::ios_enable($ios); +#$ios->cmd(); +#nms::ios_getroute($ios, "192.168.1.0"); +#$ios->cmd(""); + +#nms::ios_close($ios); + +# Disable paging + $ios->cmd("terminal length 0"); + +#my @routes = $ios->cmd("show ip route"); + + + $ios->print("telnet $newip"); + $ios->waitfor("/Password:/"); + print "Hei\n"; + $ios->cmd($nms::config::zyxel_password); + + my ($first, $second, $third, $fourth) = split(/\./, $net); + my $gw = "$first.$second.$third.".(int($fourth)+1); + $ios->cmd("ip route drop 192.168.1.0/24"); + $ios->cmd("ip route add default $gw"); + $ios->cmd("exit"); + + #system("perl ./zyxelng.pl 192.168.1.1 $newip $switchname"); + +#### + + $ios->close(); + +} + +## Collect switch ips + +my %switchips; + +open(SWITCHES, $switches) or die "Unable to open switches"; +while() { + my ($ip, $net, $name) = split; + + if ($name =~ /e\d+-\d/) { + die "We only support /26 nets for now you wanted $net" if ($net ne "26"); + $switchips{$name} = $ip; + } +} +close(SWITCHES); + +sub switch_info { + my ($switch, $distro, $port) = @_; + + $switch =~ /e(\d+)-(\d)/; + my ($row, $place) = ($1, $2); + my $ipnet = $switchips{$switch}; + my $vlan = $row . $place; + my ($first, $second, $third, $fourth) = split(/\./, $ipnet); + my $ip = "$first.$second.$third.".(int($fourth)+2); + my $dip = $distro.".net.tg07.gathering.org"; + + return ($row, $place, $ipnet, $vlan, $ip, $dip); +} + +sub first_run { + + open(PATCHLIST, $patchlist) or die "Unable to open patchlist"; + while () { + my ($switch, $distro, $port) = split; + + next if (defined($ARGV[0]) and $ARGV[0] ne $switch); + + print "First run...\n"; + my ($row, $place, $ipnet, $vlan, $ip, $dip) = switch_info($switch, $distro, $port); + print "Switch: $switch, Distro: $distro, vlan: $vlan\n"; + print "Ip net: $ipnet\n"; + print "Ip: $ip\n"; + + do_distro($dip, $ip, $ipnet, $switch); +# my ($dip, $newip, $vlan) = @_; + } + close(PATCHLIST); +} + +first_run(); + +close(LOG); + + diff --git a/clients/dhcptail.pl b/clients/dhcptail.pl index a1e1c62..6a529de 100755 --- a/clients/dhcptail.pl +++ b/clients/dhcptail.pl @@ -7,7 +7,7 @@ use strict; use warnings; # WARNING: CHANGE THIS! :-P -my $year = 2006; +my $year = 2007; my %months = ( Jan => 1, @@ -31,7 +31,7 @@ while (<>) { if (!defined($dbh) || !$dbh->ping) { $dbh = nms::db_connect(); - $q = $dbh->prepare("UPDATE dhcp SET last_ack=? WHERE inet ? << network AND ( last_ack < ? OR last_ack IS NULL )") + $q = $dbh->prepare("UPDATE dhcp SET last_ack=? WHERE ?::inet << network AND ( last_ack < ? OR last_ack IS NULL )") or die "Couldn't prepare query"; } diff --git a/clients/snmpfetch.pl b/clients/snmpfetch.pl index bc64b60..74f3aa5 100755 --- a/clients/snmpfetch.pl +++ b/clients/snmpfetch.pl @@ -144,7 +144,7 @@ while (1) { print $avgtemp." avgtemp\n"; $qtemppoll->execute($switch->{'switch'}, $avgtemp) or die "Could not exec qtemppoll"; - } elsif ($switch->{'switchtype'} eq 'cisco6509') { + } elsif ($switch->{'switchtype'} eq 'cisco6509' && 0) { # fetch load data for the entities for my $i (1..5) { # find the ID @@ -269,41 +269,41 @@ sub mylog { printf STDERR "[%s] %s\n", $time, $msg; } -sub switch_exec { - my ($cmd, $conn) = @_; - - # Send the command and get data from switch -# $conn->dump_log(*STDOUT); - my @data = $conn->cmd($cmd); - my @lines = (); - foreach my $line (@data) { - # Remove escape-7 sequence - $line =~ s/\x1b\x37//g; - push @lines, $line; - } - - return @lines; -} - -sub switch_connect { - my ($ip) = @_; - - my $conn = new Net::Telnet( Timeout => $timeout, - Dump_Log => '/tmp/dumplog-tempfetch', - Errmode => 'return', - Prompt => '/es-3024|e(\-)?\d+\-\dsw>/i'); - my $ret = $conn->open( Host => $ip); - if (!$ret || $ret != 1) { - return (0); - } - # XXX: Just send the password as text, I did not figure out how to - # handle authentication with only password through $conn->login(). - #$conn->login( Prompt => '/password[: ]*$/i', - # Name => $password, - # Password => $password); - my @data = $conn->cmd($password); - # Get rid of banner - $conn->get; - return $conn; -} +#sub switch_exec { +# my ($cmd, $conn) = @_; +# +# # Send the command and get data from switch +## $conn->dump_log(*STDOUT); +# my @data = $conn->cmd($cmd); +# my @lines = (); +# foreach my $line (@data) { +# # Remove escape-7 sequence +# $line =~ s/\x1b\x37//g; +# push @lines, $line; +# } +# +# return @lines; +#} + +#sub switch_connect { +# my ($ip) = @_; +# +# my $conn = new Net::Telnet( Timeout => $timeout, +# Dump_Log => '/tmp/dumplog-tempfetch', +# Errmode => 'return', +# Prompt => '/es-3024|e(\-)?\d+\-\dsw>/i'); +# my $ret = $conn->open( Host => $ip); +# if (!$ret || $ret != 1) { +# return (0); +# } +# # XXX: Just send the password as text, I did not figure out how to +# # handle authentication with only password through $conn->login(). +# #$conn->login( Prompt => '/password[: ]*$/i', +# # Name => $password, +# # Password => $password); +# my @data = $conn->cmd($password); +# # Get rid of banner +# $conn->get; +# return $conn; +#} diff --git a/config/make-port-config.pl b/config/make-port-config.pl index ee75cab..893d4f4 100755 --- a/config/make-port-config.pl +++ b/config/make-port-config.pl @@ -26,6 +26,7 @@ while () { } my $vlan = "$row$switch"; + my $ipv6 = sprintf "F%02u%u", $row, $switch; $distros{$distro} .= <<"EOF"; vlan $vlan @@ -39,7 +40,9 @@ interface vlan $vlan ip helper-address 87.76.254.2 no ip proxy-arp ip access-group great-wall-of-tg in - ipv6 address 2001:16D8:FFFF:$vlan::1/64 + ipv6 address 2001:16D8:FFFF:${ipv6}::1/64 + ip igmp version 3 + ip pim sparse-mode no shutdown ! @@ -52,7 +55,6 @@ interface $port spanning-tree portfast spanning-tree bpduguard enable - ip igmp snooping storm-control broadcast level 2 no shutdown ! diff --git a/mbd/mbd.pl b/mbd/mbd.pl index cbb1237..7fcc8d8 100644 --- a/mbd/mbd.pl +++ b/mbd/mbd.pl @@ -16,6 +16,8 @@ sub fhbits { return $bits; } +open LOG, ">>", "mbd.log"; + my @ports = mbd::find_all_ports(); # Open a socket for each port @@ -62,6 +64,8 @@ while (1) { last; } + print LOG "$dport $size $pass\n"; + if (!$pass) { print "$dport, $size bytes => filtered\n"; } diff --git a/web/bg07.png b/web/bg07.png index c5c3960..6c367a6 100644 Binary files a/web/bg07.png and b/web/bg07.png differ diff --git a/web/dhcpkart.pl b/web/dhcpkart.pl index 0cc0e67..e14e0c5 100755 --- a/web/dhcpkart.pl +++ b/web/dhcpkart.pl @@ -12,11 +12,11 @@ my $maxtimeout = $greentimeout*9; my $dbh = nms::db_connect(); GD::Image->trueColor(1); -$img = GD::Image->new('bg2.png'); +$img = GD::Image->new('bg07.png'); my $blk = $img->colorResolve(0, 0, 0); -$img->string(gdMediumBoldFont,0,0,"TG05 - DHCP-lease status",$blk); +$img->string(gdMediumBoldFont,0,0,"TG07 - DHCP-lease status",$blk); $img->string(gdSmallFont,0,20,"Last recieved DHCP-request",$blk); # first 1/5: green (<30 min) @@ -70,7 +70,7 @@ $dbh->disconnect; if (!defined($ARGV[0])) { print $cgi->header(-type=>'image/png', - -refresh=>'10; http://nms.tg05.gathering.org/dhcpkart.pl'); + -refresh=>'10; http://nms.tg07.gathering.org/dhcpkart.pl'); } print $img->png; diff --git a/web/ext/comparegraph.cpp b/web/ext/comparegraph.cpp new file mode 100644 index 0000000..5beb37d --- /dev/null +++ b/web/ext/comparegraph.cpp @@ -0,0 +1,172 @@ +#include +#include +#include +#include +#include +#include +#include +#include "graph.h" +#include "flowpusher.h" +#include "flowutil.h" + +namespace pqxx { + template<> + void from_string(const char *from, long long &to) + { + to = atoll(from); + } +} + + +int main(int argc, char **argv) +{ + int width = 1000, height = 500; + pqxx::connection conn05("dbname=nms05 host=localhost user=nms password=seesahS4"); + pqxx::connection conn("dbname=nms host=localhost user=nms password=seesahS4"); + + std::vector flow, total_flow, total_flow05; + FlowPusher fp(flow); + int last_port = -1; + + mallopt(M_TRIM_THRESHOLD, -1); + + int num_total = 0; + pqxx::work t(conn, "fetch_all"); + pqxx::icursorstream::icursorstream cstream(t, "select port,extract(epoch from time) as time,bytes_in,bytes_out from polls natural join switches where ((switchtype='es3024' and port < 25) or (switchtype='summit400' and port > 1)) order by switch,port,time", "fetch_all", 500); + + for ( ;; ) { + pqxx::result res; + + cstream >> res; + if (res.empty()) + break; + + for (unsigned i = 0; i < res.size(); ++i) { + int port = res[i][0].as(); + double x = res[i][1].as(); + unsigned long long y1 = res[i][2].as(), y2 = res[i][3].as(); + + if (port != last_port) { + if (last_port != -1) { + total_flow = sum_flows(total_flow, flow); + fprintf(stderr, "%u (%u)\n", last_port, ++num_total); + } + + // reset + last_port = port; + fp.reset(x, y1, y2); + continue; + } + + fp.push(x, y1, y2); + } + } + total_flow = sum_flows(total_flow, flow); + + unsigned long long min_y = 0; + unsigned long long max_y = 10000000; + + for (unsigned i = 0; i < total_flow.size(); ++i) { + flow_element fe = total_flow[i]; + + min_y = std::min(min_y, fe.y1); + max_y = std::max(max_y, fe.y1); + + min_y = std::min(min_y, fe.y2); + max_y = std::max(max_y, fe.y2); + } + + printf("06 done.\n"); + + num_total = 0; + pqxx::work t05(conn05, "fetch_all"); + pqxx::icursorstream::icursorstream cstream05(t05, "select port,extract(epoch from (time + interval '1 year 20 days')) as time,bytes_in,bytes_out from polls natural join switches where (switchtype='es3024' and port < 25) order by switch,port,time", "fetch_all", 500); + + last_port = -1; + + for ( ;; ) { + pqxx::result res; + + cstream05 >> res; + if (res.empty()) + break; + + for (unsigned i = 0; i < res.size(); ++i) { + int port = res[i][0].as(); + double x = res[i][1].as(); + unsigned long long y1 = res[i][2].as(), y2 = res[i][3].as(); + + if (port != last_port) { + if (last_port != -1) { + total_flow05 = sum_flows(total_flow05, filter_flow(flow)); + fprintf(stderr, "TG05: %u (%u)\n", last_port, ++num_total); + } + + // reset + last_port = port; + fp.reset(x, y1, y2); + continue; + } + + fp.push(x, y1, y2); + } + } + total_flow05 = sum_flows(total_flow05, filter_flow(flow)); + + for (unsigned i = 0; i < total_flow05.size(); ++i) { + flow_element fe = total_flow05[i]; + + min_y = std::min(min_y, fe.y1); + max_y = std::max(max_y, fe.y1); + + min_y = std::min(min_y, fe.y2); + max_y = std::max(max_y, fe.y2); + } + + double min_x = std::min(total_flow[0].x, total_flow05[0].x); + double max_x = std::max(total_flow[total_flow.size() - 1].x, total_flow05[total_flow05.size() - 1].x); + + graph *g = mygraph_new(width, height); + g = mygraph_make_graph(g, min_x, max_x, min_y, max_y, 5); + + // PLOT FIRST + int *x = new int[total_flow.size()]; + unsigned long long *y1 = new unsigned long long[total_flow.size()]; + unsigned long long *y2 = new unsigned long long[total_flow.size()]; + + // de-interleave + for (unsigned i = 0; i < total_flow.size(); ++i) { + x[i] = total_flow[i].x; + y1[i] = total_flow[i].y1; + y2[i] = total_flow[i].y2; + } + + mygraph_plot_series(g, x, y1, total_flow.size(), 1.0f, 0.0f, 0.0f); + mygraph_plot_series(g, x, y2, total_flow.size(), 0.0f, 0.0f, 1.0f); + + delete[] x; + delete[] y1; + delete[] y2; + + // PLOT SECOND + x = new int[total_flow05.size()]; + y1 = new unsigned long long[total_flow05.size()]; + y2 = new unsigned long long[total_flow05.size()]; + + // de-interleave + for (unsigned i = 0; i < total_flow05.size(); ++i) { + x[i] = total_flow05[i].x; + y1[i] = total_flow05[i].y1; + y2[i] = total_flow05[i].y2; + } + + mygraph_plot_series(g, x, y1, total_flow05.size(), 0.0f, 1.0f, 0.0f); + mygraph_plot_series(g, x, y2, total_flow05.size(), 1.0f, 0.0f, 1.0f); + + delete[] x; + delete[] y1; + delete[] y2; + + mygraph_to_file(g, "comparative.png"); + mygraph_cleanup(g); +} diff --git a/web/ext/flowpusher.cpp b/web/ext/flowpusher.cpp new file mode 100644 index 0000000..7bcbf6a --- /dev/null +++ b/web/ext/flowpusher.cpp @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include +#include "flowpusher.h" + +FlowPusher::FlowPusher(std::vector &flow) : flow(flow) +{ +} + +void FlowPusher::find_diff(double x, double &prev_x, unsigned long long y1, unsigned long long prev_y1, unsigned long long y2, unsigned long long prev_y2, + unsigned long long &yf1, unsigned long long &yf2) +{ + // Heuristics: if last reading was more than ten minutes away, and both + // readings went down from last reading, we assume the counters + // were zeroed. If not, we assume wraparound. + bool over_10mins = (x - prev_x >= 600); + bool y1_wrapped = ((prev_y1 == 0 && y1 == 0) || y1 < prev_y1); + bool y2_wrapped = ((prev_y2 == 0 && y2 == 0) || y2 < prev_y2); + bool both_zero = (y1 == 0 && y2 == 0); + bool any_wide = (prev_y1 > 4294967296ULL || prev_y2 > 4294967296ULL); + + if ((over_10mins && (y1_wrapped || y2_wrapped)) || both_zero || (any_wide && (y1_wrapped || y2_wrapped))) { + prev_y1 = 0; + prev_y2 = 0; + + // our best estimate for when it was zeroed :-) + prev_x = (prev_x + x) / 2; + } + + if (y1 < prev_y1) { + yf1 = (unsigned long long)(((unsigned long long)y1 + 4294967296ULL) - prev_y1); + } else { + yf1 = (unsigned long long)(y1 - prev_y1); + } + + if (y2 < prev_y2) { + yf2 = (unsigned long long)(((unsigned long long)y2 + 4294967296ULL) - prev_y2) / (x - prev_x); + } else { + yf2 = (unsigned long long)(y2 - prev_y2); + } +} + +void FlowPusher::push(double x, unsigned long long y1, unsigned long long y2) +{ + unsigned long long yf1, yf2; + + find_diff(x, prev_x, y1, prev_y1, y2, prev_y2, yf1, yf2); + yf1 /= (x - prev_x); + yf2 /= (x - prev_x); + + flow_element fe; + fe.x = unsigned((prev_x + x)*0.5); + fe.y1 = yf1; + fe.y2 = yf2; + + min_x = std::min(min_x, fe.x); + max_x = std::max(max_x, fe.x); + + min_y = std::min(min_y, fe.y1); + max_y = std::max(max_y, fe.y1); + + min_y = std::min(min_y, fe.y2); + max_y = std::max(max_y, fe.y2); + + flow.push_back(fe); + + prev_x = x; + prev_y1 = y1; + prev_y2 = y2; +} + +void FlowPusher::reset(double x, unsigned long long y1, unsigned long long y2) +{ + flow.resize(0); + + min_y = 0; + max_y = 10000000; + + max_x = time(NULL); + min_x = max_x - 86400; + + prev_x = x; + prev_y1 = y1; + prev_y2 = y2; +} diff --git a/web/ext/flowpusher.h b/web/ext/flowpusher.h new file mode 100644 index 0000000..a16f7b1 --- /dev/null +++ b/web/ext/flowpusher.h @@ -0,0 +1,31 @@ +#ifndef _FLOWPUSHER_H +#define _FLOWPUSHER_H 1 + +struct flow_element { + unsigned x; + unsigned long long y1, y2; +}; + +class FlowPusher +{ +private: + std::vector &flow; + unsigned min_x, max_x; + long long unsigned min_y, max_y; + double prev_x; + unsigned long long prev_y1, prev_y2; + +public: + FlowPusher(std::vector &flow); + void reset(double x, unsigned long long y1, unsigned long long y2); + void push(double x, unsigned long long y1, unsigned long long y2); + static void find_diff(double x, double &prev_x, unsigned long long y1, unsigned long long prev_y1, unsigned long long y2, unsigned long long prev_y2, + unsigned long long &yf1, unsigned long long &yf2); + + unsigned get_min_x() { return min_x; } + unsigned get_max_x() { return max_x; } + unsigned get_min_y() { return min_y; } + unsigned get_max_y() { return max_y; } +}; + +#endif /* !defined(_FLOWPUSHER_H) */ diff --git a/web/ext/flowutil.cpp b/web/ext/flowutil.cpp new file mode 100644 index 0000000..9df12dc --- /dev/null +++ b/web/ext/flowutil.cpp @@ -0,0 +1,128 @@ +#include +#include +#include +#include +#include +#include +#include "graph.h" +#include "flowutil.h" + +std::vector sum_flows(const std::vector &a, const std::vector &b) +{ + std::vector ret; + std::vector::const_iterator ia = a.begin(), ib = b.begin(); + + double last_xa = 0.0, last_y1a = 0.0, last_y2a = 0.0; + double last_xb = 0.0, last_y1b = 0.0, last_y2b = 0.0; + + while (ia != a.end() && ib != b.end()) { + if (ia->x == ib->x) { + flow_element fea = *ia, feb = *ib, fe; + + last_xa = fea.x; + last_y1a = fea.y1; + last_y2a = fea.y2; + + last_xb = feb.x; + last_y1b = feb.y1; + last_y2b = feb.y2; + + fe.x = fea.x; + fe.y1 = fea.y1 + feb.y1; + fe.y2 = fea.y2 + feb.y2; + + ret.push_back(fe); + + ++ia, ++ib; + } else if (ia->x < ib->x) { + flow_element fe = *ia; + + last_xa = fe.x; + last_y1a = fe.y1; + last_y2a = fe.y2; + + double t = (fe.x - last_xb) / (ib->x - last_xb); + fe.y1 += last_y1b + t * (ib->y1 - last_y1b); + fe.y2 += last_y2b + t * (ib->y2 - last_y2b); + + ret.push_back(fe); + + ++ia; + } else { + flow_element fe = *ib; + + last_xb = fe.x; + last_y1b = fe.y1; + last_y2b = fe.y2; + + double t = (fe.x - last_xa) / (ia->x - last_xa); + fe.y1 += last_y1a + t * (ia->y1 - last_y1a); + fe.y2 += last_y2a + t * (ia->y2 - last_y2a); + + ret.push_back(fe); + ++ib; + } + } + + while (ia != a.end()) { + ret.push_back(*ia); + ++ia; + } + while (ib != b.end()) { + ret.push_back(*ib); + ++ib; + } + + return ret; +} + +std::vector filter_flow(const std::vector &flow) +{ + unsigned long long last_y1 = 0, last_y2 = 0; + std::vector ret; + + for (std::vector::const_iterator i = flow.begin(); i != flow.end(); ++i) { +/* if ((i->y1 > 100000 && last_y1 < 10000 && i->y2 > 100000 && last_y2 < 1000) || + (last_y1 > 10000 && last_y2 > 10000 && i->y1 / last_y1 > 10 && i->y2 / last_y2 > 10)) { + printf("yoyo: %llu %llu (%llu %llu)\n", i->y1, i->y2, last_y1, last_y2); + } else { + ret.push_back(*i); + last_y1 = i->y1; + last_y2 = i->y2; + } */ + if (!(i->x >= 1145056800 && i->x <= 1145070800)) { + ret.push_back(*i); + } + } + + return ret; +} + +void make_graph(int port, unsigned width, unsigned height, unsigned min_x, unsigned max_x, unsigned long long min_y, unsigned long long max_y, std::vector &flow) +{ + char filename[256]; + graph *g = mygraph_new(width, height); + g = mygraph_make_graph(g, min_x, max_x, min_y, max_y, 5); + + int *x = new int[flow.size()]; + unsigned long long *y1 = new unsigned long long[flow.size()]; + unsigned long long *y2 = new unsigned long long[flow.size()]; + + // de-interleave + for (unsigned i = 0; i < flow.size(); ++i) { + x[i] = flow[i].x; + y1[i] = flow[i].y1; + y2[i] = flow[i].y2; + } + + mygraph_plot_series(g, x, y1, flow.size(), 1.0f, 0.0f, 0.0f); + mygraph_plot_series(g, x, y2, flow.size(), 0.0f, 0.0f, 1.0f); + sprintf(filename, "port-%u-500-250.png", port); + mygraph_to_file(g, filename); + mygraph_cleanup(g); + + delete[] x; + delete[] y1; + delete[] y2; +} + diff --git a/web/ext/flowutil.h b/web/ext/flowutil.h new file mode 100644 index 0000000..235ebc9 --- /dev/null +++ b/web/ext/flowutil.h @@ -0,0 +1,11 @@ +#ifndef _FLOWUTIL_H +#define _FLOWUTIL_H 1 + +#include +#include "flowpusher.h" + +std::vector sum_flows(const std::vector &a, const std::vector &b); +std::vector filter_flow(const std::vector &flow); +void make_graph(int port, unsigned width, unsigned height, unsigned min_x, unsigned max_x, unsigned long long min_y, unsigned long long max_y, std::vector &flow); + +#endif /* !defined(_FLOWUTIL_H) */ diff --git a/web/ext/graph.cpp b/web/ext/graph.cpp new file mode 100755 index 0000000..a516b31 --- /dev/null +++ b/web/ext/graph.cpp @@ -0,0 +1,240 @@ +#include "graph.h" + +int tz_local_offset() { return 7200; } // riktig? + + +void +mygraph_fill_background(graph *mygraph); + +void +mygraph_draw_graph (cairo_t *cr, + int x, + int y ); + +graph * +mygraph_new (int width, int height) +{ + graph *mygraph; + mygraph = (graph *)malloc(sizeof(graph)); + mygraph->width = width; + mygraph->height = height; + + + int stride = width * 4; + unsigned char *image; + image = (unsigned char *) malloc (sizeof(unsigned char) * stride * height); + + mygraph->surface = cairo_image_surface_create_for_data (image, CAIRO_FORMAT_ARGB32, + width, height, stride); + mygraph->cr = cairo_create (mygraph->surface); + + cairo_set_source_rgb (mygraph->cr, 1.0, 1.0, 1.0); + mygraph_fill_background (mygraph); + + cairo_select_font_face (mygraph->cr, "Sans", CAIRO_FONT_SLANT_NORMAL, + CAIRO_FONT_WEIGHT_NORMAL); + cairo_set_font_size (mygraph->cr, 10); + + cairo_set_antialias(mygraph->cr, CAIRO_ANTIALIAS_NONE); + cairo_set_line_width (mygraph->cr, 1.0); + + return mygraph; +} + +graph * +mygraph_make_graph (graph *mygraph, double min_x, double max_x, + double min_y, double max_y, int tickgran) +{ + int xoffset = 70; + cairo_text_extents_t extents; + + mygraph->xoffset = xoffset; + mygraph->min_x = min_x; + mygraph->max_x = max_x; + mygraph->min_y = min_y; + mygraph->max_y = max_y; + +/* cairo_t *cr; */ +/* cairo_surface_t *surface; */ + + double xs = ((double)mygraph->width - (double)(xoffset+2)) / + (double)(max_x - min_x); + + double ys = ((double)mygraph->height - 33.) / (double)(min_y - max_y); + + mygraph->xs = xs; + mygraph->ys = ys; + + double starthour = fmod((min_x + (double)tz_local_offset()) / 3600., 24.); + double diff, center, begin, end; + + char string[20]; + + int i; + for (i = 0; i<240; i++) + { // Hour marks and text + if ((i % 2) == 0) + cairo_set_source_rgb (mygraph->cr, 1.0, 1.0, 1.0); + else + cairo_set_source_rgb (mygraph->cr, 0.90, 0.90, 1.0); + + diff = (double)i - starthour; + begin = (diff * 3600.) * xs; + end = ((double)(i+1) - starthour) * 3600.0 * xs; + center = (begin + end) / 2.; + + if (begin < 0.0) + continue; + if (begin > ((double)mygraph->width - ((double)xoffset))) + continue; + + cairo_rectangle (mygraph->cr, xoffset+begin, 0, + end - begin, mygraph->height); + + cairo_fill (mygraph->cr); + + if (begin <= 0.0 || end >= mygraph->width - (xoffset)) + continue; + + cairo_set_source_rgb (mygraph->cr, 0.0, 0.0, 0.0); + + sprintf(string, "%d", i % 24); +// printf("showing string %s @ %fx%f\n", string, xoffset + center - (extents.width/2), (mygraph->height - extents.height - 2)); + + cairo_text_extents (mygraph->cr, string, &extents); + cairo_move_to (mygraph->cr, xoffset + center - + (extents.width/2), + (mygraph->height - extents.height - 2)); + + cairo_show_text (mygraph->cr, string); + + } + + cairo_set_source_rgb (mygraph->cr, 0.4, 0.4, 0.4); + long long ytick; + do + { + ytick = ((long long)max_y - (long long)min_y) / 11; + ytick = (long long)(ceil (ytick / tickgran) * tickgran); + tickgran /= 10; + } while (((long long)max_y - (long long)min_y) / ytick < 4); + + int y; + unsigned long long traf; + for (i = -11; i<12; i++) + { + y = (int)((i * ytick - (long long)max_y) * ys + 10); + if (y < 2 || y > mygraph->height - 18) + continue; + +/* printf("draw line at %d\n", y); */ + + cairo_move_to (mygraph->cr, xoffset, y); + cairo_line_to (mygraph->cr, mygraph->width-1, y); + + if (i == 0) + { + + cairo_set_source_rgb (mygraph->cr, 0.0, 0.0, 1.0); + cairo_stroke (mygraph->cr); + cairo_set_source_rgb (mygraph->cr, 0.6, 0.6, 0.6); + } + else + cairo_stroke (mygraph->cr); + + // draw text + traf = 8 * ((unsigned long long)i * ytick); +/* printf("traffic: %d\n", traf); */ + + if (traf >= 500000000) + sprintf (string, "%.1f Gbit", ((double)traf/1000000000)); + else if (traf >= 500000) + sprintf (string, "%.1f Mbit", ((double)traf/1000000)); + else + sprintf (string, "%.1f kbit", ((double)traf/1000)); + + cairo_text_extents (mygraph->cr, string, &extents); + +/* if (y - (extents.height/2) < 2 || + y + (extents.height/2) > mygraph->height - (extents.height + 2)) + continue; */ + + cairo_move_to (mygraph->cr, + xoffset - 4 - extents.width, + y + (extents.height/2)); + + cairo_show_text (mygraph->cr, string); + } + + cairo_rectangle (mygraph->cr, xoffset, 0, mygraph->width-xoffset-1, mygraph->height-1); + + cairo_set_source_rgb (mygraph->cr, 0.0, 0.0, 0.0); + cairo_stroke (mygraph->cr); + + return mygraph; +} + +void +mygraph_plot_series (graph *mygraph, int *xvals, unsigned long long *yvals, int n_vals, + double r, double g, double b) +{ + int x, i; + unsigned long long y; + x = xvals[0]; + y = yvals[0]; + + cairo_set_antialias(mygraph->cr, CAIRO_ANTIALIAS_DEFAULT); + cairo_set_source_rgb (mygraph->cr, r, g, b); + + int xp = (int)((x - mygraph->min_x) * mygraph->xs + mygraph->xoffset + 1); + int yp = (int)((y - mygraph->max_y) * mygraph->ys + 10); + + cairo_move_to (mygraph->cr, xp, yp); + +/* printf("Plotting from:\n"); + printf("(%d, %d) %d (%d, %d)
\n", + x, y, (int)((double)(x - (int)mygraph->min_x) * mygraph->xs + (double)(mygraph->xoffset + 1)) , + (int)((double)(x - (int)mygraph->min_x) * mygraph->xs + (double)(mygraph->xoffset + 1)), + (int)((double)(y - (int)mygraph->max_y) * mygraph->ys + 10.)); */ + + int last_xp = xp, last_yp = yp; + + for (i = 1; i < n_vals; i++) + { + x = xvals[i]; + y = yvals[i]; + + int xp = (int)((x - mygraph->min_x) * mygraph->xs + mygraph->xoffset + 1); + int yp = (int)((y - mygraph->max_y) * mygraph->ys + 10); + + if (abs(xp - last_xp) < 2 && yp > last_yp) + continue; + + cairo_line_to (mygraph->cr, xp, yp); + last_xp = xp; + last_yp = yp; + } + + cairo_stroke(mygraph->cr); +} + +void +mygraph_to_file (graph *mygraph, char *filename) +{ + cairo_surface_write_to_png (mygraph->surface, filename); +} + +void +mygraph_cleanup (graph *self) +{ + cairo_destroy (self->cr); + cairo_surface_destroy (self->surface); +} + +void +mygraph_fill_background (graph *mygraph) +{ + cairo_rectangle (mygraph->cr, 0, 0, mygraph->width, mygraph->height); + cairo_fill (mygraph->cr); +} + diff --git a/web/ext/graph.h b/web/ext/graph.h index 2d39217..c6376af 100644 --- a/web/ext/graph.h +++ b/web/ext/graph.h @@ -11,29 +11,26 @@ typedef struct _graph { int width; int height; int xoffset; - int yoffset; - float min_x; - float max_x; - float min_y; - float max_y; - float xs; - float ys; + double min_x; + double max_x; + double min_y; + double max_y; + double xs; + double ys; } graph; -int tz_local_offset() { return 7200; } // riktig? - void mygraph_fill_background(graph *mygraph); void mygraph_draw_graph (cairo_t *cr, int x, int y ); graph *mygraph_new (int width, int height); -graph *mygraph_make_graph (graph *mygraph, float min_x, - float max_x, float min_y, float max_y, +graph *mygraph_make_graph (graph *mygraph, double min_x, + double max_x, double min_y, double max_y, int tickgran); -void mygraph_plot_series (graph *mygraph, int *xvals, int *yvals, - int n_vals, float r, float g, float b); +void mygraph_plot_series (graph *mygraph, int *xvals, unsigned long long *yvals, + int n_vals, double r, double g, double b); void mygraph_to_file (graph *mygraph, char *filename); diff --git a/web/ext/graphall.cpp b/web/ext/graphall.cpp new file mode 100644 index 0000000..a21fc45 --- /dev/null +++ b/web/ext/graphall.cpp @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include +#include "graph.h" +#include "flowpusher.h" +#include "flowutil.h" + +int main(int argc, char **argv) +{ + bool total_only = false; + int width = 500, height = 250; + + std::vector flow, total_flow; + FlowPusher fp(flow); + int last_port = -1; + + mallopt(M_TRIM_THRESHOLD, -1); + + if (argc == 2 && strcmp(argv[1], "--total-only") == 0) { + width = 1000; + height = 500; + total_only = true; + } + + int num_total = 0; + + for ( ;; ) { + int port; + double x; + unsigned long long y1, y2; + + if (scanf("%d %lf %llu %llu", &port, &x, &y1, &y2) != 4) + break; + + if (port != last_port) { + if (last_port != -1) { + if (!total_only) + make_graph(last_port, width, height, fp.get_min_x(), fp.get_max_x(), fp.get_min_y(), fp.get_max_y(), flow); + total_flow = sum_flows(total_flow, flow); + fprintf(stderr, "%u (%u)\n", last_port, ++num_total); + } + + // reset + last_port = port; + fp.reset(x, y1, y2); + continue; + } + + fp.push(x, y1, y2); + } + + // last graph + if (!total_only) + make_graph(last_port, width, height, fp.get_min_x(), fp.get_max_x(), fp.get_min_y(), fp.get_max_y(), flow); + total_flow = sum_flows(total_flow, flow); + + // total graph + unsigned long long min_y = 0; + unsigned long long max_y = 10000000; + + for (unsigned i = 0; i < total_flow.size(); ++i) { + flow_element fe = total_flow[i]; + + min_y = std::min(min_y, fe.y1); + max_y = std::max(max_y, fe.y1); + + min_y = std::min(min_y, fe.y2); + max_y = std::max(max_y, fe.y2); + } + + make_graph(65535, width, height, total_flow[0].x, total_flow[total_flow.size() - 1].x, min_y, max_y, total_flow); +} diff --git a/web/ext/showswitch.pl b/web/ext/showswitch.pl index c015005..f2851c1 100755 --- a/web/ext/showswitch.pl +++ b/web/ext/showswitch.pl @@ -6,6 +6,9 @@ use POSIX ":sys_wait_h"; use strict; use warnings; +use lib '../../include'; + +use nms; use mygraph; require 'glue.pl'; @@ -22,8 +25,7 @@ $height = 250 unless (defined($height)); my $graph = mygraph::mygraph_new($width, $height); my $start = [Time::HiRes::gettimeofday]; -my $dbh = DBI->connect("dbi:Pg:dbname=tg", "tg", "tg06") - or die "Couldn't connect to database"; +my $dbh = nms::db_connect(); # Fetch the name my $ref = $dbh->selectrow_hashref('SELECT sysname FROM switches WHERE switch=?', undef, $switch); @@ -38,7 +40,7 @@ print <<"EOF";

Switch $switch ($ref->{'sysname'})

EOF -my $q = $dbh->prepare('select port,coalesce(description, \'Port \' || port) as description,extract(epoch from time) as time,bytes_in,bytes_out from polls natural join switches natural left join portnames where time between \'2005-03-23 05:17:36+01\' and \'2005-03-24 05:17:36+01\' and switch=? order by switch,port,time;'); +my $q = $dbh->prepare('select port,coalesce(description, \'Port \' || port) as description,extract(epoch from time) as time,bytes_in,bytes_out from polls natural join switches natural left join portnames where time between now() - \'1 day\'::interval and now() and switch=? order by switch,port,time;'); $q->execute($switch); my (@totx, @toty1, @toty2) = (); @@ -60,7 +62,7 @@ while (my $ref = $q->fetchrow_hashref()) { my $in = $ref->{'bytes_in'}; my $out = $ref->{'bytes_out'}; next if ($time == $prev_time); - + if ($ref->{'port'} != $last_port) { if ($last_port != -1) { my $filename = "$switch-$last_port-$width-$height.png"; diff --git a/web/ext/totalcount.cpp b/web/ext/totalcount.cpp new file mode 100644 index 0000000..bb4b1c0 --- /dev/null +++ b/web/ext/totalcount.cpp @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include +#include +#include "graph.h" +#include "flowpusher.h" +#include "flowutil.h" + +namespace pqxx { + template<> + void from_string(const char *from, long long &to) + { + to = atoll(from); + } +} + +int main(int argc, char **argv) +{ + int width = 1000, height = 500; + unsigned long long traffic = 0ULL; + pqxx::connection conn("dbname=nms host=localhost user=nms password=seesahS4"); + + std::vector flow; + int last_port = -1; + + mallopt(M_TRIM_THRESHOLD, -1); + + int num_total = 0; + pqxx::work t(conn, "fetch_all"); +// pqxx::icursorstream::icursorstream cstream(t, "select port,extract(epoch from time) as time,bytes_in,bytes_out from polls natural join switches where ((switchtype='es3024' and port < 25) or (switchtype='summit400' and port > 1)) order by switch,port,time", "fetch_all", 500); + pqxx::icursorstream::icursorstream cstream(t, "select port,extract(epoch from time) as time,bytes_in,bytes_out from polls natural join switches where switch=1447 order by switch,port,time", "fetch_all", 500); + + double prev_x; + unsigned long long prev_y1, prev_y2; + + for ( ;; ) { + pqxx::result res; + + cstream >> res; + if (res.empty()) + break; + + for (unsigned i = 0; i < res.size(); ++i) { + int port = res[i][0].as(); + double x = res[i][1].as(); + unsigned long long y1 = res[i][2].as(), y2 = res[i][3].as(); + + if (port != last_port) { + if (last_port != -1) { + fprintf(stderr, "%.2f TB (%u)\n", traffic / double(1024.0 * 1024.0 * 1024.0 * 1024.0), ++num_total); + } + + // reset + last_port = port; + prev_x = x; + prev_y1 = y1; + prev_y2 = y2; + continue; + } + + unsigned long long yf1, yf2; + FlowPusher::find_diff(x, prev_x, y1, prev_y1, y2, prev_y2, yf1, yf2); + traffic += 0.5 * (yf1 + yf2); + + prev_x = x; + prev_y1 = y1; + prev_y2 = y2; + } + } + fprintf(stderr, "%.2f TB\n", traffic / double(1024.0 * 1024.0 * 1024.0 * 1024.0)); +} diff --git a/web/ext/totalgraph.cpp b/web/ext/totalgraph.cpp new file mode 100644 index 0000000..f1301d2 --- /dev/null +++ b/web/ext/totalgraph.cpp @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include +#include +#include +#include "flowpusher.h" +#include "flowutil.h" + +namespace pqxx { + template<> + void from_string(const char *from, long long &to) + { + to = atoll(from); + } +} + + +int main(int argc, char **argv) +{ + int width = 1000, height = 500; + pqxx::connection conn("dbname=nms host=localhost user=nms password=seesahS4"); + + std::vector flow, total_flow; + FlowPusher fp(flow); + int last_port = -1; + + mallopt(M_TRIM_THRESHOLD, -1); + + int num_total = 0; + pqxx::work t(conn, "fetch_all"); + pqxx::icursorstream::icursorstream cstream(t, "select port,extract(epoch from time) as time,bytes_in,bytes_out from polls natural join switches where (switchtype='es3024' and port < 25) or (switchtype='summit400' and port > 1) order by switch,port,time", "fetch_all", 500); + + for ( ;; ) { + pqxx::result res; + + cstream >> res; + if (res.empty()) + break; + + for (unsigned i = 0; i < res.size(); ++i) { + int port = res[i][0].as(); + double x = res[i][1].as(); + unsigned long long y1 = res[i][2].as(), y2 = res[i][3].as(); + + if (port != last_port) { + if (last_port != -1) { + total_flow = sum_flows(total_flow, flow); + fprintf(stderr, "%u (%u)\n", last_port, ++num_total); + } + + // reset + last_port = port; + fp.reset(x, y1, y2); + continue; + } + + fp.push(x, y1, y2); + } + } + + unsigned long long min_y = 0; + unsigned long long max_y = 10000000; + + for (unsigned i = 0; i < total_flow.size(); ++i) { + flow_element fe = total_flow[i]; + + min_y = std::min(min_y, fe.y1); + max_y = std::max(max_y, fe.y1); + + min_y = std::min(min_y, fe.y2); + max_y = std::max(max_y, fe.y2); + } + + make_graph(65535, width, height, total_flow[0].x, total_flow[total_flow.size() - 1].x, min_y, max_y, total_flow); +} diff --git a/web/make-switches.pl b/web/make-switches.pl index 2829ed7..e1d3fe9 100644 --- a/web/make-switches.pl +++ b/web/make-switches.pl @@ -22,7 +22,7 @@ while () { $name =~ /e(\d+)-(\d+)/; my ($e, $s) = ($1, $2); - my $x = int(202 + $e * 8.25); + my $x = int(244 + $e * 9.87); my $y; $x += 7 if ($e >= 19); @@ -35,12 +35,12 @@ while () { $c = $e; $d = ($s - 1) * 64; - $y = 470 - $s * 48; + $y = 455 - $s * 48; } else { $c = $e + 1; $d = ($s - 4) * 64; - $y = 400 - $s * 48 - ($s - 3) * 2; + $y = 424 - $s * 48 - ($s - 3) * 2; } my $xx = $x + 12; diff --git a/web/nettkart-telnet.pl b/web/nettkart-telnet.pl index 3a83539..783f53e 100755 --- a/web/nettkart-telnet.pl +++ b/web/nettkart-telnet.pl @@ -6,7 +6,7 @@ use nms; my $cgi = CGI->new; my $dbh = nms::db_connect(); -print $cgi->header(-type=>'text/html', -refresh=>'45; http://nms.tg05.gathering.org/nettkart-telnet.pl'); +print $cgi->header(-type=>'text/html', -refresh=>'45; http://nms.tg07.gathering.org/nettkart-telnet.pl'); print <<"EOF"; diff --git a/web/nettkart-text.pl b/web/nettkart-text.pl index 7255e58..cf198dd 100755 --- a/web/nettkart-text.pl +++ b/web/nettkart-text.pl @@ -6,7 +6,7 @@ use nms; my $cgi = CGI->new; my $dbh = nms::db_connect(); -print $cgi->header(-type=>'text/html', -refresh=>'10; http://nms.tg05.gathering.org/nettkart-text.pl'); +print $cgi->header(-type=>'text/html', -refresh=>'10; http://nms.tg07.gathering.org/nettkart-text.pl'); print <<"EOF"; diff --git a/web/nettkart-web.pl b/web/nettkart-web.pl index 154181f..040d476 100755 --- a/web/nettkart-web.pl +++ b/web/nettkart-web.pl @@ -6,7 +6,7 @@ use nms; my $cgi = CGI->new; my $dbh = nms::db_connect(); -print $cgi->header(-type=>'text/html', -refresh=>'45; http://nms.tg05.gathering.org/nettkart-web.pl'); +print $cgi->header(-type=>'text/html', -refresh=>'45; http://nms.tg07.gathering.org/nettkart-web.pl'); print <<"EOF"; diff --git a/web/nettkart.pl b/web/nettkart.pl index e0b47e8..89c63ea 100755 --- a/web/nettkart.pl +++ b/web/nettkart.pl @@ -1,35 +1,71 @@ #! /usr/bin/perl use CGI; use GD; +use Image::Magick; use DBI; use lib '../include'; use nms; my $cgi = CGI->new; +# Sekrit night-mode +my $night = defined($cgi->param('night')); + my $dbh = nms::db_connect(); GD::Image->trueColor(1); -$img = GD::Image->new('bg2.png'); +my ($img, $text_img); + +$img = GD::Image->new('bg07.png'); +if ($night) { + my ($width, $height) = ($img->width, $img->height); + + $img = GD::Image->new($width, $height); + $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); + $text_img->alphaBlending(0); + $text_img->saveAlpha(1); + my $blank = $text_img->colorAllocateAlpha(0, 0, 0, 127); + $text_img->filledRectangle(0, 0, $text_img->width - 1, $text_img->height - 1, $blank); +} else { + $img = GD::Image->new('bg07.png'); + $text_img = $img; +} my $blk = $img->colorResolve(0, 0, 0); for my $y (42..236) { - my $i = 2.0 * ($y - 236.0) / (42.0 - 237.0); + my $i = 4.0 * ($y - 236.0) / (42.0 - 237.0); my $clr = get_color($i); - $img->filledRectangle(32,$y,53,$y+1,$clr); + $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, 1000, 620, "NMS (C) 2005-2007 Tech:Server"); + my $q = $dbh->prepare('select * from switches natural join placements natural left join -( select switch,sum(bytes_in)/count(*) as -bytes_in,sum(bytes_out)/count(*) as bytes_out from get_datarate() group -by switch ) t1 where ip<>\'127.0.0.1\''); +( select switch,sum(bytes_in) as bytes_in,sum(bytes_out) as bytes_out from get_datarate() group +by switch ) t1 order by zorder'); $q->execute(); while (my $ref = $q->fetchrow_hashref()) { # for now: - # 100kbit/port = all green - # 1gbit/port = all red + # 10Mbit/switch = green + # 100Mbit/switch = yellow + # 1Gbit/switch = red + # 10Gbit/switch = white my $clr; @@ -37,12 +73,12 @@ while (my $ref = $q->fetchrow_hashref()) { my $intensity = 0.0; my $traffic = 4.0 * $ref->{'bytes_in'} + $ref->{'bytes_out'}; # average and convert to bits (should be about the same in practice) - my $max = 20_000_000.0; # 10mbit - my $min = 100_000.0; # 100kbit + my $max = 10_000_000_000.0; # 10Gbit + my $min = 10_000_000.0; # 10Mbit if ($traffic >= $min) { - $intensity = 2.0 * (log($traffic / $min) / log(10)) / (log($max / $min) / log(10)); - $intensity = 2.0 if ($intensity > 2.0); - } + $intensity = log($traffic / $min) / log(10); + $intensity = 3.0 if ($intensity > 3.0); + } $clr = get_color($intensity); } else { $clr = $img->colorResolve(0, 0, 255); @@ -50,18 +86,44 @@ while (my $ref = $q->fetchrow_hashref()) { $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); - $img->stringUp(gdSmallFont,$3,$2-3,$ref->{'sysname'},$blk); + $text_img->rectangle($3,$4,$1,$2,$blk); + $text_img->stringUp(gdSmallFont,$3,$2-3,$ref->{'sysname'},$blk); } $dbh->disconnect; print $cgi->header(-type=>'image/png'); -print $img->png; +if ($night) { + my $magick = Image::Magick->new; + $magick->BlobToImage($img->png); + $magick->Blur(sigma=>10.0, channels=>'All'); + $magick->Gamma(gamma=>1.90); + + my $m2 = Image::Magick->new; + $m2->Read('snmp-bg.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 > 1.0) { + 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/overlay.pl b/web/overlay.pl index 95e9198..3265b07 100755 --- a/web/overlay.pl +++ b/web/overlay.pl @@ -146,7 +146,7 @@ for my $y (0..479) { } -print CGI::header(-type=>'image/png', -refresh=>'10; http://nms.tg05.gathering.org/overlay.pl?cam=' . $cam); +print CGI::header(-type=>'image/png', -refresh=>'10; http://nms.tg07.gathering.org/overlay.pl?cam=' . $cam); print $gd->png; sub get_color { diff --git a/web/portkart.pl b/web/portkart.pl index 259376e..28e043f 100755 --- a/web/portkart.pl +++ b/web/portkart.pl @@ -9,18 +9,25 @@ my $cgi = CGI->new; my $dbh = nms::db_connect(); GD::Image->trueColor(1); -$img = GD::Image->new('bg2.png'); +$img = GD::Image->new('bg07.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 $i = 3.0 * ($y - 236.0) / (42.0 - 237.0); my $clr = get_color($i); - $img->filledRectangle(32,$y,53,$y+1,$clr); + $img->filledRectangle(12,$y,33,$y+1,$clr); } -my $q = $dbh->prepare('select switch,port,bytes_in,bytes_out,placement,switchtype from switches natural join placements natural join get_current_datarate() where switchtype in (\'es3024\')'); +$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, 1000, 620, "NMS (C) 2005-2007 Tech:Server"); + +my $q = $dbh->prepare('select switch,port,bytes_in,bytes_out,placement,switchtype from switches natural join placements natural join get_datar +ate() where switchtype in (\'es3024\')'); $q->execute(); while (my $ref = $q->fetchrow_hashref()) { @@ -34,11 +41,11 @@ while (my $ref = $q->fetchrow_hashref()) { my $intensity = 0.0; my $traffic = 4.0 * $ref->{'bytes_in'} + $ref->{'bytes_out'}; # average and convert to bits (should be about the same in practice) - my $max = 20_000_000.0; # 100mbit - my $min = 100_000.0; # 100kbit + my $max = 1_000_000_000.0; # 1Gbit + my $min = 1_000_000.0; # 1Mbit if ($traffic >= $min) { - $intensity = 2.0 * (log($traffic / $min) / log(10)) / (log($max / $min) / log(10)); - $intensity = 2.0 if ($intensity > 2.0); + $intensity = log($traffic / $min) / log(10); + $intensity = 3.0 if ($intensity > 3.0); } $clr = get_color($intensity); } else { @@ -64,7 +71,9 @@ print $img->png; sub get_color { my $intensity = shift; my $gamma = 1.0/1.90; - if ($intensity > 1.0) { + if ($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/sendsms.pl b/web/sendsms.pl index 86b80ef..2f1bea2 100755 --- a/web/sendsms.pl +++ b/web/sendsms.pl @@ -14,17 +14,17 @@ my $ua = new LWP::UserAgent; $ua->timeout(15); $ua->agent('Mozilla/5.0'); -#$ua->credentials( "http://zepo.tg05.gathering.org", "/", $uname, $pass ); +#$ua->credentials( "http://zepo.tg07.gathering.org", "/", $uname, $pass ); my $content; my %form; $form{'userid'} = $uname; $form{'next'} = "Look me up"; -#my $content = $ua->get("http://zepo.tg05.gathering.org/"); +#my $content = $ua->get("http://zepo.tg07.gathering.org/"); -$content = $ua->post("http://zepo.tg05.gathering.org/login", \%form); +$content = $ua->post("http://zepo.tg07.gathering.org/login", \%form); if (!defined($content->{'_headers'}{'location'})) { die "Could not find dudes"; @@ -41,7 +41,7 @@ print Dumper($content); $form{'password'} = $pass; $form{'userid'} = 39457; $form{'next'} = "Log in"; -$content = $ua->post("https://zepo.tg05.gathering.org/enter&got=it", "cookie" => "SID=".$sessioncookie, \%form); +$content = $ua->post("https://zepo.tg07.gathering.org/enter&got=it", "cookie" => "SID=".$sessioncookie, \%form); print Dumper($content); diff --git a/web/smanagement.pl b/web/smanagement.pl index ed783b2..de7e1b8 100755 --- a/web/smanagement.pl +++ b/web/smanagement.pl @@ -4,6 +4,7 @@ use strict; use CGI; use DBI; use Data::Dumper; +use Switch; use lib '../include'; use nms; @@ -28,15 +29,15 @@ sub parse_range($) { my @rangecomma = split(/\s*,\s*/, $switches); foreach (@rangecomma) { - my ($first, $drop1, $last, $drop2) = $_ =~ /(e\d+\-[123456])(sw)?\s*\-\s*(e\d+\-[123456])?(sw)?/; - if (!defined($first) && $_ =~ /e\d+\-[123456]/) { + 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 "Parse error in: $_
\n"; next; } - my ($rowstart, $placestart) = $first =~ /e(\d+)\-([123456])/; + my ($rowstart, $placestart) = $first =~ /e(\d+)\-(?:sw)?([123456])/; if (!defined($rowstart) || !defined($placestart)) { print "Parse error in: $_
\n"; next; @@ -47,7 +48,7 @@ sub parse_range($) { $placeend = $placestart; } else { - ($rowend, $placeend) = $last =~ /e(\d+)\-([123456])/; + ($rowend, $placeend) = $last =~ /e(\d+)\-(?:sw)?([123456])/; } if (!defined($rowend) || !defined($placeend)) { print "Parse error in: $_
\n"; @@ -64,7 +65,7 @@ sub parse_range($) { } for (my $j = $dostart; $j <= 6; $j++) { last if ($i == $rowend && $j > $placeend); - push(@range, "e$i-$j"); + push(@range, "e$i-sw$j"); } } } @@ -77,9 +78,9 @@ sub parse_range($) { sub get_addr_from_switchnum($) { my ($sysname) = @_; - $sgetip->execute($sysname."sw"); + $sgetip->execute($sysname); if ($sgetip->rows() < 1) { - print "Could not get the ip for: ".$sysname."sw"; + print "Could not get the ip for: ".$sysname; return undef; } my $row = $sgetip->fetchrow_hashref(); diff --git a/web/sshow.pl b/web/sshow.pl index bae9511..b840ac8 100755 --- a/web/sshow.pl +++ b/web/sshow.pl @@ -110,9 +110,6 @@ if (defined($cgi->param('agid'))) { my $gid = $cgi->param('gid'); if (!defined($gid)) { print "Du har ikke valgt en gid å slette.\n"; - } - if ($cgi->param('agid') eq 'Disable') { - $sdisablegid->execute($gid); print "

gid: ".$cgi->param('gid')." har blitt disablet.\n"; } else { diff --git a/web/stempmap.pl b/web/stempmap.pl index 2399b31..33cad52 100755 --- a/web/stempmap.pl +++ b/web/stempmap.pl @@ -12,7 +12,7 @@ use warnings; GD::Image->trueColor(1); -my $img = GD::Image->new('bg2.png'); +my $img = GD::Image->new('bg07.png'); #my $img = GD::Image->new(100,100); my $cgi = CGI->new; diff --git a/web/streaming.pl b/web/streaming.pl index 4b12add..8137de9 100755 --- a/web/streaming.pl +++ b/web/streaming.pl @@ -20,6 +20,6 @@ $img->interlaced('true'); $img->string(gdMediumBoldFont,0,0,"TG05 - Streaming",$blu); print $cgi->header(-type=>'image/png', - -refresh=>'10; http://nms.tg05.gathering.org/streaming.pl'); + -refresh=>'10; http://nms.tg07.gathering.org/streaming.pl'); print $img->png;