#!/usr/local/bin/perl -wT # # rtg.cgi - prepare parameters to display data with rtgplot # Copyright (C) 2006 - Anthony Tonns # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # # initially written # ATonns Mon Aug 7 11:54:25 EDT 2006 # use strict; use CGI qw/-debug :standard :html3 :cgi-lib/; use CGI::Carp qw(fatalsToBrowser); use DBI; use Time::Local; ### customizable variables ### my $config = '/usr/local/rtg/etc/rtg.conf'; my $relative_image_directory = "/rtg"; ### static variables ### my $VERSION = "0.7.4"; ### CODE ### # start CGI output print header; # get the database connection properties from rtg.conf my %dbconfig; my $conf; open($conf,$config) || die "cannot open config file '$config':"; while(<$conf>) { my $line = $_; chomp $line; next if $line =~ /^#/; next if $line =~ /^$/; my ($key,$val) = split(/\s+/,$line,2); if ( $key =~ /^DB_/ ) { $dbconfig{$key} = $val; } } close $conf; # connect to the database my $dbh = DBI->connect( "DBI:mysql:database=$dbconfig{DB_Database};host=$dbconfig{DB_Host}", "$dbconfig{DB_User}", "$dbconfig{DB_Pass}", {'RaiseError' => 1} ); # parse the CGI variables my %p = Vars; my $name; my $description; my $speed; my $router; my @iid = param('iid'); # did we get the router id and the interface id? if ( $p{rid} && $p{iid} ) { # SQL to get info on router and interface my $statement; $statement .= "SELECT i.name, i.description, i.speed, r.name AS router "; $statement .= "FROM interface i, router r "; $statement .= "WHERE i.rid=r.rid "; $statement .= "AND i.rid=$p{rid} "; $statement .= "AND i.id=$iid[0] "; # my $hash_ref = $dbh->selectrow_hashref($statement); $name = $hash_ref->{name}; $description = $hash_ref->{description}; $speed = sprintf("%2.3f",$hash_ref->{speed}/1000000); $router = $hash_ref->{router}; } # if we just got the router, get just that info elsif ( $p{rid} && ! $p{iid} ) { my $statement; $statement .= "SELECT name AS router "; $statement .= "FROM router "; $statement .= "WHERE rid=$p{rid} "; # my $hash_ref = $dbh->selectrow_hashref($statement); $router = $hash_ref->{router}; } # set the title based on what we know so far my $title; $title .= "RTG: "; if ( $p{rid} && $p{iid} ) { $title .= "$router: $name"; } elsif ( $p{rid} && ! $p{iid} ) { $title .= "$router"; } # start the HTML/form print start_html(-title=>$title,-background=>"$relative_image_directory/rtgback.png"); print a({-href=>"http://rtg.sourceforge.net/"},img {-src=>"$relative_image_directory/rtg.png",-border=>0}),p; print start_form("GET"); # if we don't know the router id nor the interface id if ( !$p{rid} && !$p{iid} ) { # SQL to get a list of routers my $statement; $statement .= "SELECT DISTINCT name, rid "; $statement .= "FROM router "; $statement .= "ORDER BY name "; my $ary_ref = $dbh->selectall_arrayref($statement); # get the values/labels for the scrolling list of routers my @values; my %labels; foreach my $row (@{$ary_ref}) { my $rtr_name = $row->[0]; my $rtr_rid = $row->[1]; push(@values,$rtr_rid); $labels{$rtr_rid} = $rtr_name; } # ... and then print it print scrolling_list( -name=>'rid', -values=>\@values, -labels=>\%labels, -size=>10 ); } # if we have a time, but not and interface, warn the user if ( $p{smonth} && !$p{iid} ) { print blockquote(font({-size=>"+1"},strong("Please select an interface!\n"))); } # if we have a router, but not an interface if ( $p{rid} && !$p{iid} ) { # print a fake scrolling list with the router we have print scrolling_list( -name=>'rid', -values=>[qq/$p{rid}/], -labels=>{$p{rid}=>$router}, -size=>10 ); # SQL to get a list of interfaces on this router my $statement; $statement .= "SELECT id, name, description "; $statement .= "FROM interface "; $statement .= "WHERE rid=$p{rid} "; $statement .= "ORDER BY name "; my $ary_ref = $dbh->selectall_arrayref($statement); # get the values/labels for the scrolling list of interfaces my @values; my %labels; foreach my $row (@{$ary_ref}) { my $int_id = $row->[0]; my $int_name = $row->[1]; my $int_description = $row->[2]; push(@values,$int_id); $labels{$int_id} = "$int_name ($int_description)"; } # ... and then print it print scrolling_list( -name=>'iid', -values=>\@values, -labels=>\%labels, -size=>10, -multiple=>'true' ); # use "now" as the time to fill-in the form values by default my @now = localtime(time); print p; # print the date fill-ins for the form print table({-border=>0}, Tr( [ td( [ "From:", textfield( -name=>'smonth', -size=>3, -maxlength=>2, -default=> $now[4] + 1 ), textfield( -name=>'sday', -size=>3, -maxlength=>2, -default=> $now[3] ), textfield( -name=>'syear', -size=>5, -maxlength=>4, -default=> $now[5] + 1900), textfield( -name=>'shour', -size=>3, -maxlength=>2, -default=> "00" ), textfield( -name=>'smin', -size=>3, -maxlength=>2, -default=> "00" ), ] ), td( [ "To:", textfield( -name=>'emonth', -size=>3, -maxlength=>2, -default=> $now[4] + 1 ), textfield( -name=>'eday', -size=>3, -maxlength=>2, -default=> $now[3] ), textfield( -name=>'eyear', -size=>5, -maxlength=>4, -default=> $now[5] + 1900), textfield( -name=>'ehour', -size=>3, -maxlength=>2, -default=> "23" ), textfield( -name=>'emin', -size=>3, -maxlength=>2, -default=> "59" ), ] ), td( [ "Aggregate Interfaces:", checkbox( -name=>'aggr' ), ] ), td( [ textfield( -name=>'nth', -size=>2, -maxlength=>2, -default=>'95') . "th Percentile:", checkbox( -name=>'percentile' ), ] ), td( [ "Fit to Data:", checkbox( -name=>'scalex' ), ] ), td( [ "Fit to Speed:", checkbox( -name=>'scaley' ), ] ), td( [ "X Size:", textfield( -name=>'xplot', -size=>3, -maxlength=>3, -default=>'500'), ] ), td( [ "Y Size:", textfield( -name=>'yplot', -size=>3, -maxlength=>3, -default=>'150'), ] ), td( [ "BorderB:", textfield( -name=>'borderb', -size=>3, -maxlength=>3, -default=>'70'), ] ), ] ), ); } # we have a router and an interface and a date if ( $p{rid} && $p{iid} && $p{smonth} ) { # back-calculate unix time give the form input my $bt = timelocal(0,$p{smin},$p{shour},$p{sday},$p{smonth}-1,$p{syear}-1900); my $et = timelocal(0,$p{emin},$p{ehour},$p{eday},$p{emonth}-1,$p{eyear}-1900); # pretty-print the form input my $bt_str = localtime($bt); my $et_str = localtime($et); # print out the data that we know print table({-border=>0}, Tr( [ td( [i("Device"), "$router ($p{rid})", ] ), td( [i("Interface"), "$name ($iid[0])", ] ), td( [i("Speed"), "$speed", ] ), td( [i("Description"), "$description", ] ), td( [i("Period"), "$bt_str - $et_str", ] ), ] ), ); # collect the args for rtgplot my $args; # the basics - input/output router tables, start/end times, units, mutliplication factor $args = "t1=ifInOctets_$p{rid}&t2=ifOutOctets_$p{rid}&begin=$bt&end=$et&units=bits/s&factor=8"; # add each interface id we're interested in foreach (@iid) { my $value = $_; $args .= "&iid=$value"; } # all the other aspects in the form if ($p{scalex}) { $args .= "&scalex=yes" }; if ($p{scaley}) { $args .= "&scaley=yes" }; if ($p{xplot}) { $args .= "&xplot=$p{xplot}" }; if ($p{yplot}) { $args .= "&yplot=$p{yplot}" }; if ($p{borderb}) { $args .= "&borderb=$p{borderb}" }; if ($p{aggr}) { $args .= "&aggr=yes" }; if ($p{percentile}) { $args .= "&percentile=$p{nth}" }; # ... and finally the image print img {src=>"rtgplot.cgi?$args"}; # the basics - input/output unicast router tables, start/end times, units, mutliplication factor $args = "t1=ifInUcastPkts_$p{rid}&t2=ifOutUcastPkts_$p{rid}&begin=$bt&end=$et&units=bits/s&factor=8"; # add each interface id we're interested in foreach (@iid) { my $value = $_; $args .= "&iid=$value"; } # all the other aspects in the form if ($p{scalex}) { $args .= "&scalex=yes" }; if ($p{scaley}) { $args .= "&scaley=yes" }; if ($p{xplot}) { $args .= "&xplot=$p{xplot}" }; if ($p{yplot}) { $args .= "&yplot=$p{yplot}" }; if ($p{borderb}) { $args .= "&borderb=$p{borderb}" }; if ($p{aggr}) { $args .= "&aggr=yes" }; if ($p{percentile}) { $args .= "&percentile=$p{nth}" }; # ... and finally the image print img {src=>"rtgplot.cgi?$args"}; } # clean up database handle, incase this gets mod_perl'd in the future $dbh->disconnect; # clean up form/HTML print br,submit(-value=>'Ok'), br; print end_form; print a({-href=>"http://rtg.sourceforge.net/"},'RTG') . "Version $VERSION"; print end_html;