### -*- mode: Perl -*-
######################################################################
# 10/01/98 rcc
# Mods for code organization changes for new server
#
### SNMP_mib - MIB utilities
######################################################################
# Rough implementation of generalized SNMP utility subroutines.
# Uses MIB definitions in MOSY format.  MOSY format MIBs can be created
# from ASN.1 MIBs using AIX's 'mosy' compiler ('mosy -o hpnp.def -s hpnp.mib').
# The resulting files can be concatenated to form 'mib.defs' (usually in /etc).
######################################################################
### Created by:  Rick Cochran  07/28/98
###
### 08/11/98 rcc
### insert 'use lib'
######################################################################

package SNMP_mib;

require 5.002;

use strict;
use vars qw(@ISA @EXPORT $VERSION);
use Exporter;
use lib qw(. /usr/local/netprint/lib);
use BER;

$VERSION = '1.00';

@ISA = qw(Exporter);

@EXPORT = qw(snmp_initmib snmp_get);

### Prototypes
sub snmp_initmib ();
sub snmp_get ($@);
sub snmp_trans ($);

sub version () { $VERSION; }

#### Global variables

my ($mibinit, $mibfile, %miblist, %encoded_oids);
$mibinit = 0;
$mibfile = "/etc/mib.defs";

#### Routines

# Read in MOSY format MIB definitions
sub snmp_initmib ()
{
    # Once is enough
    return if $mibinit;
#    print "Initializing MIB data\n";
    srand();
    my ($name, $ref, @rest);
    open(F, $mibfile) or die "Unable to open $mibfile $!\n";
    $miblist{'iso'} = '.1';
    while ( <F> ) {
	s/\s*--.*//;
	next if /^$/;
	($name, $ref, @rest) = split;
	$miblist{$name} = $ref;
    }
    close(F);
    $mibinit++;
    return 1;
}

# Given a session ID and an array of alphanumeric OIDs, query the SNMP
# agent and return an array of values.  We are assuming that the values
# come back in the same order as the OIDs.
sub snmp_get ($@)
{
    my($session, @oids) = @_;
    my(@eoids, $tmp, $response, $bindings, $binding, $value, $oid, @values);

    @eoids = ();
    foreach ( @oids ) {
	if ( ! defined($tmp = $encoded_oids{$_}) ) {
	    $tmp = snmp_trans($_);
	}
	push(@eoids, $tmp);
    }

    if ($session->get_request_response(@eoids)) {
	$response = $session->pdu_buffer;
	($bindings) = $session->decode_get_response($response);
	while ($bindings ne '') {
	    ($binding, $bindings) = decode_sequence($bindings);
	    ($oid, $value) = decode_by_template($binding, "%O%@");
	    push(@values, pretty_print($value));
	}
    } else {
	return ();
    }
    return @values;
}

# Translate alphanumeric OIDs into numeric OIDs, and thence into encoded
# OIDs, suitable for transmission to the SNMP agent.  Each translation
# is 'remembered'.
sub snmp_trans ($)
{
    my($oidname) = @_;

    my($oid, $fullname, $oidn);
    $oid = '';
    $fullname = $oidname;
    $oidn = $oidname;
    if ( ($oidn =~ /([^.]*)\.(.*)/) ) {
	$oidn = $1;
	$fullname = $1;
	$oid = $2;
    }
    while ( 1 ) {
	$oidn = $miblist{$oidn};
	last if ! defined($oidn);
	$oidn =~ /([^.]*)\.(.*)/;
	$oidn = $1;
	$fullname = $1 . "." . $fullname;
	$oid = $2 . "." . $oid;
    }
    $oid =~ s/\.$//;
    $fullname =~ s/^\.//;
#    print "$fullname $oid\n";
    $oid = encode_oid(split(/\./, $oid));
    $encoded_oids{$oidname} = $oid;
    return $oid;
}

1;
