NAME

Net::Dev::Tools::MIB::MIBLoadOrder - Parse MIB files and determine MIB Load Order.

VERSION

Net::Dev::Tools::MIB::MIBLoadOrder Version 0.9.2

SYNOPSIS

use Net::Dev::Tools::MIB::MIBLoadOrder;

($load, $warn, $error) = mib_load(
   -StandardMIBs    =>  @StandardMIBs,   
   -EnterpriseMIBs  =>  @EnterpriseMIBs,
   -Extensions      =>  %FileExtensions,
   -track           =>  0|1,
   -prioritize      =>  0|1,
   -singlefile      =>  0|1,
   -maxloops        =>  Integer,
   -debug           =>  0|1,
);


mib_load_order();
@Net::Dev::Tools::MIB::MIBLoadOrder::@LOAD_ORDER

mib_load_definitions();
%Net::Dev::Tools::MIB::MIBLoadOrder::DEFINITIONS

mib_load_warnings();
@Net::Dev::Tools::MIB::MIBLoadOrder::WARNINGS

mib_load_error();
$Net::Dev::Tools::MIB::MIBLoadOrder::ERROR

mib_load_trace()
%Net::Dev::Tools::MIB::MIBLoadOrder::TRACK_HASH

mib_load_error
$Net::Dev::Tools::MIB::MIBLoadOrder::ERROR

DESCRIPTION

Module provides function that will scan a list of files and/or directories to find MIB files. Then parse each MIB file for the information required to determine a MIB Load Order for a NMS.

REQUIRES

No special requirements.

EXPORTS

Functions
    mib_load                  # create load order
    mib_load_order            # access to load order list
    mib_load_definitions      # access to definition info
    mib_load_trace            # access to trace info
    mib_load_warnings         # access to warning list
    mib_load_error            # access to last error message

FUNCTIONS

mib_load

($load, $warn, $error) = mib_load(
   -StandardMIBs    =>  \@StandardMIBs,   
   -EnterpriseMIBs  =>  \@EnterpriseMIBs,
   -Extensions      =>  \@FileExtensions,
   -exclude         =>  \@ExcludePatterns,
   -track           =>  0|1,
   -prioritize      =>  0|1,
   -singlefile      =>  0|1,
   -maxloops        =>  Integer,
   -debug           =>  0|1,
);

The mib_load function will return in array context, a reference to an ordered
list of MIB DEFINITIONs, integer value of warnings, the last error.
In scalar context, just a reference to an ordered list of MIB DEFINITIONs.
If error, $load, $warn are undefined and $error is true, it is a character string
describing the error.

At least one argument, StandardMIBs or EnterpriseMIBs, is needed. The rest will default values. The intent of these two different arguments is to allow the user to maintain their own location of Standard MIBs, then if a vendors set of MIB files also include Standard MIB's, the Load Order determined with this method can be configured to only list the 'first file found', thus the StandardMIBs locations.

Or this can be used to assure that certain files are put in the order first. StandardMIBs is search before EnterpriseMIBs. As a DEFINITION is found, the file that it was found in is stored with that DEFINITION. It is possible for a DEFINITION to be found in multiple files, it is the responsibility of the user to know how they want to handle this situation.

StandardMIBs
Reference to list of directories and/or files that define 
Standard MIBs. Read before EnterpriseMIBs.
EnterpriseMIBs
Reference to list of directories and/or files that define 
Enterprise MIBs. Read after StandardMIBs.
Extensions
Reference to list of file extensions.
Files with any of these extensions are parsed.
exclude
Reference to a list of patterns, if a pattern is matched in
in a filename, that file will not be parsed for DEFINITION.
track
Flag to enable or disable tracking.
0 disable tracking, default is 0.
Tracking is down per MIB DEFINITION, each time an action
is applied to a DEFINITION, the action is recorded in
a public accessible hash.
prioritize
Flag to enable or disable prioritization.
0 disable prioritization, default is 0.
Prioritization trys to place all DEFINITIONs found in 
StandardMIBs before any found in EnterpriseMIBs when 
calculating weights. The highest weight applied to an 
EnterpriseMIBs is found, all StandardMIBs are then made 1 
greater than this, if not already greater. This does not 
corrupt load order, if a StandardMIBs DEFINITION still needs 
the EnterpriseMIBs DEFINITION loaded, this will be done.
singlefile
Only store a single file for a DEFINITION.
1 enables this feature, default is 1.
If a DEFINITION is found in more than one file, only the first
file found with the DEFINITION is kept, all other files are 
not stored. The first file found will be influenced by the 
order of StandardMIBs list items, then EnterpriseMIBs.
maxloops
The max number of times to sort weights.
Default value is 1000.
This allows the user to prevent continous loops.
If max number is reached, no Load Order is determined.
debug
Flag to enable or disable debugging to STDOUT.
0 disables debugging, default is 0.
1 enables debugging.

Variable Access

Load Order

Direct Access
    @Net::Dev::Tools::MIB::MIBLoadOrder::@LOAD_ORDER

Function, returns a reference to array.
    mib_load_order()

Array syntax
    (DEFINITION, DEFINITION, DEFINITION, ....)

MIB Definitions

Direct Access
    %Net::Dev::Tools::MIB::MIBLoadOrder::DEFINITIONS

Function, returns a reference to hash
    mib_load_definitions()

Hash Syntax
    %DEFINITIONS{<definition>}{files}   = (file, file, ....)
    %DEFINITIONS{<definition>}{type}    = Standard | Enterprise
    %DEFINITIONS{<definition>}{imports} = (DEFINITION, DEFINITION, ...)
    %DEFINITIONS{<definition>}{weight}  = calculated weight

Warnings

Direct Access
    @Net::Dev::Tools::MIB::MIBLoadOrder::WARNINGS

Function, returns a reference to array of arrays
    mib_load_warnings()

Array Syntax
    ([<definition>, warning], [<definition>, warning], ...)

Errors

Direct Access
    $Net::Dev::Tools::MIB::MIBLoadOrder::ERROR

Function, returns a string indicating the last error
    mib_load_error()

Tracking

Direct Access
    %Net::Dev::Tools::MIB::MIBLoadOrder::TRACK_HASH

Function, returns a reference to hash
    mib_load_trace()

Hash syntax
    %TRACK{<definition>} = ([index, event], [index, event], ...)

    where 
       index = sequence number of the event
       event = description of event

Other Variables

@Net::Dev::Tools::MIB::MIBLoadOrder::WEIGHTS_SORTED = list of unique weights

$Net::Dev::Tools::MIB::MIBLoadOrder::ORDER_LOOPS  = the number of loops the sort routine ran.

@Net::Dev::Tools::MIB::MIBLoadOrder::STD_MIB_FILES = list of files tagged as Standard

@Net::Dev::Tools::MIB::MIBLoadOrder::ENT_MIB_FILES = list of files tagged as Enterprise

%Net::Dev::Tools::MIB::MIBLoadOrder::FILE_EXT = hash of desired file extension

Operation

The following details how this module works.

The mib_load function will read in and check all arguments. Dummy checks are done before any files are found and subsequently parsed. If file extension are given with -Extensions, they are stored, otherwise the extension 'mib' is used.

The files or directories given with StandardMIBs and EnterpriseMIBs are checked and put onto a file list. StandardMIBs is search first, then EnterpriseMIBs. If files or directories are not found for a given argument, then an error is returned. Each item in the StandardMIBs and EnterpriseMIBs list is examined, if it is a file that matches desired extensions, it is stored. If the item is a directory, then all files are check to see if they match the desired extensions, if so, the file is stored.

Each file stored is then parsed for DEFINITIONs and IMPORTs. If -exclude is defined and the file matches any string in the exclude list, that file is not parsed, a warning is issued, denoted as _EXCL_. If no DEFINITION is found, a warning is stored, denoted as _FILE_. If more than one DEFINTITION is found in a file, error is returned.

Weights are determined per DEFINITION. Each DEFINITION is assigned a weight of 2. If a DEFINITION requires IMPORTs, its weight is decremented by 1. For each IMPORT required, the IMPORT DEFINITION is incremented by 5. If an IMPORT requires IMPORTs, then those IMPORT DEFINITION weights are incremented by 1000.

If prioritization is enabled, then the highest Enterprise DEFINITION weight is found. Then all StandardMIBs DEFINTION weights are checked, if their weight is less than the highest EnterpriseMIB weight, the StandardMIB weight is made one greater than the highest EnterpriseMIB weight.

All DEFINITIONs are check for warnings. If no files are stored for a DEFINITION, a warning is issued. If a DEFINITION has more than one file, a warning is issued, and if -singlefile is true (1), than only the first file is kept. If files are dumped a warning is issued.

Enter a loop to sort all weights. Each DEFINITION is examined, each unique weight is stored. After all weights have been learned, they are sorted in descending order. For each weight, search all DEFINITIONs, if a DEFINITION has this weight, check that all its IMPORTS have a weight greater than the current weight. If a IMPORT DEFINITION has a lower weight then change its weight to one more than the current DEFINITIONs weight and re-start the loop. This loop will continue until all DEFINITIONs have IMPORTS with higher weights. Once this is complete, the method exits as successful. If -maxloops is exceeded before the loop can complete the method exits with error. If successful, the user can now access load order info.

Example

Determine Load Order, use direct access to variables

#!/usr/bin/perl
#
# Purpose:  Script to test mib load order module
#

use strict;
use Net::Dev::Tools::MIB::MIBLoadOrder;

our $MIBLOAD;

my $track = 0;

my ($error, $warn, $def, $file, $trace);
my @standard_mibs   = ('/usr/local/share/mibs/fore/Standard',
                       '/usr/local/share/snmp/mibs',
);
my @enterprise_mibs = ('/usr/local/share/mibs/fore/Enterprise');
my @extensions      = ('mib', 'txt');
($MIBLOAD, $warn, $error) = mib_load(
   StandardMIBs   => \@standard_mibs, 
   EnterpriseMIBs => \@enterprise_mibs,
   Extensions     => \@extensions,
   track          => $track,
   prioritize     => '0',
   singlefile     => '1',
   maxloops       => '100',
   debug          => '0',
);

unless ($MIBLOAD) {
   printf("Method failed: %s\n",  $error);
   exit(1);
}
if ($warn) {
   printf("Warnings\n");
   foreach (@Net::Dev::Tools::MIB::MIBLoadOrder::WARNINGS) 
      {printf("   %-20s  %s\n", $_->[0], $_->[1]);}
}
print "="x79, "\n";

foreach $def (@{$MIBLOAD}) {
   printf("%-35s %-10s [%s]  ", 
      $def,
      $Net::Dev::Tools::MIB::MIBLoadOrder::DEFINITIONS{$def}{type} || '-', 
      $Net::Dev::Tools::MIB::MIBLoadOrder::DEFINITIONS{$def}{weight}
   );
   if (@{$Net::Dev::Tools::MIB::MIBLoadOrder::DEFINITIONS{$def}{files}}) {
      foreach  $file (@{$Net::Dev::Tools::MIB::MIBLoadOrder::DEFINITIONS{$def}{files}}) 
         {printf("%s\n", $file);}
   }
   else 
      {printf("--\n");}

   if ($track) {
       foreach $trace (@{$Net::Dev::Tools::MIB::MIBLoadOrder::TRACK_HASH{$def}} ) 
           {printf("\t    %-4s %s\n", $trace->[0], $trace->[1]);} 
       }
}

exit(0);

Determine Load Order, use reference to variables

#!/usr/bin/perl
#
# Purpose:  Script to test mib load order module
#

use strict;
use Net::Dev::Tools::MIB::MIBLoadOrder;

our $MIBLOAD;

my $track = 0;


my ($lo_ref, $ld_ref, $lt_ref, $lw_ref);
my ($error, $warn, $def, $file, $trace);
my @standard_mibs   = ('/usr/local/share/mibs/fore/Standard',
                       '/usr/local/share/snmp/mibs',
);
my @enterprise_mibs = ('/usr/local/share/mibs/fore/Enterprise');
my @extensions      = ('mib', 'txt');


my @exclude = ('foobar');
($MIBLOAD, $warn, $error) = mib_load(
   StandardMIBs   => \@standard_mibs, 
   EnterpriseMIBs => \@enterprise_mibs,
   Extensions     => \@extensions,
   track          => $track,
   prioritize     => '1',
   singlefile     => '0',
   maxloops       => '100',
   exclude        => \@exclude,
   debug          => '0',
);

unless ($MIBLOAD) {
   printf("Method failed: %s\n",  $error);
   exit(1);
}
if ($warn) {
   $lw_ref = mib_load_warnings();
   printf("Warnings\n");
   foreach (@{$lw_ref}) {printf("   %-20s  %s\n", $_->[0], $_->[1]);}
}
print "="x79, "\n";

$lo_ref = mib_load_order();
$ld_ref = mib_load_definitions();
$lt_ref = mib_load_trace();

foreach $def (@{$lo_ref}) {
   printf("%-35s %-10s [%s]  ", 
      $def,
      $ld_ref->{$def}{type} || '-', 
      $ld_ref->{$def}{weight}
   );
   if (@{$ld_ref->{$def}{files}}) {
      foreach  $file (@{$ld_ref->{$def}{files}}) 
         {printf("%s\n", $file);}
   }
   else 
      {printf("--\n");}

   if ($track) {
   foreach $trace (@{$lt_ref->{$def}} ) 
      {printf("\t    %-4s %s\n", $trace->[0], $trace->[1]);} 
   }
}

exit(0);

AUTHOR

perlnetdev@netscape.net

COPYRIGHT

Copyright (c) 2003 Scott Parsons All rights reserved.
This program is free software; you may redistribute it 
and/or modify it under the same terms as Perl itself.