agent.pm
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:13k
- 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.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