Blame perl/TrapReceiver/TrapReceiver.pm

Packit fcad23
package NetSNMP::TrapReceiver;
Packit fcad23
Packit fcad23
use 5.00006;
Packit fcad23
use strict;
Packit fcad23
use Carp;
Packit fcad23
Packit fcad23
require Exporter;
Packit fcad23
require DynaLoader;
Packit fcad23
Packit fcad23
use AutoLoader;
Packit fcad23
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $AUTOLOAD);
Packit fcad23
@ISA = qw(Exporter
Packit fcad23
	DynaLoader);
Packit fcad23
Packit fcad23
require NetSNMP::OID;
Packit fcad23
Packit fcad23
Packit fcad23
# Items to export into callers namespace by default. Note: do not export
Packit fcad23
# names by default without a very good reason. Use EXPORT_OK instead.
Packit fcad23
# Do not simply export all your public functions/methods/constants.
Packit fcad23
Packit fcad23
# This allows declaration	use NetSNMP::TrapReceiver ':all';
Packit fcad23
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
Packit fcad23
# will save memory.
Packit fcad23
%EXPORT_TAGS = ( 'all' => [ qw(
Packit fcad23
	NETSNMPTRAPD_AUTH_HANDLER
Packit fcad23
	NETSNMPTRAPD_HANDLER_BREAK
Packit fcad23
	NETSNMPTRAPD_HANDLER_FAIL
Packit fcad23
	NETSNMPTRAPD_HANDLER_FINISH
Packit fcad23
	NETSNMPTRAPD_HANDLER_OK
Packit fcad23
	NETSNMPTRAPD_POST_HANDLER
Packit fcad23
	NETSNMPTRAPD_PRE_HANDLER
Packit fcad23
	netsnmp_add_default_traphandler
Packit fcad23
	netsnmp_add_global_traphandler
Packit fcad23
	netsnmp_add_traphandler
Packit fcad23
) ] );
Packit fcad23
Packit fcad23
@EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
Packit fcad23
Packit fcad23
@EXPORT = qw(
Packit fcad23
	NETSNMPTRAPD_AUTH_HANDLER
Packit fcad23
	NETSNMPTRAPD_HANDLER_BREAK
Packit fcad23
	NETSNMPTRAPD_HANDLER_FAIL
Packit fcad23
	NETSNMPTRAPD_HANDLER_FINISH
Packit fcad23
	NETSNMPTRAPD_HANDLER_OK
Packit fcad23
	NETSNMPTRAPD_POST_HANDLER
Packit fcad23
	NETSNMPTRAPD_PRE_HANDLER
Packit fcad23
);
Packit fcad23
Packit fcad23
$VERSION = '5.08';
Packit fcad23
Packit fcad23
# sub new {
Packit fcad23
#     my $type = shift;
Packit fcad23
#     my ($self);
Packit fcad23
#     %$self = @_;
Packit fcad23
#     bless($self, $type);
Packit fcad23
#     return $self;
Packit fcad23
# }
Packit fcad23
Packit fcad23
# sub register($$$$) {
Packit fcad23
#     my ($self, $oid, $sub) = @_;
Packit fcad23
#     my $reg = NetSNMP::TrapReceiver::registration::new($oid, $sub);
Packit fcad23
#     if ($reg) {
Packit fcad23
# 	$reg->register();
Packit fcad23
# 	$self->{'regobjs'}{$name} = $reg;
Packit fcad23
#     }
Packit fcad23
#     return $reg;
Packit fcad23
# }
Packit fcad23
Packit fcad23
sub AUTOLOAD {
Packit fcad23
    # This AUTOLOAD is used to 'autoload' constants from the constant()
Packit fcad23
    # XS function.
Packit fcad23
Packit fcad23
    my $constname;
Packit fcad23
    ($constname = $AUTOLOAD) =~ s/.*:://;
Packit fcad23
    croak "&NetSNMP::TrapReceiver::constant not defined" if $constname eq 'constant';
Packit fcad23
    my ($error, $val) = constant($constname);
Packit fcad23
    if ($error) { croak $error; }
Packit fcad23
    {
Packit fcad23
	no strict 'refs';
Packit fcad23
	# Fixed between 5.005_53 and 5.005_61
Packit fcad23
#XXX	if ($] >= 5.00561) {
Packit fcad23
#XXX	    *$AUTOLOAD = sub () { $val };
Packit fcad23
#XXX	}
Packit fcad23
#XXX	else {
Packit fcad23
	    *$AUTOLOAD = sub { $val };
Packit fcad23
#XXX	}
Packit fcad23
    }
Packit fcad23
    goto &$AUTOLOAD;
Packit fcad23
}
Packit fcad23
Packit fcad23
bootstrap NetSNMP::TrapReceiver $VERSION;
Packit fcad23
Packit fcad23
# Preloaded methods go here.
Packit fcad23
Packit fcad23
# Autoload methods go after =cut, and are processed by the autosplit program.
Packit fcad23
Packit fcad23
1;
Packit fcad23
__END__
Packit fcad23
Packit fcad23
=head1 NAME
Packit fcad23
Packit fcad23
NetSNMP::TrapReceiver - Embedded perl trap handling for Net-SNMP's snmptrapd
Packit fcad23
Packit fcad23
=head1 SYNOPSIS
Packit fcad23
Packit fcad23
Put the following lines in your snmptrapd.conf file:
Packit fcad23
Packit fcad23
  perl NetSNMP::TrapReceiver::register("trapOID", \&myfunc);
Packit fcad23
Packit fcad23
=head1 ABSTRACT
Packit fcad23
Packit fcad23
The NetSNMP::TrapReceiver module is used to register perl
Packit fcad23
subroutines into the Net-SNMP snmptrapd process.  Net-SNMP MUST have
Packit fcad23
been configured using --enable-embedded-perl.  Registration of
Packit fcad23
functions is then done through the snmptrapd.conf configuration
Packit fcad23
file.  This module can NOT be used in a normal perl script to
Packit fcad23
receive traps.  It is intended solely for embedded use within the
Packit fcad23
snmptrapd demon.
Packit fcad23
Packit fcad23
=head1 DESCRIPTION
Packit fcad23
Packit fcad23
Within the snmptrapd.conf file, the keyword "perl" may be used to call
Packit fcad23
any perl expression and using this ability, you can use the
Packit fcad23
NetSNMP::TrapReceiver module to register functions which will be
Packit fcad23
called every time a given notification (a trap or an inform) is
Packit fcad23
received.  Registered functions are called with 2 arguments.  The
Packit fcad23
first is a reference to a hash containing information about how the
Packit fcad23
trap was received (what version of the SNMP protocol was used, where
Packit fcad23
it came from, what SNMP user name or community name it was sent under,
Packit fcad23
etc).  The second argument is a reference to an array containing the
Packit fcad23
variable bindings (OID and value information) that define the
Packit fcad23
noification itself.  Each variable is itself a reference to an array
Packit fcad23
containing four values: a NetSNMP::OID object, a string representation
Packit fcad23
of the value that came associated with it, the value's numeric type (see
Packit fcad23
NetSNMP::ASN for further details on SNMP typing information), and the raw
Packit fcad23
value of the trap, encoded according to its type, 64-bit integer types are
Packit fcad23
returned as strings, integer types as integers, strings as strings, object
Packit fcad23
identifiers as NetSNMP::OID objects, and any other types as undefs.
Packit fcad23
Packit fcad23
Registered functions should return one of the following values:
Packit fcad23
Packit fcad23
=over 2
Packit fcad23
Packit fcad23
=item NETSNMPTRAPD_HANDLER_OK
Packit fcad23
Packit fcad23
Handling the trap succeeded, but lets the snmptrapd demon check for
Packit fcad23
further appropriate handlers.
Packit fcad23
Packit fcad23
=item NETSNMPTRAPD_HANDLER_FAIL
Packit fcad23
Packit fcad23
Handling the trap failed, but lets the snmptrapd demon check for
Packit fcad23
further appropriate handlers.
Packit fcad23
Packit fcad23
=item NETSNMPTRAPD_HANDLER_BREAK
Packit fcad23
Packit fcad23
Stops evaluating the list of handlers for this specific trap, but lets
Packit fcad23
the snmptrapd demon apply global handlers.
Packit fcad23
Packit fcad23
=item NETSNMPTRAPD_HANDLER_FINISH
Packit fcad23
Packit fcad23
Stops searching for further appropriate handlers.
Packit fcad23
Packit fcad23
=back
Packit fcad23
Packit fcad23
If a handler function does not return anything appropriate or even
Packit fcad23
nothing at all, a return value of NETSNMPTRAPD_HANDLER_OK is assumed.
Packit fcad23
Packit fcad23
Subroutines are registered using the NetSNMP::TrapReceiver::register
Packit fcad23
function, which takes two arguments.  The first is a string describing
Packit fcad23
the notification you want to register for (such as "linkUp" or
Packit fcad23
"MyMIB::MyTrap" or ".1.3.6.1.4.1.2021....").  Two special keywords can
Packit fcad23
be used in place of an OID: "default" and "all".  The "default"
Packit fcad23
keyword indicates you want your handler to be called in the case where
Packit fcad23
no other handlers are called.  The "all" keyword indicates that the
Packit fcad23
handler should ALWAYS be called for every notification.
Packit fcad23
Packit fcad23
Packit fcad23
=head1 EXAMPLE
Packit fcad23
Packit fcad23
As an example, put the following code into a file (say
Packit fcad23
"/usr/local/share/snmp/mytrapd.pl"):
Packit fcad23
Packit fcad23
  #!/usr/bin/perl
Packit fcad23
Packit fcad23
  sub my_receiver {
Packit fcad23
      print "********** PERL RECEIVED A NOTIFICATION:\n";
Packit fcad23
Packit fcad23
      # print the PDU info (a hash reference)
Packit fcad23
      print "PDU INFO:\n";
Packit fcad23
      foreach my $k(keys(%{$_[0]})) {
Packit fcad23
        if ($k eq "securityEngineID" || $k eq "contextEngineID") {
Packit fcad23
          printf "  %-30s 0x%s\n", $k, unpack('h*', $_[0]{$k});
Packit fcad23
        }
Packit fcad23
        else {
Packit fcad23
          printf "  %-30s %s\n", $k, $_[0]{$k};
Packit fcad23
        }
Packit fcad23
      }
Packit fcad23
Packit fcad23
      # print the variable bindings:
Packit fcad23
      print "VARBINDS:\n";
Packit fcad23
      foreach my $x (@{$_[1]}) { 
Packit fcad23
	  printf "  %-30s type=%-2d value=%s\n", $x->[0], $x->[2], $x->[1]; 
Packit fcad23
      }
Packit fcad23
  }
Packit fcad23
Packit fcad23
  NetSNMP::TrapReceiver::register("all", \&my_receiver) || 
Packit fcad23
    warn "failed to register our perl trap handler\n";
Packit fcad23
Packit fcad23
  print STDERR "Loaded the example perl snmptrapd handler\n";
Packit fcad23
Packit fcad23
Then, put the following line in your snmprapd.conf file:
Packit fcad23
Packit fcad23
  perl do "/usr/local/share/snmp/mytrapd.pl";
Packit fcad23
Packit fcad23
Start snmptrapd (as root, and the following other opions make it stay
Packit fcad23
in the foreground and log to stderr):
Packit fcad23
Packit fcad23
  snmptrapd -f -Le
Packit fcad23
Packit fcad23
You should see it start up and display the final message from the end
Packit fcad23
of the above perl script:
Packit fcad23
Packit fcad23
  Loaded the perl snmptrapd handler
Packit fcad23
  2004-02-11 10:08:45 NET-SNMP version 5.2 Started.
Packit fcad23
Packit fcad23
Then, if you send yourself a fake trap using the following example command:
Packit fcad23
Packit fcad23
  snmptrap -v 2c -c mycommunity localhost 0 linkUp ifIndex.1 i 1 \
Packit fcad23
      ifAdminStatus.1 i up ifOperStatus.1 i up ifDescr s eth0
Packit fcad23
Packit fcad23
You should see the following output appear from snmptrapd as your perl
Packit fcad23
code gets executed:
Packit fcad23
Packit fcad23
  ********** PERL RECEIVED A NOTIFICATION:
Packit fcad23
  PDU INFO:
Packit fcad23
    notificationtype               TRAP
Packit fcad23
    receivedfrom                   127.0.0.1
Packit fcad23
    version                        1
Packit fcad23
    errorstatus                    0
Packit fcad23
    messageid                      0
Packit fcad23
    community                      mycommunity
Packit fcad23
    transactionid                  2
Packit fcad23
    errorindex                     0
Packit fcad23
    requestid                      765160220
Packit fcad23
  VARBINDS:
Packit fcad23
    sysUpTimeInstance              type=67 value=0:0:00:00.00
Packit fcad23
    snmpTrapOID.0                  type=6  value=linkUp
Packit fcad23
    ifIndex.1                      type=2  value=1
Packit fcad23
    ifAdminStatus.1                type=2  value=1
Packit fcad23
    ifOperStatus.1                 type=2  value=1
Packit fcad23
    ifDescr                        type=4  value="eth0"
Packit fcad23
Packit fcad23
=head2 Passing Arguments
Packit fcad23
Packit fcad23
If you need to pass arguments in to the script, you'll need to do it
Packit fcad23
by one of two methods:
Packit fcad23
Packit fcad23
=head3 Using Subroutines
Packit fcad23
Packit fcad23
You can either define a subroutine in the file rather than have
Packit fcad23
the file itself do something.  IE, in the file if you put:
Packit fcad23
Packit fcad23
  sub foo {
Packit fcad23
     print "$_[0]\n";
Packit fcad23
  }
Packit fcad23
Packit fcad23
and then put these lines in the snmptrapd.conf file:
Packit fcad23
Packit fcad23
  perl do /path/to/script
Packit fcad23
  perl foo("hello world");
Packit fcad23
  perl foo("now I am passing something different");
Packit fcad23
Packit fcad23
It'd call the foo function twice, and print the results to the console
Packit fcad23
where snmptrapd was started.
Packit fcad23
Packit fcad23
=head3 Using Variables
Packit fcad23
Packit fcad23
Or you could always set a variable ahead of time:
Packit fcad23
Packit fcad23
  perl $myVariable = 42;
Packit fcad23
  perl do /path/to/script
Packit fcad23
Packit fcad23
And have the script look for and use the $myVariable value in the script
Packit fcad23
Packit fcad23
=head1 EXPORT
Packit fcad23
Packit fcad23
None by default.
Packit fcad23
Packit fcad23
=head2 Exportable constants
Packit fcad23
Packit fcad23
  NETSNMPTRAPD_AUTH_HANDLER
Packit fcad23
  NETSNMPTRAPD_HANDLER_BREAK
Packit fcad23
  NETSNMPTRAPD_HANDLER_FAIL
Packit fcad23
  NETSNMPTRAPD_HANDLER_FINISH
Packit fcad23
  NETSNMPTRAPD_HANDLER_OK
Packit fcad23
  NETSNMPTRAPD_POST_HANDLER
Packit fcad23
  NETSNMPTRAPD_PRE_HANDLER
Packit fcad23
Packit fcad23
=head1 SEE ALSO
Packit fcad23
Packit fcad23
NetSNMP::OID, NetSNMP::ASN
Packit fcad23
Packit fcad23
snmptrapd.conf(5) for configuring the Net-SNMP trap receiver.
Packit fcad23
Packit fcad23
snmpd.conf(5) for configuring the Net-SNMP snmp agent for sending traps.
Packit fcad23
Packit fcad23
http://www.Net-SNMP.org/
Packit fcad23
Packit fcad23
=head1 AUTHOR
Packit fcad23
Packit fcad23
W. Hardaker, E<lt>hardaker@users.sourceforge.netE<gt>
Packit fcad23
Packit fcad23
=head1 COPYRIGHT AND LICENSE
Packit fcad23
Packit fcad23
Copyright 2004 by W. Hardaker
Packit fcad23
Packit fcad23
This library is free software; you can redistribute it and/or modify
Packit fcad23
it under the same terms as Perl itself.
Packit fcad23
Packit fcad23
=cut