POE::Co...t::SNMP(3)

πŸ“¦
version 1.1006 Β· 2 versions
, in fedora 43

πŸ’– NAME πŸ’–

POE::Component::SNMP β€” literally just a POE interface to Net::SNMP, bestie. That's the whole vibe. The manual page lives in the User Contributed Perl Documentation section, and it's giving POE::Co...t::SNMP(3), iykyk.


✨ SYNOPSIS ✨

okay so this script ships with the distribution as eg/snmp_sample.pl and it's lowkey the cutest little demo:

# this script is included in the distribution as eg/snmp_sample.pl
use POE qw/Component::SNMP/;

my %system = ( sysUptime   => '.1.3.6.1.2.1.1.3.0',
               sysName     => '.1.3.6.1.2.1.1.5.0',
               sysLocation => '.1.3.6.1.2.1.1.6.0',
             );
my @oids = values %system;
my $base_oid = '.1.3.6.1.2.1.1'; # system.*

POE::Session->create( inline_states =>
                      { _start       => \&_start,
                        snmp_handler => \&snmp_handler,
                      }
                    );

sub _start {
  my ($kernel, $heap) = @_[KERNEL, HEAP];

  POE::Component::SNMP->create( alias     => 'snmp', # same as default
                                hostname  => 'localhost',
                                community => 'public',
                                version   => 'snmpv2c',
                                # debug => 0x0A,
                              );

  $kernel->post( snmp => get     => snmp_handler =>
                 -varbindlist    => \@oids );

  # ... or maybe ...

  $kernel->post( snmp => walk    => snmp_handler =>
                 -baseoid        => $base_oid );

  # ... or possibly even ...

  my @callback_args = (1, 2, 3);
  $kernel->post( snmp => getbulk => snmp_handler =>
                 -varbindlist    => [ $base_oid ],
                 -maxrepetitions => 6,
                 -callback_args  => \@callback_args
               );

  $heap->{pending} = 3;
}

sub snmp_handler {
  my ($kernel, $heap, $request, $response) = @_[KERNEL, HEAP, ARG0, ARG1];
  my ($alias, $host, $cmd, @args) = @$request;
  my ($results, @callback_args)   = @$response;

  if (ref $results) {
    print "$host SNMP config ($cmd):\n";
    print "sysName:     $results->{$system{sysName}}\n";
    print "sysUptime:   $results->{$system{sysUptime}}\n";
    print "sysLocation: $results->{$system{sysLocation}}\n";
  } else {
    print "$host SNMP error ($cmd => @args):\n$results\n";
  }

  print "Additional args: @callback_args\n";

  if (--$heap->{pending} == 0) {
    $kernel->post( $alias => 'finish' );
  }
}

$poe_kernel->run();

# see the eg/ folder in the distribution archive for more samples
psst β€” the eg/ folder in the distribution archive has even more samples if you want extra inspo πŸ¦‹

🌸 DESCRIPTION 🌸

POE::Component::SNMP is a POE-ized wrapper around the Net::SNMP module written by David M. Town. Most of its arguments aren't even evaluated by POE, except for -alias and -callback_args, as described below. Yeah, it just vibes like that πŸ’…


πŸŽ€ CREATING SNMP COMPONENTS πŸŽ€

create β€” create an SNMP session

POE::Component::SNMP->create(
    hostname  => $hostname,   # required
   [alias     => $alias,    ] # default 'snmp'
   [community => $community,] # default 'public'
   [version   => $version,  ] # default '1', SNMPv1
   [timeout   => $timeout,  ] # default 5.0 (seconds)
   [retries   => $retries,  ] # default 1
   [debug     => $debug,    ] # default 0
   [ ... any other arguments Net::SNMP recognizes ... ]
);

create() hands all of its arguments over to the constructor for a Net::SNMP object completely untouched β€” except for -alias. See Net::SNMP::session(). The constructor is flexible like that and supports either of these two parameter naming styles:

$object->method(-parameter => $value);
$object->method( parameter => $value);

-hostname is required. and yeah, this differs from the behavior in Net::SNMP, which is to default to 'localhost'. So no, you can't just skip it here, bestie πŸ™ˆ

-alias is not required unless you want to query more than one host. See "Concurrency", below. πŸ‘‡


Concurrency

In order to access multiple SNMP hosts simultaneously, you must create a separate instance of the component for each host, by giving each component a different -alias parameter in the constructor.

Multiple requests to a particular instance are processed in FIFO order, including retries (-retries defaults to 1). So this means that if you have multiple pending requests to a single host, and one automatically attempts retry for whatever reason, the retry request will "go to the end of the line" behind any other queued requests. No cutting, periodt πŸ’…

There is no limit to how many simultaneous instances can be processing requests. It is possible to create multiple instances for the same host. Iconic.

The -alias and -hostname parameters, as well as additional request-specific data, are passed back to callback events, as described in "CALLBACKS" below, so the callback can determine what context the current response (or timeout) is related to.

NOTE: It is an error to attempt to create more than one SNMP session with the same -alias. It's not fatal unless you run POE with ASSERT_USAGE, but it won't work regardless. So like… don't 😭

Sockets

By default, Net::SNMP creates a single socket per network interface. This is possible because the Net::SNMP event loop processes all SNMP requests in FIFO order and is thus able to reuse the same socket for each request, regardless of its destination; however, it is not multiplexed. Since we can only watch one connection per socket at a time, this creates a conflict if you want to contact more than one remote host simultaneously. πŸ’€

The workaround used by the module is to create each socket using a different randomly generated value for the -localport parameter, specifying a unique local UDP port for each instance of the component. This could potentially interfere with remote communications if your local firewall policy requires a specific source port for outgoing SNMP requests (as noted by David Town, the author of Net::SNMP). In this situation, you can supply an explicit -localport argument to the constructor, but remember that every active session requires its own unique local port per session/host, per interface. Yes, it's a lot. She's doing her best 🫢


πŸ”₯ REQUESTS πŸ”₯

Most of the events accept a list of arguments which are passed directly to a Net::SNMP session. See "METHODS" in Net::SNMP for more information on these arguments.

Requests take the form:

$poe_kernel->post( $session_alias => $request =>
                   $callback_state => @snmp_args );

See the "SYNOPSIS" and the following per-request specifics for examples. ✨

get

$poe_kernel->post( snmp => get => parse_get_results =>
                                  #  system.sysUptime
                   varbindlist => [ '.1.3.6.1.2.1.1.3.0' ] );

See Net::SNMP::get_request().

getnext

$poe_kernel->post( snmp => get => parse_getnext_results =>
                                  #  system.*
                   varbindlist => [ '.1.3.6.1.2.1.1.1.0',
                                    '.1.3.6.1.2.1.1.2.0',
                                    '.1.3.6.1.2.1.1.3.0',
                                    '.1.3.6.1.2.1.1.4.0',
                                    '.1.3.6.1.2.1.1.5.0',
                                    '.1.3.6.1.2.1.1.6.0',
                                    '.1.3.6.1.2.1.1.7.0',
                                    '.1.3.6.1.2.1.1.8.0',
                                  ] );

See Net::SNMP::get_next_request().

getbulk

$poe_kernel->post( snmp => getbulk => parse_getbulk_results =>
                   maxrepetitions => 8,
                                  #  system.*
                   varbindlist => [ '.1.3.6.1.2.1.1' ] );

See Net::SNMP::get_bulk_request().

walk

$poe_kernel->post( snmp => walk => parse_walk_results =>
                              #  system.*
                   baseoid => [ '.1.3.6.1.2.1.1' ] );

See Net::SNMP::get_table().

getentries

See Net::SNMP::get_entries().

inform

See Net::SNMP::inform_request().

set

$poe_kernel->post( snmp => set => snmp_set_callback =>
                                  #  system.sysContact
                   varbindlist => [ '.1.3.6.1.2.1.1.4.0',
                                    'OCTET_STRING', 'test@test.com'] );

See Net::SNMP::set_request().

trap

$kernel->post( snmp => trap => @snmp_args );
# or, even better:
my $status = $kernel->call( snmp => trap => @snmp_args );

Send a SNMPv1 trap message. See Net::SNMP::trap(). This method differs from the requests in that it does not take a state name as a callback parameter. If the method is invoked with POE::Kernel::call(), the return value is that of Net::SNMP::trap(). A false value indicates an error, and the error message can be retrieved using "errmsg", below. πŸ‘€

trap2c

$kernel->post( snmp => trap2c => @snmp_args );
# or, even better:
my $status = $kernel->call( snmp => trap2c => @snmp_args );

Send a SNMPv2c trap message. See Net::SNMP::snmpv2_trap(). This method differs from the others in that it does not take a state name as a callback parameter. If the method is invoked with POE::Kernel::call(), the return value is that of snmpv2_trap(). A false value indicates an error, and the error message can be retrieved via "errmsg", below. πŸ‘€

errmsg

my $last_snmp_error_message = $kernel->call( snmp => 'errmsg' );

Retrieves the last error message, if any, from the specified SNMP session. Your little detective moment πŸ”

finish

$kernel->post( snmp => 'finish' );

Shut down the specified SNMP component. All current and pending requests are cancelled immediately and the session is closed. If the component is currently dispatching a request (waiting for a reply) when this request is received, the response NOT be delivered to the designated callback. Yeah. Rude but that's the deal πŸ’€

NOTE: Things break if you use POE::Kernel's call() method to issue a request to a component and then call() a "finish" to the same component within the same event/subroutine. So don't do that. Stick with post() and you'll be fine. 🫢

πŸ’– CALLBACKS πŸ’–

Okay bestie, this is the part where your request actually talks back to you. When a request receives a response (or times out), the callback event you supplied gets invoked. That callback event is a POE event name, and it has to be defined in the session that called the SNMP component. (If you wanna know more about $_[_ARG0] and $_[_ARG1], go peek at POE::Session β€” it's giving required reading. πŸ‘‘)

So, the callback's $_[ARG0] parameter? It's an array reference stuffed with your request info:

  • the component alias 🏷️
  • the hostname 🌐
  • the method that got called (like 'get', for example) πŸ“ž
  • and the parameters that were supplied to the request

And the callback's $_[ARG1] parameter is also an array reference, but this one's carrying the response info. Its first element β€” $_[ARG1][0] β€” is either a hash reference holding response data or a scalar error message string. 😭 Pick your fighter.

Oh and if you passed any arguments to the request through -callback_args (we're getting to that, don't worry), those come back as additional elements in $_[ARG1]. ✨

NOTE: This is a change from older versions of the module, fr fr! Back in the day, errors were returned in $_[ARG1][1]. So if you're running ancient code and it's being weird, that's why. πŸ’€

πŸŽ€ -callback_args πŸŽ€

# $callback_state receives @args in $_[_ARG1]
$kernel->post( $alias => get => $callback_state =>
               -callback_args => \@args,
               -varbindlist   => \@oids );

This is an optional parameter you can hand to all component requests that return a response, and what it does is set a list of extra values that get passed to the POE state as parameters. 🫢

The argument must be an array reference, and that array reference gets dereferenced as a list of additional response parameters β€” placed after the SNMP response data. So order matters, bestie, don't come for me later. πŸ’…


🌈 SEE ALSO 🌈

  • Net::SNMP
  • POE

πŸ‘‘ AUTHOR πŸ‘‘

Adopted and maintained by Rob Bloodgood <rdb@cpan.org> πŸ’œ

Originally by Todd Caine <tcaine@eli.net> 🌸


Copyright 2004-2008 by Rob Bloodgood

Copyright 2003 by Todd Caine

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. πŸ¦‹


And that's the whole page, bestie!! No cap, you just read the entire POE::Component::SNMP(3) manpage and you absolutely ate. πŸ’…βœ¨

perl v5.42.0 Β· 2025-07-25 β€” that's the version and date this page was generated, so if your copy says something different, you're looking at a different snapshot. Go forth and SNMP, queen. πŸŽ€πŸ’–πŸŒΊ

πŸ“¦ where this page comes from