AnyEvent-SNMP-TrapReceiver

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN


AnyEvent::SNMP::TrapReceiver - SNMP trap receiver by help of AnyEvent

# SYNOPSIS

    use AnyEvent::SNMP::TrapReceiver;

    my $cond = AnyEvent->condvar;

    my $echo_server = AnyEvent::SNMP::TrapReceiver->new(
        bind => ['0.0.0.0', 162],
        cb => sub {
            my ( $trap) = @_;
        },
    );

    my $done = $cond->recv;

# DESCRIPTION

This is a wrapper for the AnyEvent::Handle::UDP with embedded SNMP trap decoder.

Currently only v1 and v2c traps are supported.

The trap decoder code was copied from Net::SNMPTrapd by Michael Vincent.

# ATTRIBUTES

## bind

The IP address and port to bind the UDP listener/handle.

## cb

The codeblock to be called when a trap is received.

# TIPS&TRICKS

The default port for SNMP traps is 162. In Linux ports below 1024 are privileged ports and typically
only root can acccess these ports. If you don't want to run your script as root user you can use

lib/AnyEvent/SNMP/TrapReceiver.pm  view on Meta::CPAN

    TimeTicks ::= [APPLICATION 3] INTEGER
    Opaque    ::= [APPLICATION 4] STRING
    Counter64 ::= [APPLICATION 6] INTEGER

    PDUv1 ::= SEQUENCE {
        ent_oid         OBJECT IDENTIFIER,
        agent_addr      IPAddress,
        generic_trap    INTEGER,
        specific_trap   INTEGER,
        timeticks       TimeTicks,
        varbindlist     VARBINDS
    }
    PDUv2 ::= SEQUENCE {
        request_id      INTEGER,
        error_status    INTEGER,
        error_index     INTEGER,
        varbindlist     VARBINDS
    }
    VARBINDS ::= SEQUENCE OF SEQUENCE {
        oid    OBJECT IDENTIFIER,
        value  CHOICE {
            integer   INTEGER,
            string    STRING,
            oid       OBJECT IDENTIFIER,
            ipaddr    IPAddress,
            counter32 Counter32,
            guage32   Guage32,

lib/AnyEvent/SNMP/TrapReceiver.pm  view on Meta::CPAN

" );
my $snmpasn = $asn->find('PDU');
########################################################
# End Variables
########################################################

sub new {
    my ( $class, %args ) = @_;
    my $self = bless { cb => $args{cb} || croak('cb not given'), }, $class;

    my $bindTo;
    if ( exists $args{bind} ) {
        $bindTo = $args{bind};
    } else {
        $bindTo = [ '0.0.0.0', SNMPTRAPD_DEFAULT_PORT ],;
    }

    $self->{server} = AnyEvent::Handle::UDP->new(
        bind    => $bindTo,
        on_recv => sub {
            my $trap = _handle_trap(@_);

            $self->format($trap);

            &{ $self->{cb} }($trap);
        }
    );

    return $self;

lib/AnyEvent/SNMP/TrapReceiver.pm  view on Meta::CPAN

        $trap->{timeticks} = $timeticks;
        my @uptime = (
            int( $timeticks / 8640000 ),    # days
            int( ( $timeticks % 8640000 ) / 360000 ),    # hours
            int( ( $timeticks % 360000 ) / 6000 ),       # minutes
            int( ( $timeticks % 6000 ) / 100 ),          # seconds
        );
        $trap->{uptime} = \@uptime;
    } ## end if ( exists $trap->{timeticks...})

    # convert varbindlist to key->value
    foreach my $var ( @{ $trap->{varbindlist} } ) {
        my $oid   = $var->{oid};
        my $value = $var->{value};
        $trap->{oid}{$oid} = ( values( %{$value} ) )[0];
    }

    delete $trap->{varbindlist};

    return $trap;
} ## end sub format

1;
__END__

=encoding utf-8

=head1 NAME

AnyEvent::SNMP::TrapReceiver - SNMP trap receiver by help of AnyEvent

=head1 SYNOPSIS

    use AnyEvent::SNMP::TrapReceiver;

    my $cond = AnyEvent->condvar;

    my $echo_server = AnyEvent::SNMP::TrapReceiver->new(
        bind => ['0.0.0.0', 162],
        cb => sub {
            my ( $trap) = @_;
        },
    );

    my $done = $cond->recv;

=head1 DESCRIPTION

This is a wrapper for the AnyEvent::Handle::UDP with embedded SNMP trap decoder.

Currently only v1 and v2c traps are supported.

The trap decoder code was copied from Net::SNMPTrapd by Michael Vincent.

=head1 ATTRIBUTES

=head2 bind

The IP address and port to bind the UDP listener/handle.

=head2 cb

The codeblock to be called when a trap is received.

=head1 TIPS&TRICKS

The default port for SNMP traps is 162. In Linux ports below 1024 are privileged ports and typically
only root can acccess these ports. If you don't want to run your script as root user you can use

t/01-listen.t  view on Meta::CPAN

use AnyEvent;
use AnyEvent::Socket;
use Test::More;
use IO::Socket::INET;
use AnyEvent::SNMP::TrapReceiver;
use Socket qw/unpack_sockaddr_in/;

{
	my $cv = AnyEvent->condvar;
    my $trapd = AnyEvent::SNMP::TrapReceiver->new(
        bind => ['localhost', 0],
        cb => sub {
            $cv->send( @_);
        },
    );
	my $port = (unpack_sockaddr_in($trapd->{server}->{fh}->sockname))[0];
	my $client = IO::Socket::INET->new(PeerHost => 'localhost', PeerPort => $port, Proto => 'udp');
    # hard coded v2c trap
    my $raw = pack( 'H*', '3041020101040464656d6fa7360204779778cc0201000201003028300e06082b06010201010300430203d43016060a2b06010603010104010006082b06010603010101');
	send $client, $raw, 0;
	is( $cv->recv->{oid}{'1.3.6.1.2.1.1.3.0'}, 980, "Verify v2c trap content");
}

{
	my $cv = AnyEvent->condvar;
    my $trapd = AnyEvent::SNMP::TrapReceiver->new(
        bind => ['localhost', 0],
        cb => sub {
            $cv->send( @_);
        },
    );
	my $port = (unpack_sockaddr_in($trapd->{server}->{fh}->sockname))[0];
	my $client = IO::Socket::INET->new(PeerHost => 'localhost', PeerPort => $port, Proto => 'udp');
    # hard coded v1 trap
    my $raw = pack( 'H*', '3034020100040464656d6fa429060357060840047f000001020101020101430400e268ea3010300e06032b0601040761626364656667');
	send $client, $raw, 0;
    ok( $cv->recv->{oid}{'1.3.6.1'} eq 'abcdefg', "Verify v1 trap content");



( run in 1.909 second using v1.01-cache-2.11-cpan-2398b32b56e )