1 # SNMP.pm -- Perl 5 interface to the net-snmp toolkit
3 # written by G. S. Marzot (gmarzot@nortelnetworks.com)
5 # Copyright (c) 1995-2000 G. S. Marzot. All rights reserved.
6 # This program is free software; you can redistribute it and/or
7 # modify it under the same terms as Perl itself.
10 $VERSION = '5.0.8'; # current release version number
16 use NetSNMP::default_store (':all');
18 @SNMP::ISA = qw(Exporter AutoLoader DynaLoader);
19 # Items to export into callers namespace by default. Note: do not export
20 # names by default without a very good reason. Use EXPORT_OK instead.
21 # Do not simply export all your public functions/methods/constants.
30 SNMP_DEFAULT_COMMUNITY_LEN
31 SNMP_DEFAULT_ENTERPRISE_LENGTH
49 # This AUTOLOAD is used to 'autoload' constants from the constant()
50 # XS function. If a constant is not found then control is passed
51 # to the AUTOLOAD in AutoLoader.
52 my($val,$pack,$file,$line);
54 ($constname = $AUTOLOAD) =~ s/.*:://;
55 # croak "&$module::constant not defined" if $constname eq 'constant';
56 $val = constant($constname, @_ ? $_[0] : 0);
58 if ($! =~ /Invalid/) {
59 $AutoLoader::AUTOLOAD = $AUTOLOAD;
60 goto &AutoLoader::AUTOLOAD;
63 ($pack,$file,$line) = caller;
64 die "Your vendor has not defined SNMP macro $constname, used at $file line $line.
68 eval "sub $AUTOLOAD { $val }";
74 # Preloaded methods go here.
77 tie $SNMP::debugging, SNMP::DEBUGGING;
78 tie $SNMP::debug_internals, SNMP::DEBUG_INTERNALS;
79 tie $SNMP::dump_packet, SNMP::DUMP_PACKET;
80 tie %SNMP::MIB, SNMP::MIB;
81 tie $SNMP::save_descriptions, SNMP::MIB::SAVE_DESCR;
82 tie $SNMP::replace_newer, SNMP::MIB::REPLACE_NEWER;
84 %SNMP::V3_SEC_LEVEL_MAP = (noAuthNoPriv => 1, authNoPriv => 2, authPriv =>3);
86 $auto_init_mib = 1; # enable automatic MIB loading at session creation time
87 $use_long_names = 0; # non-zero to prefer longer mib textual identifiers rather
88 # than just leaf indentifiers (see translateObj)
89 # may also be set on a per session basis(see UseLongNames)
90 $use_sprint_value = 0; # non-zero to enable formatting of response values
91 # using the snmp libraries "snprint_value"
92 # may also be set on a per session basis(see UseSprintValue)
93 # note: returned values not suitable for 'set' operations
94 $use_enums = 0; # non-zero to return integers as enums and allow sets
95 # using enums where appropriate - integer data will
96 # still be accepted for set operations
97 # may also be set on a per session basis (see UseEnums)
98 $use_numeric = 0; # non-zero to return object tags as numeric OID's instead
99 # of converting to textual representations. use_long_names,
100 # if non-zero, returns the entire OID, otherwise, return just
101 # the label portion. use_long_names is also set if the
102 # use_numeric variable is set.
103 %MIB = (); # tied hash to access libraries internal mib tree structure
104 # parsed in from mib files
105 $verbose = 0; # controls warning/info output of SNMP module,
106 # 0 => no output, 1 => enables warning and info
107 # output from SNMP module itself (is also controlled
108 # by SNMP::debugging)
109 $debugging = 0; # non-zero to globally enable libsnmp do_debugging output
110 # set to >= 2 to enabling packet dumping (see below)
111 $dump_packet = 0; # non-zero to globally enable libsnmp dump_packet output.
112 # is also enabled when $debugging >= 2
113 $save_descriptions = 0; #tied scalar to control saving descriptions during
114 # mib parsing - must be set prior to mib loading
115 $best_guess = 0; # determine whether or not to enable best-guess regular
116 # expression object name translation
117 $replace_newer = 0; # determine whether or not to tell the parser to replace
118 # older MIB modules with newer ones when loading MIBs.
119 # WARNING: This can cause an incorrect hierarchy.
122 # loads mib from file name provided
123 # setting second arg to true causes currently loaded mib to be replaced
124 # otherwise mib file will be added to existing loaded mib database
125 # NOTE: now deprecated in favor of addMibFiles and new module based funcs
127 my $force = shift || '0';
128 return 0 if $file and not (-r $file);
129 SNMP::_read_mib($file,$force);
133 # eqivalent to calling the snmp library init_mib if Mib is NULL
134 # if Mib is already loaded this function does nothing
135 # Pass a zero valued argument to get minimal mib tree initialzation
136 # If non zero agrgument or no argument then full mib initialization
138 SNMP::init_snmp("perl");
142 if (defined $_[0] and $_[0] == 0) {
143 SNMP::_init_mib_internals();
150 # adds directories to search path when a module is requested to be loaded
151 SNMP::init_snmp("perl");
153 SNMP::_add_mib_dir($_) or return undef;
159 # adds mib definitions to currently loaded mib database from
161 SNMP::init_snmp("perl");
163 SNMP::_read_mib($_) or return undef;
169 # adds mib module definitions to currently loaded mib database.
170 # Modules will be searched from previously defined mib search dirs
171 # Passing and arg of 'ALL' will cause all known modules to be loaded
172 SNMP::init_snmp("perl");
174 SNMP::_read_module($_) or return undef;
180 # causes modules to be unloaded from mib database
181 # Passing and arg of 'ALL' will cause all known modules to be unloaded
182 warn("SNMP::unloadModules not implemented! (yet)");
186 # translate object identifier(tag or numeric) into alternate representation
187 # (i.e., sysDescr => '.1.3.6.1.2.1.1.1' and '.1.3.6.1.2.1.1.1' => sysDescr)
188 # when $SNMP::use_long_names or second arg is non-zero the translation will
189 # return longer textual identifiers (e.g., system.sysDescr)
190 # if Mib is not loaded and $SNMP::auto_init_mib is enabled Mib will be loaded
191 # returns 'undef' upon failure
192 SNMP::init_snmp("perl");
194 my $long_names = shift || $SNMP::use_long_names;
195 return undef if not defined $obj;
197 if ($obj =~ /^\.?(\d+\.)*\d+$/) {
198 $res = SNMP::_translate_obj($obj,1,$long_names,$SNMP::auto_init_mib,0);
199 } elsif ($obj =~ /(\.\d+)*$/ && $SNMP::best_guess == 0) {
200 $res = SNMP::_translate_obj($`,0,$long_names,$SNMP::auto_init_mib,0);
201 $res .= $& if defined $res and defined $&;
202 } elsif ($SNMP::best_guess) {
203 $res = SNMP::_translate_obj($obj,0,$long_names,$SNMP::auto_init_mib,$SNMP::best_guess);
210 # return SNMP data type for given textual identifier
211 # OBJECTID, OCTETSTR, INTEGER, NETADDR, IPADDR, COUNTER
212 # GAUGE, TIMETICKS, OPAQUE, or undef
214 SNMP::_get_type($tag);
218 # return the corresponding integer value *or* tag for a given MIB attribute
219 # and value. The function will sense which direction to perform the conversion
220 # various arg formats are supported
221 # $val = SNMP::mapEnum($varbind); # note: will update $varbind
222 # $val = SNMP::mapEnum('ipForwarding', 'forwarding');
223 # $val = SNMP::mapEnum('ipForwarding', 1);
226 my ($tag, $val, $update);
227 if (ref($var) =~ /ARRAY/ or ref($var) =~ /Varbind/) {
228 $tag = $var->[$SNMP::Varbind::tag_f];
229 $val = $var->[$SNMP::Varbind::val_f];
235 my $iflag = $val =~ /^\d+$/;
236 my $res = SNMP::_map_enum($tag, $val, $iflag);
237 if ($update and defined $res) { $var->[$SNMP::Varbind::val_f] = $res; }
241 %session_params = (DestHost => 1,
249 sub strip_session_params {
253 while ($param = shift) {
254 push(@params,$param, shift), next
255 if $session_params{$param};
264 # procedural form of 'get' method. sometimes quicker to code
265 # but is less efficient since the Session is created and destroyed
266 # with each call. Takes all the parameters of both SNMP::Session::new and
267 # SNMP::Session::get (*NOTE*: this api does not support async callbacks)
269 my @sess_params = &strip_session_params;
270 my $sess = new SNMP::Session(@sess_params);
276 # procedural form of 'getnext' method. sometimes quicker to code
277 # but is less efficient since the Session is created and destroyed
278 # with each call. Takes all the parameters of both SNMP::Session::new and
279 # SNMP::Session::getnext (*NOTE*: this api does not support async callbacks)
281 my @sess_params = &strip_session_params;
282 my $sess = new SNMP::Session(@sess_params);
288 # procedural form of 'set' method. sometimes quicker to code
289 # but is less efficient since the Session is created and destroyed
290 # with each call. Takes all the parameters of both SNMP::Session::new and
291 # SNMP::Session::set (*NOTE*: this api does not support async callbacks)
293 my @sess_params = &strip_session_params;
294 my $sess = new SNMP::Session(@sess_params);
300 # procedural form of 'trap' method. sometimes quicker to code
301 # but is less efficient since the Session is created and destroyed
302 # with each call. Takes all the parameters of both SNMP::TrapSession::new and
303 # SNMP::TrapSession::trap
305 my @sess_params = &strip_session_params;
306 my $sess = new SNMP::TrapSession(@sess_params);
313 my $callback = shift;
314 my $time_sec = ($time ? int $time : 0);
315 my $time_usec = ($time ? int(($time-$time_sec)*1000000) : 0);
316 SNMP::_main_loop($time_sec,$time_usec,$callback);
320 SNMP::_mainloop_finish();
324 # callback function for async snmp calls
325 # when triggered, will do a SNMP read on the
328 SNMP::_read_on_fd($fd);
332 # retrieves SNMP used fd's and timeout info
333 # calculates timeout in fractional seconds
334 # ( easy to use with select statement )
335 my($block, $to_sec, $to_usec, @fd_set)=SNMP::_get_select_info();
336 my $time_sec_dec = ($block? 0 : $to_sec + $to_usec * 1e-6);
337 #print "fd's for snmp -> ", @fd_set, "\n";
338 #print "block -> ", $block, "\n";
339 #print "timeout_sec -> ", $to_sec, "\n";
340 #print "timeout_usec -> ", $to_usec, "\n";
341 #print "timeout dec -> ", $time_sec_dec, "\n";
342 return ($time_sec_dec,@fd_set);
346 # check to see if a snmp session
347 # timed out, and if so triggers
348 # the callback function
349 SNMP::_check_timeout();
350 # check to see when have to check again
351 my($block, $to_sec, $to_usec, @fd_set)=SNMP::_get_select_info();
352 my $time_sec_dec = ($block? 0 : $to_sec + $to_usec * 1e-6);
353 #print "fd's for snmp -> ", @fd_set, "\n";
354 #print "block -> ", $block, "\n";
355 #print "timeout_sec -> ", $to_sec, "\n";
356 #print "timeout_usec -> ", $to_usec, "\n";
357 #print "timeout dec -> ", $time_sec_dec, "\n";
358 return ($time_sec_dec);
362 # this is a little implementation hack so ActiveState can access pp_tie
363 # thru perl code. All other environments allow the calling of pp_tie from
364 # XS code but AS was not exporting it when PERL_OBJECT was used.
366 # short term solution was call this perl func which calls 'tie'
368 # longterm fix is to supply a patch which allows AS to export pp_tie in
369 # such a way that it can be called from XS code. gsarathy says:
370 # a patch to util.c is needed to provide access to PL_paddr
371 # so it is possible to call PL_paddr[OP_TIE] as the compiler does
372 tie($_[0],$_[1],$_[2],$_[3]);
375 package SNMP::Session;
380 my ($name, $aliases, $host_type, $len, $thisaddr);
382 SNMP::init_snmp("perl");
386 $this->{ErrorStr} = ''; # if methods return undef check for expln.
387 $this->{ErrorNum} = 0; # contains SNMP error return
390 NetSNMP::default_store::netsnmp_ds_get_int(NetSNMP::default_store::NETSNMP_DS_LIBRARY_ID,
391 NetSNMP::default_store::NETSNMP_DS_LIB_SNMPVERSION) ||
392 SNMP::SNMP_DEFAULT_VERSION();
394 if ($this->{Version} eq 128) {
395 # special handling of the bogus v1 definition.
396 $this->{Version} = 1;
399 # allow override of local SNMP port
400 $this->{LocalPort} ||= 0;
402 # destination host defaults to localhost
403 $this->{DestHost} ||= 'localhost';
405 # community defaults to public
406 $this->{Community} ||= NetSNMP::default_store::netsnmp_ds_get_string(NetSNMP::default_store::NETSNMP_DS_LIBRARY_ID(),
407 NetSNMP::default_store::NETSNMP_DS_LIB_COMMUNITY()) || 'public';
409 # number of retries before giving up, defaults to SNMP_DEFAULT_RETRIES
410 $this->{Retries} = SNMP::SNMP_DEFAULT_RETRIES() unless defined($this->{Retries});
412 # timeout before retry, defaults to SNMP_DEFAULT_TIMEOUT
413 $this->{Timeout} = SNMP::SNMP_DEFAULT_TIMEOUT() unless defined($this->{Timeout});
414 # flag to enable fixing pdu and retrying with a NoSuch error
415 $this->{RetryNoSuch} ||= 0;
417 # backwards compatibility. Make host = host:port
418 if ($this->{RemotePort} && $this->{DestHost} !~ /:/) {
419 $this->{DestHost} = $this->{DestHost} . ":" . $this->{RemotePort};
422 if ($this->{Version} eq '1' or $this->{Version} eq '2'
423 or $this->{Version} eq '2c') {
424 $this->{SessPtr} = SNMP::_new_session($this->{Version},
431 } elsif ($this->{Version} eq '3' ) {
433 NetSNMP::default_store::netsnmp_ds_get_string(NetSNMP::default_store::NETSNMP_DS_LIBRARY_ID(),
434 NetSNMP::default_store::NETSNMP_DS_LIB_SECNAME()) ||
436 if (!$this->{SecLevel}) {
438 NetSNMP::default_store::netsnmp_ds_get_int(NetSNMP::default_store::NETSNMP_DS_LIBRARY_ID(),
439 NetSNMP::default_store::NETSNMP_DS_LIB_SECLEVEL()) ||
440 $SNMP::V3_SEC_LEVEL_MAP{'noAuthNoPriv'};
441 } elsif ($this->{SecLevel} !~ /^\d+$/) {
442 $this->{SecLevel} = $SNMP::V3_SEC_LEVEL_MAP{$this->{SecLevel}};
444 $this->{SecEngineId} ||= '';
445 $this->{ContextEngineId} ||= $this->{SecEngineId};
447 NetSNMP::default_store::netsnmp_ds_get_string(NetSNMP::default_store::NETSNMP_DS_LIBRARY_ID(),
448 NetSNMP::default_store::NETSNMP_DS_LIB_CONTEXT()) || '';
449 $this->{AuthProto} ||= 'MD5'; # defaults XXX
450 $this->{AuthPass} ||=
451 NetSNMP::default_store::netsnmp_ds_get_string(NetSNMP::default_store::NETSNMP_DS_LIBRARY_ID(),
452 NetSNMP::default_store::NETSNMP_DS_LIB_AUTHPASSPHRASE()) ||
453 NetSNMP::default_store::netsnmp_ds_get_string(NetSNMP::default_store::NETSNMP_DS_LIBRARY_ID(),
454 NetSNMP::default_store::NETSNMP_DS_LIB_PASSPHRASE()) || '';
455 $this->{PrivProto} ||= 'DES'; # defaults XXX
456 $this->{PrivPass} ||=
457 NetSNMP::default_store::netsnmp_ds_get_string(NetSNMP::default_store::NETSNMP_DS_LIBRARY_ID(),
458 NetSNMP::default_store::NETSNMP_DS_LIB_PRIVPASSPHRASE()) ||
459 NetSNMP::default_store::netsnmp_ds_get_string(NetSNMP::default_store::NETSNMP_DS_LIBRARY_ID(),
460 NetSNMP::default_store::NETSNMP_DS_LIB_PASSPHRASE()) || '';
461 $this->{EngineBoots} = 0 if not defined $this->{EngineBoots};
462 $this->{EngineTime} = 0 if not defined $this->{EngineTime};
464 $this->{SessPtr} = SNMP::_new_v3_session($this->{Version},
470 $this->{SecEngineId},
471 $this->{ContextEngineId},
477 $this->{EngineBoots},
481 unless ($this->{SessPtr}) {
482 warn("unable to create session") if $SNMP::verbose;
486 SNMP::initMib($SNMP::auto_init_mib); # ensures that *some* mib is loaded
488 $this->{UseLongNames} ||= $SNMP::use_long_names;
489 $this->{UseSprintValue} ||= $SNMP::use_sprint_value;
490 $this->{UseEnums} ||= $SNMP::use_enums;
491 $this->{UseNumeric} ||= $SNMP::use_numeric;
493 # Force UseLongNames if UseNumeric is in use.
494 $this->{UseLongNames}++ if $this->{UseNumeric};
501 # designed to update the fields of session to allow retargetting to different
502 # host, community name change, timeout, retry changes etc. Unfortunately not
503 # working yet because some updates (the address in particular) need to be
504 # done on the internal session pointer which cannot be fetched w/o touching
505 # globals at this point which breaks win32. A patch to the ucd-snmp toolkit
508 my ($name, $aliases, $host_type, $len, $thisaddr);
511 @$this{keys %new_fields} = values %new_fields;
513 $this->{UseLongNames} ||= $SNMP::use_long_names;
514 $this->{UseSprintValue} ||= $SNMP::use_sprint_value;
515 $this->{UseEnums} ||= $SNMP::use_enums;
516 $this->{UseNumeric} ||= $SNMP::use_numeric;
518 # Force UseLongNames if UseNumeric is in use.
519 $this->{UseLongNames}++ if $this->{UseNumeric};
521 SNMP::_update_session($this->{Version},
536 my $varbind_list_ref;
539 if (ref($vars) =~ /SNMP::VarList/) {
540 $varbind_list_ref = $vars;
541 } elsif (ref($vars) =~ /SNMP::Varbind/) {
542 $varbind_list_ref = [$vars];
543 } elsif (ref($vars) =~ /ARRAY/) {
544 $varbind_list_ref = [$vars];
545 $varbind_list_ref = $vars if ref($$vars[0]) =~ /ARRAY/;
547 my ($tag, $iid) = ($vars =~ /^((?:\.\d+)+|(?:\w+(?:\-*\w+)+))\.?(.*)$/);
549 $varbind_list_ref = [[$tag, $iid, $val]];
553 $res = SNMP::_set($this, $varbind_list_ref, $cb);
559 my ($varbind_list_ref, @res);
561 if (ref($vars) =~ /SNMP::VarList/) {
562 $varbind_list_ref = $vars;
563 } elsif (ref($vars) =~ /SNMP::Varbind/) {
564 $varbind_list_ref = [$vars];
565 } elsif (ref($vars) =~ /ARRAY/) {
566 $varbind_list_ref = [$vars];
567 $varbind_list_ref = $vars if ref($$vars[0]) =~ /ARRAY/;
569 my ($tag, $iid) = ($vars =~ /^((?:\.\d+)+|(?:\w+(?:\-*\w+)+))\.?(.*)$/);
570 $varbind_list_ref = [[$tag, $iid]];
575 @res = SNMP::_get($this, $this->{RetryNoSuch}, $varbind_list_ref, $cb);
577 return(wantarray() ? @res : $res[0]);
583 my ($varbind_list_ref, @res);
585 if (ref($vars) =~ /SNMP::VarList/) {
586 $varbind_list_ref = $vars;
587 } elsif (ref($vars) =~ /SNMP::Varbind/) {
588 $varbind_list_ref = [$vars];
589 } elsif (ref($vars) =~ /ARRAY/) {
590 $varbind_list_ref = [$vars];
591 $varbind_list_ref = $vars if ref($$vars[0]) =~ /ARRAY/;
593 my ($tag, $iid) = ($vars =~ /^((?:\.\d+)+|(?:\w+(?:\-*\w+)+))\.?(.*)$/);
594 $varbind_list_ref = [[$tag, $iid]];
599 SNMP::_get($this, $this->{RetryNoSuch}, $varbind_list_ref, $cb);
601 foreach $varbind (@$varbind_list_ref) {
602 $sub = $this->{VarFormats}{$varbind->[$SNMP::Varbind::tag_f]} ||
603 $this->{TypeFormats}{$varbind->[$SNMP::Varbind::type_f]};
604 &$sub($varbind) if defined $sub;
605 push(@res, $varbind->[$SNMP::Varbind::val_f]);
608 return(wantarray() ? @res : $res[0]);
614 my ($varbind_list_ref, @res);
616 if (ref($vars) =~ /SNMP::VarList/) {
617 $varbind_list_ref = $vars;
618 } elsif (ref($vars) =~ /SNMP::Varbind/) {
619 $varbind_list_ref = [$vars];
620 } elsif (ref($vars) =~ /ARRAY/) {
621 $varbind_list_ref = [$vars];
622 $varbind_list_ref = $vars if ref($$vars[0]) =~ /ARRAY/;
624 my ($tag, $iid) = ($vars =~ /^((?:\.\d+)+|(?:\w+(?:\-*\w+)+))\.?(.*)$/);
625 $varbind_list_ref = [[$tag, $iid]];
630 @res = SNMP::_getnext($this, $varbind_list_ref, $cb);
632 return(wantarray() ? @res : $res[0]);
638 my ($varbind_list_ref, @res);
640 if (ref($vars) =~ /SNMP::VarList/) {
641 $varbind_list_ref = $vars;
642 } elsif (ref($vars) =~ /SNMP::Varbind/) {
643 $varbind_list_ref = [$vars];
644 } elsif (ref($vars) =~ /ARRAY/) {
645 $varbind_list_ref = [$vars];
646 $varbind_list_ref = $vars if ref($$vars[0]) =~ /ARRAY/;
648 my ($tag, $iid) = ($vars =~ /^((?:\.\d+)+|(?:\w+(?:\-*\w+)+))\.?(.*)$/);
649 $varbind_list_ref = [[$tag, $iid]];
654 SNMP::_getnext($this, $varbind_list_ref, $cb);
656 foreach $varbind (@$varbind_list_ref) {
657 $sub = $this->{VarFormats}{$varbind->[$SNMP::Varbind::tag_f]} ||
658 $this->{TypeFormats}{$varbind->[$SNMP::Varbind::type_f]};
659 &$sub($varbind) if defined $sub;
660 push(@res, $varbind->[$SNMP::Varbind::val_f]);
663 return(wantarray() ? @res : $res[0]);
668 my $nonrepeaters = shift;
669 my $maxrepetitions = shift;
671 my ($varbind_list_ref, @res);
673 if (ref($vars) =~ /SNMP::VarList/) {
674 $varbind_list_ref = $vars;
675 } elsif (ref($vars) =~ /SNMP::Varbind/) {
676 $varbind_list_ref = [$vars];
677 } elsif (ref($vars) =~ /ARRAY/) {
678 $varbind_list_ref = [$vars];
679 $varbind_list_ref = $vars if ref($$vars[0]) =~ /ARRAY/;
681 my ($tag, $iid) = ($vars =~ /^((?:\.\d+)+|(?:\w+(?:\-*\w+)+))\.?(.*)$/);
682 $varbind_list_ref = [[$tag, $iid]];
687 @res = SNMP::_getbulk($this, $nonrepeaters, $maxrepetitions, $varbind_list_ref, $cb);
689 return(wantarray() ? @res : $res[0]);
694 my $nonrepeaters = shift;
695 my $maxrepetitions = shift;
697 my ($varbind_list_ref, @res);
699 if (ref($vars) =~ /SNMP::VarList/) {
700 $varbind_list_ref = $vars;
701 } elsif (ref($vars) =~ /SNMP::Varbind/) {
702 $varbind_list_ref = [$vars];
703 } elsif (ref($vars) =~ /ARRAY/) {
704 $varbind_list_ref = [$vars];
705 $varbind_list_ref = $vars if ref($$vars[0]) =~ /ARRAY/;
707 my ($tag, $iid) = ($vars =~ /^((?:\.\d+)+|\w+)\.?(.*)$/);
708 $varbind_list_ref = [[$tag, $iid]];
711 if (scalar @$varbind_list_ref == 0) {
712 $this->{ErrorNum} = SNMP::constant("SNMPERR_GENERR", 0);
713 $this->{ErrorStr} = "cannot bulkwalk() empty variable list";
716 if (scalar @$varbind_list_ref < $nonrepeaters) {
717 $this->{ErrorNum} = SNMP::constant("SNMPERR_GENERR", 0);
718 $this->{ErrorStr} = "bulkwalk() needs at least $nonrepeaters varbinds";
723 @res = SNMP::_bulkwalk($this, $nonrepeaters, $maxrepetitions,
724 $varbind_list_ref, $cb);
726 # Return, in list context, a copy of the array of arrays of Varbind refs.
727 # In scalar context, return either a reference to the array of arrays of
728 # Varbind refs, or the request ID for an asynchronous bulkwalk. This is
729 # a compromise between the getbulk()-ish return, and the more useful array
730 # of arrays of Varbinds return from the synchronous bulkwalk().
732 return @res if (wantarray());
733 return defined($cb) ? $res[0] : \@res;
736 %trap_type = (coldStart => 0, warmStart => 1, linkDown => 2, linkUp => 3,
737 authFailure => 4, egpNeighborLoss => 5, specific => 6 );
739 # (v1) enterprise, agent, generic, specific, uptime, <vars>
740 # $sess->trap(enterprise=>'.1.3.6.1.4.1.2021', # or 'ucdavis' [default]
741 # agent => '127.0.0.1', # or 'localhost',[default 1st intf on host]
742 # generic => specific, # can be omitted if 'specific' supplied
743 # specific => 5, # can be omitted if 'generic' supplied
744 # uptime => 1234, # default to localhost uptime (0 on win32)
745 # [[ifIndex, 1, 1],[sysLocation, 0, "here"]]); # optional vars
747 # (v2) oid, uptime, <vars>
748 # $sess->trap(uptime => 1234,
749 # oid => 'snmpRisingAlarm',
750 # [[ifIndex, 1, 1],[sysLocation, 0, "here"]]); # optional vars
756 my $vars = pop if ref($_[$#_]); # last arg may be varbind or varlist
758 my ($varbind_list_ref, @res);
760 if (ref($vars) =~ /SNMP::VarList/) {
761 $varbind_list_ref = $vars;
762 } elsif (ref($vars) =~ /SNMP::Varbind/) {
763 $varbind_list_ref = [$vars];
764 } elsif (ref($vars) =~ /ARRAY/) {
765 $varbind_list_ref = [$vars];
766 $varbind_list_ref = $vars if ref($$vars[0]) =~ /ARRAY/;
769 if ($this->{Version} eq '1') {
770 my $enterprise = $param{enterprise} || 'ucdavis';
771 $enterprise = SNMP::translateObj($enterprise)
772 unless $enterprise =~ /^[\.\d]+$/;
773 my $agent = $param{agent} || '';
774 my $generic = $param{generic} || 'specific';
775 $generic = $trap_type{$generic} || $generic;
776 my $uptime = $param{uptime} || SNMP::_sys_uptime();
777 my $specific = $param{specific} || 0;
778 @res = SNMP::_trapV1($this, $enterprise, $agent, $generic, $specific,
779 $uptime, $varbind_list_ref);
780 } elsif (($this->{Version} eq '2')|| ($this->{Version} eq '2c')) {
781 my $trap_oid = $param{oid} || $param{trapoid} || '.0.0';
782 my $uptime = $param{uptime} || SNMP::_sys_uptime();
783 @res = SNMP::_trapV2($this, $uptime, $trap_oid, $varbind_list_ref);
786 return(wantarray() ? @res : $res[0]);
790 # (v3) oid, uptime, <vars>
791 # $sess->inform(uptime => 1234,
792 # oid => 'coldStart',
793 # [[ifIndex, 1, 1],[sysLocation, 0, "here"]]); # optional vars
801 $cb = pop if ref($_[$#_]) eq 'CODE'; # last arg may be code
802 $vars = pop if ref($_[$#_]); # varbind or varlist
804 my ($varbind_list_ref, @res);
806 if (ref($vars) =~ /SNMP::VarList/) {
807 $varbind_list_ref = $vars;
808 } elsif (ref($vars) =~ /SNMP::Varbind/) {
809 $varbind_list_ref = [$vars];
810 } elsif (ref($vars) =~ /ARRAY/) {
811 $varbind_list_ref = [$vars];
812 $varbind_list_ref = $vars if ref($$vars[0]) =~ /ARRAY/;
815 my $trap_oid = $param{oid} || $param{trapoid};
816 my $uptime = $param{uptime} || SNMP::_sys_uptime();
818 if($this->{Version} eq '3') {
819 @res = SNMP::_inform($this, $uptime, $trap_oid, $varbind_list_ref, $cb);
821 warn("error:inform: This version doesn't support the command\n");
824 return(wantarray() ? @res : $res[0]);
827 package SNMP::TrapSession;
828 @ISA = ('SNMP::Session');
833 # allow override of remote SNMP trap port
834 unless (grep(/RemotePort/, @_)) {
835 push(@_, 'RemotePort', 162); # push on new default for trap session
838 SNMP::Session::new($type, @_);
841 package SNMP::Varbind;
873 if (defined($_[0]->[$iid_f]) && ($_[0]->[$iid_f] =~ m/^[0-9]+$/)) {
874 return $_[0]->[$tag_f] . "." . $_[0]->[$iid_f];
877 return $_[0]->[$tag_f];
882 return $self->name . " = \"" . $self->val . "\" (" . $self->type . ")";
887 # print "SNMP::Varbind::DESTROY($_[0])\n";
890 package SNMP::VarList;
897 $varb = new SNMP::Varbind($varb) unless ref($varb) =~ /SNMP::Varbind/;
898 push(@{$this}, $varb);
905 # print "SNMP::VarList::DESTROY($_[0])\n";
908 package SNMP::DEBUGGING;
909 # controls info/debugging output from SNMP module and libsnmp
910 # $SNMP::debugging == 1 => enables general info and warning output
911 # (eqiv. to setting $SNMP::verbose)
912 # $SNMP::debugging == 2 => enables do_debugging from libsnmp as well
913 # $SNMP::debugging == 3 => enables packet_dump from libsnmp as well
914 sub TIESCALAR { my $class = shift; my $val; bless \$val, $class; }
916 sub FETCH { ${$_[0]}; }
919 $SNMP::verbose = $_[1];
920 SNMP::_set_debugging($_[1]>1);
921 $SNMP::dump_packet = ($_[1]>2);
927 SNMP::_set_debugging(0);
928 $SNMP::dump_packet = 0;
932 package SNMP::DEBUG_INTERNALS; # Controls SNMP.xs debugging.
933 sub TIESCALAR { my $class = shift; my $val; bless \$val, $class; }
935 sub FETCH { ${$_[0]}; }
938 SNMP::_debug_internals($_[1]);
943 SNMP::_debug_internals(0);
947 package SNMP::DUMP_PACKET;
948 # controls packet dump output from libsnmp
950 sub TIESCALAR { my $class = shift; my $val; bless \$val, $class; }
952 sub FETCH { ${$_[0]}; }
954 sub STORE { SNMP::_dump_packet($_[1]); ${$_[0]} = $_[1]; }
956 sub DELETE { SNMP::_dump_packet(0); ${$_[0]} = 0; }
968 if (!defined $this->{$key}) {
969 tie(%{$this->{$key}}, SNMP::MIB::NODE, $key) or return undef;
975 warn "STORE(@_) : write access to the MIB not implemented\n";
979 delete $_[0]->{$_[1]}; # just delete cache entry
982 sub FIRSTKEY { return '.1'; } # this should actually start at .0 but
983 # because nodes are not stored in lexico
984 # order in ucd-snmp node tree walk will
985 # miss most of the tree
986 sub NEXTKEY { # this could be sped up by using an XS __get_next_oid maybe
987 my $node = $_[0]->FETCH($_[1])->{nextNode};
990 sub EXISTS { exists $_[0]->{$_[1]} || $_[0]->FETCH($_[1]); }
991 sub CLEAR { undef %{$_[0]}; } # clear the cache
993 package SNMP::MIB::NODE;
996 objectID => 0, # dotted decimal fully qualified OID
997 label => 0, # leaf textual identifier (e.g., 'sysDescr')
998 subID => 0, # leaf numeric OID component of objectID (e.g., '1')
999 moduleID => 0, # textual identifier for module (e.g., 'RFC1213-MIB')
1000 parent => 0, # parent node
1001 children => 0, # array reference of children nodes
1002 indexes => 0, # returns array of column labels
1003 varbinds => 0, # returns array of trap/notification varbinds
1004 nextNode => 0, # next lexico node (BUG! does not return in lexico order)
1005 type => 0, # returns simple type (see getType for values)
1006 access => 0, # returns ACCESS (ReadOnly, ReadWrite, WriteOnly,
1007 # NoAccess, Notify, Create)
1008 status => 0, # returns STATUS (Mandatory, Optional, Obsolete,
1010 syntax => 0, # returns 'textualConvention' if defined else 'type'
1011 textualConvention => 0, # returns TEXTUAL-CONVENTION
1012 units => 0, # returns UNITS
1013 hint => 0, # returns HINT
1014 enums => 0, # returns hash ref {tag => num, ...}
1015 ranges => 0, # returns array ref of hash ref [{low => num, high => num}]
1016 defaultValue => 0, # returns default value
1017 description => 0, # returns DESCRIPTION ($SNMP::save_descriptions must
1018 # be set prior to MIB initialization/parsing
1021 # sub TIEHASH - implemented in SNMP.xs
1023 # sub FETCH - implemented in SNMP.xs
1026 warn "STORE(@_): write access to MIB node not implemented\n";
1030 warn "DELETE(@_): write access to MIB node not implemented\n";
1033 sub FIRSTKEY { my $k = keys %node_elements; (each(%node_elements))[0]; }
1034 sub NEXTKEY { (each(%node_elements))[0]; }
1035 sub EXISTS { exists($node_elements{$_[1]}); }
1037 warn "CLEAR(@_): write access to MIB node not implemented\n";
1041 # warn "DESTROY(@_): write access to MIB node not implemented\n";
1042 # # print "SNMP::MIB::NODE::DESTROY : $_[0]->{label} ($_[0])\n";
1044 package SNMP::MIB::SAVE_DESCR;
1046 sub TIESCALAR { my $class = shift; my $val; bless \$val, $class; }
1048 sub FETCH { ${$_[0]}; }
1050 sub STORE { SNMP::_set_save_descriptions($_[1]); ${$_[0]} = $_[1]; }
1052 sub DELETE { SNMP::_set_save_descriptions(0); ${$_[0]} = 0; }
1054 package SNMP::MIB::REPLACE_NEWER; # Controls MIB parsing
1056 sub TIESCALAR { my $class = shift; my $val; bless \$val, $class; }
1058 sub FETCH { ${$_[0]}; }
1061 SNMP::_set_replace_newer($_[1]);
1066 SNMP::_set_replace_newer(0);
1071 END{SNMP::_sock_cleanup() if defined &SNMP::_sock_cleanup;}
1072 # Autoload methods go after __END__, and are processed by the autosplit prog.
1079 SNMP - The Perl5 'SNMP' Extension Module v3.1.0 for the UCD SNMPv3 Library
1085 $sess = new SNMP::Session(DestHost => localhost, Community => public);
1086 $val = $sess->get('sysDescr.0');
1088 $vars = new SNMP::VarList([sysDescr,0], [sysContact,0], [sysLocation,0]);
1089 @vals = $sess->get($vars);
1091 $vb = new SNMP::Varbind();
1093 $val = $sess->getnext($vb);
1095 } until ($sess->{ErrorNum});
1097 $SNMP::save_descriptions = 1;
1098 SNMP::initMib(); # assuming mib is not already loaded
1099 print "$SNMP::MIB{sysDescr}{description}\n";
1104 Note: The perl SNMP 5.0 module which comes with net-snmp 5.0 and
1105 higher is different than previous versions in a number of ways. Most
1106 importantly, it behaves like a proper net-snmp application and calls
1107 init_snmp properly, which means it will read configuration files and
1108 use those defaults where appropriate automatically parse MIB files,
1109 etc. This will likely affect your perl applications if you have, for
1110 instance, default values set up in your snmp.conf file (as the perl
1111 module will now make use of those defaults). The docmuentation,
1112 however, has sadly not been updated yet (aside from this note), nor is
1113 the read_config default usage implementation fully complete.
1115 The basic operations of the SNMP protocol are provided by this module
1116 through an object oriented interface for modularity and ease of use.
1117 The primary class is SNMP::Session which encapsulates the persistent
1118 aspects of a connection between the management application and the
1119 managed agent. Internally the class is implemented as a blessed hash
1120 reference. This class supplies 'get', 'getnext', 'set', 'fget', and
1121 'fgetnext' method calls. The methods take a variety of input argument
1122 formats and support both syncronous and asyncronous operation through
1123 a polymorphic API (i.e., method behaviour varies dependent on args
1124 passed - see below).
1126 =head1 SNMP::Session
1128 $sess = new SNMP::Session(DestHost => 'host', ...)
1130 The following arguments may be passed to new as a hash.
1136 default 'localhost', hostname or ip addr of SNMP agent
1140 default 'public', SNMP community string (used for both R/W)
1144 default '1', [2 (same as 2c), 2c, 3]
1148 default '161', allow remote UDP port to be overriden
1152 default '1000000', micro-seconds before retry
1156 default '5', retries before failure
1160 default '0', if enabled NOSUCH errors in 'get' pdus will
1161 be repaired, removing the varbind in error, and resent -
1162 undef will be returned for all NOSUCH varbinds, when set
1163 to '0' this feature is disabled and the entire get request
1164 will fail on any NOSUCH error (applies to v1 only)
1168 default 'initial', security name (v3)
1172 default 'noAuthNoPriv', security level [noAuthNoPriv,
1173 authNoPriv, authPriv] (v3)
1177 default <none>, security engineID, will be probed if not
1180 =item ContextEngineId
1182 default <SecEngineId>, context engineID, will be
1183 probed if not supplied (v3)
1187 default '', context name (v3)
1191 default 'MD5', authentication protocol [MD5, SHA] (v3)
1195 default <none>, authentication passphrase
1199 default 'DES', privacy protocol [DES] (v3)
1203 default <none>, privacy passphrase (v3)
1207 default 'undef', used by 'fget[next]', holds an hash
1208 reference of output value formatters, (e.g., {<obj> =>
1209 <sub-ref>, ... }, <obj> must match the <obj> and format
1210 used in the get operation. A special <obj>, '*', may be
1211 used to apply all <obj>s, the supplied sub is called to
1212 translate the value to a new format. The sub is called
1213 passing the Varbind as the arg
1217 default 'undef', used by 'fget[next]', holds an hash
1218 reference of output value formatters, (e.g., {<type> =>
1219 <sub-ref>, ... }, the supplied sub is called to translate
1220 the value to a new format, unless a VarFormat mathces first
1221 (e.g., $sess->{TypeFormats}{INTEGER} = \&mapEnum();
1222 although this can be done more efficiently by enabling
1223 $SNMP::use_enums or session creation param 'UseEnums')
1227 defaults to the value of SNMP::use_long_names at time
1228 of session creation. set to non-zero to have <tags>
1229 for 'getnext' methods generated preferring longer Mib name
1230 convention (e.g., system.sysDescr vs just sysDescr)
1232 =item UseSprintValue
1234 defaults to the value of SNMP::use_sprint_value at time
1235 of session creation. set to non-zero to have return values
1236 for 'get' and 'getnext' methods formatted with the libraries
1237 snprint_value function. This will result in certain data types
1238 being returned in non-canonical format Note: values returned
1239 with this option set may not be appropriate for 'set' operations
1240 (see discussion of value formats in <vars> description section)
1244 defaults to the value of SNMP::use_enums at time of session
1245 creation. set to non-zero to have integer return values
1246 converted to enumeration identifiers if possible, these values
1247 will also be acceptable when supplied to 'set' operations
1251 defaults to the value of SNMP::use_numeric at time of session
1252 creation. set to non-zero to have <tags> for get methods returned
1253 as numeric OID's rather than descriptions. UseLongNames will be
1254 set so that the full OID is returned to the caller.
1258 read-only, holds the error message assoc. w/ last request
1262 read-only, holds the snmp_err or staus of last request
1266 read-only, holds the snmp_err_index when appropriate
1276 internal field used to hold the translated DestHost field
1280 internal field used to cache a created session structure
1284 =head2 SNMP::Session methods
1288 =item $sess->update(E<lt>fieldsE<gt>)
1290 Updates the SNMP::Session object with the values fields
1291 passed in as a hash list (similar to new(E<lt>fieldsE<gt>))
1292 B<(WARNING! not fully implemented)>
1294 =item $sess->get(E<lt>varsE<gt> [,E<lt>callbackE<gt>])
1296 do SNMP GET, multiple <vars> formats accepted.
1297 for syncronous operation <vars> will be updated
1298 with value(s) and type(s) and will also return
1299 retrieved value(s). If <callback> supplied method
1300 will operate asyncronously
1302 =item $sess->fget(E<lt>varsE<gt> [,E<lt>callbackE<gt>])
1304 do SNMP GET like 'get' and format the values according
1305 the handlers specified in $sess->{VarFormats} and
1306 $sess->{TypeFormats}
1308 =item $sess->getnext(E<lt>varsE<gt> [,E<lt>callbackE<gt>])
1310 do SNMP GETNEXT, multiple <vars> formats accepted,
1311 returns retrieved value(s), <vars> passed as arguments are
1312 updated to indicate next lexicographical <obj>,<iid>,<val>,
1315 Note: simple string <vars>,(e.g., 'sysDescr.0')
1316 form is not updated. If <callback> supplied method
1317 will operate asyncronously
1319 =item $sess->fgetnext(E<lt>varsE<gt> [,E<lt>callbackE<gt>])
1321 do SNMP GETNEXT like getnext and format the values according
1322 the handlers specified in $sess->{VarFormats} and
1323 $sess->{TypeFormats}
1325 =item $sess->set(E<lt>varsE<gt> [,E<lt>callbackE<gt>])
1327 do SNMP SET, multiple <vars> formats accepted.
1328 the value field in all <vars> formats must be in a canonical
1329 format (i.e., well known format) to ensure unambiguous
1330 translation to SNMP MIB data value (see discussion of
1331 canonical value format <vars> description section),
1332 returns snmp_errno. If <callback> supplied method
1333 will operate asyncronously
1335 =item $sess->getbulk(E<lt>non-repeatersE<gt>, E<lt>max-repeatersE<gt>, E<lt>varsE<gt>)
1337 do an SNMP GETBULK, from the list of Varbinds, the single
1338 next lexico instance is fetched for the first n Varbinds
1339 as defined by <non-repeaters>. For remaining Varbinds,
1340 the m lexico instances are retrieved each of the remaining
1341 Varbinds, where m is <max-repeaters>.
1343 =item $sess->bulkwalk(E<lt>non-repeatersE<gt>, E<lt>max-repeatersE<gt>, E<lt>varsE<gt> [,E<lt>callbackE<gt>])
1345 Do a "bulkwalk" of the list of Varbinds. This is done by
1346 sending a GETBULK request (see getbulk() above) for the
1347 Varbinds. For each requested variable, the response is
1348 examined to see if the next lexico instance has left the
1349 requested sub-tree. Any further instances returned for
1350 this variable are ignored, and the walk for that sub-tree
1351 is considered complete.
1353 If any sub-trees were not completed when the end of the
1354 responses is reached, another request is composed, consisting
1355 of the remaining variables. This process is repeated until
1356 all sub-trees have been completed, or too many packets have
1357 been exchanged (to avoid loops).
1359 The bulkwalk() method returns an array containing an array of
1360 Varbinds, one for each requested variable, in the order of the
1361 variable requests. Upon error, bulkwalk() returns undef and
1362 sets $sess->ErrorStr and $sess->ErrorNum. If a callback is
1363 supplied, bulkwalk() returns the SNMP request id, and returns
1364 immediately. The callback will be called with the supplied
1365 argument list and the returned variables list.
1367 Note: Because the client must "discover" that the tree is
1368 complete by comparing the returned variables with those that
1369 were requested, there is a potential "gotcha" when using the
1370 max-repeaters value. Consider the following code to print a
1371 list of interfaces and byte counts:
1373 $numInts = $sess->get('ifNumber.0');
1374 ($desc, $in, $out) = $sess->bulkwalk(0, $numInts,
1375 [['ifDescr'], ['ifInOctets'], ['ifOutOctets']]);
1377 for $i (0..($numInts - 1)) {
1378 printf "Interface %4s: %s inOctets, %s outOctets\n",
1379 $$desc[$i]->val, $$in[$i]->val, $$out[$i]->val;
1382 This code will produce *two* requests to the agent -- the first
1383 to get the interface values, and the second to discover that all
1384 the information was in the first packet. To get around this,
1385 use '$numInts + 1' for the max_repeaters value. This asks the
1386 agent to include one additional (unrelated) variable that signals
1387 the end of the sub-tree, allowing bulkwalk() to determine that
1388 the request is complete.
1392 =head1 SNMP::TrapSession
1394 $sess = new SNMP::Session(DestHost => 'host', ...)
1396 supports all applicable fields from SNMP::Session
1399 =head2 SNMP::TrapSession methods
1403 =item $sess->trap(enterprise, agent, generic, specific, uptime, <vars>)
1405 $sess->trap(enterprise=>'.1.3.6.1.4.1.2021', # or 'ucdavis' [default]
1406 agent => '127.0.0.1', # or 'localhost',[dflt 1st intf on host]
1407 generic => specific, # can be omitted if 'specific' supplied
1408 specific => 5, # can be omitted if 'generic' supplied
1409 uptime => 1234, # dflt to localhost uptime (0 on win32)
1410 [[ifIndex, 1, 1],[sysLocation, 0, "here"]]); # optional vars
1413 =item trap(oid, uptime, <vars>) - v2 format
1415 $sess->trap(oid => 'snmpRisingAlarm',
1417 [[ifIndex, 1, 1],[sysLocation, 0, "here"]]); # optional vars
1422 =head1 Acceptable variable formats:
1424 <vars> may be one of the following forms:
1430 represents an array of MIB objects to get or set,
1431 implemented as a blessed reference to an array of
1432 SNMP::Varbinds, (e.g., [<varbind1>, <varbind2>, ...])
1436 represents a single MIB object to get or set, implemented as
1437 a blessed reference to a 4 element array;
1438 [<obj>, <iid>, <val>, <type>].
1444 one of the following forms:
1450 leaf identifier (e.g., 'sysDescr') assumed to be
1451 unique for practical purposes
1455 fully qualified identifier (e.g.,
1456 '.iso.org.dod.internet.mgmt.mib-2.system.sysDescr')
1460 fully qualified, dotted-decimal, numeric OID (e.g.,
1467 the dotted-decimal, instance identifier. for
1468 scalar MIB objects use '0'
1472 the SNMP data value retrieved from or being set
1473 to the agents MIB. for (f)get(next) operations
1474 <val> may have a variety of formats as determined by
1475 session and package settings. However for set
1476 operations the <val> format must be canonical to
1477 ensure unambiguous translation. The canonical forms
1484 dotted-decimal (e.g., .1.3.6.1.2.1.1.1)
1488 perl scalar containing octets
1492 decimal signed integer (or enum)
1504 decimal unsigned integer
1508 decimal unsigned integer
1512 decimal unsigned integer
1516 decimal unsigned integer
1520 decimal unsigned integer
1524 perl scalar containing octets
1528 perl scalar containing nothing
1534 SNMP data type (see list above), this field is
1535 populated by 'get' and 'getnext' operations. In
1536 some cases the programmer needs to populate this
1537 field when passing to a 'set' operation. this
1538 field need not be supplied when the attribute
1539 indicated by <tag> is already described by loaded
1540 Mib modules. for 'set's, if a numeric OID is used
1541 and the object is not currently in the loaded Mib,
1542 the <type> field must be supplied
1548 light weight form of <var> used to 'set' or 'get' a
1549 single attribute without constructing an SNMP::Varbind.
1550 stored in a perl scalar, has the form '<tag>.<iid>',
1551 (e.g., 'sysDescr.0'). for 'set' operations the value
1552 is passed as a second arg. Note: This argument form is
1553 not updated in get[next] operations as are the other forms.
1557 =head1 Acceptable callback formats
1559 <callback> may be one of the following forms:
1563 =item without arguments
1573 =item or with arguments
1577 =item [ \&subname, $arg1, ... ]
1579 =item [ sub { ... }, $arg1, ... ]
1581 =item [ "method", $obj, $arg1, ... ]
1587 callback will be called when response is received or timeout
1588 occurs. the last argument passed to callback will be a
1589 SNMP::VarList reference. In case of timeout the last argument
1594 =item &SNMP::MainLoop([<timeout>, [<callback>]])
1596 to be used with async SNMP::Session
1597 calls. MainLoop must be called after initial async calls
1598 so return packets from the agent will not be processed.
1599 If no args suplied this function enters an infinite loop
1600 so program must be exited in a callback or externally
1601 interupted. If <timeout(sic)
1603 =item &SNMP::finish()
1605 This function, when called from an SNMP::MainLoop() callback
1606 function, will cause the current SNMP::MainLoop() to return
1607 after the callback is completed. finish() can be used to
1608 terminate an otherwise-infinite MainLoop. A new MainLoop()
1609 instance can then be started to handle further requests.
1613 =head1 SNMP package variables and functions
1617 =item $SNMP::VERSION
1619 the current version specifier (e.g., 3.1.0)
1621 =item $SNMP::auto_init_mib
1623 default '1', set to 0 to disable automatic reading
1624 of the MIB upon session creation. set to non-zero
1625 to call initMib at session creation which will result
1626 in MIB loading according to UCD env. variables (see
1629 =item $SNMP::verbose
1631 default '0', controls warning/info output of
1632 SNMP module, 0 => no output, 1 => enables warning/info
1633 output from SNMP module itself (is also controlled
1634 by SNMP::debugging - see below)
1636 =item $SNMP::use_long_names
1638 default '0', set to non-zero to enable the use of
1639 longer Mib identifiers. see translateObj. will also
1640 influence the formatting of <tag> in varbinds returned
1641 from 'getnext' operations. Can be set on a per session
1642 basis (UseLongNames)
1644 =item $SNMP::use_sprint_value
1646 default '0', set to non-zero to enable formatting of
1647 response values using the snmp libraries snprint_value
1648 function. can also be set on a per session basis (see
1649 UseSprintValue) Note: returned values may not be
1650 suitable for 'set' operations
1652 =item $SNMP::use_enums
1654 default '0',set non-zero to return values as enums and
1655 allow sets using enums where appropriate. integer data
1656 will still be accepted for set operations. can also be
1657 set on a per session basis (see UseEnums)
1659 =item $SNMP::use_numeric
1661 default to '0',set to non-zero to have <tags> for 'get'
1662 methods returned as numeric OID's rather than descriptions.
1663 UseLongNames will be set so that the entire OID will be
1664 returned. Set on a per-session basis (see UseNumeric).
1666 =item $SNMP::save_descriptions
1668 default '0',set non-zero to have mib parser save
1669 attribute descriptions. must be set prior to mib
1672 =item $SNMP::debugging
1674 default '0', controlls debugging output level
1675 within SNMP module and libsnmp
1681 enables 'SNMP::verbose' (see above)
1685 level 1 plus snmp_set_do_debugging(1)
1689 level 2 plus snmp_set_dump_packet(1)
1693 =item $SNMP::dump_packet
1695 default '0', set [non-]zero to independently set
1696 snmp_set_dump_packet()
1702 a tied hash to access parsed MIB information. After
1703 the MIB has been loaded this hash allows access to
1704 to the parsed in MIB meta-data(the structure of the
1705 MIB (i.e., schema)). The hash returns blessed
1706 references to SNMP::MIB::NODE objects which represent
1707 a single MIB attribute. The nodes can be fetched with
1708 multiple 'key' formats - the leaf name (e.g.,sysDescr)
1709 or fully/partially qualified name (e.g.,
1710 system.sysDescr) or fully qualified numeric OID. The
1711 returned node object supports the following fields:
1717 dotted decimal fully qualified OID
1721 leaf textual identifier (e.g., 'sysDescr')
1725 leaf numeric OID component of objectID (e.g., '1')
1729 textual identifier for module (e.g., 'RFC1213-MIB')
1737 array reference of children nodes
1741 next lexico node B<(BUG!does not return in lexico order)>
1745 returns application type (see getType for values)
1749 returns ACCESS (ReadOnly, ReadWrite, WriteOnly,
1750 NoAccess, Notify, Create)
1754 returns STATUS (Mandatory, Optional, Obsolete,
1759 returns 'textualConvention' if defined else 'type'
1761 =item textualConvention
1763 returns TEXTUAL-CONVENTION
1775 returns hash ref {tag => num, ...}
1779 returns array ref of hash ref [{low => num, high => num}, ...]
1783 returns DESCRIPTION ($SNMP::save_descriptions must
1784 be set prior to MIB initialization/parsing)
1788 =head1 MIB Functions
1792 =item &SNMP::setMib(<file>)
1794 allows dynamic parsing of the mib and explicit
1795 specification of mib file independent of enviroment
1796 variables. called with no args acts like initMib,
1797 loading MIBs indicated by environment variables (see
1798 ucd mib_api docs). passing non-zero second arg
1799 forces previous mib to be freed and replaced
1800 B<(Note: second arg not working since freeing previous
1801 Mib is more involved than before)>.
1803 =item &SNMP::initMib()
1805 calls library init_mib function if Mib not already
1806 loaded - does nothing if Mib already loaded. will
1807 parse directories and load modules according to
1808 environment variables described in UCD documentations.
1809 (see man mib_api, MIBDIRS, MIBS, MIBFILE(S), etc.)
1811 =item &SNMP::addMibDirs(<dir>,...)
1813 calls library add_mibdir for each directory
1814 supplied. will cause directory(s) to be added to
1815 internal list and made available for searching in
1816 subsequent loadModules calls
1818 =item &SNMP::addMibFiles(<file>,...)
1820 calls library read_mib function. The file(s)
1821 supplied will be read and all Mib module definitions
1822 contained therein will be added to internal mib tree
1825 =item &SNMP::loadModules(<mod>,...)
1827 calls library read_module function. The
1828 module(s) supplied will be searched for in the
1829 current mibdirs and and added to internal mib tree
1830 structure. Passing special <mod>, 'ALL', will cause
1831 all known modules to be loaded.
1833 =item &SNMP::unloadModules(<mod>,...)
1835 B<*Not Implemented*>
1837 =item &SNMP::translateObj(<var>[,arg])
1839 will convert a text obj tag to an OID and
1840 vice-versa. any iid suffix is retained numerically.
1841 default behaviour when converting a numeric OID
1842 to text form is to return leaf indentifier only
1843 (e.g.,'sysDescr') but when $SNMP::use_long_names
1844 is non-zero or a non-zero second arg is supplied
1845 will return longer textual identifier. If no Mib
1846 is loaded when called and $SNMP::auto_init_mib is
1847 enabled then the Mib will be loaded. Will return
1848 'undef' upon failure.
1850 =item &SNMP::getType(<var>)
1852 return SNMP data type for given textual identifier
1853 OBJECTID, OCTETSTR, INTEGER, NETADDR, IPADDR, COUNTER
1854 GAUGE, TIMETICKS, OPAQUE, or undef
1856 =item &SNMP::mapEnum(<var>)
1858 converts integer value to enumertion tag defined
1859 in Mib or converts tag to integer depending on
1860 input. the function will return the corresponding
1861 integer value *or* tag for a given MIB attribute
1862 and value. The function will sense which direction
1863 to perform the conversion. Various arg formats are
1868 =item $val = SNMP::mapEnum($varbind);
1870 where $varbind is SNMP::Varbind or equiv.
1871 note: $varbind will be updated
1873 =item $val = SNMP::mapEnum('ipForwarding', 'forwarding');
1875 =item $val = SNMP::mapEnum('ipForwarding', 1);
1881 =head1 Exported SNMP utility functions
1883 Note: utility functions do not support async operation yet.
1889 takes args of SNMP::Session::new followed by those of
1892 =item &snmp_getnext()
1894 takes args of SNMP::Session::new followed by those of
1895 SNMP::Session::getnext
1899 takes args of SNMP::Session::new followed by those of
1904 takes args of SNMP::TrapSession::new followed by those of
1905 SNMP::TrapSession::trap
1909 =head1 Trouble Shooting
1911 If problems occur there are number areas to look at to narrow down the
1914 The first step should be to test the UCD SNMP installation
1915 independently from the Perl5 SNMP interface.
1917 Try running the apps from the UCD SNMP distribution.
1919 Make sure your agent (snmpd) is running and properly configured with
1920 read-write access for the community you are using.
1922 Ensure that your MIBs are installed and enviroment variables are set
1923 appropriately (see man mib_api)
1925 Be sure to remove old ucd-snmp installations and ensure headers and
1926 libraries from old CMU installations are not being used by mistake.
1928 If the problem occurs during compilation/linking check that the snmp
1929 library being linked is actually the UCD SNMP library (there have been
1930 name conflicts with existing snmp libs).
1932 Also check that the header files are correct and up to date.
1934 Sometimes compiling the UCD SNMP library with
1935 'position-independent-code' enabled is required (HPUX specifically).
1937 If you cannot resolve the problem you can post to
1938 comp.lang.perl.modules or
1939 net-snmp-users@net-snmp-users@lists.sourceforge.net
1941 please give sufficient information to analyze the problem (OS type,
1942 versions for OS/Perl/UCD/compiler, complete error output, etc.)
1944 =head1 Acknowledments
1946 Many thanks to all those who supplied patches, suggestions and
1949 Joe Marzot (the original author)
1950 Wes Hardaker and the net-snmp-coders
1966 Apologies to any/all who's patch/feature/request was not mentioned or
1967 included - most likely it was lost when paying work intruded on my
1968 fun. Please try again if you do not see a desired feature. This may
1969 actually turn out to be a decent package with such excellent help and
1970 the fact that I have more time to work on it than in the past.
1974 bugs, comments, questions to net-snmp-users@lists.sourceforge.net
1978 Copyright (c) 1995-2000 G. S. Marzot. All rights reserved.
1979 This program is free software; you can redistribute it and/or
1980 modify it under the same terms as Perl itself.
1982 Copyright (c) 2001-2002 Networks Associates Technology, Inc. All
1983 Rights Reserved. This program is free software; you can
1984 redistribute it and/or modify it under the same terms as Perl