package snmp;

use Exporter;
use Socket;
use cfgfile;

@EXPORT = qw (myEntOID myOID mySNMPtraps);

my $myEntOID = "1.3.6.1.4.1.5281";

my %myOID = (
    "enterprise", "1.3.6.1.4.1",
    "graeff", $myEntOID,
    "bshost", $myEntOID.".1.1.1",
    "bsservice", $myEntOID.".1.1.2",
    "bsstatus", $myEntOID.".1.1.3",
    "bscomment", $myEntOID.".1.1.4",
    "bsseverity", $myEntOID.".1.1.5",
    "bsackmode", $myEntOID.".1.1.6",
    "bsackuser", $myEntOID.".1.1.7"
);

my %mySNMPtraps = (
    "coldstart", [ 0, 0 ],
    "bsstatuschange", [6, 1],
    "bsserviceup", [6, 2],
    "bsservicedown", [6, 3],
    "bsalarmack", [6, 4],
    "bsremind", [6, 5]
);

my $have_snmp = 0;
my $offlmib = 0;

eval {
    require BER;
    require SNMP_Session;
    require SNMP_util;
    $have_snmp = 1;
};
load_mib( "mibs.txt" );


sub trap {
    my( $host, $community, $agent, $type, $args ) = @_;

    print STDERR "snmp::trap to $host ($community) from $agent of type $type\n" if( $BigSister::common::dl>4 );
    return unless $have_snmp;
    if( (! $community) && ($host =~ /^(.*)\@(.*)$/) ) {
	$community = $1;
	$host = $2;
    }
    ($community = "public") unless( $community );
    my $itype;
    unless( $type =~ /^\d+$/ ) {
	$itype = $mySNMPtraps{$type};
	unless( $itype ) {
	    BigSister::common::log( "warning", "internal error: invalid SNMP trap" );
	}
    }
    else {
       $itype = {6,$type};
    }

    my $arg;
    my @args;
    foreach $arg (sort { $myOID{$a} cmp $myOID{$b} } keys %$args) {
	my $oid = $myOID{$arg};
	next unless( $oid );
	push( @args, $oid, @{$args->{$arg}} );
    }

    $agent =~ s/.*://;
    unless( $agent && inet_aton($agent) ) {
	$agent = Platform::hostname();
    }
    my $result = SNMP_util::snmptrap( 
	$community."\@".$host, 
	$myOID{"graeff"},
	$agent,
	$itype->[0],
	$itype->[1],
	@args );
    unless( $result ) {
	BigSister::common::log( "warning", "SNMP trap $type to $host failed" );
    }
}



sub load_mib {
    my( $file ) = @_;

    $file = new cfgfile( $file );
    $file->rewind();
    while( $_ = $file->nextline() ) {
	chomp;
	next if( /^#/ );
	if( /^([^\s\t]+)[\s\t]+([^\s\t]+)$/ ) {
	    $SNMP_util::OIDS{$1} = $2;
	}
    }
}


sub get {
    my( $community, $host, @oid ) = @_;

    if( $offlmib ) {
	 my @ret = ();
	 print "snmpget/debug $offlmib\n" if( $BigSister::common::dl>3 );
	 my $i;
	 foreach $i (@oid) {
	     push( @ret, undef );
	     open( _IN, "<$offlmib" );
	     while( <_IN> ) {
		 chomp;
		 if( /^$i = (.*)/ ) {
		     close(_IN);
		     print "  snmpget/debug $i:$1\n" if( $BigSister::common::dl>4 );
		     $ret[$#ret] = $1;
		     last;
		 }
	     }
	     close( _IN );
	 }
	 return( @ret );
    }
    return() unless $have_snmp;
    my @result = SNMP_util::snmpget( "$community\@$host", @oid );
    return( ) if( $#result < $#oid );
    return @result;
}


sub walk {
    my( $community, $host, $oid ) = @_;

    if( $offlmib ) {
	 my( @ret );
	 print "snmpwalk/debug $offlmib\n" if( $BigSister::common::dl>3 );
	 open( _IN, "<$offlmib" );
	 while( <_IN> ) {
	     chomp;
	     if( /^$oid\.([^\s]+) = (.*)/ ) {
		 push( @ret, "$1:$2" );
		 print "  snmpwalk/debug $1:$2\n" if( $BigSister::common::dl>4 );
	     }
	 }
	 close( _IN );
	 return( @ret );
    }
    return() unless $have_snmp;
    return( SNMP_util::snmpwalk( "$community\@$host", $oid ) );
}

1;
