You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-11-05 04:50:35 +03:00
542 lines
13 KiB
Perl
542 lines
13 KiB
Perl
package NetSNMP::agent;
|
|
|
|
use strict;
|
|
use Carp;
|
|
|
|
require Exporter;
|
|
require DynaLoader;
|
|
use AutoLoader;
|
|
|
|
use NetSNMP::default_store (':all');
|
|
use NetSNMP::agent::default_store (':all');
|
|
use NetSNMP::OID (':all');
|
|
use NetSNMP::agent::netsnmp_request_infoPtr;
|
|
|
|
use vars qw(@ISA %EXPORT_TAGS @EXPORT_OK @EXPORT $VERSION $AUTOLOAD);
|
|
|
|
@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.
|
|
|
|
# This allows declaration use NetSNMP::agent ':all';
|
|
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
|
|
# will save memory.
|
|
%EXPORT_TAGS = ( 'all' => [ qw(
|
|
MODE_GET
|
|
MODE_GETBULK
|
|
MODE_GETNEXT
|
|
MODE_SET_ACTION
|
|
MODE_SET_BEGIN
|
|
MODE_SET_COMMIT
|
|
MODE_SET_FREE
|
|
MODE_SET_RESERVE1
|
|
MODE_SET_RESERVE2
|
|
MODE_SET_UNDO
|
|
SNMP_ERR_NOERROR
|
|
SNMP_ERR_TOOBIG
|
|
SNMP_ERR_NOSUCHNAME
|
|
SNMP_ERR_BADVALUE
|
|
SNMP_ERR_READONLY
|
|
SNMP_ERR_GENERR
|
|
SNMP_ERR_NOACCESS
|
|
SNMP_ERR_WRONGTYPE
|
|
SNMP_ERR_WRONGLENGTH
|
|
SNMP_ERR_WRONGENCODING
|
|
SNMP_ERR_WRONGVALUE
|
|
SNMP_ERR_NOCREATION
|
|
SNMP_ERR_INCONSISTENTVALUE
|
|
SNMP_ERR_RESOURCEUNAVAILABLE
|
|
SNMP_ERR_COMMITFAILED
|
|
SNMP_ERR_UNDOFAILED
|
|
SNMP_ERR_AUTHORIZATIONERROR
|
|
SNMP_ERR_NOTWRITABLE
|
|
) ] );
|
|
|
|
@EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
|
|
|
@EXPORT = qw(
|
|
MODE_GET
|
|
MODE_GETBULK
|
|
MODE_GETNEXT
|
|
MODE_SET_ACTION
|
|
MODE_SET_BEGIN
|
|
MODE_SET_COMMIT
|
|
MODE_SET_FREE
|
|
MODE_SET_RESERVE1
|
|
MODE_SET_RESERVE2
|
|
MODE_SET_UNDO
|
|
SNMP_ERR_NOERROR
|
|
SNMP_ERR_TOOBIG
|
|
SNMP_ERR_NOSUCHNAME
|
|
SNMP_ERR_BADVALUE
|
|
SNMP_ERR_READONLY
|
|
SNMP_ERR_GENERR
|
|
SNMP_ERR_NOACCESS
|
|
SNMP_ERR_WRONGTYPE
|
|
SNMP_ERR_WRONGLENGTH
|
|
SNMP_ERR_WRONGENCODING
|
|
SNMP_ERR_WRONGVALUE
|
|
SNMP_ERR_NOCREATION
|
|
SNMP_ERR_INCONSISTENTVALUE
|
|
SNMP_ERR_RESOURCEUNAVAILABLE
|
|
SNMP_ERR_COMMITFAILED
|
|
SNMP_ERR_UNDOFAILED
|
|
SNMP_ERR_AUTHORIZATIONERROR
|
|
SNMP_ERR_NOTWRITABLE
|
|
);
|
|
$VERSION = '5.2.1.2';
|
|
|
|
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 $constname;
|
|
($constname = $AUTOLOAD) =~ s/.*:://;
|
|
croak "& not defined" if $constname eq 'constant';
|
|
my $val = constant($constname, @_ ? $_[0] : 0);
|
|
if ($! != 0) {
|
|
if ($! =~ /Invalid/ || $!{EINVAL}) {
|
|
$AutoLoader::AUTOLOAD = $AUTOLOAD;
|
|
goto &AutoLoader::AUTOLOAD;
|
|
}
|
|
else {
|
|
croak "Your vendor has not defined NetSNMP::agent macro $constname";
|
|
}
|
|
}
|
|
{
|
|
no strict 'refs';
|
|
# Fixed between 5.005_53 and 5.005_61
|
|
# if ($] >= 5.00561) {
|
|
# *$AUTOLOAD = sub () { $val };
|
|
# }
|
|
# else {
|
|
*$AUTOLOAD = sub { $val };
|
|
# }
|
|
}
|
|
goto &$AUTOLOAD;
|
|
}
|
|
|
|
{
|
|
my $haveinit = 0;
|
|
|
|
sub mark_init_agent_done {
|
|
$haveinit = 1;
|
|
}
|
|
|
|
sub maybe_init_agent {
|
|
return if ($haveinit);
|
|
$haveinit = 1;
|
|
|
|
snmp_enable_stderrlog();
|
|
my $flags = $_[0];
|
|
if ($flags->{'AgentX'}) {
|
|
netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1);
|
|
}
|
|
init_agent($flags->{'Name'} || "perl");
|
|
if ($flags->{'Ports'}) {
|
|
netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_PORTS, $flags->{'Ports'});
|
|
}
|
|
init_mib();
|
|
}
|
|
}
|
|
|
|
{
|
|
my $haveinit = 0;
|
|
|
|
sub mark_init_lib_done {
|
|
$haveinit = 1;
|
|
}
|
|
|
|
sub maybe_init_lib {
|
|
return if ($haveinit);
|
|
$haveinit = 1;
|
|
|
|
my $flags = $_[0];
|
|
init_snmp($flags->{'Name'} || "perl");
|
|
if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE) != 1) {
|
|
init_master_agent();
|
|
}
|
|
}
|
|
}
|
|
|
|
sub new {
|
|
my $type = shift;
|
|
my ($self);
|
|
%$self = @_;
|
|
bless($self, $type);
|
|
if ($self->{'dont_init_agent'}) {
|
|
$self->mark_init_agent_done();
|
|
} else {
|
|
$self->maybe_init_agent();
|
|
}
|
|
if ($self->{'dont_init_lib'}) {
|
|
$self->mark_init_lib_done();
|
|
}
|
|
return $self;
|
|
}
|
|
|
|
sub register($$$$) {
|
|
my ($self, $name, $oid, $sub) = @_;
|
|
my $reg = NetSNMP::agent::netsnmp_handler_registration::new($name, $oid, $sub);
|
|
$reg->register() if ($reg);
|
|
return $reg;
|
|
}
|
|
|
|
sub main_loop {
|
|
my $self = shift;
|
|
while(1) {
|
|
$self->agent_check_and_process(1);
|
|
}
|
|
}
|
|
|
|
sub agent_check_and_process {
|
|
my ($self, $blocking) = @_;
|
|
$self->maybe_init_lib();
|
|
__agent_check_and_process($blocking || 0);
|
|
}
|
|
|
|
bootstrap NetSNMP::agent $VERSION;
|
|
|
|
# Preloaded methods go here.
|
|
|
|
# Autoload methods go after =cut, and are processed by the autosplit program.
|
|
|
|
1;
|
|
__END__
|
|
|
|
=head1 NAME
|
|
|
|
NetSNMP::agent - Perl extension for the net-snmp agent.
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
use NetSNMP::agent;
|
|
|
|
my $agent = new NetSNMP::agent('Name' => 'my_agent_name');
|
|
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
This module implements an API set to make a SNMP agent act as a snmp
|
|
agent, a snmp subagent (using the AgentX subagent protocol) and/or
|
|
embedded perl-APIs directly within the traditional net-snmp agent demon.
|
|
|
|
Also see the tutorial about the genaral Net-SNMP C API, which this
|
|
module implements in a perl-way, and a perl specific tutorial at:
|
|
|
|
http://www.net-snmp.org/tutorial-5/toolkit/
|
|
|
|
=head1 EXAMPLES
|
|
|
|
=head2 Sub-agent example
|
|
|
|
use NetSNMP::agent (':all');
|
|
|
|
my $value = "hello world";
|
|
sub myhandler {
|
|
my ($handler, $registration_info, $request_info, $requests) = @_;
|
|
my $request;
|
|
|
|
for($request = $requests; $request; $request = $request->next()) {
|
|
my $oid = $request->getOID();
|
|
if ($request_info->getMode() == MODE_GET) {
|
|
# ... generally, you would calculate value from oid
|
|
if ($oid == new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.7375.1.0")) {
|
|
$request->setValue(ASN_OCTET_STR, $value);
|
|
}
|
|
} elsif ($request_info->getMode() == MODE_GETNEXT) {
|
|
# ... generally, you would calculate value from oid
|
|
if ($oid < new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.7375.1.0")) {
|
|
$request->setOID(".1.3.6.1.4.1.8072.9999.9999.7375.1.0");
|
|
$request->setValue(ASN_OCTET_STR, $value);
|
|
}
|
|
} elsif ($request_info->getMode() == MODE_SET_RESERVE1) {
|
|
if ($oid != new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.7375.1.0")) { # do error checking here
|
|
$request->setError($request_info, SNMP_ERR_NOSUCHNAME);
|
|
}
|
|
} elsif ($request_info->getMode() == MODE_SET_ACTION) {
|
|
# ... (or use the value)
|
|
$value = $request->getValue();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
my $agent = new NetSNMP::agent(
|
|
# makes the agent read a my_agent_name.conf file
|
|
'Name' => "my_agent_name",
|
|
'AgentX' => 1
|
|
);
|
|
}
|
|
|
|
$agent->register("my_agent_name", ".1.3.6.1.4.1.8072.9999.9999.7375",
|
|
\&myhandler);
|
|
|
|
my $running = 1;
|
|
while($running) {
|
|
$agent->agent_check_and_process(1);
|
|
}
|
|
|
|
$agent->shutdown();
|
|
|
|
|
|
=head2 Embedded agent example
|
|
|
|
# place this in a .pl file, and then in your snmpd.conf file put:
|
|
# perl do '/path/to/file.pl';
|
|
|
|
use NetSNMP::agent;
|
|
my $agent;
|
|
|
|
sub myhandler {
|
|
my ($handler, $registration_info, $request_info, $requests) = @_;
|
|
# ...
|
|
}
|
|
|
|
$agent = new NetSNMP::agent(
|
|
'Name' => 'my_agent_name'
|
|
);
|
|
|
|
$agent->register("my_agent_name", ".1.3.6.1.4.1.8072.9999.9999.7375",
|
|
\&myhandler);
|
|
|
|
$agent->main_loop();
|
|
|
|
|
|
=head1 CONSTRUCTOR
|
|
|
|
new ( OPTIONS )
|
|
This is the constructor for a new NetSNMP::agent object.
|
|
|
|
Possible options are:
|
|
|
|
Name - Name of the agent (optional, defaults to "perl")
|
|
(The snmp library will read a NAME.conf snmp
|
|
configuration file based on this argument.)
|
|
AgentX - Make us a sub-agent (0 = false, 1 = true)
|
|
(The Net-SNMP master agent must be running first)
|
|
Ports - Ports this agent will listen on (EG: "udp:161,tcp:161")
|
|
|
|
Example:
|
|
|
|
$agent = new NetSNMP::agent(
|
|
'Name' => 'my_agent_name',
|
|
'AgentX' => 1
|
|
);
|
|
|
|
|
|
=head1 METHODS
|
|
|
|
register (NAME, OID, \&handler_routine )
|
|
Registers the callback handler with given OID.
|
|
|
|
$agent->register();
|
|
|
|
A return code of 0 indicates no error.
|
|
|
|
agent_check_and_process ( BLOCKING )
|
|
Run one iteration of the main loop.
|
|
|
|
BLOCKING - Blocking or non-blocking call. 1 = true, 0 = false.
|
|
|
|
$agent->agent_check_and_process(1);
|
|
|
|
main_loop ()
|
|
Runs the agent in a loop. Does not return.
|
|
|
|
shutdown ()
|
|
Nicely shuts down the agent or sub-agent.
|
|
|
|
$agent->shutdown();
|
|
|
|
=head1 HANDLER CALLBACKS
|
|
|
|
handler ( HANDLER, REGISTRATION_INFO, REQUEST_INFO, REQUESTS )
|
|
|
|
The handler is called with the following parameters:
|
|
|
|
HANDLER - FIXME
|
|
REGISTRATION_INFO - what are the correct meanings of these?
|
|
REQUEST_INFO -
|
|
REQUESTS -
|
|
|
|
Example handler:
|
|
|
|
sub myhandler {
|
|
my ($handler, $reg_info, $request_info, $requests) = @_;
|
|
# ...
|
|
}
|
|
|
|
The handler subroutine will be called when a SNMP request received by
|
|
the agent for anything below the registered OID. The handler is
|
|
passed 4 arguments: $handler, $registration_info, $request_info,
|
|
$requests. These match the arguments passed to the C version of the
|
|
same API. Note that they are not entirely complete objects but are
|
|
functional "enough" at this point in time.
|
|
|
|
=head2 $request_info object functions
|
|
|
|
getMode ()
|
|
Returns the mode of the request. See the MODES section for
|
|
list of valid modes.
|
|
|
|
$mode = $request->getMode();
|
|
|
|
getRootOID ()
|
|
Returns a NetSNMP::OID object that describes the registration
|
|
point that the handler is getting called for (in case you
|
|
register one handler function with multiple OIDs, which should
|
|
be rare anyway)
|
|
|
|
$root_oid = $request->getRootOID();
|
|
|
|
=head2 $request object functions
|
|
|
|
next ()
|
|
Returns the next request in the list or undef if there is no
|
|
next request.
|
|
|
|
$request = $request->next();
|
|
|
|
getOID ()
|
|
Returns the oid of the request (a NetSNMP::OID class).
|
|
|
|
$oid = $request->getOID();
|
|
|
|
setOID (new NetSNMP::OID("someoid"))
|
|
Sets the OID of the request to a passed oid value. This
|
|
should generally only be done during handling of GETNEXT
|
|
requests.
|
|
|
|
$request->setOID(new NetSNMP::OID("someoid"));
|
|
|
|
getValue ()
|
|
Returns the value of the request. Used for example when
|
|
setting values.
|
|
|
|
$value = $request->getValue();
|
|
|
|
FIXME: how to get the type of the value? Is it even available?
|
|
[Wes: no, not yet.]
|
|
|
|
setValue ( TYPE, DATA )
|
|
Sets the data to be returned to the daemon.
|
|
|
|
Returns 1 on success, 0 on error.
|
|
|
|
TYPE - Type of the data. See NetSNMP::ASN for valid types.
|
|
DATA - The data to return.
|
|
|
|
$ret = $request->setValue(ASN_OCTET_STR, "test");
|
|
|
|
setError ( REQUEST_INFO, ERROR_CODE )
|
|
Sets the given error code for the request. See the ERROR CODES
|
|
section for list of valid codes.
|
|
|
|
$request->setError($request_info, SNMP_ERR_NOTWRITABLE);
|
|
|
|
getProcessed ()
|
|
The processed flag indicates that a request does not need to
|
|
be dealt with because someone else (a higher handler) has
|
|
dealt with it already.
|
|
|
|
$processed = $request->getProcessed();
|
|
|
|
setProcessed ( PROCESSED )
|
|
Sets the processed flag flag in the request. You generally
|
|
should not have to set this yourself.
|
|
|
|
PROCESSED - 0 = false, 1 = true
|
|
|
|
$request->setProcessed(1);
|
|
|
|
getDelegated ()
|
|
If you can handle a request in the background or at a future
|
|
time (EG, you're waiting on a file handle, or network traffic,
|
|
or ...), the delegated flag can be set in the request. When
|
|
the request is processed in the future the flag should be set
|
|
back to 0 so the agent will know that it can wrap up the
|
|
original request and send it back to the manager. This has
|
|
not been tested within perl, but it hopefully should work.
|
|
|
|
$delegated = $request->getDelegated();
|
|
|
|
setDelegated ( DELEGATED )
|
|
Sets the delegated flag.
|
|
|
|
DELEGATED - 0 = false, 1 = true
|
|
|
|
$request->setDelegated(1);
|
|
|
|
getRepeat ()
|
|
The repeat flag indicates that a getbulk operation is being
|
|
handled and this indicates how many answers need to be
|
|
returned. Generally, if you didn't register to directly
|
|
handle getbulk support yourself, you won't need to deal with
|
|
this value.
|
|
|
|
$repeat = $request->getRepeat();
|
|
|
|
setRepeat ( REPEAT )
|
|
Sets the repeat count (decrement after answering requests if
|
|
you handle getbulk requests yourself)
|
|
|
|
REPEAT - repeat count FIXME
|
|
|
|
$request->setRepeat(5);
|
|
|
|
=head1 MODES
|
|
|
|
MODE_GET
|
|
MODE_GETBULK
|
|
MODE_GETNEXT
|
|
MODE_SET_ACTION
|
|
MODE_SET_BEGIN
|
|
MODE_SET_COMMIT
|
|
MODE_SET_FREE
|
|
MODE_SET_RESERVE1
|
|
MODE_SET_RESERVE2
|
|
MODE_SET_UNDO
|
|
|
|
=head1 ERROR CODES
|
|
|
|
SNMP_ERR_NOERROR
|
|
SNMP_ERR_TOOBIG
|
|
SNMP_ERR_NOSUCHNAME
|
|
SNMP_ERR_BADVALUE
|
|
SNMP_ERR_READONLY
|
|
SNMP_ERR_GENERR
|
|
SNMP_ERR_NOACCESS
|
|
SNMP_ERR_WRONGTYPE
|
|
SNMP_ERR_WRONGLENGTH
|
|
SNMP_ERR_WRONGENCODING
|
|
SNMP_ERR_WRONGVALUE
|
|
SNMP_ERR_NOCREATION
|
|
SNMP_ERR_INCONSISTENTVALUE
|
|
SNMP_ERR_RESOURCEUNAVAILABLE
|
|
SNMP_ERR_COMMITFAILED
|
|
SNMP_ERR_UNDOFAILED
|
|
SNMP_ERR_AUTHORIZATIONERROR
|
|
SNMP_ERR_NOTWRITABLE
|
|
|
|
=head1 AUTHOR
|
|
|
|
Please mail the net-snmp-users@lists.sourceforge.net mailing list for
|
|
help, questions or comments about this module.
|
|
|
|
Module written by:
|
|
Wes Hardaker <hardaker@users.sourceforge.net>
|
|
|
|
Documentation written by:
|
|
Toni Willberg <toniw@iki.fi>
|
|
Wes Hardaker <hardaker@users.sourceforge.net>
|
|
|
|
=head1 SEE ALSO
|
|
|
|
NetSNMP::OID(3), NetSNMP::ASN(3), perl(1).
|
|
|
|
=cut
|