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.

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().

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.

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.

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.

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.

SNMP::Multi::error()

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:

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.

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:

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():

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'.

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:

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.

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 interfaces).

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).

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 SNMP.pm module, but is consistent with the return value of SNMP.pm'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.