tkmib
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:30k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. #!/usr/bin/perl
  2. #!/usr/bin/perl -w
  3. require 5;
  4. # attempt to determine if they have the proper modules installed.
  5. # SNMP
  6. my $havesnmp = eval {require SNMP;};
  7. # the Tk packages
  8. my $havetk = eval {require Tk;
  9.    require Tk::Table;
  10.    require Tk::HList;
  11.    require Tk::FileSelect;
  12.    require Tk::Dialog;};
  13. if (!$havesnmp) {
  14.     print "
  15. ERROR:  You don't have the SNMP perl module installed.  Please obtain this by
  16. getting the latest source release of the net-snmp toolkit from
  17. http://www.net-snmp.org/download/ .  The perl module is contained in
  18. the perl/SNMP directory.  See the INSTALL file there for
  19. instructions.
  20. ";
  21. }
  22. if (!$havetk) {
  23.     print "
  24. ERROR:  You don't have the Tk module installed.  You should be able to
  25. install this by running (as root):
  26.     perl -MCPAN -e 'install Tk'
  27. ";
  28. }
  29. if (!$havetk || !$havesnmp) {
  30.     print "n";
  31.     exit;
  32. }
  33. if ($havetk) {
  34.   # Tk doesn't seem to like require so we force use here.
  35.     eval {import Tk;
  36.   import Tk::Table;
  37.   import Tk::HList;
  38.   import Tk::FileSelect;
  39.   import Tk::Dialog;
  40.           import SNMP;};
  41. }
  42. use Getopt::Std;
  43. use Data::Dumper;
  44. $host = 'localhost';
  45. $OID = '.1.3.6.1';
  46. $opts{'C'}=$ENV{'HOME'} . "/.snmp/tkmibrc";
  47. # default session options
  48. if (test_version(1,5,0,0)) {
  49.     print "setting optsn";
  50.     %opts = (
  51.      'c'          => "public",
  52.      'p'   => 161,
  53.      't'      => 5000000,
  54.      'r'      => 5,
  55.      'v'      => 1,
  56.      'a'    => 'MD5',
  57.      'x'    => 'DES',
  58.      'A'     => '',
  59.      'X'     => '',
  60.      'n'      => '',
  61.      'u'      => 'initial',
  62.      'l'     => 'authNoPriv',
  63.      );
  64. }
  65. getopts("hp:v:a:A:x:X:n:u:l:r:t:o:c:C", %opts);
  66. sub usage {
  67.     print "
  68. tkmib [-C] [-o OID] [SNMPCMD arguments] [host]
  69.   -C CONFIG_FILE  load CONFIG_FILE after starting up. (default: ~/.snmp/tkmibrc)
  70.                   (use -C /dev/null to not read one).
  71.   See the snmpcmd manual page for related SNMPCMD arguments.  (Not all
  72.   options are currently supported.)
  73. ";
  74.     exit();
  75. }
  76. usage() if ($opts{'h'});
  77. # initialize defaults, may be overridden by config file below
  78. @displayInfo=qw(type access status units hint moduleID enums indexes);
  79. @saveoptions = ('displayoidas', 'writecolor', 'graphtime', 'graphdelta');
  80. $displayoidas='full';
  81. $writecolor = "blue";
  82. $graphtime=5;
  83. $graphdelta=1;
  84. foreach $i (@displayInfo) {
  85.     $displayInfoStates{$i} = 1;
  86. }
  87. # source config file
  88. do $opts{'C'} if ($opts{'C'} && -f $opts{'C'});
  89. $session_opts{'UseLongNames'} => 1;
  90. $session_opts{'RemotePort'} = $opts{'p'} if ($opts{'p'});
  91. $session_opts{'Community'} = $opts{'c'} if ($opts{'c'});
  92. $session_opts{'Version'} = $opts{'v'} if ($opts{'v'});
  93. $session_opts{'AuthProto'} = $opts{'a'} if ($opts{'a'});
  94. $session_opts{'AuthPass'} = $opts{'A'} if ($opts{'A'});
  95. $session_opts{'PrivProto'} = $opts{'x'} if ($opts{'x'});
  96. $session_opts{'PrivPass'} = $opts{'X'} if ($opts{'X'});
  97. $session_opts{'Context'} = $opts{'n'} if ($opts{'n'});
  98. $session_opts{'SecName'} = $opts{'u'} if ($opts{'u'});
  99. $session_opts{'SecLevel'} = $opts{'l'} if ($opts{'l'});
  100. $session_opts{'Retries'} = $opts{'r'} if ($opts{'r'});
  101. $session_opts{'Timeout'} = $opts{'t'} if ($opts{'t'});
  102. $host = shift if ($#ARGV > -1);
  103. $session_opts{'Community'} = shift if ($#ARGV > -1);
  104. @graphcolors=qw(blue red green yellow purple);
  105. # initialize SNMP module
  106. $SNMP::save_descriptions=1;
  107. $SNMP::use_long_names=1;
  108. $SNMP::use_enums=1;
  109. $SNMP::verbose = 1;
  110. my $tmpbd = 1;
  111. $top = MainWindow->new();
  112. $top->title("tkmib");
  113. #Menus
  114. $MenuFrame = $top->Frame(-relief => "raised",-borderwidth => 2);
  115. $MenuFrame->pack(-fill => "x",-expand => 1);
  116. $FileMenuBut = $MenuFrame->Menubutton(-pady => $tmpbd, -padx => $tmpbd, -text => "File",
  117.       -menuitems =>
  118.       [
  119. #       [Button => "Save Output", -command => [&saveOutput]],
  120.        [Button => "Quit",        -command => [&exit]]
  121.        ]);
  122. $FileMenuBut->pack(-side => 'left');
  123. $MibMenuBut = $MenuFrame->Menubutton(-pady => $tmpbd, -padx => $tmpbd, -text => "Mib",
  124.       -menuitems =>
  125.       [[Button => "Find a mib node", 
  126. -command => sub { my $var;
  127.   entryBox("Find a Mib Node", 
  128.    "Enter a mib node name to search for:",
  129.    $var, &findANode );}],
  130.        [Button => "Load a New Mib File", -command => [&loadNewMibFile]],
  131.        [Button => "Load a New Mib Module", 
  132. -command => sub { my $var;
  133.   entryBox("Load a Module", 
  134.    "Enter a SNMP MIB module name to load:",
  135.    $var, &loadIt);}]
  136.        ]);
  137. $MibMenuBut->pack(-side => 'left');
  138. $OptMenuBut = $MenuFrame->Menubutton(-pady => $tmpbd, -padx => $tmpbd, -text => "Options",
  139.      -menuitems =>
  140.       [[Cascade => "~Display", -menuitems =>
  141. [
  142.  [Cascade => "~MIB Information"],
  143.  [Cascade => "~OID Display", -menuitems =>
  144.   [
  145.    [Radiobutton => 'full', -variable => $displayoidas],
  146.    [Radiobutton => 'numeric', -variable => $displayoidas],
  147.    [Radiobutton => 'short', -variable => $displayoidas],
  148.    [Radiobutton => 'module', -variable => $displayoidas]
  149.    ]
  150.   ],
  151.  [Button => "Writable Color", 
  152.   -command => [&entryBox,"Writable Color",
  153.        "Color for writable objects:",
  154.        $writecolor]]
  155.  ]],
  156.        [Cascade => "Use SNMP Version", -menuitems =>
  157. [
  158.  [Radiobutton => '1', -variable => $session_opts{'Version'}],
  159.  [Radiobutton => '2c', -variable => $session_opts{'Version'}],
  160.  [Radiobutton => '3', -variable => $session_opts{'Version'}]
  161. ]
  162.        ], # ends version number specification
  163.        [Cascade => "SNMPv1/2c options", -menuitems =>
  164. [
  165.  [Button => "Community Name", 
  166.   -command => [&entryBox,"Community Name", "Community name to use:", 
  167.        $session_opts{'Community'}]]
  168. ]
  169.        ],
  170.        [Cascade => "SNMP3 options", -menuitems =>
  171. [
  172.  [Button => "Security Name", 
  173.   -command => [&entryBox,"Security Name", "Security Name to use:", 
  174.        $session_opts{'SecName'}]],
  175.          [Cascade => "Security Level", -menuitems =>
  176.           [
  177.    [Radiobutton => 'noAuthNoPriv',
  178.     -variable => $session_opts{'SecLevel'}],
  179.            [Radiobutton => 'authNoPriv', 
  180.     -variable => $session_opts{'SecLevel'}],
  181.    [Radiobutton => 'authPriv', 
  182.             -variable => $session_opts{'SecLevel'}]
  183.           ]
  184.          ],
  185.  [Button => "Authentication Passphrase", 
  186.   -command => [&entryBox,"Authentication Passphrase", 
  187.        "Authentication Passphrase to use:", 
  188.        $session_opts{'AuthPass'}]],
  189.          [Cascade => "Authentication Type", -menuitems =>
  190.           [
  191.    [Radiobutton => 'MD5',
  192.     -variable => $session_opts{'AuthProto'}],
  193.    [Radiobutton => 'SHA',
  194.     -variable => $session_opts{'AuthProto'}],
  195.           ]
  196.          ],
  197.  [Button => "Privacy Passphrase", 
  198.   -command => [&entryBox,"Privacy Passphrase", 
  199.        "Privacy Passphrase to use:", 
  200.        $session_opts{'PrivPass'}]],
  201.          [Cascade => "Privacy Type", -menuitems =>
  202.           [
  203.    [Radiobutton => 'DES',
  204.     -variable => $session_opts{'PrivProto'}],
  205.           ]
  206.          ],
  207. ]
  208.        ],
  209.        [Button => "Time between graph polls", 
  210. -command => sub { entryBox("graph polls", "Time between graph polls:", 
  211.     $graphtime);}],
  212.        [Button => "Port number", 
  213. -command => sub { entryBox("Port Number", "SNMP Port number to use:", 
  214.     $session_opts{'RemotePort'});}],
  215.        [Button => "TimeOut", 
  216. -command => sub { entryBox("Time Out", "Timeout for SNMP requests:", 
  217.     $session_opts{'Timeout'});}],
  218.        [Button => "Retries", 
  219. -command => sub { entryBox("Retries", 
  220.    "Number of Times to Retransmit Requests:", 
  221.     $session_opts{'Retries'});}],
  222.        [Button => "Save Options",
  223. -command => &save_options]
  224.        ])->pack(-side => 'left');
  225.         
  226. $tmp = $OptMenuBut->cget(-menu);
  227. $OptMenuWidgets = $tmp->entrycget("Display", -menu);
  228. $OptMenuWidgets = $OptMenuWidgets->entrycget("MIB Information", -menu);
  229. $hlist=$top->Scrolled(qw(HList -itemtype imagetext -browsecmd main::showInfo
  230.  -command main::showChildren -width 80 -height 15));
  231. $hlist->pack(-side => 'top', -expand => 1, -fill => 'both');
  232. my $sFrame = $top->Frame(-relief => 'raised', -borderwidth => $tmpbd);
  233. $sFrame->pack(-side => 'top', -fill => 'x');
  234. $sFrame->Label(-pady => $tmpbd, -padx => $tmpbd, -text => 'OID: ', -relief => 'raised', -borderwidth => $tmpbd)
  235.     ->pack(-side => 'left');
  236. $mibOID = $sFrame->Entry(-textvariable => $OID, -relief => 'flat', -width => 40);
  237. $mibOID->pack(-side => 'left');
  238. $mibTextOID = $sFrame->Label(-pady => $tmpbd, -padx => $tmpbd, -text => '');
  239. $mibTextOID->pack(-side => 'right');
  240. $dispFrame=$top->Frame(-relief => 'raised', -borderwidth => $tmpbd);
  241. $dispFrame->pack(-side => 'top', -fill =>'x');
  242. for($i=0;$i<= $#displayInfo;$i++) {
  243.     createRow($i) if ($displayInfoStates{$displayInfo[$i]});
  244.     optionalWidget($i,$OptMenuWidgets, $displayInfoStates{$displayInfo[$i]});
  245. }
  246.     
  247. $descrFrame=$top->Frame(-relief => 'raised', -borderwidth => $tmpbd);
  248. $descrFrame->pack(-side => 'top', -fill =>'x');
  249. $descrFrame->Label(-pady => $tmpbd, -padx => $tmpbd, -text => 'Description:', -anchor => 'w')->pack(-side => 'top',
  250. -fill => 'x');
  251. $descr = $descrFrame->Scrolled(qw(Text -width 80 -height 4));
  252. $descr->pack(-side => 'top', -fill => 'x');
  253. $bFrame = $top->Frame(-relief => 'raised', -borderwidth => $tmpbd);
  254. $bFrame->pack(-side => 'top', -fill => 'x');
  255. $hostEntry = $bFrame->Entry(-textvariable => $host, -width => 12);
  256. $hostEntry->pack(-side => 'left');
  257. $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'graph', -command => &snmpgraph)->pack(-side => 'right');
  258. $tablebutton = $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'table', -command => &snmptable);
  259. $tablebutton->pack(-side => 'right');
  260. $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'walk', -command => &snmpwalk)->pack(-side => 'right');
  261. $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'getnext', -command => &snmpgetnext)->pack(-side => 'right');
  262. $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'get', -command => &snmpget)->pack(-side => 'right');
  263. $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'set', -command => [&snmpsetbegin, 'OID'])->pack(-side => 'right');
  264. $stopBut = $bFrame->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'stop', -command => sub { stop(1) },
  265.    -state => 'disabled');
  266. $stopBut->pack(-side => 'right');
  267. $oFrame = $top->Frame(-borderwidth => $tmpbd, -relief => 'raised');
  268. $oFrame->pack(-side => 'top', -fill => 'both');
  269. $output = $oFrame->Scrolled(qw(Text -width 80 -height 14));
  270. $output->pack(-side => 'top', -fill => 'both', -expand => 1);
  271. $tmpFrame = $top->Frame(-relief => 'raised', -borderwidth => $tmpbd);
  272. $tmpFrame->pack(-side => 'top', -fill => 'x');
  273. $tmpFrame->Label(-pady => $tmpbd, -padx => $tmpbd, -text => "Status:  ", -anchor => 'w')
  274. #  -relief => 'raised', -borderwidth => $tmpbd)
  275.     ->pack(-side => 'left');
  276. $status = $tmpFrame->Label(-pady => $tmpbd, -padx => $tmpbd, -anchor => 'w');
  277. $status->pack(-side => 'left', -fill => 'x');
  278. # initialize the browser
  279. foreach $i (qw(.1 .1.3 .1.3.6 .1.3.6.1)) {
  280.     addMibOID($i);
  281. }
  282. showChildren("$OID");
  283. if (defined($opts{'o'})) {
  284.     findANode($opts{'o'});
  285. }
  286. MainLoop();
  287. sub insertresult {
  288.     my $oid = shift;
  289.     my $val = shift;
  290.     $oid = $OID if ($oid eq "OID");
  291.     $output->insert('end', $oid, "oid:$oid");
  292.     $output->tagBind("oid:$oid", '<1>', [sub{shift; 
  293.      my $oid = shift;
  294.      findANode($oid);
  295.      my $tag = SNMP::translateObj($oid);
  296.      showInfo($tag);},$oid]);
  297.     $output->insert('end', " = ");
  298.     my $mib = $SNMP::MIB{format_oid("$oid",'numeric')};
  299.     $output->insert('end', $val, "value:$oid");
  300.     if ($mib->{'access'} =~ /(Write|Create)/) {
  301. $output->tagConfigure("value:$oid", -foreground => $writecolor);
  302. $output->tagBind("value:$oid", '<1>', [sub{shift; 
  303.    my $oid = shift;
  304.    my $value = shift;
  305.    snmpsetmaybebegin($oid, $value);
  306.    findANode($oid);
  307.    my $tag = SNMP::translateObj($oid);
  308.    showInfo($tag);},format_oid($oid,'full'), $val]);
  309.     }
  310.     $output->insert('end', "n");
  311. }
  312. sub insertvar {
  313.     my $var = shift;
  314.     my $name = get_oid($var);
  315.     insertresult($name,"$var->[$SNMP::Varbind::val_f]");
  316. }
  317. sub snmpsetup {
  318.     my $oid = $OID;
  319.     my $tag = SNMP::translateObj($oid);
  320.     my $sess = new SNMP::Session(DestHost => $host, %session_opts);
  321.     my $var = new SNMP::Varbind([$oid]);
  322.     if (!defined($var)) {
  323. print "ack:  $@ $SNMP::ErrorStr $!n";
  324.     }
  325.     stop(0);
  326.     initText();
  327.     $oid = "." . $oid if ($oid !~ /^./);
  328.     return ($oid, $sess, $var);
  329. }
  330. sub initText {
  331.     if (ref($output) eq "Tk::Frame" && defined($$output{'_#text'})) {
  332. $output->delete('0.0','end');
  333.     } else {
  334. $output->destroy();
  335. $output = $oFrame->Scrolled(qw(Text -width 80 -height 14));
  336. $output->pack(-side => 'top', -fill => 'both', -expand => 1);
  337.     }
  338. }
  339. sub initTable {
  340.     $output->destroy();
  341.     $oFrame->packPropagate(0);
  342.     $output = $oFrame->Table(-columns => shift, -width => 80, -height => 14,
  343.      -fixedrows => 2, -fixedcolumns => 1);
  344.     $output->pack(-side => 'top', -fill => 'both', -expand => 1);
  345. }
  346. sub initCanvas {
  347.     $output->destroy();
  348.     $oFrame->packPropagate(0);
  349.     $output = $oFrame->Scrolled(qw(Canvas -width 80c -height 14c));
  350.     $output->pack(-side => 'top', -fill => 'both', -expand => 1);
  351. }
  352. sub snmpget {
  353.     (my $oid, my $sess, my $var) = snmpsetup();
  354.     $status->configure(-text => "getting:  $host $community $oid");
  355.     $top->update();
  356.     my $val = $sess->get($var);
  357.     if ($sess->{ErrorStr}) {
  358. $status->configure(-text => $sess->{ErrorStr});
  359.     } else {
  360. insertvar($var);
  361. $status->configure(-text => "");
  362.     }
  363. }
  364. sub snmpsetbegin {
  365.     my $startoid = shift;
  366.     my $startval = shift;
  367.     my $setwin = MainWindow->new();
  368.     $setwin->title("SNMP set");
  369.     my $varswin = $setwin->Frame(-relief => "raised",-borderwidth => $tmpbd);
  370.     my $vars = new SNMP::VarList;
  371.     $varswin->pack(-side => 'top');
  372.     my $buttons = $setwin->Frame(-relief => "raised")->pack(-side => 'top', -fill => "x",-expand => 1);
  373.     $buttons->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'Add a varbind', -command => [&snmpsetbegin_addvar, $vars, $varswin, 'OID'])->pack(-side => 'left', -fill => "x",-expand => 1);
  374.     $buttons->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'perform set', -command => [&snmpsetbegin_ok, $vars, $setwin, $varswin])->pack(-side => 'left');
  375.     $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');
  376.     if ($startoid ne "") {
  377. snmpsetbegin_addvar($vars, $varswin, $startoid, $startval);
  378.     }
  379.     if (!$setmain) {
  380. $setmain = $varswin;
  381. $setvars = $vars;
  382.     }
  383. }
  384. sub make_enum_button {
  385.     my $win = shift;
  386.     my $var = shift;
  387.     my @objs;
  388.     foreach my $i (@_) {
  389. push @objs,[Radiobutton => $i, -variable => $var];
  390.     }
  391.     return $win->Menubutton(-pady => $tmpbd, -padx => $tmpbd, -textvariable => $var,
  392.     -relief => raised,
  393.     -menuitems => @objs);
  394. }
  395. sub snmpsetmaybebegin {
  396.     my ($oid, $val) = @_;
  397.     if ($setmain) {
  398. snmpsetbegin_addvar($setvars, $setmain, $oid, $val);
  399.     } else {
  400. snmpsetbegin($oid, $val);
  401.     }
  402. }
  403. sub snmpsetbegin_addvar {
  404.     my ($vars, $place, $oid, $val) = @_;
  405.     $oid = $OID if ($oid eq "OID");
  406.     my $mib = $SNMP::MIB{format_oid("$oid",'numeric')};
  407.     my $var = new SNMP::Varbind([$oid, '', $val, $mib->{'type'} || 'INTEGER']);
  408.     push @$vars,$var;
  409.     my $frame = $place->Frame();
  410.     $frame->Entry(-textvariable => $var->[0], -width => 20)->pack(-side => 'left');
  411.     make_enum_button($frame, $var->[3], qw(OBJECTID OCTETSTR INTEGER NETADDR IPADDR COUNTER COUNTER64 GAUGE UINTEGER TICKS OPAQUE NULL))->pack(-side => 'left');
  412.     if (ref($mib->{'enums'}) eq HASH && scalar(keys(%{$mib->{'enums'}})) > 0) {
  413. make_enum_button($frame, $var->[2], keys(%{$mib->{'enums'}}))->pack(-side => 'left');
  414.     } else {
  415. $frame->Entry(-textvariable => $var->[2])->pack(-side => 'left');
  416.     }
  417.     $frame->pack(-expand => 1, -fill => 'x');
  418. }
  419. sub snmpsetbegin_ok {
  420.     my ($vars, $win, $frame) = @_;
  421.     snmpset($vars);
  422.     $setmain = undef if ($setmain == $frame);
  423.     $win->destroy();
  424. }
  425. sub snmpset {
  426.     my $vars = shift;
  427.     (my $oid, my $sess, my $var) = snmpsetup();
  428.     $status->configure(-text => "setting:  $host -> " . Dumper($vars) . "n");
  429.     $top->update();
  430.     my $val = $sess->set($vars);
  431.     if ($sess->{ErrorStr}) {
  432. $output->insert('end', "Set failed.nReason:  $sess->{ErrorStr}");
  433. $status->configure(-text => $sess->{ErrorStr});
  434.     } else {
  435. foreach my $i (@$vars) {
  436.     insertvar($i);
  437. }
  438. $status->configure(-text => "");
  439.     }
  440. }
  441. sub snmpgetnext {
  442.     (my $oid, my $sess, my $var) = snmpsetup();
  443.     $status->configure(-text => "get next:  $host $community $oid");
  444.     $top->update();
  445.     my $val = $sess->getnext($var);
  446.     if ($sess->{ErrorStr}) {
  447. $status->configure(-text => $sess->{ErrorStr});
  448.     } else {
  449. insertvar($var);
  450. $status->configure(-text => "");
  451.     }
  452. }
  453. sub snmpwalk {
  454.     (my $oid, my $sess, my $var) = snmpsetup();
  455.     $status->configure(-text => "walking:  $host $community $oid");
  456.     $top->update();
  457.     while (!$sess->{ErrorStr} && !$stopit) {
  458. my $val = $sess->getnext($var);
  459. last if (!defined($var->tag) ||
  460.  $sess->{ErrorStr} ||
  461.  $val eq "ENDOFMIBVIEW" ||
  462.          !is_in_subtree($oid, $var->tag . "." . $var->iid));
  463. insertvar($var);
  464. $top->update();
  465.     }
  466.     if ($sess->{ErrorStr}) {
  467. $status->configure(-text => $sess->{ErrorStr});
  468. $output->insert('end',"$sess->{ErrorStr} ($sess->{ErrorNum})n");
  469.     } else {
  470. $status->configure(-text => "");
  471.     }
  472.     stop(1);
  473. }
  474. sub snmptable {
  475.     (my $oid, my $sess, my $var) = snmpsetup();
  476.     $status->configure(-text => "collecting data:  $host $community $oid");
  477.     $top->update();
  478.     my (%tb, @tags, @index, %tboids);
  479.     while (!$sess->{ErrorStr} && !$stopit) {
  480. my $val = $sess->getnext($var);
  481. last if (!defined($var->tag) ||
  482.  $sess->{ErrorStr} ||
  483.  $val eq "ENDOFMIBVIEW" ||
  484.          !is_in_subtree($oid, $var->tag . "." . $var->iid));
  485. $newoid = "$var->[$SNMP::Varbind::tag_f].$var->[$SNMP::Varbind::iid_f]";
  486. insertvar($var);
  487. $top->update();
  488. $newoid =~ /([^.]+).([0-9.]+)$/;
  489. if (!grep(/$1/,@tags)) {
  490.     push @tags,$1;
  491. }
  492. if (!grep(/$2/,@index)) {
  493.     push @index,$2;
  494. }
  495. $tb{$2}{$1} = $var->val;
  496. # $tboids{$2}{$1} = $var->tag;
  497. $tboids{$2}{$1} = $newoid;
  498.     }
  499.     initTable($#tags+1);
  500.     for(my $k=0;$k <= $#tags;$k++) {
  501. $output->put(1,$k+2,$tags[$k]);
  502.     }
  503.     $output->put(1,1,"Index");
  504.     for(my $i=0;$i <= $#index;$i++) {
  505. $output->put($i+2,1,$index[$i]);
  506.     }
  507.     for(my $i=0;$i <= $#index; $i++) {
  508. for(my $k=0;$k <= $#tags;$k++) {
  509.     my $mib = $SNMP::MIB{format_oid("$tboids{$index[$i]}{$tags[$k]}",'numeric')};
  510.     if ($mib->{'access'} =~ /(Write|Create)/) {
  511. $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));
  512.     } else {
  513. $output->put($i+2,$k+2,$tb{$index[$i]}{$tags[$k]});
  514.     }
  515. }
  516.     }
  517.     $status->configure(-text => "");
  518.     stop(1);
  519. }
  520. sub snmpgraph {
  521.     ($graphoid, $graphsess, my $graphvar) = snmpsetup();
  522.     $top->update();
  523.     %graphtb = ();
  524.     @graphvars = ();
  525.     initCanvas();
  526.     $gcount=0;
  527.     $max=-1;
  528.     $min=2**32-1;
  529.     updateGraph();
  530.     $output->repeat($graphtime*1000, &updateGraph);
  531. }
  532. sub updateGraph() {
  533.     $status->configure(-text => "collecting data:  $host $community $graphoid");
  534.     my $oid = $graphoid;
  535.     my $tag = SNMP::translateObj($graphoid,0);
  536.     my $var = new SNMP::Varbind([$oid]);
  537.     $graphsess->{ErrorStr} = "";    
  538.     while (!$graphsess->{ErrorStr} && !$stopit) {
  539. my $val = $graphsess->getnext($var);
  540. if ($#graphvars == -1 && SNMP::translateObj($var->tag) !~ /^$oid/) {
  541.     # if an exact oid, do a get instead.
  542.     $var = new SNMP::Varbind([$oid]);
  543.     $val = $graphsess->get($var);
  544. }
  545. if ($graphsess->{ErrorStr} ||
  546.     !defined($var->tag) ||
  547.     SNMP::translateObj($var->tag) !~ /^$oid/) {
  548.     last;
  549. }
  550. my $newoid = SNMP::translateObj("$var->[$SNMP::Varbind::tag_f].$var->[$SNMP::Varbind::iid_f]");
  551. $top->update();
  552. $newoid =~ /$oid.([0-9.]+)$/;
  553. if (defined($1)) {
  554.     if (!grep(/$1/,@graphvars)) {
  555. push @graphvars,$1;
  556.     }
  557.     if ($graphdelta) {
  558. if ($gcount > 0) {
  559.     $graphtb{$1}[$gcount-1] = $var->val - $prev{$1};
  560. }
  561. $prev{$1} = $var->val;
  562.     } else {
  563. $graphtb{$1}[$gcount] = $var->val;
  564.     }
  565.     $max = $graphtb{$1}[$#{$graphtb{$1}}] 
  566. if ($#{$graphtb{$1}} >= 0 &&
  567.     $graphtb{$1}[$#{$graphtb{$1}}] > $max);
  568.     $min = $graphtb{$1}[$#{$graphtb{$1}}] 
  569. if ($#{$graphtb{$1}} >= 0 &&
  570.     $graphtb{$1}[$#{$graphtb{$1}}] < $min);
  571. }
  572.     }
  573.     if ($gcount > 1) {
  574. $output->delete('all');
  575. my $canvas = $$output{'SubWidget'}{'canvas'};
  576. my $h=$canvas->cget(-height);
  577. foreach $i (@graphvars) {
  578.     my @a = ();
  579.     for(my $j=0; $j <= $#{$graphtb{$i}}; $j++) {
  580. $a[$j*2] = $j;
  581. $a[$j*2+1] = $h-(($h-3)*($graphtb{$i}[$j]-$min))/($max-$min)-3;
  582.     }
  583.     $output->createLine(@a, -fill => $graphcolors[$i%$#graphcolors]);
  584. }
  585. $output->create('text',5, $h-3, -text => "$max");
  586. $output->create('text',5, 3, -text => "$min");
  587.     }
  588.     $gcount++;
  589.     $status->configure(-text => "sleeping for $graphtime seconds");
  590. }
  591. sub addMibOID {
  592.     my $i = shift;
  593.     $i = ".$i" if ($i !~ /^./);
  594.     my $name = SNMP::translateObj($i,1);
  595.     if (defined($name)) {
  596. $name =~ s/.*.([^.]+)$/$1/;
  597.     } else {
  598. return;
  599.     }
  600.     $i =~ s/^.//;
  601.     $hlist->add($i, -text => $name);
  602. }
  603. sub showInfo {
  604.     my $full = shift;
  605.     $full = ".$full" if ($full !~ /^./);
  606.     my $oid = $full;
  607.     my $tag = $oid;
  608.     if ($tag =~ /^[.0-9]+$/) {
  609. # strip off index in case there is one
  610. $tag = SNMP::translateObj("$oid");
  611. $tag = ".iso.org.dod.internet.private.$tag" if $tag =~ /^enterprises/;
  612.     } else {
  613. $full = SNMP::translateObj("$oid");
  614.     }
  615.     $tag =~ s/[.0-9]+$//;
  616.     $oid = SNMP::translateObj($tag);
  617.     if (!defined($last) || "$last" ne $oid) {
  618. updateInfo($oid);
  619.     }
  620.     $OID = $full;
  621.     $mibOID->configure(-textvariable => $OID);
  622.     $mibOID->update();
  623.     $last = $oid;
  624. }
  625. sub showAllChildren {
  626.     my $id = shift;
  627.     $id =~ s/^.//;
  628.     my @pieces = split(/./,$id);
  629.     my ($i, $lastvalid);
  630.     for($i = 0; $i <= $#pieces; $i++) {
  631. my $a = join(".", @pieces[0..$i]);
  632. if ($hlist->infoExists($a) && !($hlist->infoChildren($a))) {
  633.     showChildren(join(".", $a));
  634. }
  635. if ($hlist->infoExists($a)) {
  636.     $lastvalid = $a;
  637. } else {
  638.     last;
  639. }
  640.     }
  641.     $hlist->see($lastvalid);
  642.     $hlist->selectionClear($hlist->selectionGet);
  643.     $hlist->selectionSet($lastvalid);
  644. }
  645. sub showChildren {
  646.     $OID = shift;
  647.     $OID =~ s/^.//;
  648.     my $oid = $OID;
  649.     $mibOID->configure(-textvariable => $OID);
  650.     if ($hlist->infoChildren($oid)) {
  651. my @a = $hlist->infoChildren($oid);
  652. my $i;
  653. foreach $i (@a) {
  654.     $hlist->deleteEntry($i);
  655. }
  656.     } else {
  657. $oid = ".$oid";
  658. my $mib = $SNMP::MIB{format_oid($oid,'full')};
  659. if (defined($mib)) {
  660.     my $children = $$mib{'children'}; 
  661.     if (ref($children) eq "ARRAY") {
  662. foreach $i (sort {$$a{'subID'} <=> $$b{'subID'}} @{$children}) {
  663.     addMibOID($$i{'objectID'});
  664. }
  665.     } else {
  666. $status->configure(-text => SNMP::translateObj($oid,1) . 
  667.    " has no children");
  668. return;
  669.     }
  670. }
  671.     }
  672.     $status->configure(-text => "");
  673. }
  674. sub updateInfo {
  675.     $OID = shift;
  676.     my $oid = $OID;
  677.     my $mib = $SNMP::MIB{format_oid("$oid",'numeric')};
  678.     if (!defined($mib->{'description'}) || $mib->{'description'} eq "") {
  679. $oid =~ s/[.0-9]+$//;
  680. $mib = $SNMP::MIB{format_oid("$oid",'numeric')};
  681.     }
  682.     if (defined($mib)) {
  683. if ($mib->{'label'} =~ /Table$/) {
  684.     $tablebutton->configure(-state => 'normal');
  685. } else {
  686.     $tablebutton->configure(-state => 'disabled');
  687. }
  688. $mibOID->configure(-text => $mib->{'objectID'});
  689. $mibTextOID->configure(-text => 
  690.      SNMP::translateObj($mib->{'objectID'},1));
  691. $descr->delete('0.0','end');
  692. if (defined($mib->{'description'}) && 
  693.     $mib->{'description'} ne "") {
  694.     my $desc = $mib->{'description'};
  695.     $desc =~ s/n[ t]+/n/g;
  696.       $desc =~ s/^n//;
  697.     $descr->insert('end',$desc);
  698. }
  699. for($i=0; $i<= $#displayInfo;$i++) {
  700.     $dpyInfo[$i] = $mib->{$displayInfo[$i]};
  701.     if (ref($dpyInfo[$i]) eq HASH) {
  702. my %hash = %{$dpyInfo[$i]};
  703. $dpyInfo[$i] = "";
  704. foreach $j (sort { $hash{$a} <=> $hash{$b} } keys(%hash)) {
  705.     $dpyInfo[$i] .= "$j = $hash{$j},";
  706. }
  707.     } elsif (ref($dpyInfo[$i]) eq ARRAY) {
  708. $dpyInfo[$i] = join(", ", @{$dpyInfo[$i]});
  709.     }
  710. }
  711.     }
  712. }
  713. sub optionalWidget {
  714.     my $num = shift;
  715.     my $menu = shift;
  716.     my $var = shift;
  717.     $menu->checkbutton(-label => $displayInfo[$num], 
  718.        -variable => $var,
  719.        -command => [&toggleWidgetShown, $num, $var]);
  720. }
  721. sub createRow {
  722.     my $i = shift;
  723.     if (!$displayLabels[$i]) {
  724. $displayLabels[$i] = $dispFrame->Label(-pady => $tmpbd, -padx => $tmpbd,
  725.        -text => $displayInfo[$i], 
  726.        -anchor => 'w',
  727.        -borderwidth => $tmpbd);
  728.     }
  729.     if (!$displayEntries[$i]) {
  730. $displayEntries[$i] = $dispFrame->Entry(-textvariable => $dpyInfo[$i],
  731. -width => 40, -relief => 'flat',
  732. -borderwidth => $tmpbd);
  733.     }
  734.     $displayLabels[$i]->grid(-ipady => $tmpbd, -ipadx => $tmpbd,
  735.      -column => ($i%2)*2, -row => int($i/2),
  736.      -sticky => 'w');
  737.     $dpyInfo[$i] = "" if (!defined($dpyInfo[$i]));
  738.     $displayEntries[$i]->grid(-ipady => $tmpbd, -ipadx => $tmpbd, -column => ($i%2)*2 + 1, -row => int($i/2), -sticky => 'w');
  739. }
  740. sub toggleWidgetShown {
  741.     my ($num, $var) = @_;
  742.     if ($$var) {
  743. createRow($num);
  744.     } else {
  745. $displayLabels[$num]->gridForget();
  746. $displayEntries[$num]->gridForget()
  747.     }
  748. #    my @widgets = $dispFrame->gridSlaves(-row => $num);
  749. }
  750. sub loadNewMibFile {
  751.     my $sel = $top->FileSelect();
  752.     my $file = $sel->Show();
  753.     if (defined($file)) {
  754.       SNMP::addMibFiles($file);
  755. showChildren("1.3.6.1");
  756. showChildren("1.3.6.1");
  757.     }
  758. }
  759. sub loadNewMibModule {
  760.     my $tmptop = MainWindow->new();
  761.     my $var = "";
  762.     $tmptop->Label(-pady => $tmpbd, -padx => $tmpbd, -text => "Enter a SNMP MIB module name")
  763. ->pack(-side => 'top');
  764.     my $e = $tmptop->Entry(-textvariable => $var);
  765.     $e->pack(-side => 'top');
  766.     $e->bind('<Return>',[&loadIt,$var,$tmptop]);
  767.     my $f = $tmptop->Frame();
  768.     $f->pack(-side => 'top');
  769.     $f->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'Ok', -command => [&loadIt,"",$var,$tmptop])
  770. ->pack(-side => 'left');
  771.     $f->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'Cancel', -command => [sub { my $wid = shift;
  772.      $wid->destroy(); },
  773.        $tmptop])
  774. ->pack(-side => 'left');
  775. }
  776. sub loadIt {
  777.     my $var = shift;
  778.     if ($var ne "") {
  779.         my $ret = SNMP::loadModules($var);
  780. if ($ret) {
  781.     showChildren("1.3.6.1");
  782.     showChildren("1.3.6.1");
  783.     return 1;
  784. } else {
  785.     $status->configure(-text => "Failed reading module $var");
  786.     return 0;
  787. }
  788.     }
  789.     return 0;
  790. }
  791. sub stop {
  792.     $stopit = shift;
  793.     if ($stopit) {
  794. $stopBut->configure(-state => 'disabled');
  795.     } else {
  796. $stopBut->configure(-state => 'normal');
  797.     }
  798. }
  799. sub entryBox {
  800.     my $title = shift;
  801.     my $text = shift;
  802.     my $var = shift;
  803.     my $callback = shift;
  804.     my $top = MainWindow->new();
  805.     my $newvar = $$var if defined($var);
  806.     $top->title($title);
  807.     my $f = $top->Frame();
  808.     $f->pack(-side => 'top');
  809.     $f->Label(-pady => $tmpbd, -padx => $tmpbd,
  810.       -text => $text)->pack(-side => 'left');
  811.     my $e = $f->Entry(-textvariable => $newvar);
  812.     $e->pack(-side => 'left');
  813.     $f = $top->Frame();
  814.     $f->pack(-side => 'bottom');
  815.     my $b = $f->Button(-pady => $tmpbd, -padx => $tmpbd, -text => 'Ok', 
  816.        -command => [sub { my $w = shift;
  817.   my $v1 = shift;
  818.   my $v2 = shift;
  819.   my $call = shift;
  820.   my $ret = 1;
  821.   $$v1 = $$v2 if defined($v1);
  822.   $ret = $call->($$v2) 
  823.       if defined($call);
  824.   $w->destroy() if ($ret);}, $top, $var,
  825.     $newvar, $callback]);
  826.     $b->pack(-side => 'left');
  827.     $e->bind('<Return>',[$b,'invoke']);
  828.     $b = $f->Button(-pady => $tmpbd, -padx => $tmpbd, 
  829.     -text => 'Cancel', -command => [sub { my $w = shift;
  830.   $w->destroy();}, $top
  831.     ]);
  832.     $b->pack(-side => 'right');
  833.     $e->bind('<Escape>',[$b,'invoke']);
  834.     
  835. }
  836. sub findANode {     
  837.     my $val = shift;
  838.     my $tag = SNMP::translateObj($val);
  839.     if ($tag) {
  840. showAllChildren($tag);
  841. return 1;
  842.     } else {
  843. $top->Dialog(-text => "$val not found")->Show();
  844. return 0;
  845.     }
  846. }
  847. sub test_version {
  848.     my ($gt, $major, $minor, $sub) = @_;
  849.     $SNMP::VERSION =~ /(d).(d).(d)/;
  850.     if ($gt) {
  851. if ($1 > $major || ($1 == $major && $2 > $minor) || 
  852.     ($1 == $major && $2 == $minor && $3 >= $sub)) {
  853.     return 1;
  854. }
  855.     } else {
  856. if ($1 < $major || ($1 == $major && $2 < $minor) || ($1 == $major && $2 == $minor && $3 < $sub)) {
  857.     return 1;
  858. }
  859.     }
  860.     return 0;
  861. }
  862. sub save_options {
  863.     my $umask = umask();
  864.     umask 0077; # make sure its not readable by the world by default.
  865.     if (!open(O,">$opts{C}")) {
  866. warn "can't save to $opts{C}n";
  867. umask $umask;
  868. return;
  869.     }
  870.     umask $umask;
  871.     print O Data::Dumper->Dump([%session_opts], [qw(*session_opts)]);
  872.     print O Data::Dumper->Dump([%displayInfoStates], [qw(*displayInfoStates)]);
  873.     foreach my $var (@saveoptions) {
  874. print O Data::Dumper->Dump([$$var], [$var]);
  875.     }
  876.     close(O);
  877.     $status->configure(-text => "saved options to $opts{C}");
  878. }
  879. # returns 1 if $oid2 is below $oid1 in the hierarchy
  880. sub is_in_subtree {
  881.     my ($oid1, $oid2) = @_;
  882.     # get pure numeric
  883.     $oid1 = SNMP::translateObj($oid1) if ($oid1 !~ /^[d.]*$/);
  884.     $oid2 = SNMP::translateObj($oid2) if ($oid2 !~ /^[d.]*$/);
  885.     # has more on it or is exactly the same
  886.     return 1 if ($oid2 =~ /^$oid1./ || $oid2 =~ /^$oid1$/);
  887.     return 0;
  888. }
  889. sub format_oid {
  890.     my ($oid, $type) = @_;
  891.     $oid =~ s/.$//;
  892.     $type = $displayoidas if ($type eq "");
  893.     if ($type eq 'numeric') {
  894. return SNMP::translateObj($oid) if ($oid !~ /^[d.]*$/);
  895. return $oid;
  896.     } elsif ($type eq 'full') {
  897. return SNMP::translateObj($oid, 1) if ($oid =~ /^[d.]*$/);
  898. return SNMP::translateObj(SNMP::translateObj($oid), 1) if ($oid !~ /^./);
  899. return $oid;
  900.     } elsif ($type eq 'short' || $type eq 'module') {
  901. $oid = SNMP::translateObj($oid) if ($oid =~ /^[d.]*$/);
  902. $oid =~ s/.*.([a-zA-Z]w+).(.*)/$1.$2/;
  903. if ($type eq 'module') {
  904.     $oid = $SNMP::MIB{format_oid($oid,'numeric')}->{'moduleID'} . "::" . $oid;
  905. }
  906. return $oid;
  907.     } elsif ($type eq 'module') {
  908. $oid = SNMP::translateObj($oid) if ($oid =~ /^[d.]*$/);
  909. $oid =~ s/.*.([a-zA-Z]w+).(.*)/$1.$2/;
  910. return $oid;
  911.     } else {
  912. warn 'unknown oid translation type: $type';
  913. return $oid;
  914.     }
  915. }
  916. sub get_oid {
  917.     my ($var, $type) = @_;
  918.     return format_oid($var->tag . "." . $var->iid, $type);
  919. }