| #!/usr/bin/perl |
| #!/usr/bin/perl -w |
| |
| require 5; |
| |
| # attempt to determine if they have the proper modules installed. |
| |
| # SNMP |
| my $havesnmp = eval {require SNMP;}; |
| |
| # the Tk packages |
| |
| my $havetk = eval {require Tk; |
| require Tk::Table; |
| require Tk::HList; |
| require Tk::FileSelect; |
| require Tk::Dialog;}; |
| if (!$havesnmp) { |
| print " |
| ERROR: You don't have the SNMP perl module installed. Please obtain this by |
| getting the latest source release of the net-snmp toolkit from |
| http://www.net-snmp.org/download/ . The perl module is contained in |
| the perl/SNMP directory. See the INSTALL file there for |
| instructions. |
| "; |
| } |
| |
| if (!$havetk) { |
| print " |
| ERROR: You don't have the Tk module installed. You should be able to |
| install this by running (as root): |
| |
| perl -MCPAN -e 'install Tk' |
| "; |
| } |
| |
| if (!$havetk || !$havesnmp) { |
| print "\n"; |
| exit; |
| } |
| |
| if ($havetk) { |
| # Tk doesn't seem to like require so we force use here. |
| eval {import Tk; |
| import Tk::Table; |
| import Tk::HList; |
| import Tk::FileSelect; |
| import Tk::Dialog; |
| import SNMP;}; |
| } |
| |
| use Getopt::Std; |
| use Data::Dumper; |
| |
| $host = 'localhost'; |
| $OID = '.1.3.6.1'; |
| $opts{'f'} = $ENV{'HOME'} . "/.snmp/tkmibrc"; |
| |
| getopts("hp:v:a:A:x:X:n:u:l:r:t:o:c:Cf:", \%opts); |
| |
| # default session options |
| print "setting opts\n"; |
| %session_opts = ( |
| 'Community' => "public", |
| 'RemotePort' => 161, |
| 'Timeout' => 5000000, |
| 'Retries' => 5, |
| 'Version' => 1, |
| 'AuthProto' => 'MD5', |
| 'PrivProto' => 'DES', |
| 'AuthPass' => '', |
| 'PrivPass' => '', |
| 'Context' => '', |
| 'SecName' => 'initial', |
| 'SecLevel' => 'authNoPriv', |
| ); |
| |
| sub usage { |
| print " |
| tkmib [-C] [-o OID] [SNMPCMD arguments] [host] |
| -f CONFIG_FILE load CONFIG_FILE after starting up. (default: ~/.snmp/tkmibrc) |
| (use -f /dev/null to not read one). |
| |
| See the snmpcmd manual page for related SNMPCMD arguments. (Not all |
| options are currently supported.) |
| "; |
| exit(); |
| } |
| |
| usage() if ($opts{'h'}); |
| |
| # initialize defaults, may be overridden by config file below |
| @displayInfo=qw(type access status units hint moduleID enums indexes); |
| @saveoptions = ('displayoidas', 'writecolor', 'graphtime', 'graphdelta'); |
| $displayoidas='full'; |
| $writecolor = "blue"; |
| $graphtime=5; |
| $graphdelta=1; |
| foreach $i (@displayInfo) { |
| $displayInfoStates{$i} = 1; |
| } |
| |
| |
| # source config file |
| do $opts{'f'} if ($opts{'f'} && -f $opts{'f'}); |
| |
| $session_opts{'UseLongNames'} => 1; |
| $session_opts{'RemotePort'} = $opts{'p'} if ($opts{'p'}); |
| $session_opts{'Community'} = $opts{'c'} if ($opts{'c'}); |
| $session_opts{'Version'} = $opts{'v'} if ($opts{'v'}); |
| $session_opts{'AuthProto'} = $opts{'a'} if ($opts{'a'}); |
| $session_opts{'AuthPass'} = $opts{'A'} if ($opts{'A'}); |
| $session_opts{'PrivProto'} = $opts{'x'} if ($opts{'x'}); |
| $session_opts{'PrivPass'} = $opts{'X'} if ($opts{'X'}); |
| $session_opts{'Context'} = $opts{'n'} if ($opts{'n'}); |
| $session_opts{'SecName'} = $opts{'u'} if ($opts{'u'}); |
| $session_opts{'SecLevel'} = $opts{'l'} if ($opts{'l'}); |
| $session_opts{'Retries'} = $opts{'r'} if ($opts{'r'}); |
| $session_opts{'Timeout'} = $opts{'t'} if ($opts{'t'}); |
| |
| $host = shift if ($#ARGV > -1); |
| $session_opts{'Community'} = shift if ($#ARGV > -1); |
| |
| @graphcolors=qw(blue red green yellow purple); |
| |
| # initialize SNMP module |
| $SNMP::save_descriptions=1; |
| $SNMP::use_long_names=1; |
| $SNMP::use_enums=1; |
| $SNMP::verbose = 1; |
| my $tmpbd = 1; |
| |
| $top = MainWindow->new(); |
| $top->title("tkmib"); |
| |
| #Menus |
| $MenuFrame = $top->Frame(-relief => "raised",-borderwidth => 2); |
| $MenuFrame->pack(-fill => "x",-expand => 1); |
| $FileMenuBut = $MenuFrame->Menubutton(-pady => $tmpbd, -padx => $tmpbd, -text => "File", |
| -menuitems => |
| [ |
| # [Button => "Save Output", -command => [\&saveOutput]], |
| [Button => "Quit", -command => [\&exit]] |
| ]); |
| $FileMenuBut->pack(-side => 'left'); |
| |
| $MibMenuBut = $MenuFrame->Menubutton(-pady => $tmpbd, -padx => $tmpbd, -text => "Mib", |
| -menuitems => |
| [[Button => "Find a mib node", |
| -command => sub { my $var; |
| entryBox("Find a Mib Node", |
| "Enter a mib node name to search for:", |
| \$var, \&findANode );}], |
| [Button => "Load a New Mib File", -command => [\&loadNewMibFile]], |
| [Button => "Load a New Mib Module", |
| -command => sub { my $var; |
| entryBox("Load a Module", |
| "Enter a SNMP MIB module name to load:", |
| \$var, \&loadIt);}] |
| ]); |
| $MibMenuBut->pack(-side => 'left'); |
| |
| $OptMenuBut = $MenuFrame->Menubutton(-pady => $tmpbd, -padx => $tmpbd, -text => "Options", |
| -menuitems => |
| [[Cascade => "~Display", -menuitems => |
| [ |
| [Cascade => "~MIB Information"], |
| [Cascade => "~OID Display", -menuitems => |
| [ |
| [Radiobutton => 'full', -variable => \$displayoidas], |
| [Radiobutton => 'numeric', -variable => \$displayoidas], |
| [Radiobutton => 'short', -variable => \$displayoidas], |
| [Radiobutton => 'module', -variable => \$displayoidas] |
| ] |
| ], |
| [Button => "Writable Color", |
| -command => [\&entryBox,"Writable Color", |
| "Color for writable objects:", |
| \$writecolor]] |
| ]], |
| [Cascade => "Use SNMP Version", -menuitems => |
| [ |
| [Radiobutton => '1', -variable => \$session_opts{'Version'}], |
| [Radiobutton => '2c', -variable => \$session_opts{'Version'}], |
| [Radiobutton => '3', -variable => \$session_opts{'Version'}] |
| ] |
| ], # ends version number specification |
| [Cascade => "SNMPv1/2c options", -menuitems => |
| [ |
| [Button => "Community Name", |
| -command => [\&entryBox,"Community Name", "Community name to use:", |
| \$session_opts{'Community'}]] |
| ] |
| ], |
| [Cascade => "SNMP3 options", -menuitems => |
| [ |
| [Button => "Security Name", |
| -command => [\&entryBox,"Security Name", "Security Name to use:", |
| \$session_opts{'SecName'}]], |
| [Cascade => "Security Level", -menuitems => |
| [ |
| [Radiobutton => 'noAuthNoPriv', |
| -variable => \$session_opts{'SecLevel'}], |
| [Radiobutton => 'authNoPriv', |
| -variable => \$session_opts{'SecLevel'}], |
| [Radiobutton => 'authPriv', |
| -variable => \$session_opts{'SecLevel'}] |
| ] |
| ], |
| [Button => "Authentication Passphrase", |
| -command => [\&entryBox,"Authentication Passphrase", |
| "Authentication Passphrase to use:", |
| \$session_opts{'AuthPass'}]], |
| [Cascade => "Authentication Type", -menuitems => |
| [ |
| [Radiobutton => 'MD5', |
| -variable => \$session_opts{'AuthProto'}], |
| [Radiobutton => 'SHA', |
| -variable => \$session_opts{'AuthProto'}], |
| ] |
| ], |
| [Button => "Privacy Passphrase", |
| -command => [\&entryBox,"Privacy Passphrase", |
| "Privacy Passphrase to use:", |
| \$session_opts{'PrivPass'}]], |
| [Cascade => "Privacy Type", -menuitems => |
| [ |
| [Radiobutton => 'DES', |
| -variable => \$session_opts{'PrivProto'}], |
| ] |
| ], |
| ] |
| ], |
| [Button => "Time between graph polls", |
| -command => sub { entryBox("graph polls", "Time between graph polls:", |
| \$graphtime);}], |
| [Button => "Port number", |
| -command => sub { entryBox("Port Number", "SNMP Port number to use:", |
| \$session_opts{'RemotePort'});}], |
| [Button => "TimeOut", |
| -command => sub { entryBox("Time Out", "Timeout for SNMP requests:", |
| \$session_opts{'Timeout'});}], |
| [Button => "Retries", |
| -command => sub { entryBox("Retries", |
| "Number of Times to Retransmit Requests:", |
| \$session_opts{'Retries'});}], |
| [Button => "Save Options", |
| -command => \&save_options] |
| ])->pack(-side => 'left'); |
| |
| $tmp = $OptMenuBut->cget(-menu); |
| $OptMenuWidgets = $tmp->entrycget("Display", -menu); |
| $OptMenuWidgets = $OptMenuWidgets->entrycget("MIB Information", -menu); |
| |
| $hlist=$top->Scrolled(qw(HList -itemtype imagetext -browsecmd main::showInfo |
| -command main::showChildren -width 80 -height 15)); |
| $hlist->pack(-side => 'top', -expand => 1, -fill => 'both'); |
| my $sFrame = $top->Frame(-relief => 'raised', -borderwidth => $tmpbd); |
| $sFrame->pack(-side => 'top', -fill => 'x'); |
| $sFrame->Label(-pady => $tmpbd, -padx => $tmpbd, -text => 'OID: ', -relief => 'raised', -borderwidth => $tmpbd) |
| ->pack(-side => 'left'); |
| $mibOID = $sFrame->Entry(-textvariable => \$OID, -relief => 'flat', -width => 40); |
| $mibOID->pack(-side => 'left'); |
| $mibTextOID = $sFrame->Label(-pady => $tmpbd, -padx => $tmpbd, -text => ''); |
| $mibTextOID->pack(-side => 'right'); |
| |
| $dispFrame=$top->Frame(-relief => 'raised', -borderwidth => $tmpbd); |
| $dispFrame->pack(-side => 'top', -fill =>'x'); |
| for($i=0;$i<= $#displayInfo;$i++) { |
| createRow($i) if ($displayInfoStates{$displayInfo[$i]}); |
| optionalWidget($i,$OptMenuWidgets, \$displayInfoStates{$displayInfo[$i]}); |
| } |
| |
| $descrFrame=$top->Frame(-relief => 'raised', -borderwidth => $tmpbd); |
| $descrFrame->pack(-side => 'top', -fill =>'x'); |
| $descrFrame->Label(-pady => $tmpbd, -padx => $tmpbd, -text => 'Description:', -anchor => 'w')->pack(-side => 'top', |
| -fill => 'x'); |
| $descr = $descrFrame->Scrolled(qw(Text -width 80 -height 4)); |
| $descr->pack(-side => 'top', -fill => 'x'); |
| |
| $bFrame = $top->Frame(-relief => 'raised', -borderwidth => $tmpbd); |
| $bFrame->pack(-side => 'top', -fill => 'x'); |
| $hostEntry = $bFrame->Entry(-textvariable => \$host, -width => 12); |
| $hostEntry->pack(-side => 'left'); |
| $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'graph', -command => \&snmpgraph)->pack(-side => 'right'); |
| $tablebutton = $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'table', -command => \&snmptable); |
| $tablebutton->pack(-side => 'right'); |
| $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'walk', -command => \&snmpwalk)->pack(-side => 'right'); |
| $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'getnext', -command => \&snmpgetnext)->pack(-side => 'right'); |
| $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'get', -command => \&snmpget)->pack(-side => 'right'); |
| $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'set', -command => [\&snmpsetbegin, 'OID'])->pack(-side => 'right'); |
| $stopBut = $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'stop', -command => sub { stop(1) }, |
| -state => 'disabled'); |
| $stopBut->pack(-side => 'right'); |
| $oFrame = $top->Frame(-borderwidth => $tmpbd, -relief => 'raised'); |
| $oFrame->pack(-side => 'top', -fill => 'both'); |
| $output = $oFrame->Scrolled(qw(Text -width 80 -height 14)); |
| $output->pack(-side => 'top', -fill => 'both', -expand => 1); |
| |
| $tmpFrame = $top->Frame(-relief => 'raised', -borderwidth => $tmpbd); |
| $tmpFrame->pack(-side => 'top', -fill => 'x'); |
| $tmpFrame->Label(-pady => $tmpbd, -padx => $tmpbd, -text => "Status: ", -anchor => 'w') |
| # -relief => 'raised', -borderwidth => $tmpbd) |
| ->pack(-side => 'left'); |
| $status = $tmpFrame->Label(-pady => $tmpbd, -padx => $tmpbd, -anchor => 'w'); |
| $status->pack(-side => 'left', -fill => 'x'); |
| |
| # initialize the browser |
| foreach $i (qw(.1 .1.3 .1.3.6 .1.3.6.1)) { |
| addMibOID($i); |
| } |
| showChildren("$OID"); |
| if (defined($opts{'o'})) { |
| findANode($opts{'o'}); |
| } |
| |
| MainLoop(); |
| |
| sub insertresult { |
| my $oid = shift; |
| my $val = shift; |
| $oid = $OID if ($oid eq "OID"); |
| $output->insert('end', $oid, "oid:$oid"); |
| $output->tagBind("oid:$oid", '<1>', [sub{shift; |
| my $oid = shift; |
| findANode($oid); |
| my $tag = SNMP::translateObj($oid); |
| showInfo($tag);},$oid]); |
| $output->insert('end', " = "); |
| my $mib = $SNMP::MIB{format_oid("$oid",'numeric')}; |
| $output->insert('end', $val, "value:$oid"); |
| if ($mib->{'access'} =~ /(Write|Create)/) { |
| $output->tagConfigure("value:$oid", -foreground => $writecolor); |
| $output->tagBind("value:$oid", '<1>', [sub{shift; |
| my $oid = shift; |
| my $value = shift; |
| snmpsetmaybebegin($oid, $value); |
| findANode($oid); |
| my $tag = SNMP::translateObj($oid); |
| showInfo($tag);},format_oid($oid,'full'), $val]); |
| } |
| $output->insert('end', "\n"); |
| } |
| |
| sub insertvar { |
| my $var = shift; |
| my $name = get_oid($var); |
| |
| insertresult($name,SNMP::Varbind::val($var)); |
| } |
| |
| sub snmpsetup { |
| my $oid = $OID; |
| my $tag = SNMP::translateObj($oid); |
| my $sess = new SNMP::Session(DestHost => $host, %session_opts); |
| my $var = new SNMP::Varbind([$oid]); |
| if (!defined($var)) { |
| print "ack: $@ $SNMP::ErrorStr $!\n"; |
| } |
| stop(0); |
| initText(); |
| $oid = "." . $oid if ($oid !~ /^\./); |
| return ($oid, $sess, $var); |
| } |
| |
| sub initText { |
| if (ref($output) eq "Tk::Frame" && defined($$output{'_#text'})) { |
| $output->delete('0.0','end'); |
| } else { |
| $output->destroy(); |
| $output = $oFrame->Scrolled(qw(Text -width 80 -height 14)); |
| $output->pack(-side => 'top', -fill => 'both', -expand => 1); |
| } |
| } |
| |
| sub initTable { |
| $output->destroy(); |
| $oFrame->packPropagate(0); |
| $output = $oFrame->Table(-columns => shift, -width => 80, -height => 14, |
| -fixedrows => 2, -fixedcolumns => 1); |
| $output->pack(-side => 'top', -fill => 'both', -expand => 1); |
| } |
| |
| sub initCanvas { |
| $output->destroy(); |
| $oFrame->packPropagate(0); |
| $output = $oFrame->Scrolled(qw(Canvas -width 80c -height 14c)); |
| $output->pack(-side => 'top', -fill => 'both', -expand => 1); |
| } |
| |
| sub snmpget { |
| (my $oid, my $sess, my $var) = snmpsetup(); |
| $status->configure(-text => "getting: $host $community $oid"); |
| $top->update(); |
| my $val = $sess->get($var); |
| if ($sess->{ErrorStr}) { |
| $status->configure(-text => $sess->{ErrorStr}); |
| } else { |
| insertvar($var); |
| $status->configure(-text => ""); |
| } |
| } |
| |
| sub snmpsetbegin { |
| my $startoid = shift; |
| my $startval = shift; |
| my $setwin = MainWindow->new(); |
| $setwin->title("SNMP set"); |
| my $varswin = $setwin->Frame(-relief => "raised",-borderwidth => $tmpbd); |
| my $vars = new SNMP::VarList; |
| $varswin->pack(-side => 'top'); |
| my $buttons = $setwin->Frame(-relief => "raised")->pack(-side => 'top', -fill => "x",-expand => 1); |
| $buttons->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'Add a varbind', -command => [\&snmpsetbegin_addvar, $vars, $varswin, 'OID'])->pack(-side => 'left', -fill => "x",-expand => 1); |
| $buttons->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'perform set', -command => [\&snmpsetbegin_ok, $vars, $setwin, $varswin])->pack(-side => 'left'); |
| $buttons->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'Cancel', -command => [sub { my $widget = shift; $varswin = shift; if ($setmain == $varswin) { $setmain = undef; } $widget->destroy();}, $setwin, $varswin])->pack(-side => 'right'); |
| if ($startoid ne "") { |
| snmpsetbegin_addvar($vars, $varswin, $startoid, $startval); |
| } |
| if (!$setmain) { |
| $setmain = $varswin; |
| $setvars = $vars; |
| } |
| } |
| |
| sub make_enum_button { |
| my $win = shift; |
| my $var = shift; |
| my @objs; |
| foreach my $i (@_) { |
| push @objs,[Radiobutton => $i, -variable => $var]; |
| } |
| return $win->Menubutton(-pady => $tmpbd, -padx => $tmpbd, -textvariable => $var, |
| -relief => raised, |
| -menuitems => \@objs); |
| } |
| |
| sub snmpsetmaybebegin { |
| my ($oid, $val) = @_; |
| if ($setmain) { |
| snmpsetbegin_addvar($setvars, $setmain, $oid, $val); |
| } else { |
| snmpsetbegin($oid, $val); |
| } |
| } |
| |
| |
| sub snmpsetbegin_addvar { |
| my ($vars, $place, $oid, $val) = @_; |
| $oid = $OID if ($oid eq "OID"); |
| my $mib = $SNMP::MIB{format_oid("$oid",'numeric')}; |
| my $var = new SNMP::Varbind([$oid, '', $val, $mib->{'type'} || 'INTEGER']); |
| push @$vars,$var; |
| my $frame = $place->Frame(); |
| $frame->Entry(-textvariable => \$var->[0], -width => 20)->pack(-side => 'left'); |
| make_enum_button($frame, \$var->[3], qw(OBJECTID OCTETSTR INTEGER NETADDR IPADDR COUNTER COUNTER64 GAUGE UINTEGER TICKS OPAQUE NULL))->pack(-side => 'left'); |
| if (ref($mib->{'enums'}) eq HASH && scalar(keys(%{$mib->{'enums'}})) > 0) { |
| make_enum_button($frame, \$var->[2], keys(%{$mib->{'enums'}}))->pack(-side => 'left'); |
| } else { |
| $frame->Entry(-textvariable => \$var->[2])->pack(-side => 'left'); |
| } |
| $frame->pack(-expand => 1, -fill => 'x'); |
| } |
| |
| sub snmpsetbegin_ok { |
| my ($vars, $win, $frame) = @_; |
| snmpset($vars); |
| $setmain = undef if ($setmain == $frame); |
| $win->destroy(); |
| } |
| |
| sub snmpset { |
| my $vars = shift; |
| (my $oid, my $sess, my $var) = snmpsetup(); |
| $status->configure(-text => "setting: $host -> " . Dumper($vars) . "\n"); |
| $top->update(); |
| my $val = $sess->set($vars); |
| if ($sess->{ErrorStr}) { |
| $output->insert('end', "Set failed.\nReason: $sess->{ErrorStr}"); |
| $status->configure(-text => $sess->{ErrorStr}); |
| } else { |
| foreach my $i (@$vars) { |
| insertvar($i); |
| } |
| $status->configure(-text => ""); |
| } |
| } |
| |
| sub snmpgetnext { |
| (my $oid, my $sess, my $var) = snmpsetup(); |
| $status->configure(-text => "get next: $host $community $oid"); |
| $top->update(); |
| my $val = $sess->getnext($var); |
| if ($sess->{ErrorStr}) { |
| $status->configure(-text => $sess->{ErrorStr}); |
| } else { |
| insertvar($var); |
| $status->configure(-text => ""); |
| } |
| } |
| |
| sub snmpwalk { |
| (my $oid, my $sess, my $var) = snmpsetup(); |
| $status->configure(-text => "walking: $host $community $oid"); |
| $top->update(); |
| while (!$sess->{ErrorStr} && !$stopit) { |
| my $val = $sess->getnext($var); |
| last if (!defined($var->tag) || |
| $sess->{ErrorStr} || |
| $val eq "ENDOFMIBVIEW" || |
| !is_in_subtree($oid, $var->tag . "." . $var->iid)); |
| insertvar($var); |
| $top->update(); |
| } |
| if ($sess->{ErrorStr}) { |
| $status->configure(-text => $sess->{ErrorStr}); |
| $output->insert('end',"$sess->{ErrorStr} ($sess->{ErrorNum})\n"); |
| } else { |
| $status->configure(-text => ""); |
| } |
| stop(1); |
| } |
| |
| sub snmptable { |
| (my $oid, my $sess, my $var) = snmpsetup(); |
| $status->configure(-text => "collecting data: $host $community $oid"); |
| $top->update(); |
| my (%tb, @tags, @index, %tboids); |
| while (!$sess->{ErrorStr} && !$stopit) { |
| my $val = $sess->getnext($var); |
| last if (!defined($var->tag) || |
| $sess->{ErrorStr} || |
| $val eq "ENDOFMIBVIEW" || |
| !is_in_subtree($oid, $var->tag . "." . $var->iid)); |
| $newoid = SNMP::Varbind::tag($var).".".SNMP::Varbind::iid($var); |
| insertvar($var); |
| $top->update(); |
| $newoid =~ /([^\.]+)\.([0-9\.]+)$/; |
| if (!grep(/$1/,@tags)) { |
| push @tags,$1; |
| } |
| if (!grep(/$2/,@index)) { |
| push @index,$2; |
| } |
| $tb{$2}{$1} = $var->val; |
| # $tboids{$2}{$1} = $var->tag; |
| $tboids{$2}{$1} = $newoid; |
| } |
| initTable($#tags+1); |
| for(my $k=0;$k <= $#tags;$k++) { |
| $output->put(1,$k+2,$tags[$k]); |
| } |
| $output->put(1,1,"Index"); |
| for(my $i=0;$i <= $#index;$i++) { |
| $output->put($i+2,1,$index[$i]); |
| } |
| for(my $i=0;$i <= $#index; $i++) { |
| for(my $k=0;$k <= $#tags;$k++) { |
| my $mib = $SNMP::MIB{format_oid("$tboids{$index[$i]}{$tags[$k]}",'numeric')}; |
| if ($mib->{'access'} =~ /(Write|Create)/) { |
| $output->put($i+2,$k+2,$output->Button(-fg => $writecolor, -pady => $tmpbd, -padx => $tmpbd, -text => $tb{$index[$i]}{$tags[$k]}, -command => [\&snmpsetmaybebegin, $tboids{$index[$i]}{$tags[$k]}, $tb{$index[$i]}{$tags[$k]}], -padx => 0, -pady => 0)); |
| } else { |
| $output->put($i+2,$k+2,$tb{$index[$i]}{$tags[$k]}); |
| } |
| } |
| } |
| $status->configure(-text => ""); |
| stop(1); |
| } |
| |
| sub snmpgraph { |
| ($graphoid, $graphsess, my $graphvar) = snmpsetup(); |
| $top->update(); |
| %graphtb = (); |
| @graphvars = (); |
| initCanvas(); |
| $gcount=0; |
| $max=-1; |
| $min=2**32-1; |
| updateGraph(); |
| $output->repeat($graphtime*1000, \&updateGraph); |
| } |
| |
| sub updateGraph() { |
| $status->configure(-text => "collecting data: $host $community $graphoid"); |
| my $oid = $graphoid; |
| my $tag = SNMP::translateObj($graphoid,0); |
| my $var = new SNMP::Varbind([$oid]); |
| $graphsess->{ErrorStr} = ""; |
| while (!$graphsess->{ErrorStr} && !$stopit) { |
| my $val = $graphsess->getnext($var); |
| if ($#graphvars == -1 && SNMP::translateObj($var->tag) !~ /^$oid/) { |
| # if an exact oid, do a get instead. |
| $var = new SNMP::Varbind([$oid]); |
| $val = $graphsess->get($var); |
| } |
| if ($graphsess->{ErrorStr} || |
| !defined($var->tag) || |
| SNMP::translateObj($var->tag) !~ /^$oid/) { |
| last; |
| } |
| my $newoid = SNMP::translateObj(SNMP::Varbind::tag($var).".".SNMP::Varbind::iid($var)); |
| $top->update(); |
| $newoid =~ /$oid\.([0-9\.]+)$/; |
| if (defined($1)) { |
| if (!grep(/$1/,@graphvars)) { |
| push @graphvars,$1; |
| } |
| if ($graphdelta) { |
| if ($gcount > 0) { |
| $graphtb{$1}[$gcount-1] = $var->val - $prev{$1}; |
| } |
| $prev{$1} = $var->val; |
| } else { |
| $graphtb{$1}[$gcount] = $var->val; |
| } |
| $max = $graphtb{$1}[$#{$graphtb{$1}}] |
| if ($#{$graphtb{$1}} >= 0 && |
| $graphtb{$1}[$#{$graphtb{$1}}] > $max); |
| $min = $graphtb{$1}[$#{$graphtb{$1}}] |
| if ($#{$graphtb{$1}} >= 0 && |
| $graphtb{$1}[$#{$graphtb{$1}}] < $min); |
| } |
| } |
| if ($gcount > 1) { |
| $output->delete('all'); |
| my $canvas = $$output{'SubWidget'}{'canvas'}; |
| my $h=$canvas->cget(-height); |
| foreach $i (@graphvars) { |
| my @a = (); |
| for(my $j=0; $j <= $#{$graphtb{$i}}; $j++) { |
| $a[$j*2] = $j; |
| $a[$j*2+1] = $h-(($h-3)*($graphtb{$i}[$j]-$min))/($max-$min)-3; |
| } |
| $output->createLine(@a, -fill => $graphcolors[$i%$#graphcolors]); |
| } |
| $output->create('text',5, $h-3, -text => "$max"); |
| $output->create('text',5, 3, -text => "$min"); |
| } |
| $gcount++; |
| $status->configure(-text => "sleeping for $graphtime seconds"); |
| } |
| |
| sub addMibOID { |
| my $i = shift; |
| $i = ".$i" if ($i !~ /^\./); |
| my $name = SNMP::translateObj($i,1); |
| if (defined($name)) { |
| $name =~ s/.*\.([^.]+)$/$1/; |
| } else { |
| return; |
| } |
| $i =~ s/^\.//; |
| $hlist->add($i, -text => $name); |
| } |
| |
| sub showInfo { |
| my $full = shift; |
| $full = ".$full" if ($full !~ /^\./); |
| my $oid = $full; |
| my $tag = $oid; |
| |
| if ($tag =~ /^[.0-9]+$/) { |
| # strip off index in case there is one |
| $tag = SNMP::translateObj("$oid"); |
| $tag = ".iso.org.dod.internet.private.$tag" if $tag =~ /^enterprises/; |
| } else { |
| $full = SNMP::translateObj("$oid"); |
| } |
| |
| $tag =~ s/\.[.0-9]+$//; |
| $oid = SNMP::translateObj($tag); |
| |
| if (!defined($last) || "$last" ne $oid) { |
| updateInfo($oid); |
| } |
| $OID = $full; |
| $mibOID->configure(-textvariable => \$OID); |
| $mibOID->update(); |
| $last = $oid; |
| } |
| |
| sub showAllChildren { |
| my $id = shift; |
| $id =~ s/^\.//; |
| my @pieces = split(/\./,$id); |
| my ($i, $lastvalid); |
| for($i = 0; $i <= $#pieces; $i++) { |
| my $a = join(".", @pieces[0..$i]); |
| if ($hlist->infoExists($a) && !($hlist->infoChildren($a))) { |
| showChildren(join(".", $a)); |
| } |
| if ($hlist->infoExists($a)) { |
| $lastvalid = $a; |
| } else { |
| last; |
| } |
| } |
| $hlist->see($lastvalid); |
| $hlist->selectionClear($hlist->selectionGet); |
| $hlist->selectionSet($lastvalid); |
| } |
| |
| sub showChildren { |
| $OID = shift; |
| $OID =~ s/^\.//; |
| my $oid = $OID; |
| $mibOID->configure(-textvariable => \$OID); |
| if ($hlist->infoChildren($oid)) { |
| my @a = $hlist->infoChildren($oid); |
| my $i; |
| foreach $i (@a) { |
| $hlist->deleteEntry($i); |
| } |
| } else { |
| $oid = ".$oid"; |
| my $mib = $SNMP::MIB{format_oid($oid,'full')}; |
| if (defined($mib)) { |
| my $children = $$mib{'children'}; |
| if (ref($children) eq "ARRAY") { |
| foreach $i (sort {$$a{'subID'} <=> $$b{'subID'}} @{$children}) { |
| addMibOID($$i{'objectID'}); |
| } |
| } else { |
| $status->configure(-text => SNMP::translateObj($oid,1) . |
| " has no children"); |
| return; |
| } |
| } |
| } |
| $status->configure(-text => ""); |
| } |
| |
| sub updateInfo { |
| $OID = shift; |
| my $oid = $OID; |
| my $mib = $SNMP::MIB{format_oid("$oid",'numeric')}; |
| if (!defined($mib->{'description'}) || $mib->{'description'} eq "") { |
| $oid =~ s/[.0-9]+$//; |
| $mib = $SNMP::MIB{format_oid("$oid",'numeric')}; |
| } |
| if (defined($mib)) { |
| if ($mib->{'label'} =~ /Table$/) { |
| $tablebutton->configure(-state => 'normal'); |
| } else { |
| $tablebutton->configure(-state => 'disabled'); |
| } |
| $mibOID->configure(-text => $mib->{'objectID'}); |
| $mibTextOID->configure(-text => |
| SNMP::translateObj($mib->{'objectID'},1)); |
| $descr->delete('0.0','end'); |
| if (defined($mib->{'description'}) && |
| $mib->{'description'} ne "") { |
| my $desc = $mib->{'description'}; |
| $desc =~ s/\n[ \t]+/\n/g; |
| $desc =~ s/^\n//; |
| $descr->insert('end',$desc); |
| } |
| for($i=0; $i<= $#displayInfo;$i++) { |
| $dpyInfo[$i] = $mib->{$displayInfo[$i]}; |
| if (ref($dpyInfo[$i]) eq HASH) { |
| my %hash = %{$dpyInfo[$i]}; |
| $dpyInfo[$i] = ""; |
| foreach $j (sort { $hash{$a} <=> $hash{$b} } keys(%hash)) { |
| $dpyInfo[$i] .= "$j = $hash{$j},"; |
| } |
| } elsif (ref($dpyInfo[$i]) eq ARRAY) { |
| $dpyInfo[$i] = join(", ", @{$dpyInfo[$i]}); |
| } |
| } |
| } |
| } |
| |
| sub optionalWidget { |
| my $num = shift; |
| my $menu = shift; |
| my $var = shift; |
| $menu->checkbutton(-label => $displayInfo[$num], |
| -variable => $var, |
| -command => [\&toggleWidgetShown, $num, $var]); |
| } |
| |
| sub createRow { |
| my $i = shift; |
| if (!$displayLabels[$i]) { |
| $displayLabels[$i] = $dispFrame->Label(-pady => $tmpbd, -padx => $tmpbd, |
| -text => $displayInfo[$i], |
| -anchor => 'w', |
| -borderwidth => $tmpbd); |
| } |
| if (!$displayEntries[$i]) { |
| $displayEntries[$i] = $dispFrame->Entry(-textvariable => \$dpyInfo[$i], |
| -width => 40, -relief => 'flat', |
| -borderwidth => $tmpbd); |
| } |
| $displayLabels[$i]->grid(-ipady => $tmpbd, -ipadx => $tmpbd, |
| -column => ($i%2)*2, -row => int($i/2), |
| -sticky => 'w'); |
| $dpyInfo[$i] = "" if (!defined($dpyInfo[$i])); |
| $displayEntries[$i]->grid(-ipady => $tmpbd, -ipadx => $tmpbd, -column => ($i%2)*2 + 1, -row => int($i/2), -sticky => 'w'); |
| } |
| |
| sub toggleWidgetShown { |
| my ($num, $var) = @_; |
| if ($$var) { |
| createRow($num); |
| } else { |
| $displayLabels[$num]->gridForget(); |
| $displayEntries[$num]->gridForget() |
| } |
| # my @widgets = $dispFrame->gridSlaves(-row => $num); |
| } |
| |
| sub loadNewMibFile { |
| my $sel = $top->FileSelect(); |
| my $file = $sel->Show(); |
| if (defined($file)) { |
| SNMP::addMibFiles($file); |
| showChildren("1.3.6.1"); |
| showChildren("1.3.6.1"); |
| } |
| } |
| |
| sub loadNewMibModule { |
| my $tmptop = MainWindow->new(); |
| my $var = ""; |
| $tmptop->Label(-pady => $tmpbd, -padx => $tmpbd, -text => "Enter a SNMP MIB module name") |
| ->pack(-side => 'top'); |
| my $e = $tmptop->Entry(-textvariable => \$var); |
| $e->pack(-side => 'top'); |
| $e->bind('<Return>',[\&loadIt,\$var,$tmptop]); |
| my $f = $tmptop->Frame(); |
| $f->pack(-side => 'top'); |
| $f->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'Ok', -command => [\&loadIt,"",\$var,$tmptop]) |
| ->pack(-side => 'left'); |
| $f->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'Cancel', -command => [sub { my $wid = shift; |
| $wid->destroy(); }, |
| $tmptop]) |
| ->pack(-side => 'left'); |
| } |
| |
| sub loadIt { |
| my $var = shift; |
| if ($var ne "") { |
| my $ret = SNMP::loadModules($var); |
| if ($ret) { |
| showChildren("1.3.6.1"); |
| showChildren("1.3.6.1"); |
| return 1; |
| } else { |
| $status->configure(-text => "Failed reading module $var"); |
| return 0; |
| } |
| } |
| return 0; |
| } |
| |
| sub stop { |
| $stopit = shift; |
| if ($stopit) { |
| $stopBut->configure(-state => 'disabled'); |
| } else { |
| $stopBut->configure(-state => 'normal'); |
| } |
| } |
| |
| sub entryBox { |
| my $title = shift; |
| my $text = shift; |
| my $var = shift; |
| my $callback = shift; |
| my $top = MainWindow->new(); |
| my $newvar = $$var if defined($var); |
| $top->title($title); |
| my $f = $top->Frame(); |
| $f->pack(-side => 'top'); |
| $f->Label(-pady => $tmpbd, -padx => $tmpbd, |
| -text => $text)->pack(-side => 'left'); |
| my $e = $f->Entry(-textvariable => \$newvar); |
| $e->pack(-side => 'left'); |
| $f = $top->Frame(); |
| $f->pack(-side => 'bottom'); |
| my $b = $f->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'Ok', |
| -command => [sub { my $w = shift; |
| my $v1 = shift; |
| my $v2 = shift; |
| my $call = shift; |
| my $ret = 1; |
| $$v1 = $$v2 if defined($v1); |
| $ret = $call->($$v2) |
| if defined($call); |
| $w->destroy() if ($ret);}, $top, $var, |
| \$newvar, $callback]); |
| $b->pack(-side => 'left'); |
| $e->bind('<Return>',[$b,'invoke']); |
| $b = $f->Button(-pady => $tmpbd, -padx => $tmpbd, |
| -text => 'Cancel', -command => [sub { my $w = shift; |
| $w->destroy();}, $top |
| ]); |
| $b->pack(-side => 'right'); |
| $e->bind('<Escape>',[$b,'invoke']); |
| |
| } |
| |
| sub findANode { |
| my $val = shift; |
| my $tag = SNMP::translateObj($val); |
| if ($tag) { |
| showAllChildren($tag); |
| return 1; |
| } else { |
| $top->Dialog(-text => "$val not found")->Show(); |
| return 0; |
| } |
| } |
| |
| sub test_version { |
| my ($gt, $major, $minor, $sub) = @_; |
| $SNMP::VERSION =~ /(\d)\.(\d).(\d)/; |
| if ($gt) { |
| if ($1 > $major || ($1 == $major && $2 > $minor) || |
| ($1 == $major && $2 == $minor && $3 >= $sub)) { |
| return 1; |
| } |
| } else { |
| if ($1 < $major || ($1 == $major && $2 < $minor) || ($1 == $major && $2 == $minor && $3 < $sub)) { |
| return 1; |
| } |
| } |
| return 0; |
| } |
| |
| sub save_options { |
| my $umask = umask(); |
| umask 0077; # make sure its not readable by the world by default. |
| if (!open(O,">$opts{'f'}")) { |
| warn "can't save to $opts{'f'}\n"; |
| umask $umask; |
| return; |
| } |
| umask $umask; |
| print O Data::Dumper->Dump([\%session_opts], [qw(*session_opts)]); |
| print O Data::Dumper->Dump([\%displayInfoStates], [qw(*displayInfoStates)]); |
| foreach my $var (@saveoptions) { |
| print O Data::Dumper->Dump([$$var], [$var]); |
| } |
| close(O); |
| $status->configure(-text => "saved options to $opts{'f'}"); |
| } |
| |
| # returns 1 if $oid2 is below $oid1 in the hierarchy |
| sub is_in_subtree { |
| my ($oid1, $oid2) = @_; |
| # get pure numeric |
| $oid1 = SNMP::translateObj($oid1) if ($oid1 !~ /^[\d\.]*$/); |
| $oid2 = SNMP::translateObj($oid2) if ($oid2 !~ /^[\d\.]*$/); |
| |
| # has more on it or is exactly the same |
| return 1 if ($oid2 =~ /^$oid1\./ || $oid2 =~ /^$oid1$/); |
| return 0; |
| } |
| |
| sub format_oid { |
| my ($oid, $type) = @_; |
| $oid =~ s/\.$//; |
| $type = $displayoidas if ($type eq ""); |
| |
| if ($type eq 'numeric') { |
| return SNMP::translateObj($oid) if ($oid !~ /^[\d\.]*$/); |
| return $oid; |
| } elsif ($type eq 'full') { |
| return SNMP::translateObj($oid, 1) if ($oid =~ /^[\d\.]*$/); |
| return SNMP::translateObj(SNMP::translateObj($oid), 1) if ($oid !~ /^\./); |
| return $oid; |
| } elsif ($type eq 'short' || $type eq 'module') { |
| $oid = SNMP::translateObj($oid) if ($oid =~ /^[\d\.]*$/); |
| $oid =~ s/.*\.([a-zA-Z]\w+)\.(.*)/$1.$2/; |
| if ($type eq 'module') { |
| $oid = $SNMP::MIB{format_oid($oid,'numeric')}->{'moduleID'} . "::" . $oid; |
| } |
| return $oid; |
| } elsif ($type eq 'module') { |
| $oid = SNMP::translateObj($oid) if ($oid =~ /^[\d\.]*$/); |
| $oid =~ s/.*\.([a-zA-Z]\w+)\.(.*)/$1.$2/; |
| return $oid; |
| } else { |
| warn 'unknown oid translation type: $type'; |
| return $oid; |
| } |
| } |
| |
| sub get_oid { |
| my ($var, $type) = @_; |
| return format_oid($var->tag . "." . $var->iid, $type); |
| } |