Provided by: libsnmp-multi-perl_2.1-4_all bug


       SNMP::Multi - Perform SNMP operations on multiple hosts simultaneously


           use SNMP::Multi;

           my $req = SNMP::Multi::VarReq->new (
               nonrepeaters => 1,
               hosts => [ qw/ / ],
               vars  => [ [ 'sysUpTime' ], [ 'ifInOctets' ], [ 'ifOutOctets' ] ],
           die "VarReq: $SNMP::Multi::VarReq::error\n" unless $req;

           my $sm = SNMP::Multi->new (
               Method      => 'bulkwalk',
               MaxSessions => 32,
               PduPacking  => 16,
               Community   => 'public',
               Version     => '2c',
               Timeout     => 5,
               Retries     => 3,
               UseNumeric  => 1,
               # Any additional options for SNMP::Session::new() ...
           or die "$SNMP::Multi::error\n";

           $sm->request($req) or die $sm->error;
           my $resp = $sm->execute() or die "Execute: $SNMP::Multi::error\n";

           print "Got response for ", (join ' ', $resp->hostnames()), "\n";
           for my $host ($resp->hosts()) {

               print "Results for $host: \n";
               for my $result ($host->results()) {
                   if ($result->error()) {
                       print "Error with $host: ", $result->error(), "\n";

                   print "Values for $host: ", (join ' ', $result->values());
                   for my $varlist ($result->varlists()) {
                       print map { "\t" . $_->fmt() . "\n" } @$varlist;
                   print "\n";


       The SNMP::Multi package provides a mechanism to perform SNMP operations on several hosts
       simultaneously.  SNMP::Multi builds on G. Marzot's SNMP Perl interface to the UC-Davis
       SNMP libraries, using asynchronous SNMP operations to send queries/sets to multiple hosts

       Results from all hosts are compiled into a single object, which offers methods to access
       the data in aggregate, or broken down by host or the individual request.

       SNMP::Multi supports SNMP GET, SET, GETNEXT, GETBULK and BULKWALK requests.  It also
       performs PDU packing in order to improve network efficiency, when packing is possible.


       The SNMP::Multi constructor takes the following options to control its behavior.  Any
       other options are stored and handed to the SNMP::Session constructor when a new SNMP
       session is created.  As the behavior of SNMP::Multi depends upon certain SNMP::Session
       parameters (i.e. Timeout), these will be listed below as SNMP::Multi options.  These
       "overlapped" options will be passed un-changed to SNMP::Session's constructor.

               Specify one of get, set, getnext, getbulk or bulkwalk.  The appropriate SNMP
               request will be made to each host for each set of variables requested by the user.

               This parameter is required.  There is no default value.

               The SNMP::Multi object may be given a new set of requests via the request()
               method, or by passing a reference to an SNMP::Multi::VarReq object into the
               constructor.  Any VarReq requests given to the SNMP::Multi object through the
               constructor will be overwritten by subsequent calls to SNMP::Multi::request().

               This parameter is optional.

               The maximum number of variable requests that will be packed into a single SNMP
               request is controlled by the ``PduPacking'' parameter.  PDU packing improves the
               efficiency and accuracy of SNMP requests by reducing the number of packets
               exchanged.  Setting this variable to '0' will disable PDU packing altogether.  PDU
               packing is not performed for SNMP GETBULK or BULKWALK requests.

               This optional parameter defaults to the value of $SNMP::Multi::pdupacking.

               This variable controls the maximum number of SNMP sessions that will be kept open
               simultaneously.  Setting ``MaxSessions'' higher increases the number of agents
               being queried at any time, up to the maximum limit of file descriptors available
               to the process.  SNMP::Multi detects "out of resources" conditions (i.e. EMFILE)
               and adjusts the number of open connections accordingly.

               This optional parameter defaults to the value of $SNMP::Multi::maxsessions.

               The value of ``Concurrent'' limits the number of requests that may be "in flight"
               at any time.  It defaults to the value of ``MaxSessions'' (see above).  Setting
               this value higher may reduce the overall runtime of the SNMP::Multi request, but
               will also likely increase network traffic and congestion (current maintainer has
               had SNMP::Multi running smoothly with concurrent set to 512).

               This optional parameter defaults to the value of $SNMP::Multi::maxsessions or the
               object's 'MaxSessions' parameter.

               Sets the default "maxrepetitions" value for SNMP GETBULK and BULKWALK requests.
               This value may be overridden on a per-request basis (by specifying the
               'maxrepetitions' parameter in the SNMP::Multi::VarReq constructor).

               This optional parameter defaults to the value of $SNMP::Multi::getbulkmax.

               If ``ExternalSelect'' is specified, the SNMP::Multi's execute() method will return
               immediately after dispatching the first volley of SNMP requests.  The caller can
               then use SNMP::select_info() to get a list of the current file descriptors for the
               SNMP sessions, and select() on them.  When one of the fd's becomes readable, it
               should be handed to SNMP::reply_cb() to handle it.

               Note that SNMP bulkwalks use the callbacks to dispatch continuing GETBULK
               requests.  This causes the file descriptor to be readable, but SNMP::reply_cb()
               calls an internal callback in SNMP.xs's bulkwalk implementation, not the
               SNMP::Multi handler callback.  When the walk completes, the SNMP::Multi callback
               will be called with the specified arguments.

       ``Retries'' (shared with SNMP::Session)
               The ``Retries'' options specifies the maximum number of retries for each SNMP
               request.  Note that this is the number of retries, not the total number of
               attempted requests.

               This optional parameter defaults to the value of $SNMP::Multi::maxretries.

       ``Timeout'' (shared with SNMP::Session)
               The ``Timeout'' parameter specifies the timeout in seconds between successive
               retries for SNMP requests.  The overall runtime for the complete SNMP::Multi
               request will be approximately :

                       (retries + 1) * timeout

               Please note that this is the lower-bound on the time-out.  Without sufficient
               resources (especially file descriptors) to optimize the network communications,
               completing all requested SNMP operations can take considerably longer.

               An over-all timeout may be specified as the optional "timeout" parameter to the
               SNMP::Multi's execute() method.

               This optional parameter defaults to the value of $SNMP::Multi::timeout.

       ``Community'' (shared with SNMP::Session)
               The ``Community'' parameter specifies the SNMP community string to use when making
               requests from SNMP agents.  No mechanism exists at this time to specify a
               different community for individual agents.

               This optional parameter defaults to the value of $SNMP::Multi::community.

       ``Version'' (shared with SNMP::Session)
               The ``Version'' option specifies the SNMP protocol to use with the agents.  Due to
               the poor error reporting in SNMP v1, it is recommended that SNMP v2c or v3 be used
               to communicate with the agents when possible.

               This optional parameter defaults to the value of $SNMP::Multi::snmpversion.


       The SNMP::Multi object provides several methods for the caller.  In most cases, only the
       new(), request(), and execute() methods need to be used.  The various methods are
       documented in approximately the order in which they are normally called.

               Create a new instance of an SNMP::Multi object.  See above for a description of
               the available constructor options.

       SNMP::Multi::request( <ref to SNMP::Multi::VarReq> )
               request() arranges for the set of host/variable requests stored in the
               SNMP::Multi::VarReq object to be transferred to the SNMP::Multi object.  This can
               also be done in the constructor using the ``requests'' option.

               Note that the request() method is not cumulative -- previous requests will be
               overwritten by subsequent calls to request().

               SNMP::Multi::execute( [timeout] )

                   The execute() function performs the actual work in SNMP::Multi, returning when
                   all requests have been answered or timed out.  An optional `timeout' argument
                   to execute() specifies an overall timeout, regardless of the number and timing
                   of retries.

                   execute() returns a reference to an SNMP::Multi::Response object.  This object
                   provides methods to conveniently access the returned data values.


                   If an error occurs while SNMP::Multi is executing, the caller may retrieve a
                   descriptive string describing the error from the error() method.

               SNMP::Multi::remaining( $req )

                   The remaining() method produces an SNMP::Multi::VarReq that is populated with
                   the requests for any un-answered or un-sent request hunks.  This VarReq may
                   then be passed to another SNMP::Multi object (or the same one).  This allows
                   an application to loop on timeouts like this:

                       my $req = SNMP::Multi::VarReq->new( ... );
                       my $sm  = SNMP::Multi->new( ... );
                       while ($req) {
                           my $resp = $sm->execute();

                           print "Timeout - retrying" if ($req = $sm->remaining());

                   You can accumulate remaining requests by passing an already existing
                   SNMP::Multi::VarReq object as an argument. Remaining requests will then be
                   added to that object. That allows us to to collect all remaining ones with
                   ease, while looping over huge number of hosts.

Building SNMP::Multi::VarReq Requests

       SNMP variable requests are composed and passed to the SNMP::Multi object through an
       auxiliary class called an SNMP::Multi::VarReq.  This class simply collects SNMP requests
       for variables and hosts (and optionally validates them).

       The interface to SNMP::Multi::VarReq is very simple, providing only new() and add()
       methods.  They take the following arguments:

           'vars'           => [ list of Varbinds to be requested (REQUIRED) ]
           'hosts'          => [ list of hosts for this variable list ]
           'nonrepeaters'   => [ GETBULK/BULKWALK "nonrepeaters" parameter ]
           'maxrepetitions' => [ GETBULK/BULKWALK "maxrepetitions" parameter ]

       Every call to new() or add() must contain a list of SNMP variables.  If the hosts
       parameter is not specified, the variable list will be requested from all hosts currently
       known by the SNMP::Multi::VarReq object.  If a host list is given, the variables will be
       requested only from the named hosts.

       Some simple sanity checks can be performed on the VarReq by calling its validate() method,
       or by setting $SNMP::Multi::VarReq::autovalidate to 1 before calling the new() method.

       An example of building up a complicated request using new() and add():

           Start with:

               $r = SNMP::Multi::VarReq->new(
                   hosts => [ qw/ A B C / ],
                   vars  => [ qw/ 1 2 3 / ]

           to get:

               A: 1 2 3
               B: 1 2 3
               C: 1 2 3

           Now add a var to each host:

               $r->add( vars => [ qw/ 4 / ] );

           to get:

               A: 1 2 3 4
               B: 1 2 3 4
               C: 1 2 3 4

           Add a var to a specific set of hosts:

               $r->add( hosts => [ qw/ A C / ],
                        vars  => [ qw/ 5   / ] );

           to get:

               A: 1 2 3 4 5
               B: 1 2 3 4
               C: 1 2 3 4 5

           Finally, create two new hosts and add a pair of vars to them:

               $r->add( hosts => [ qw/ D E / ],
                        vars =>  [ qw/ 6 7 / ] );

           to get:

               A: 1 2 3 4 5
               B: 1 2 3 4
               C: 1 2 3 4 5
               D: 6 7
               E: 6 7

       The SNMP::Multi::VarReq object also provides a dump() method which generates a simple dump
       of the current host/var requests.

SNMP PDU Packing Features

       SNMP::Multi packs SNMP::Varbind requests into larger request "hunks" to reduce the number
       of request/response pairs required to complete the SNMP::Multi request.  This packing is
       controlled by the SNMP::Multi 'PduPacking' parameter.

       For instance, assume your application creates an SNMP::Multi object with a 'PduPacking'
       value of 3.  SNMP::Multi will pack 5 single SNMP variable requests into two distinct
       requests.  The first request will contain the first 3 variables, the second will get the
       remaining two variables.

       PDU packing is not done for SNMP GETBULK and BULKWALK requests.  The feature may be
       disabled by setting the 'PduPacking' parameter to '0'.

Accessing SNMP Data From Agent Responses

       The SNMP::Multi::execute() method returns the responses from the SNMP agents in an
       SNMP::Multi::Response object.  This object, indexed by hostname, consists of per-host
       response objects (SNMP::Multi::Response::Host's), each of which contains a list of
       SNMP::Multi::Result objects.  The Result objects connect an SNMP::VarList with the error
       status (if any) from the SNMP request.  An entry is only made in the Response object if
       the SNMP agent returned some response to SNMP::Multi.

       This is fairly complicated, but the various objects provide accessor methods to make
       access to the SNMP responses simple.  Assume your application is structured something like
       this example source code:

           my $req = SNMP::Multi::VarReq->new( hosts => [...],
                                               vars  => [...] );
           my $sm  = SNMP::Multi->new( ... requests => $req, ... );
           my $response = $sm->execute( $overall_timeout );
           die $sm->error() if $sm->error();

       Now the data can be accessed through methods on the objects that make up the
       SNMP::Multi::Response returned by execute().  An SNMP::VarList object is returned for each
       variable requested.  This normalizes the return format across all SNMP operations
       (including bulkwalks).

       See the SYNOPSIS section above for an example of how to access the SNMP data values after
       calling the execute() method.

       SNMP::Multi::Response methods
                   Return a list of the hosts that responded to the SNMP queries made by

                   Return all values returned by the SNMP agents, collated into a single list.
                   This method can be used when the application is not concerned with which value
                   was returned by a specific host (i.e. summing up octet counts on router

                   Returns a list of SNMP::Multi::Response::Host objects, one per host queried by
                   the SNMP::Multi::execute() method.

       SNMP::Multi::Response::Host methods
                   Return the hostname associated with this set of responses.  The reference may
                   also be stringified to get the hostname :

                           print "This is the list of results for $host: \n";

                   Return all values received in response to requests made to the associated

                   Returns a list of SNMP::Multi::Result objects for this host.  There is one
                   Result object for each request sent to the SNMP agent on this host.

       SNMP::Multi::Result methods
           The SNMP::Multi::Result object correlates SNMP error information with the response to
           an SNMP request.

                   Return a printable string describing the error encountered for this variable,
                   or undef if no error occurred.

                   Return a list of the values received for this request.

                   Return an array of SNMP::VarList objects, one per variable requested in the
                   SNMP packet.  This format is consistent for all SNMP operations, and is
                   required to support bulkwalks (in which the number of returned values per
                   variable is not known a priori to the calling application).


       A complete example is given in the "SYNOPSIS" section above.


       The VarList returned for GETBULK requests is "decoded" by SNMP::Multi into an array of
       single VarLists, one for each requested variable.  This behavior differs from the return
       from the getbulk() method in the module, but is consistent with the return value
       of's bulkwalk() method.

       Note that the V1 SNMP protocol has very limited error reporting (the agent returns no
       values, and the 'errind' is set to the index of the offending SNMP variable request).  The
       SNMP::Multi module adjusts the 'errind' index to indicate which of the variables request
       requested for a host have failed, regardless of the number of actual packets exchanged.
       This is necessary to support SNMP::Multi's transparent pdu-packing feature.

       SNMP::Multi relies on features added to the SNMP module by Electric Lightwave, Inc.  These
       features have been incorporated into UCD-SNMP releases 4.2 and later.  You must have SNMP
       4.2 or later installed to use this package.

       Using SNMP::Multi with large numbers of hosts or large requests may cause network
       congestion.  All targets may send PDU's to the originating host simultaneously, which
       could cause heavy traffic and/or dropped packets at the host.  Adjusting the Concurrent
       and PduPacking variables can mitigate this problem.

       Network congestion may be a serious problem for bulkwalks, due to multiple packets being
       exchanged per session.  However, network latency and variable target response times cause
       packets in multiple bulkwalk exchanges to become spread out as the walk progresses.  The
       initial exchange, however, will always cause congestion.


       There is no interface to specify a different SNMP community string for a specific host,
       although the community is stored on a per-host basis.


       SNMP, the NetSNMP homepage at


       Karl ("Terminator rAT") Schilke <>


       Joshua Keroes, Todd Caine, Toni Prug <>


       Developed by Karl "Terminator rAT" Schilke for Electric Lightwave, Inc.  Copyright (c)
       2000-2002 Electric Lightwave, Inc.  All rights reserved.

       Co-maintained by Toni Prug.

       This software is provided ``as is'' and without any express or implied warranties,
       including, without limitation, the implied warranties of merchantibility and/or fitness
       for a particular purpose.

       This program is free software; you may redistribute it and/or modify it under the same
       terms as Perl itself.


       Hey! The above document had some coding errors, which are explained below:

       Around line 93:
           '=item' outside of any '=over'

       Around line 250:
           You forgot a '=back' before '=head1'

       Around line 257:
           '=item' outside of any '=over'

       Around line 268:
           You can't have =items (as at line 277) unless the first thing after the =over is an

       Around line 326:
           You forgot a '=back' before '=head1'

           You forgot a '=back' before '=head1'

       Around line 444:
           '=item' outside of any '=over'

       Around line 480:
           '=item' outside of any '=over'

       Around line 551:
           You forgot a '=back' before '=head1'