⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snmp.pm

📁 ucd-snmp源代码
💻 PM
📖 第 1 页 / 共 4 页
字号:
# SNMP.pm -- Perl 5 interface to the UCD SNMP toolkit## written by G. S. Marzot (gmarzot@nortelnetworks.com)##     Copyright (c) 1995-2000 G. S. Marzot. All rights reserved.#     This program is free software; you can redistribute it and/or#     modify it under the same terms as Perl itself.package SNMP;$VERSION = '4.2.6';   # current release version numberrequire Exporter;require DynaLoader;require AutoLoader;@SNMP::ISA = qw(Exporter AutoLoader DynaLoader);# Items to export into callers namespace by default. Note: do not export# names by default without a very good reason. Use EXPORT_OK instead.# Do not simply export all your public functions/methods/constants.@SNMP::EXPORT = qw(	RECEIVED_MESSAGE	SNMPERR_BAD_ADDRESS	SNMPERR_BAD_LOCPORT	SNMPERR_BAD_SESSION	SNMPERR_GENERR	SNMPERR_TOO_LONG	SNMP_DEFAULT_ADDRESS	SNMP_DEFAULT_COMMUNITY_LEN	SNMP_DEFAULT_ENTERPRISE_LENGTH	SNMP_DEFAULT_ERRINDEX	SNMP_DEFAULT_ERRSTAT	SNMP_DEFAULT_PEERNAME	SNMP_DEFAULT_REMPORT	SNMP_DEFAULT_REQID	SNMP_DEFAULT_RETRIES	SNMP_DEFAULT_TIME	SNMP_DEFAULT_TIMEOUT	SNMP_DEFAULT_VERSION	TIMED_OUT	snmp_get        snmp_getnext        snmp_set        snmp_trap);sub AUTOLOAD {    # This AUTOLOAD is used to 'autoload' constants from the constant()    # XS function.  If a constant is not found then control is passed    # to the AUTOLOAD in AutoLoader.    my($val,$pack,$file,$line);    local($constname);    ($constname = $AUTOLOAD) =~ s/.*:://;    # croak "&$module::constant not defined" if $constname eq 'constant';    $val = constant($constname, @_ ? $_[0] : 0);    if ($! != 0) {	if ($! =~ /Invalid/) {	    $AutoLoader::AUTOLOAD = $AUTOLOAD;	    goto &AutoLoader::AUTOLOAD;	}	else {	    ($pack,$file,$line) = caller;	    die "Your vendor has not defined SNMP macro $constname, used at $file line $line.";	}    }    eval "sub $AUTOLOAD { $val }";    goto &$AUTOLOAD;}bootstrap SNMP;# Preloaded methods go here.# Package variablestie $SNMP::debugging, SNMP::DEBUGGING;tie $SNMP::debug_internals, SNMP::DEBUG_INTERNALS;tie $SNMP::dump_packet, SNMP::DUMP_PACKET;tie %SNMP::MIB, SNMP::MIB;tie $SNMP::save_descriptions, SNMP::MIB::SAVE_DESCR;%SNMP::V3_SEC_LEVEL_MAP = (noAuthNoPriv => 1, authNoPriv => 2, authPriv =>3);$auto_init_mib = 1; # enable automatic MIB loading at session creation time$use_long_names = 0; # non-zero to prefer longer mib textual identifiers rather                   # than just leaf indentifiers (see translateObj)                   # may also be set on a per session basis(see UseLongNames)$use_sprint_value = 0; # non-zero to enable formatting of response values                   # using the snmp libraries "sprint_value"                   # may also be set on a per session basis(see UseSprintValue)                   # note: returned values not suitable for 'set' operations$use_enums = 0; # non-zero to return integers as enums and allow sets                # using enums where appropriate - integer data will                # still be accepted for set operations                # may also be set on a per session basis (see UseEnums)$use_numeric = 0; # non-zero to return object tags as numeric OID's instead                  # of converting to textual representations.  use_long_names,                  # if non-zero, returns the entire OID, otherwise, return just                  # the label portion.  Probably want to use_long_names in most                  # cases.%MIB = ();      # tied hash to access libraries internal mib tree structure                # parsed in from mib files$verbose = 0;   # controls warning/info output of SNMP module,                # 0 => no output, 1 => enables warning and info                # output from SNMP module itself (is also controlled                # by SNMP::debugging)$debugging = 0; # non-zero to globally enable libsnmp do_debugging output                # set to >= 2 to enabling packet dumping (see below)$dump_packet = 0; # non-zero to globally enable libsnmp dump_packet output.                  # is also enabled when $debugging >= 2$save_descriptions = 0; #tied scalar to control saving descriptions during               # mib parsing - must be set prior to mib loading$best_guess = 0;  # determine whether or not to enable best-guess regular                  # expression object name translation$timestamp_vars = 0; # Add a timestamp to each Varbindsub setMib {# loads mib from file name provided# setting second arg to true causes currently loaded mib to be replaced# otherwise mib file will be added to existing loaded mib database# NOTE: now deprecated in favor of addMibFiles and new module based funcs   my $file = shift;   my $force = shift || '0';   return 0 if $file and not (-r $file);   SNMP::_read_mib($file,$force);}sub initMib {# eqivalent to calling the snmp library init_mib if Mib is NULL# if Mib is already loaded this function does nothing# Pass a zero valued argument to get minimal mib tree initialzation# If non zero agrgument or no argument then full mib initialization  if (defined $_[0] and $_[0] == 0) {    SNMP::_init_mib_internals();  } else {    SNMP::_read_mib("");  }}sub addMibDirs {# adds directories to search path when a module is requested to be loaded  foreach (@_) {    SNMP::_add_mib_dir($_) or return undef;  }  return 1;}sub addMibFiles {# adds mib definitions to currently loaded mib database from# file(s) supplied  foreach (@_) {    SNMP::_read_mib($_) or return undef;  }  return 1;}sub loadModules {# adds mib module definitions to currently loaded mib database.# Modules will be searched from previously defined mib search dirs# Passing and arg of 'ALL' will cause all known modules to be loaded   foreach (@_) {     SNMP::_read_module($_) or return undef;   }   return 1;}sub unloadModules {# causes modules to be unloaded from mib database# Passing and arg of 'ALL' will cause all known modules to be unloaded  warn("SNMP::unloadModules not implemented! (yet)");}sub translateObj {# translate object identifier(tag or numeric) into alternate representation# (i.e., sysDescr => '.1.3.6.1.2.1.1.1' and '.1.3.6.1.2.1.1.1' => sysDescr)# when $SNMP::use_long_names or second arg is non-zero the translation will# return longer textual identifiers (e.g., system.sysDescr)# if Mib is not loaded and $SNMP::auto_init_mib is enabled Mib will be loaded# returns 'undef' upon failure   my $obj = shift;   my $long_names = shift || $SNMP::use_long_names;   return undef if not defined $obj;   my $res;   if ($obj =~ /^\.?(\d+\.)*\d+$/) {      $res = SNMP::_translate_obj($obj,1,$long_names,$SNMP::auto_init_mib,0);   } elsif ($obj =~ /(\.\d+)*$/ && $SNMP::best_guess == 0) {      $res = SNMP::_translate_obj($`,0,$long_names,$SNMP::auto_init_mib,0);      $res .= $& if defined $res and defined $&;   } elsif ($SNMP::best_guess) {      $res = SNMP::_translate_obj($obj,0,$long_names,$SNMP::auto_init_mib,$SNMP::best_guess);   }   return($res);}sub getType {# return SNMP data type for given textual identifier# OBJECTID, OCTETSTR, INTEGER, NETADDR, IPADDR, COUNTER# GAUGE, TIMETICKS, OPAQUE, or undef  my $tag = shift;  SNMP::_get_type($tag);}sub mapEnum {# return the corresponding integer value *or* tag for a given MIB attribute# and value. The function will sense which direction to perform the conversion# various arg formats are supported#    $val = SNMP::mapEnum($varbind); # note: will update $varbind#    $val = SNMP::mapEnum('ipForwarding', 'forwarding');#    $val = SNMP::mapEnum('ipForwarding', 1);#  my $var = shift;  my ($tag, $val, $update);  if (ref($var) =~ /ARRAY/ or ref($var) =~ /Varbind/) {      $tag = $var->[$SNMP::Varbind::tag_f];      $val = $var->[$SNMP::Varbind::val_f];      $update = 1;  } else {      $tag = $var;      $val = shift;  }  my $iflag = $val =~ /^\d+$/;  my $res = SNMP::_map_enum($tag, $val, $iflag);  if ($update and defined $res) { $var->[$SNMP::Varbind::val_f] = $res; }  return($res);}%session_params = (DestHost => 1,		   Community => 1,		   Version => 1,		   Timeout => 1,		   Retries => 1,		   RemotePort => 1);sub strip_session_params {    my @params;    my @args;    my $param;    while ($param = shift) {	push(@params,$param, shift), next	    if $session_params{$param};	push(@args,$param);    }    @_ = @args;    @params;}sub snmp_get {# procedural form of 'get' method. sometimes quicker to code# but is less efficient since the Session is created and destroyed# with each call. Takes all the parameters of both SNMP::Session::new and# SNMP::Session::get (*NOTE*: this api does not support async callbacks)    my @sess_params = &strip_session_params;    my $sess = new SNMP::Session(@sess_params);    $sess->get(@_);}sub snmp_getnext {# procedural form of 'getnext' method. sometimes quicker to code# but is less efficient since the Session is created and destroyed# with each call. Takes all the parameters of both SNMP::Session::new and# SNMP::Session::getnext (*NOTE*: this api does not support async callbacks)    my @sess_params = &strip_session_params;    my $sess = new SNMP::Session(@sess_params);    $sess->getnext(@_);}sub snmp_set {# procedural form of 'set' method. sometimes quicker to code# but is less efficient since the Session is created and destroyed# with each call. Takes all the parameters of both SNMP::Session::new and# SNMP::Session::set (*NOTE*: this api does not support async callbacks)    my @sess_params = &strip_session_params;    my $sess = new SNMP::Session(@sess_params);    $sess->set(@_);}sub snmp_trap {# procedural form of 'trap' method. sometimes quicker to code# but is less efficient since the Session is created and destroyed# with each call. Takes all the parameters of both SNMP::TrapSession::new and# SNMP::TrapSession::trap    my @sess_params = &strip_session_params;    my $sess = new SNMP::TrapSession(@sess_params);    $sess->trap(@_);}sub MainLoop {    my $time = shift;    my $callback = shift;    my $time_sec = ($time ? int $time : 0);    my $time_usec = ($time ? int(($time-$time_sec)*1000000) : 0);    SNMP::_main_loop($time_sec,$time_usec,$callback);}sub finish {    SNMP::_mainloop_finish();}sub reply_cb {    # callback function for async snmp calls    # when triggered, will do a SNMP read on the    # given fd    my $fd = shift;  SNMP::_read_on_fd($fd);}sub select_info {    # retrieves SNMP used fd's and timeout info    # calculates timeout in fractional seconds    # ( easy to use with select statement )    my($block, $to_sec, $to_usec, @fd_set)=SNMP::_get_select_info();    my $time_sec_dec = ($block? 0 : $to_sec + $to_usec * 1e-6);    #print "fd's for snmp -> ", @fd_set, "\n";    #print "block		-> ", $block, "\n";    #print "timeout_sec	-> ", $to_sec, "\n";    #print "timeout_usec	-> ", $to_usec, "\n";    #print "timeout dec	-> ", $time_sec_dec, "\n";    return ($time_sec_dec,@fd_set);}sub check_timeout {  # check to see if a snmp session  # timed out, and if so triggers  # the callback function  SNMP::_check_timeout();  # check to see when have to check again  my($block, $to_sec, $to_usec, @fd_set)=SNMP::_get_select_info();  my $time_sec_dec = ($block? 0 : $to_sec + $to_usec * 1e-6);  #print "fd's for snmp -> ", @fd_set, "\n";  #print "block		-> ", $block, "\n";  #print "timeout_sec	-> ", $to_sec, "\n";  #print "timeout_usec	-> ", $to_usec, "\n";  #print "timeout dec	-> ", $time_sec_dec, "\n";  return ($time_sec_dec);}sub _tie {# this is a little implementation hack so ActiveState can access pp_tie# thru perl code. All other environments allow the calling of pp_tie from# XS code but AS was not exporting it when PERL_OBJECT was used.## short term solution was call this perl func which calls 'tie'## longterm fix is to supply a patch which allows AS to export pp_tie in# such a way that it can be called from XS code. gsarathy says:# a patch to util.c is needed to provide access to PL_paddr# so it is possible to call PL_paddr[OP_TIE] as the compiler does    tie($_[0],$_[1],$_[2],$_[3]);}package SNMP::Session;sub new {   my $type = shift;   my $this = {};   my ($name, $aliases, $host_type, $len, $thisaddr);   %$this = @_;   $this->{ErrorStr} = ''; # if methods return undef check for expln.   $this->{ErrorNum} = 0;  # contains SNMP error return   # v1 or v2, defaults to v1   $this->{Version} ||= 1;   # allow override of remote SNMP port   $this->{RemotePort} ||= 161;   # destination host defaults to localhost   $this->{DestHost} ||= 'localhost';   # community defaults to public   $this->{Community} ||= 'public';   # number of retries before giving up, defaults to SNMP_DEFAULT_RETRIES   $this->{Retries} = SNMP::SNMP_DEFAULT_RETRIES() unless defined($this->{Retries});   # timeout before retry, defaults to SNMP_DEFAULT_TIMEOUT   $this->{Timeout} = SNMP::SNMP_DEFAULT_TIMEOUT() unless defined($this->{Timeout});   # flag to enable fixing pdu and retrying with a NoSuch error   $this->{RetryNoSuch} ||= 0;   # convert to dotted ip addr if needed   if ($this->{DestHost} =~ /\d+\.\d+\.\d+\.\d+/) {     $this->{DestAddr} = $this->{DestHost};   } else {     if (($name, $aliases, $host_type, $len, $thisaddr) =	 gethostbyname($this->{DestHost})) {	 $this->{DestAddr} = join('.', unpack("C4", $thisaddr));     } else {	 warn("unable to resolve destination address($this->{DestHost}!")	     if $SNMP::verbose;	 return undef;     }   }   if ($this->{Version} eq '1' or $this->{Version} eq '2'       or $this->{Version} eq '2c') {       $this->{SessPtr} = SNMP::_new_session($this->{Version},					     $this->{Community},					     $this->{DestAddr},					     $this->{RemotePort},					     $this->{Retries},					     $this->{Timeout},					     );   } elsif ($this->{Version} eq '3' ) {       $this->{SecName} ||= 'initial';       $this->{SecLevel} ||= 'noAuthNoPriv';       $this->{SecLevel} = $SNMP::V3_SEC_LEVEL_MAP{$this->{SecLevel}}          if $this->{SecLevel} !~ /^\d+$/;       $this->{SecEngineId} ||= '';       $this->{ContextEngineId} ||= $this->{SecEngineId};       $this->{Context} ||= '';       $this->{AuthProto} ||= 'MD5';       $this->{AuthPass} ||= '';       $this->{PrivProto} ||= 'DES';       $this->{PrivPass} ||= '';       $this->{EngineBoots} = 0 if not defined $this->{EngineBoots};       $this->{EngineTime} = 0 if not defined $this->{EngineTime};       $this->{SessPtr} = SNMP::_new_v3_session($this->{Version},						$this->{DestAddr},						$this->{RemotePort},						$this->{Retries},						$this->{Timeout},						$this->{SecName},						$this->{SecLevel},						$this->{SecEngineId},						$this->{ContextEngineId},						$this->{Context},						$this->{AuthProto},						$this->{AuthPass},						$this->{PrivProto},						$this->{PrivPass},						$this->{EngineBoots},						$this->{EngineTime},						);   }   unless ($this->{SessPtr}) {       warn("unable to create session") if $SNMP::verbose;       return undef;   }   SNMP::initMib($SNMP::auto_init_mib); # ensures that *some* mib is loaded   $this->{UseLongNames} ||= $SNMP::use_long_names;   $this->{UseSprintValue} ||= $SNMP::use_sprint_value;   $this->{UseEnums} ||= $SNMP::use_enums;   $this->{UseNumeric} ||= $SNMP::use_numeric;   $this->{TimeStamp} ||= $SNMP::timestamp_vars;   bless $this, $type;}sub update {# *Not Implemented*# designed to update the fields of session to allow retargettinf to different# host, community name change, timeout, retry changes etc. Unfortunately not# working yet because some updates (the address in particular) need to be# done on the internal session pointer which cannot be fetched w/o touching# globals at this point which breaks win32. A patch to the ucd-snmp toolkit# is needed   my $this = shift;   my ($name, $aliases, $host_type, $len, $thisaddr);   my %new_fields = @_;   @$this{keys %new_fields} = values %new_fields;   # convert to dotted ip addr if needed   if (exists $new_fields{DestHost}) {      if ($this->{DestHost} =~ /\d+\.\d+\.\d+\.\d+/) {        $this->{DestAddr} = $this->{DestHost};      } else {        if (($name, $aliases, $host_type, $len, $thisaddr) =           gethostbyname($this->{DestHost})) {           $this->{DestAddr} = join('.', unpack("C4", $thisaddr));        } else {           warn("unable to resolve destination address($this->{DestHost}!")              if $SNMP::verbose;           return undef;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -