6 # attempt to determine if they have the proper modules installed.
9 my $havesnmp = eval {require SNMP;};
13 my $havetk = eval {require Tk;
16 require Tk::FileSelect;
20 ERROR: You don't have the SNMP perl module installed. Please obtain this by
21 getting the latest source release of the net-snmp toolkit from
22 http://www.net-snmp.org/download/ . The perl module is contained in
23 the perl/SNMP directory. See the INSTALL file there for
30 ERROR: You don't have the Tk module installed. You should be able to
31 install this by running (as root):
33 perl -MCPAN -e 'install Tk'
37 if (!$havetk || !$havesnmp) {
43 # Tk doesn't seem to like require so we force use here.
47 import Tk::FileSelect;
57 $opts{'C'}=$ENV{'HOME'} . "/.snmp/tkmibrc";
59 # default session options
60 if (test_version(1,5,0,0)) {
61 print "setting opts\n";
78 getopts("hp:v:a:A:x:X:n:u:l:r:t:o:c:C", \%opts);
82 tkmib [-C] [-o OID] [SNMPCMD arguments] [host]
83 -C CONFIG_FILE load CONFIG_FILE after starting up. (default: ~/.snmp/tkmibrc)
84 (use -C /dev/null to not read one).
86 See the snmpcmd manual page for related SNMPCMD arguments. (Not all
87 options are currently supported.)
92 usage() if ($opts{'h'});
94 # initialize defaults, may be overridden by config file below
95 @displayInfo=qw(type access status units hint moduleID enums indexes);
96 @saveoptions = ('displayoidas', 'writecolor', 'graphtime', 'graphdelta');
101 foreach $i (@displayInfo) {
102 $displayInfoStates{$i} = 1;
107 do $opts{'C'} if ($opts{'C'} && -f $opts{'C'});
109 $session_opts{'UseLongNames'} => 1;
110 $session_opts{'RemotePort'} = $opts{'p'} if ($opts{'p'});
111 $session_opts{'Community'} = $opts{'c'} if ($opts{'c'});
112 $session_opts{'Version'} = $opts{'v'} if ($opts{'v'});
113 $session_opts{'AuthProto'} = $opts{'a'} if ($opts{'a'});
114 $session_opts{'AuthPass'} = $opts{'A'} if ($opts{'A'});
115 $session_opts{'PrivProto'} = $opts{'x'} if ($opts{'x'});
116 $session_opts{'PrivPass'} = $opts{'X'} if ($opts{'X'});
117 $session_opts{'Context'} = $opts{'n'} if ($opts{'n'});
118 $session_opts{'SecName'} = $opts{'u'} if ($opts{'u'});
119 $session_opts{'SecLevel'} = $opts{'l'} if ($opts{'l'});
120 $session_opts{'Retries'} = $opts{'r'} if ($opts{'r'});
121 $session_opts{'Timeout'} = $opts{'t'} if ($opts{'t'});
123 $host = shift if ($#ARGV > -1);
124 $session_opts{'Community'} = shift if ($#ARGV > -1);
126 @graphcolors=qw(blue red green yellow purple);
128 # initialize SNMP module
129 $SNMP::save_descriptions=1;
130 $SNMP::use_long_names=1;
135 $top = MainWindow->new();
136 $top->title("tkmib");
139 $MenuFrame = $top->Frame(-relief => "raised",-borderwidth => 2);
140 $MenuFrame->pack(-fill => "x",-expand => 1);
141 $FileMenuBut = $MenuFrame->Menubutton(-pady => $tmpbd, -padx => $tmpbd, -text => "File",
144 # [Button => "Save Output", -command => [\&saveOutput]],
145 [Button => "Quit", -command => [\&exit]]
147 $FileMenuBut->pack(-side => 'left');
149 $MibMenuBut = $MenuFrame->Menubutton(-pady => $tmpbd, -padx => $tmpbd, -text => "Mib",
151 [[Button => "Find a mib node",
152 -command => sub { my $var;
153 entryBox("Find a Mib Node",
154 "Enter a mib node name to search for:",
155 \$var, \&findANode );}],
156 [Button => "Load a New Mib File", -command => [\&loadNewMibFile]],
157 [Button => "Load a New Mib Module",
158 -command => sub { my $var;
159 entryBox("Load a Module",
160 "Enter a SNMP MIB module name to load:",
163 $MibMenuBut->pack(-side => 'left');
165 $OptMenuBut = $MenuFrame->Menubutton(-pady => $tmpbd, -padx => $tmpbd, -text => "Options",
167 [[Cascade => "~Display", -menuitems =>
169 [Cascade => "~MIB Information"],
170 [Cascade => "~OID Display", -menuitems =>
172 [Radiobutton => 'full', -variable => \$displayoidas],
173 [Radiobutton => 'numeric', -variable => \$displayoidas],
174 [Radiobutton => 'short', -variable => \$displayoidas],
175 [Radiobutton => 'module', -variable => \$displayoidas]
178 [Button => "Writable Color",
179 -command => [\&entryBox,"Writable Color",
180 "Color for writable objects:",
183 [Cascade => "Use SNMP Version", -menuitems =>
185 [Radiobutton => '1', -variable => \$session_opts{'Version'}],
186 [Radiobutton => '2c', -variable => \$session_opts{'Version'}],
187 [Radiobutton => '3', -variable => \$session_opts{'Version'}]
189 ], # ends version number specification
190 [Cascade => "SNMPv1/2c options", -menuitems =>
192 [Button => "Community Name",
193 -command => [\&entryBox,"Community Name", "Community name to use:",
194 \$session_opts{'Community'}]]
197 [Cascade => "SNMP3 options", -menuitems =>
199 [Button => "Security Name",
200 -command => [\&entryBox,"Security Name", "Security Name to use:",
201 \$session_opts{'SecName'}]],
202 [Cascade => "Security Level", -menuitems =>
204 [Radiobutton => 'noAuthNoPriv',
205 -variable => \$session_opts{'SecLevel'}],
206 [Radiobutton => 'authNoPriv',
207 -variable => \$session_opts{'SecLevel'}],
208 [Radiobutton => 'authPriv',
209 -variable => \$session_opts{'SecLevel'}]
212 [Button => "Authentication Passphrase",
213 -command => [\&entryBox,"Authentication Passphrase",
214 "Authentication Passphrase to use:",
215 \$session_opts{'AuthPass'}]],
216 [Cascade => "Authentication Type", -menuitems =>
218 [Radiobutton => 'MD5',
219 -variable => \$session_opts{'AuthProto'}],
220 [Radiobutton => 'SHA',
221 -variable => \$session_opts{'AuthProto'}],
224 [Button => "Privacy Passphrase",
225 -command => [\&entryBox,"Privacy Passphrase",
226 "Privacy Passphrase to use:",
227 \$session_opts{'PrivPass'}]],
228 [Cascade => "Privacy Type", -menuitems =>
230 [Radiobutton => 'DES',
231 -variable => \$session_opts{'PrivProto'}],
236 [Button => "Time between graph polls",
237 -command => sub { entryBox("graph polls", "Time between graph polls:",
239 [Button => "Port number",
240 -command => sub { entryBox("Port Number", "SNMP Port number to use:",
241 \$session_opts{'RemotePort'});}],
242 [Button => "TimeOut",
243 -command => sub { entryBox("Time Out", "Timeout for SNMP requests:",
244 \$session_opts{'Timeout'});}],
245 [Button => "Retries",
246 -command => sub { entryBox("Retries",
247 "Number of Times to Retransmit Requests:",
248 \$session_opts{'Retries'});}],
249 [Button => "Save Options",
250 -command => \&save_options]
251 ])->pack(-side => 'left');
253 $tmp = $OptMenuBut->cget(-menu);
254 $OptMenuWidgets = $tmp->entrycget("Display", -menu);
255 $OptMenuWidgets = $OptMenuWidgets->entrycget("MIB Information", -menu);
257 $hlist=$top->Scrolled(qw(HList -itemtype imagetext -browsecmd main::showInfo
258 -command main::showChildren -width 80 -height 15));
259 $hlist->pack(-side => 'top', -expand => 1, -fill => 'both');
260 my $sFrame = $top->Frame(-relief => 'raised', -borderwidth => $tmpbd);
261 $sFrame->pack(-side => 'top', -fill => 'x');
262 $sFrame->Label(-pady => $tmpbd, -padx => $tmpbd, -text => 'OID: ', -relief => 'raised', -borderwidth => $tmpbd)
263 ->pack(-side => 'left');
264 $mibOID = $sFrame->Entry(-textvariable => \$OID, -relief => 'flat', -width => 40);
265 $mibOID->pack(-side => 'left');
266 $mibTextOID = $sFrame->Label(-pady => $tmpbd, -padx => $tmpbd, -text => '');
267 $mibTextOID->pack(-side => 'right');
269 $dispFrame=$top->Frame(-relief => 'raised', -borderwidth => $tmpbd);
270 $dispFrame->pack(-side => 'top', -fill =>'x');
271 for($i=0;$i<= $#displayInfo;$i++) {
272 createRow($i) if ($displayInfoStates{$displayInfo[$i]});
273 optionalWidget($i,$OptMenuWidgets, \$displayInfoStates{$displayInfo[$i]});
276 $descrFrame=$top->Frame(-relief => 'raised', -borderwidth => $tmpbd);
277 $descrFrame->pack(-side => 'top', -fill =>'x');
278 $descrFrame->Label(-pady => $tmpbd, -padx => $tmpbd, -text => 'Description:', -anchor => 'w')->pack(-side => 'top',
280 $descr = $descrFrame->Scrolled(qw(Text -width 80 -height 4));
281 $descr->pack(-side => 'top', -fill => 'x');
283 $bFrame = $top->Frame(-relief => 'raised', -borderwidth => $tmpbd);
284 $bFrame->pack(-side => 'top', -fill => 'x');
285 $hostEntry = $bFrame->Entry(-textvariable => \$host, -width => 12);
286 $hostEntry->pack(-side => 'left');
287 $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'graph', -command => \&snmpgraph)->pack(-side => 'right');
288 $tablebutton = $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'table', -command => \&snmptable);
289 $tablebutton->pack(-side => 'right');
290 $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'walk', -command => \&snmpwalk)->pack(-side => 'right');
291 $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'getnext', -command => \&snmpgetnext)->pack(-side => 'right');
292 $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'get', -command => \&snmpget)->pack(-side => 'right');
293 $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'set', -command => [\&snmpsetbegin, 'OID'])->pack(-side => 'right');
294 $stopBut = $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'stop', -command => sub { stop(1) },
295 -state => 'disabled');
296 $stopBut->pack(-side => 'right');
297 $oFrame = $top->Frame(-borderwidth => $tmpbd, -relief => 'raised');
298 $oFrame->pack(-side => 'top', -fill => 'both');
299 $output = $oFrame->Scrolled(qw(Text -width 80 -height 14));
300 $output->pack(-side => 'top', -fill => 'both', -expand => 1);
302 $tmpFrame = $top->Frame(-relief => 'raised', -borderwidth => $tmpbd);
303 $tmpFrame->pack(-side => 'top', -fill => 'x');
304 $tmpFrame->Label(-pady => $tmpbd, -padx => $tmpbd, -text => "Status: ", -anchor => 'w')
305 # -relief => 'raised', -borderwidth => $tmpbd)
306 ->pack(-side => 'left');
307 $status = $tmpFrame->Label(-pady => $tmpbd, -padx => $tmpbd, -anchor => 'w');
308 $status->pack(-side => 'left', -fill => 'x');
310 # initialize the browser
311 foreach $i (qw(.1 .1.3 .1.3.6 .1.3.6.1)) {
314 showChildren("$OID");
315 if (defined($opts{'o'})) {
316 findANode($opts{'o'});
324 $oid = $OID if ($oid eq "OID");
325 $output->insert('end', $oid, "oid:$oid");
326 $output->tagBind("oid:$oid", '<1>', [sub{shift;
329 my $tag = SNMP::translateObj($oid);
330 showInfo($tag);},$oid]);
331 $output->insert('end', " = ");
332 my $mib = $SNMP::MIB{format_oid("$oid",'numeric')};
333 $output->insert('end', $val, "value:$oid");
334 if ($mib->{'access'} =~ /(Write|Create)/) {
335 $output->tagConfigure("value:$oid", -foreground => $writecolor);
336 $output->tagBind("value:$oid", '<1>', [sub{shift;
339 snmpsetmaybebegin($oid, $value);
341 my $tag = SNMP::translateObj($oid);
342 showInfo($tag);},format_oid($oid,'full'), $val]);
344 $output->insert('end', "\n");
349 my $name = get_oid($var);
351 insertresult($name,"$var->[$SNMP::Varbind::val_f]");
356 my $tag = SNMP::translateObj($oid);
357 my $sess = new SNMP::Session(DestHost => $host, %session_opts);
358 my $var = new SNMP::Varbind([$oid]);
359 if (!defined($var)) {
360 print "ack: $@ $SNMP::ErrorStr $!\n";
364 $oid = "." . $oid if ($oid !~ /^\./);
365 return ($oid, $sess, $var);
369 if (ref($output) eq "Tk::Frame" && defined($$output{'_#text'})) {
370 $output->delete('0.0','end');
373 $output = $oFrame->Scrolled(qw(Text -width 80 -height 14));
374 $output->pack(-side => 'top', -fill => 'both', -expand => 1);
380 $oFrame->packPropagate(0);
381 $output = $oFrame->Table(-columns => shift, -width => 80, -height => 14,
382 -fixedrows => 2, -fixedcolumns => 1);
383 $output->pack(-side => 'top', -fill => 'both', -expand => 1);
388 $oFrame->packPropagate(0);
389 $output = $oFrame->Scrolled(qw(Canvas -width 80c -height 14c));
390 $output->pack(-side => 'top', -fill => 'both', -expand => 1);
394 (my $oid, my $sess, my $var) = snmpsetup();
395 $status->configure(-text => "getting: $host $community $oid");
397 my $val = $sess->get($var);
398 if ($sess->{ErrorStr}) {
399 $status->configure(-text => $sess->{ErrorStr});
402 $status->configure(-text => "");
407 my $startoid = shift;
408 my $startval = shift;
409 my $setwin = MainWindow->new();
410 $setwin->title("SNMP set");
411 my $varswin = $setwin->Frame(-relief => "raised",-borderwidth => $tmpbd);
412 my $vars = new SNMP::VarList;
413 $varswin->pack(-side => 'top');
414 my $buttons = $setwin->Frame(-relief => "raised")->pack(-side => 'top', -fill => "x",-expand => 1);
415 $buttons->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'Add a varbind', -command => [\&snmpsetbegin_addvar, $vars, $varswin, 'OID'])->pack(-side => 'left', -fill => "x",-expand => 1);
416 $buttons->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'perform set', -command => [\&snmpsetbegin_ok, $vars, $setwin, $varswin])->pack(-side => 'left');
417 $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');
418 if ($startoid ne "") {
419 snmpsetbegin_addvar($vars, $varswin, $startoid, $startval);
427 sub make_enum_button {
432 push @objs,[Radiobutton => $i, -variable => $var];
434 return $win->Menubutton(-pady => $tmpbd, -padx => $tmpbd, -textvariable => $var,
436 -menuitems => \@objs);
439 sub snmpsetmaybebegin {
440 my ($oid, $val) = @_;
442 snmpsetbegin_addvar($setvars, $setmain, $oid, $val);
444 snmpsetbegin($oid, $val);
449 sub snmpsetbegin_addvar {
450 my ($vars, $place, $oid, $val) = @_;
451 $oid = $OID if ($oid eq "OID");
452 my $mib = $SNMP::MIB{format_oid("$oid",'numeric')};
453 my $var = new SNMP::Varbind([$oid, '', $val, $mib->{'type'} || 'INTEGER']);
455 my $frame = $place->Frame();
456 $frame->Entry(-textvariable => \$var->[0], -width => 20)->pack(-side => 'left');
457 make_enum_button($frame, \$var->[3], qw(OBJECTID OCTETSTR INTEGER NETADDR IPADDR COUNTER COUNTER64 GAUGE UINTEGER TICKS OPAQUE NULL))->pack(-side => 'left');
458 if (ref($mib->{'enums'}) eq HASH && scalar(keys(%{$mib->{'enums'}})) > 0) {
459 make_enum_button($frame, \$var->[2], keys(%{$mib->{'enums'}}))->pack(-side => 'left');
461 $frame->Entry(-textvariable => \$var->[2])->pack(-side => 'left');
463 $frame->pack(-expand => 1, -fill => 'x');
466 sub snmpsetbegin_ok {
467 my ($vars, $win, $frame) = @_;
469 $setmain = undef if ($setmain == $frame);
475 (my $oid, my $sess, my $var) = snmpsetup();
476 $status->configure(-text => "setting: $host -> " . Dumper($vars) . "\n");
478 my $val = $sess->set($vars);
479 if ($sess->{ErrorStr}) {
480 $output->insert('end', "Set failed.\nReason: $sess->{ErrorStr}");
481 $status->configure(-text => $sess->{ErrorStr});
483 foreach my $i (@$vars) {
486 $status->configure(-text => "");
491 (my $oid, my $sess, my $var) = snmpsetup();
492 $status->configure(-text => "get next: $host $community $oid");
494 my $val = $sess->getnext($var);
495 if ($sess->{ErrorStr}) {
496 $status->configure(-text => $sess->{ErrorStr});
499 $status->configure(-text => "");
504 (my $oid, my $sess, my $var) = snmpsetup();
505 $status->configure(-text => "walking: $host $community $oid");
507 while (!$sess->{ErrorStr} && !$stopit) {
508 my $val = $sess->getnext($var);
509 last if (!defined($var->tag) ||
511 $val eq "ENDOFMIBVIEW" ||
512 !is_in_subtree($oid, $var->tag . "." . $var->iid));
516 if ($sess->{ErrorStr}) {
517 $status->configure(-text => $sess->{ErrorStr});
518 $output->insert('end',"$sess->{ErrorStr} ($sess->{ErrorNum})\n");
520 $status->configure(-text => "");
526 (my $oid, my $sess, my $var) = snmpsetup();
527 $status->configure(-text => "collecting data: $host $community $oid");
529 my (%tb, @tags, @index, %tboids);
530 while (!$sess->{ErrorStr} && !$stopit) {
531 my $val = $sess->getnext($var);
532 last if (!defined($var->tag) ||
534 $val eq "ENDOFMIBVIEW" ||
535 !is_in_subtree($oid, $var->tag . "." . $var->iid));
536 $newoid = "$var->[$SNMP::Varbind::tag_f].$var->[$SNMP::Varbind::iid_f]";
539 $newoid =~ /([^\.]+)\.([0-9\.]+)$/;
540 if (!grep(/$1/,@tags)) {
543 if (!grep(/$2/,@index)) {
546 $tb{$2}{$1} = $var->val;
547 # $tboids{$2}{$1} = $var->tag;
548 $tboids{$2}{$1} = $newoid;
551 for(my $k=0;$k <= $#tags;$k++) {
552 $output->put(1,$k+2,$tags[$k]);
554 $output->put(1,1,"Index");
555 for(my $i=0;$i <= $#index;$i++) {
556 $output->put($i+2,1,$index[$i]);
558 for(my $i=0;$i <= $#index; $i++) {
559 for(my $k=0;$k <= $#tags;$k++) {
560 my $mib = $SNMP::MIB{format_oid("$tboids{$index[$i]}{$tags[$k]}",'numeric')};
561 if ($mib->{'access'} =~ /(Write|Create)/) {
562 $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));
564 $output->put($i+2,$k+2,$tb{$index[$i]}{$tags[$k]});
568 $status->configure(-text => "");
573 ($graphoid, $graphsess, my $graphvar) = snmpsetup();
582 $output->repeat($graphtime*1000, \&updateGraph);
586 $status->configure(-text => "collecting data: $host $community $graphoid");
588 my $tag = SNMP::translateObj($graphoid,0);
589 my $var = new SNMP::Varbind([$oid]);
590 $graphsess->{ErrorStr} = "";
591 while (!$graphsess->{ErrorStr} && !$stopit) {
592 my $val = $graphsess->getnext($var);
593 if ($#graphvars == -1 && SNMP::translateObj($var->tag) !~ /^$oid/) {
594 # if an exact oid, do a get instead.
595 $var = new SNMP::Varbind([$oid]);
596 $val = $graphsess->get($var);
598 if ($graphsess->{ErrorStr} ||
599 !defined($var->tag) ||
600 SNMP::translateObj($var->tag) !~ /^$oid/) {
603 my $newoid = SNMP::translateObj("$var->[$SNMP::Varbind::tag_f].$var->[$SNMP::Varbind::iid_f]");
605 $newoid =~ /$oid\.([0-9\.]+)$/;
607 if (!grep(/$1/,@graphvars)) {
612 $graphtb{$1}[$gcount-1] = $var->val - $prev{$1};
614 $prev{$1} = $var->val;
616 $graphtb{$1}[$gcount] = $var->val;
618 $max = $graphtb{$1}[$#{$graphtb{$1}}]
619 if ($#{$graphtb{$1}} >= 0 &&
620 $graphtb{$1}[$#{$graphtb{$1}}] > $max);
621 $min = $graphtb{$1}[$#{$graphtb{$1}}]
622 if ($#{$graphtb{$1}} >= 0 &&
623 $graphtb{$1}[$#{$graphtb{$1}}] < $min);
627 $output->delete('all');
628 my $canvas = $$output{'SubWidget'}{'canvas'};
629 my $h=$canvas->cget(-height);
630 foreach $i (@graphvars) {
632 for(my $j=0; $j <= $#{$graphtb{$i}}; $j++) {
634 $a[$j*2+1] = $h-(($h-3)*($graphtb{$i}[$j]-$min))/($max-$min)-3;
636 $output->createLine(@a, -fill => $graphcolors[$i%$#graphcolors]);
638 $output->create('text',5, $h-3, -text => "$max");
639 $output->create('text',5, 3, -text => "$min");
642 $status->configure(-text => "sleeping for $graphtime seconds");
647 $i = ".$i" if ($i !~ /^\./);
648 my $name = SNMP::translateObj($i,1);
649 if (defined($name)) {
650 $name =~ s/.*\.([^.]+)$/$1/;
655 $hlist->add($i, -text => $name);
660 $full = ".$full" if ($full !~ /^\./);
664 if ($tag =~ /^[.0-9]+$/) {
665 # strip off index in case there is one
666 $tag = SNMP::translateObj("$oid");
667 $tag = ".iso.org.dod.internet.private.$tag" if $tag =~ /^enterprises/;
669 $full = SNMP::translateObj("$oid");
672 $tag =~ s/[.0-9]+$//;
673 $oid = SNMP::translateObj($tag);
675 if (!defined($last) || "$last" ne $oid) {
679 $mibOID->configure(-textvariable => \$OID);
684 sub showAllChildren {
687 my @pieces = split(/\./,$id);
689 for($i = 0; $i <= $#pieces; $i++) {
690 my $a = join(".", @pieces[0..$i]);
691 if ($hlist->infoExists($a) && !($hlist->infoChildren($a))) {
692 showChildren(join(".", $a));
694 if ($hlist->infoExists($a)) {
700 $hlist->see($lastvalid);
701 $hlist->selectionClear($hlist->selectionGet);
702 $hlist->selectionSet($lastvalid);
709 $mibOID->configure(-textvariable => \$OID);
710 if ($hlist->infoChildren($oid)) {
711 my @a = $hlist->infoChildren($oid);
714 $hlist->deleteEntry($i);
718 my $mib = $SNMP::MIB{format_oid($oid,'full')};
720 my $children = $$mib{'children'};
721 if (ref($children) eq "ARRAY") {
722 foreach $i (sort {$$a{'subID'} <=> $$b{'subID'}} @{$children}) {
723 addMibOID($$i{'objectID'});
726 $status->configure(-text => SNMP::translateObj($oid,1) .
732 $status->configure(-text => "");
738 my $mib = $SNMP::MIB{format_oid("$oid",'numeric')};
739 if (!defined($mib->{'description'}) || $mib->{'description'} eq "") {
740 $oid =~ s/[.0-9]+$//;
741 $mib = $SNMP::MIB{format_oid("$oid",'numeric')};
744 if ($mib->{'label'} =~ /Table$/) {
745 $tablebutton->configure(-state => 'normal');
747 $tablebutton->configure(-state => 'disabled');
749 $mibOID->configure(-text => $mib->{'objectID'});
750 $mibTextOID->configure(-text =>
751 SNMP::translateObj($mib->{'objectID'},1));
752 $descr->delete('0.0','end');
753 if (defined($mib->{'description'}) &&
754 $mib->{'description'} ne "") {
755 my $desc = $mib->{'description'};
756 $desc =~ s/\n[ \t]+/\n/g;
758 $descr->insert('end',$desc);
760 for($i=0; $i<= $#displayInfo;$i++) {
761 $dpyInfo[$i] = $mib->{$displayInfo[$i]};
762 if (ref($dpyInfo[$i]) eq HASH) {
763 my %hash = %{$dpyInfo[$i]};
765 foreach $j (sort { $hash{$a} <=> $hash{$b} } keys(%hash)) {
766 $dpyInfo[$i] .= "$j = $hash{$j},";
768 } elsif (ref($dpyInfo[$i]) eq ARRAY) {
769 $dpyInfo[$i] = join(", ", @{$dpyInfo[$i]});
779 $menu->checkbutton(-label => $displayInfo[$num],
781 -command => [\&toggleWidgetShown, $num, $var]);
786 if (!$displayLabels[$i]) {
787 $displayLabels[$i] = $dispFrame->Label(-pady => $tmpbd, -padx => $tmpbd,
788 -text => $displayInfo[$i],
790 -borderwidth => $tmpbd);
792 if (!$displayEntries[$i]) {
793 $displayEntries[$i] = $dispFrame->Entry(-textvariable => \$dpyInfo[$i],
794 -width => 40, -relief => 'flat',
795 -borderwidth => $tmpbd);
797 $displayLabels[$i]->grid(-ipady => $tmpbd, -ipadx => $tmpbd,
798 -column => ($i%2)*2, -row => int($i/2),
800 $dpyInfo[$i] = "" if (!defined($dpyInfo[$i]));
801 $displayEntries[$i]->grid(-ipady => $tmpbd, -ipadx => $tmpbd, -column => ($i%2)*2 + 1, -row => int($i/2), -sticky => 'w');
804 sub toggleWidgetShown {
805 my ($num, $var) = @_;
809 $displayLabels[$num]->gridForget();
810 $displayEntries[$num]->gridForget()
812 # my @widgets = $dispFrame->gridSlaves(-row => $num);
816 my $sel = $top->FileSelect();
817 my $file = $sel->Show();
818 if (defined($file)) {
819 SNMP::addMibFiles($file);
820 showChildren("1.3.6.1");
821 showChildren("1.3.6.1");
825 sub loadNewMibModule {
826 my $tmptop = MainWindow->new();
828 $tmptop->Label(-pady => $tmpbd, -padx => $tmpbd, -text => "Enter a SNMP MIB module name")
829 ->pack(-side => 'top');
830 my $e = $tmptop->Entry(-textvariable => \$var);
831 $e->pack(-side => 'top');
832 $e->bind('<Return>',[\&loadIt,\$var,$tmptop]);
833 my $f = $tmptop->Frame();
834 $f->pack(-side => 'top');
835 $f->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'Ok', -command => [\&loadIt,"",\$var,$tmptop])
836 ->pack(-side => 'left');
837 $f->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'Cancel', -command => [sub { my $wid = shift;
840 ->pack(-side => 'left');
846 my $ret = SNMP::loadModules($var);
848 showChildren("1.3.6.1");
849 showChildren("1.3.6.1");
852 $status->configure(-text => "Failed reading module $var");
862 $stopBut->configure(-state => 'disabled');
864 $stopBut->configure(-state => 'normal');
872 my $callback = shift;
873 my $top = MainWindow->new();
874 my $newvar = $$var if defined($var);
876 my $f = $top->Frame();
877 $f->pack(-side => 'top');
878 $f->Label(-pady => $tmpbd, -padx => $tmpbd,
879 -text => $text)->pack(-side => 'left');
880 my $e = $f->Entry(-textvariable => \$newvar);
881 $e->pack(-side => 'left');
883 $f->pack(-side => 'bottom');
884 my $b = $f->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'Ok',
885 -command => [sub { my $w = shift;
890 $$v1 = $$v2 if defined($v1);
893 $w->destroy() if ($ret);}, $top, $var,
894 \$newvar, $callback]);
895 $b->pack(-side => 'left');
896 $e->bind('<Return>',[$b,'invoke']);
897 $b = $f->Button(-pady => $tmpbd, -padx => $tmpbd,
898 -text => 'Cancel', -command => [sub { my $w = shift;
899 $w->destroy();}, $top
901 $b->pack(-side => 'right');
902 $e->bind('<Escape>',[$b,'invoke']);
908 my $tag = SNMP::translateObj($val);
910 showAllChildren($tag);
913 $top->Dialog(-text => "$val not found")->Show();
919 my ($gt, $major, $minor, $sub) = @_;
920 $SNMP::VERSION =~ /(\d)\.(\d).(\d)/;
922 if ($1 > $major || ($1 == $major && $2 > $minor) ||
923 ($1 == $major && $2 == $minor && $3 >= $sub)) {
927 if ($1 < $major || ($1 == $major && $2 < $minor) || ($1 == $major && $2 == $minor && $3 < $sub)) {
936 umask 0077; # make sure its not readable by the world by default.
937 if (!open(O,">$opts{C}")) {
938 warn "can't save to $opts{C}\n";
943 print O Data::Dumper->Dump([\%session_opts], [qw(*session_opts)]);
944 print O Data::Dumper->Dump([\%displayInfoStates], [qw(*displayInfoStates)]);
945 foreach my $var (@saveoptions) {
946 print O Data::Dumper->Dump([$$var], [$var]);
949 $status->configure(-text => "saved options to $opts{C}");
952 # returns 1 if $oid2 is below $oid1 in the hierarchy
954 my ($oid1, $oid2) = @_;
956 $oid1 = SNMP::translateObj($oid1) if ($oid1 !~ /^[\d\.]*$/);
957 $oid2 = SNMP::translateObj($oid2) if ($oid2 !~ /^[\d\.]*$/);
959 # has more on it or is exactly the same
960 return 1 if ($oid2 =~ /^$oid1\./ || $oid2 =~ /^$oid1$/);
965 my ($oid, $type) = @_;
967 $type = $displayoidas if ($type eq "");
969 if ($type eq 'numeric') {
970 return SNMP::translateObj($oid) if ($oid !~ /^[\d\.]*$/);
972 } elsif ($type eq 'full') {
973 return SNMP::translateObj($oid, 1) if ($oid =~ /^[\d\.]*$/);
974 return SNMP::translateObj(SNMP::translateObj($oid), 1) if ($oid !~ /^\./);
976 } elsif ($type eq 'short' || $type eq 'module') {
977 $oid = SNMP::translateObj($oid) if ($oid =~ /^[\d\.]*$/);
978 $oid =~ s/.*\.([a-zA-Z]\w+)\.(.*)/$1.$2/;
979 if ($type eq 'module') {
980 $oid = $SNMP::MIB{format_oid($oid,'numeric')}->{'moduleID'} . "::" . $oid;
983 } elsif ($type eq 'module') {
984 $oid = SNMP::translateObj($oid) if ($oid =~ /^[\d\.]*$/);
985 $oid =~ s/.*\.([a-zA-Z]\w+)\.(.*)/$1.$2/;
988 warn 'unknown oid translation type: $type';
994 my ($var, $type) = @_;
995 return format_oid($var->tag . "." . $var->iid, $type);