1SNMP_Session(3)       User Contributed Perl Documentation      SNMP_Session(3)
2
3
4

NAME

6       SNMP_Session - SNMPv1/v2 Protocol Handling
7

SYNOPSIS

9           use SNMP_Session;
10           $session = SNMP_Session->open ($host, $community, $port)
11               or die "couldn't open SNMP session to $host";
12           if ($session->get_request_response ($oid1, $oid2, ...)) {
13               ($bindings) = $session->decode_get_response ($session->{pdu_buffer});
14               while ($bindings ne '') {
15                   ($binding,$bindings) = decode_sequence ($bindings);
16                   ($oid,$value) = decode_by_template ($binding, "%O%@");
17                   print pretty_print ($oid)," => ", pretty_print ($value), "\n";
18               }
19           } else {
20               die "No response from agent on $host";
21           }
22

VARIABLES

24       The "default_..." variables all specify default values that are used
25       for "SNMP_Session" objects when no other value is specified.  These
26       values can be overridden on a per-session basis, for example by passing
27       additional arguments to the constructor.
28
29   $default_max_repetitions - default value for "maxRepetitions".
30       This specifies how many table rows are requested in "getBulk" requests.
31       Used when walking tables using "getBulk" (only available in SNMPv2(c)
32       and later).  If this is too small, then a table walk will need
33       unnecessarily many request/response exchanges.  If it is too big, the
34       agent may compute many variables after the end of the table.  It is
35       recommended to set this explicitly for each table walk by using
36       map_table_4().
37
38   $default_avoid_negative_request_ids - default value for
39       "avoid_negative_request_ids".
40       Set this to non-zero if you have agents that have trouble with negative
41       request IDs, and don't forget to complain to your agent vendor.
42       According to the spec (RFC 1905), the request-id is an "Integer32",
43       i.e. its range is from -(2^31) to (2^31)-1.  However, some agents
44       erroneously encode the response ID as an unsigned, which prevents this
45       code from matching such responses to requests.
46
47   $default_use_16bit_request_ids - default value for "use_16bit_request_ids".
48       Set this to non-zero if you have agents that use 16bit request IDs, and
49       don't forget to complain to your agent vendor.
50
51   $errmsg - error message from last failed operation.
52       When they encounter errors, the routines in this module will generally
53       return "undef") and leave an informative error message in $errmsg).
54
55   $suppress_warnings - whether warnings should be suppressed.
56       If this variable is zero, as is the default, this code will output
57       informative error messages whenever it encounters an error.  Set this
58       to a non-zero value if you want to suppress these messages.  In any
59       case, the last error message can be found in $errmsg.
60

METHODS in package SNMP_Session

62       The abstract class "SNMP_Session" defines objects that can be used to
63       communicate with SNMP entities.  It has methods to send requests to and
64       receive responses from an agent.
65
66       Two instantiable subclasses are defined: "SNMPv1_Session" implements
67       SNMPv1 (RFC 1157) functionality "SNMPv2c_Session" implements community-
68       based SNMPv2 (RFC 3410-3417).
69
70   open() - create an SNMP session object
71           $session = SNMP_Session->open
72             ($host, $community, $port,
73              $max_pdu_len, $local_port, $max_repetitions,
74              $local_host, $ipv4only);
75
76       The calling and return conventions are identical to
77       SNMPv1_Session::open().
78
79   timeout() - return timeout value.
80       Initial timeout, in seconds, to wait for a response PDU after a request
81       is sent.  Note that when a request is retried, the timeout is increased
82       by backoff (see below).  The standard value is 2.0 (seconds).
83
84   retries() - number of attempts to get a reply.
85       Maximum number of attempts to get a reply for an SNMP request.  If no
86       response is received after timeout seconds, the request is resent and a
87       new response awaited with a longer timeout, see the documentation on
88       backoff below.  The retries value should be at least 1, because the
89       first attempt counts, too (the name "retries" is confusing, sorry for
90       that).
91
92   backoff() - backoff factor.for timeout on successive retries.
93       Default backoff factor for "SNMP_Session" objects.  This factor is used
94       to increase the TIMEOUT every time an SNMP request is retried.  The
95       standard value is 1.0, which means the same timeout is used for all
96       attempts.
97
98   set_timeout() - set initial timeout for session
99   set_retries() - set maximum number of attempts for session
100   set_backoff() - set backoff factor for session
101       Example usage:
102
103           $session->set_backoff (1.5);
104
105   ..._request_response() - Send some request and receive response.
106       Encodes a specific SNMP request, sends it to the destination address of
107       the session, and waits for a matching response.  If such a response is
108       received, this function will return the size of the response, which is
109       necessarily greater than zero.
110
111       An undefined value is returned if some error happens during encoding or
112       sending, or if no matching response is received after the wait/retry
113       schedule is exhausted.  See the documentation on the timeout(),
114       retries(), and backoff() methods on how the wait/retry logic works.
115
116   get_request_response() - Send "get" request and receive response.
117   getnext_request_response() - Send "get-next" request and receive response.
118           $result = $session->get_request_response (@encoded_oids);
119           $result = $session->getnext_request_response (@encoded_oids);
120
121   set_request_response() - Send "set" request and receive response.
122           $result = $session->set_request_response (@encoded_pair_list);
123
124       This method takes its arguments in a different form; they are a list of
125       pairs - references to two-element arrays - which respresent the
126       variables to be set and the intended values, e.g.
127
128           ([$encoded_oid_0, $encoded_value_0],
129            [$encoded_oid_1, $encoded_value_1],
130            [$encoded_oid_2, $encoded_value_2], ...)
131
132   trap_request_send() - send SNMPv1 Trap.
133           $result = $session->trap_request_send ($ent, $gent, $gen, $spec, $dt, @pairs);
134
135   v2_trap_request_send() - send SNMPv2 Trap.
136           $result = $session->v2_trap_request_send ($trap_oid, $dt, @pairs);
137
138   map_table() - traverse an SNMP table.
139           $result = $session->map_table ([$col0, $col1, ...], $mapfn);
140
141       This will call the provided function (&$mapfn) once for each row of the
142       table defined by the column OIDs $col0, $col1...  If the session can
143       handle SNMPv2 operations, "get-bulk" will be used to traverse the
144       table.  Otherwise, "get-next" will be used.
145
146       If the first argument is a list of n columns, the mapping function will
147       be called with n+1 arguments.  The first argument will be the row
148       index, i.e. the list of sub-IDs that was appended to the provided
149       column OIDs for this row.  Note that the row index will be represented
150       as a string, using dot-separated numerical OID notation.
151
152       The remaining arguments to the mapping function will be the values of
153       each column at the current index.  It is possible that the table has
154       "holes", i.e. that for a given row index, not all columns have a value.
155       For columns with no value at the current row index, "undef" will be
156       passed to the mapping function.
157
158       If an error is encountered at any point during the table traversal,
159       this method will return undef and leave an error message in $errmsg
160       (which is also written out unless $suppress_warnings is non-zero).
161
162       Otherwise, the function will return the number of rows traversed, i.e.
163       the number of times that the mapping function has been called.
164
165   map_table_4() - traverse an SNMP table with more control.
166   map_table_start_end() - traverse an SNMP table with lower/upper index
167       limits.
168           $result = $session->map_table_start_end ($columns, $mapfn,
169               $start, $end, $max_repetition);
170
171       Similar to map_table_4(), except that the start and end index can be
172       specified.
173
174   receive_trap_1() - receive message on trap socket.
175       This method waits until a message is received on the trap socket.  If
176       successful, it returns two values: the message that was received, and
177       the address of the sender as a "sockaddr" structure.  This address can
178       be passed to getnameinfo() to convert it to readable output.
179
180       This method doesn't check whether the message actually encodes a trap
181       or anything else - the caller should use decode_trap_request() to find
182       out.
183
184   receive_trap() - receive message on trap socket (deprecated version).
185       This function is identical to receive_trap_1(), except that it returns
186       the sender address as three (formerly two) separate values: The host IP
187       address, the port, and (since version 1.14) the address family.  If you
188       use this, please consider moving to receive_trap_1(), because it is
189       easier to process the sender address in sockaddr format, in particular
190       in a world where IPv4 and IPv6 coexist.
191
192   decode_trap_request()
193           ($community, $ent, $agent, $gen, $spec, $dt, $bindings)
194             = $session->decode_trap_request ($trap);
195
196       Given a message such as one returned as the first return value from
197       receive_trap_1() or receive_trap(), try to decode it as some
198       notification PDU.  The code can handle SNMPv1 and SNMPv2 traps as well
199       as SNMPv2 INFORMs, although it fails to distinguish traps from informs,
200       which makes it hard to handle informs correctly (they should be
201       acknowledged).
202
203       The $ent, $agent, $gen, $spec, and $dt values will only be defined for
204       SNMPv1 traps.  For SNMPv2 traps and informs, some of this information
205       will be encoded as bindings.
206

METHODS in package SNMPv1_Session

208   open() - create an SNMPv1 session object
209           $session = SNMPv1_Session->open
210             ($host, $community, $port,
211              $max_pdu_len, $local_port, $max_repetitions,
212              $local_host, $ipv4only);
213
214       Note that all arguments except for $host are optional.  The $host can
215       be specified either as a hostname or as a numeric address.  Numeric
216       IPv6 addresses must be enclosed in square brackets []
217
218       $community defaults to "public".
219
220       $port defaults to 161, the standard UDP port to send SNMP requests to.
221
222       $max_pdu_len defaults to 8000.
223
224       $local_port can be specified if a specific local port is desired, for
225       example because of firewall rules for the response packets.  If none is
226       specified, the operating system will choose a random port.
227
228       $max_repetitions is the maximum number of repetitions requested in
229       "get-bulk" requests.  It is only relevant in SNMPv2(c) and later.
230
231       $local_host can be used to specify a specific address/interface.  It is
232       useful on hosts that have multiple addresses if a specific address
233       should be used, for example because of firewall rules.
234
235       If $ipv4only is either not present or non-zero, then an IPv4-only
236       socket will be used.  This is also the case if the system only supports
237       IPv4.  Otherwise, an IPv6 socket is created.  IPv6 sockets support both
238       IPv6 and IPv4 requests and responses.
239
240   open_trap_session() - create a session for receiving SNMP traps.
241           $session = open_trap_session ($port, $ipv4only);
242
243       $port defaults to 162, the standard UDP port that SNMP notifications
244       are sent to.
245
246       If $ipv4only is either not present or non-zero, then an IPv4-only
247       socket will be used.  This is also the case if the system only supports
248       IPv4.  Otherwise, an IPv6 socket is created.  IPv6 sockets can receive
249       messages over both IPv6 and IPv4.
250

METHODS in package SNMPv2c_Session

252   open() - create an SNMPv2(c) session object
253           $session = SNMPv2c_Session->open
254             ($host, $community, $port,
255              $max_pdu_len, $local_port, $max_repetitions,
256              $local_host, $ipv4only);
257
258       The calling and return conventions are identical to
259       SNMPv1_Session::open(), except that this returns a session object that
260       supports SNMPv2 operations.
261

EXAMPLES

263       The basic usage of these routines works like this:
264
265        use BER;
266        use SNMP_Session;
267
268        # Set $host to the name of the host whose SNMP agent you want
269        # to talk to.  Set $community to the community name under
270        # which you want to talk to the agent. Set port to the UDP
271        # port on which the agent listens (usually 161).
272
273        $session = SNMP_Session->open ($host, $community, $port)
274            or die "couldn't open SNMP session to $host";
275
276        # Set $oid1, $oid2... to the BER-encoded OIDs of the MIB
277        # variables you want to get.
278
279        if ($session->get_request_response ($oid1, $oid2, ...)) {
280            ($bindings) = $session->decode_get_response ($session->{pdu_buffer});
281
282            while ($bindings ne '') {
283               ($binding,$bindings) = decode_sequence ($bindings);
284               ($oid,$value) = decode_by_template ($binding, "%O%@");
285               print pretty_print ($oid)," => ", pretty_print ($value), "\n";
286            }
287        } else {
288            die "No response from agent on $host";
289        }
290
291   Encoding OIDs
292       In order to BER-encode OIDs, you can use the function BER::encode_oid.
293       It takes (a vector of) numeric subids as an argument. For example,
294
295        use BER;
296        encode_oid (1, 3, 6, 1, 2, 1, 1, 1, 0)
297
298       will return the BER-encoded OID for the sysDescr.0 (1.3.6.1.2.1.1.1.0)
299       instance of MIB-2.
300
301   Decoding the results
302       When get_request_response() returns success, you must decode the
303       response PDU from the remote agent. The function decode_get_response()
304       can be used to do this. It takes a "get-response" PDU, checks its
305       syntax and returns the bindings part of the PDU. This is where the
306       remote agent actually returns the values of the variables in your
307       query.
308
309       You should iterate over the individual bindings in this bindings part
310       and extract the value for each variable. In the example above, the
311       returned bindings are simply printed using the BER::pretty_print()
312       function.
313
314       For better readability of the OIDs, you can also use the following
315       idiom, where the %pretty_oids hash maps BER-encoded numerical OIDs to
316       symbolic OIDs. Note that this simple-minded mapping only works for
317       response OIDs that exactly match known OIDs, so it's unsuitable for
318       table walking (where the response OIDs include an additional row
319       index).
320
321        %ugly_oids = qw(sysDescr.0     1.3.6.1.2.1.1.1.0
322                       sysContact.0    1.3.6.1.2.1.1.4.0);
323        foreach (keys %ugly_oids) {
324            $ugly_oids{$_} = encode_oid (split (/\./, $ugly_oids{$_}));
325            $pretty_oids{$ugly_oids{$_}} = $_;
326        }
327        ...
328        if ($session->get_request_response ($ugly_oids{'sysDescr.0'},
329                                           $ugly_oids{'sysContact.0'})) {
330            ($bindings) = $session->decode_get_response ($session->{pdu_buffer});
331            while ($bindings ne '') {
332               ($binding,$bindings) = decode_sequence ($bindings);
333               ($oid,$value) = decode_by_template ($binding, "%O%@");
334               print $pretty_oids{$oid}," => ",
335                     pretty_print ($value), "\n";
336            }
337        } ...
338
339   Set Requests
340       Set requests are generated much like "get" or "getNext" requests are,
341       with the exception that you have to specify not just OIDs, but also the
342       values the variables should be set to. Every binding is passed as a
343       reference to a two-element array, the first element being the encoded
344       OID and the second one the encoded value. See the "test/set-test.pl"
345       script for an example, in particular the subroutine "snmpset".
346
347   Walking Tables
348       Beginning with version 0.57 of "SNMP_Session.pm", there is API support
349       for walking tables. The map_table() method can be used for this as
350       follows:
351
352        sub walk_function ($$$) {
353          my ($index, $val1, $val3) = @_;
354          ...
355        }
356
357        ...
358        $columns = [$base_oid1, $base_oid3];
359        $n_rows = $session->map_table ($columns, \&walk_function);
360
361       The columns argument must be a reference to a list of OIDs for table
362       columns sharing the same index. The method will traverse the table and
363       call the walk_function for each row. The arguments for these calls will
364       be:
365
366       1. the row index as a partial OID in dotted notation, e.g. 1.3, or
367       10.0.1.34.
368       2. the values of the requested table columns in that row, in BER-
369       encoded form. If you want to use the standard pretty_print() subroutine
370       to decode the values, you can use the following idiom:
371             grep (defined $_ && ($_=pretty_print $_), ($val1, $val3));
372
373   Walking Tables With "get-bulk"
374       Since version 0.67, "SNMP_Session" uses a different "get_table"
375       implementation for "SNMPv2c_Session"s. This version uses the ``powerful
376       "get-bulk" operator'' to retrieve many table rows with each request. In
377       general, this will make table walking much faster under SNMPv2c,
378       especially when round-trip times to the agent are long.
379
380       There is one difficulty, however: With "get-bulk", a management
381       application can specify the maximum number of rows to return in a
382       single response. "SNMP_Session.pm" provides a new function,
383       "map_table_4", in which this "maxRepetitions" value can be specified
384       explicitly.
385
386       For maximum efficiency, it should be set to a value that is one greater
387       than the number of rows in the table. If it is smaller, then
388       map_table() will use more request/response cycles than necessary; if it
389       is bigger, the agent will have to compute variable bindings beyond the
390       end of the table (which map_table() will throw away).
391
392       Of course it is usually impossible to know the size of the table in
393       advance. If you don't specify "maxRepetitions" when walking a table,
394       then map_table() will use a per-session default
395       ("$session->default_max_repetitions"). The default value for this
396       default is 12.
397
398       If you walk a table multiple times, and the size of the table is
399       relatively stable, you should use the return value of map_table()
400       (which is the number of rows it has encountered) to compute the next
401       value of "maxRepetitions". Remember to add one so that map_table()
402       notices when the table is finished!
403
404       Note that for really big tables, this doesn't make a big difference,
405       since the table won't fit in a single response packet anyway.
406
407   Sending Traps
408       To send a trap, you have to open an SNMP session to the trap receiver.
409       Usually this is a process listening to UDP port 162 on a network
410       management station. Then you can use the trap_request_send() method to
411       encode and send SNMPv1 traps. There is no way to find out whether the
412       trap was actually received at the management station - SNMP traps are
413       fundamentally unreliable.
414
415       When constructing an SNMPv1 trap, you must provide
416
417       •   the "enterprise" Object Identifier for the entity that generates
418           the trap
419
420       •   your IP address
421
422       •   the generic trap type
423
424       •   the specific trap type
425
426       •   the "sysUpTime" at the time of trap generation
427
428       •   a sequence (may be empty) of variable bindings further describing
429           the trap.
430
431       For SNMPv2 traps, you need:
432
433       •   the trap's OID
434
435       •   the "sysUpTime" at the time of trap generation
436
437       •   the bindings list as above
438
439       For SNMPv2 traps, the uptime and trap OID are encoded as bindings which
440       are added to the front of the other bindings you provide.
441
442       Here is a short example:
443
444        my $trap_receiver = "netman.noc";
445        my $trap_community = "SNMP_Traps";
446        my $trap_session = $version eq '1'
447            ? SNMP_Session->open ($trap_receiver, $trap_community, 162)
448            : SNMPv2c_Session->open ($trap_receiver, $trap_community, 162);
449        my $myIpAddress = ...;
450        my $start_time = time;
451
452        ...
453
454        sub link_down_trap ($$) {
455          my ($if_index, $version) = @_;
456          my $genericTrap = 2;         # linkDown
457          my $specificTrap = 0;
458          my @ifIndexOID = ( 1,3,6,1,2,1,2,2,1,1 );
459          my $upTime = int ((time - $start_time) * 100.0);
460          my @myOID = ( 1,3,6,1,4,1,2946,0,8,15 );
461
462          warn "Sending trap failed"
463            unless ($version eq '1')
464               ? $trap_session->trap_request_send (encode_oid (@myOID),
465                                                   encode_ip_address ($myIpAddress),
466                                                   encode_int ($genericTrap),
467                                                   encode_int ($specificTrap),
468                                                   encode_timeticks ($upTime),
469                                                   [encode_oid (@ifIndex_OID,$if_index),
470                                                    encode_int ($if_index)],
471                                                   [encode_oid (@ifDescr_OID,$if_index),
472                                                    encode_string ("foo")])
473                   : $trap_session->v2_trap_request_send (\@linkDown_OID, $upTime,
474                                                          [encode_oid (@ifIndex_OID,$if_index),
475                                                           encode_int ($if_index)],
476                                                          [encode_oid (@ifDescr_OID,$if_index),
477                                                           encode_string ("foo")]);
478        }
479
480   Receiving Traps
481       Since version 0.60, "SNMP_Session.pm" supports the receipt and decoding
482       of SNMPv1 trap requests. Since version 0.75, SNMPv2 Trap PDUs are also
483       recognized.
484
485       To receive traps, you have to create a special SNMP session that
486       passively listens on the SNMP trap transport address, usually on UDP
487       port 162.  Then you can receive traps - actually, SNMPv1 traps, SNMPv2
488       traps, and SNMPv2 informs, using the receive_trap_1() method and decode
489       them using decode_trap_request(). The enterprise, agent, generic,
490       specific and sysUptime return values are only defined for SNMPv1 traps.
491       In SNMPv2 traps and informs, the equivalent information is contained in
492       the bindings.
493
494        my $trap_session = SNMPv1_Session->open_trap_session (162, 0)
495          or die "cannot open trap session";
496        my ($trap, $sender_sockaddr) = $trap_session->receive_trap_1 ()
497          or die "cannot receive trap";
498        my ($community, $enterprise, $agent,
499            $generic, $specific, $sysUptime, $bindings)
500          = $trap_session->decode_trap_request ($trap)
501            or die "cannot decode trap received"
502        ...
503        my ($binding, $oid, $value);
504        while ($bindings ne '') {
505            ($binding,$bindings) = decode_sequence ($bindings);
506            ($oid, $value) = decode_by_template ($binding, "%O%@");
507            print BER::pretty_oid ($oid)," => ",pretty_print ($value),"\n";
508        }
509

AUTHORS

511       Created by:  Simon Leinen  <simon.leinen@switch.ch>
512
513       Contributions and fixes by:
514
515       Matthew Trunnell <matter@media.mit.edu>
516       Tobias Oetiker <tobi@oetiker.ch>
517       Heine Peters <peters@dkrz.de>
518       Daniel L. Needles <dan_needles@INS.COM>
519       Mike Mitchell <mcm@unx.sas.com>
520       Clinton Wong <clintdw@netcom.com>
521       Alan Nichols <Alan.Nichols@Ebay.Sun.COM>
522       Mike McCauley <mikem@open.com.au>
523       Andrew W. Elble <elble@icculus.nsg.nwu.edu>
524       Brett T Warden <wardenb@eluminant.com>: pretty "UInteger32"
525       Michael Deegan <michael@cnspc18.murdoch.edu.au>
526       Sergio Macedo <macedo@tmp.com.br>
527       Jakob Ilves (/IlvJa) <jakob.ilves@oracle.com>: PDU capture
528       Valerio Bontempi <v.bontempi@inwind.it>: IPv6 support
529       Lorenzo Colitti <lorenzo@colitti.com>: IPv6 support
530       Philippe Simonet <Philippe.Simonet@swisscom.com>: Export "avoid..."
531       Luc Pauwels <Luc.Pauwels@xalasys.com>: "use_16bit_request_ids"
532       Andrew Cornford-Matheson <andrew.matheson@corenetworks.com>: inform
533       Gerry Dalton <gerry.dalton@consolidated.com>: "strict subs" bug
534       Mike Fischer <mlf2@tampabay.rr.com>: pass MSG_DONTWAIT to recv()
535
537       Copyright (c) 1995-2009, Simon Leinen.
538
539       This program is free software; you can redistribute it under the
540       "Artistic License 2.0" included in this distribution (file "Artistic").
541
542
543
544perl v5.38.0                      2023-07-21                   SNMP_Session(3)
Impressum