Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > ffc809cbc9d93cae30b2bd1c647c9f92 > files > 29

perl-SNMP_Session-1.12-3mdv2010.0.noarch.rpm

#!/usr/bin/perl -w
###
### Listen for SNMP traps, decode and print them
### Simple example for a trap listener program.
###
### To make this useful, you should probably add some filtering
### capabilities and trap-specific pretty-printing.
###
package main;

use strict;

use SNMP_Session;
use SNMP_util;
use BER;
use Socket;

### Forward declarations
sub print_trap ($$);
sub usage ($ );
sub print_ip_addr ($ );
sub pretty_addr ($ );
sub hostname ($ );
sub fromOID ($ );
sub fromOID_aux ($$);
sub really_pretty_oid ($);

my $port = 162;

my $print_community = 0;
my $print_port = 0;
my $print_hostname = 1;

register_pretty_printer {BER::object_id_tag(), \&really_pretty_oid};

while (defined $ARGV[0] && $ARGV[0] =~ /^-/) {
    if ($ARGV[0] eq '-p') {
	shift @ARGV;
	usage (1) unless defined $ARGV[0];
	$port = $ARGV[0];
	usage (1) unless $port > 0 && $port < 65536;
    } elsif ($ARGV[0] eq '-h') {
	usage (0);
	exit 0;
    } else {
	usage (1);
    }
}
snmpLoad_OID_Cache($SNMP_util::CacheFile);
die unless SNMP_util::toOID("mib-2") eq SNMP_util::toOID ("1.3.6.1.2.1");
%SNMP_util::revOIDS = reverse %SNMP_util::OIDS unless %SNMP_util::revOIDS;
my $session = SNMPv2c_Session->open_trap_session ($port)
    or die "couldn't open trap session";
$SNMP_Session::suppress_warnings = 1; # We print all error messages ourselves.
my ($trap, $sender, $sender_port);

while (($trap, $sender, $sender_port) = $session->receive_trap ()) {
    my $now_string = localtime time;
    print "$now_string ";
    print pretty_addr (inet_ntoa ($sender));
    print ".$sender_port" if $print_port;
    print "\n";
    print_trap ($session, $trap);
}
1;

sub print_trap ($$) {
    my ($this, $trap) = @_;
    my ($encoded_pair, $oid, $value);
    my ($community, $ent, $agent, $gen, $spec, $dt, $bindings)
	= $this->decode_trap_request ($trap);
    if (defined $community) {
	my ($binding, $prefix);
	if (defined $community) {
	    print "    community: ".$community."\n"
		if $print_community;
	    if (defined $ent) {
		## SNMPv1 Trap
		print "   enterprise: ".BER::pretty_oid ($ent)."\n";
		print "   agent addr: ".inet_ntoa ($agent)."\n";
		print "   generic ID: $gen\n";
		print "  specific ID: $spec\n";
		print "       uptime: ".BER::pretty_uptime_value ($dt)."\n";
	    }
	    ## Otherwise we have an SNMPv1 Trap which basically just
	    ## consists of bindings.
	    ##
	    $prefix = "     bindings: ";
	    while ($bindings) {
		($binding,$bindings) = decode_sequence ($bindings);
		($oid,$value) = decode_by_template ($binding, "%O%@");
		$oid = fromOID (BER::pretty_oid ($oid));
		print $prefix.$oid.": ".pretty_print ($value)."\n";
		$prefix = "               ";
	    }
	} else {
	    warn "decoding trap request failed:\n".$SNMP_Session::errmsg;
	}
    } else {
	warn "receiving trap request failed:\n".$SNMP_Session::errmsg;
    }
}

sub usage ($) {
    warn <<EOM;
Usage: $0 [-p port]
       $0 -h

  -h           print this usage message and exit.

  -p port      Select the UDP port on which the program will listen
  	       for SNMP traps.  The default port is 162.

EOM
    exit (1) if $_[0];
}

sub pretty_addr ($ ) {
    my ($addr) = @_;
    my ($hostname,$aliases,$addrtype,$length,@addrs)
	= gethostbyaddr (inet_aton ($addr), AF_INET);
    $hostname ? $hostname." [".$addr."]" : $addr;
}

sub hostname ($ ) {
    my ($addr) = @_;
    my ($hostname,$aliases,$addrtype,$length,@addrs)
	= gethostbyaddr (inet_aton ($addr), AF_INET);
    $hostname || "[".$addr."]";
}

sub fromOID ($ ) {
    my ($oid) = @_;
    return fromOID_aux ($oid, '') || $oid;
}

sub fromOID_aux ($$) {
    my ($pref, $suf) = @_;
    while (1) {
	return $SNMP_util::revOIDS{$pref}.$suf if exists $SNMP_util::revOIDS{$pref};
	return undef unless $pref =~ /(.*)(\.[0-9]+)$/;
	$pref = $1; $suf = $2.$suf;
    }
}

sub really_pretty_oid ($) {
    fromOID (BER::pretty_oid ($_[0]));
}