### -*- 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;