The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

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

VERSION

Net::Dev::Tools::MIB::MIBLoadOrder Version 1.1.0

SYNOPSIS

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

    ($load, $warn, $error) = mib_load(
       -StandardMIBs    =>  @StandardMIBs,   
       -EnterpriseMIBs  =>  @EnterpriseMIBs,
       -Extensions      =>  %FileExtensions,
       -track           =>  0|1,
       -prioritize      =>  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,
       -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, as it is a character string describing the error.

At least one argument, StandardMIBs or EnterpriseMIBs, is needed. The rest will get 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.

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. Multiple DEFINITIONs can be in one file, multiple files can not contain the same DEFINITION, in this case a warning is issued and the first DEFINITION is associated with the first file it was found in.

-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. Default extension is 'mib'. If you define any file extensions then 'mib' is not include, you will have to include this in your list. If you need to parse files without and extension, then use 'noExt' as an argument to --ext.

-exclude

Reference to a list of patterns, if a pattern is matched 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 done 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 disables 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.

-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
        (modName, modName, modName, ...)

MIB Definitions (modName)

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

    Function, returns a reference to hash
        mib_load_definitions()

    Hash Syntax
        %DEFINITIONS{<definition>}{file}    = file containing definition
        %DEFINITIONS{<definition>}{type}    = Standard | Enterprise
        %DEFINITIONS{<definition>}{import}  = number of times imported
        %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 file contains the same DEFINTITION (modName) then the DEFINITION is only associated with the first file.

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 is in more than one file, a warning is issued. 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 function exits as successful. If -maxloops is exceeded before the loop can complete the function 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
    #
    # Net::Dev::Tools::MIB::MIBLoadOrder example using direct access
    #
    
    use strict;
    use Net::Dev::Tools::MIB::MIBLoadOrder;
    
    our $MIBLOAD;
    
    my $track    = 0;
    my $prio     = 0;
    my $maxloop  = 100;
    my $debug    = 0;
    
    my ($error, $warn, $def, $file, $trace);
    
    # set location of mibs
    # standard mib files
    my @standard_mibs   = ('./mibs/std');
    # enterprise mib files
    my @enterprise_mibs = ('./mibs/fore',
                           './mibs/marconi'
    );
    # set desired extensions
    my @extensions      = ('mib', 'txt');
    
    #determine load order
    ($MIBLOAD, $warn, $error) = mib_load(
       StandardMIBs   => \@standard_mibs,
       EnterpriseMIBs => \@enterprise_mibs,
       Extensions     => \@extensions,
       track          => $track,
       prioritize     => $prio,
       maxloops       => $maxloop,
       debug          => $debug,
    );
    
    # check for failure
    unless ($MIBLOAD) {
       printf("mib_load function failed: %s\n",  $error);
       exit(1);
    }
    # check for warinings
    if ($warn) {
       printf("Warnings\n");
       foreach (@Net::Dev::Tools::MIB::MIBLoadOrder::WARNINGS)
          {printf("   %-20s  %s\n", $_->[0], $_->[1]);}
    }
    print "="x79, "\n\n";
    
    # print load order
    printf("Load Order:\n");
    foreach $def (@{$MIBLOAD}) {
       printf("   %-35s  %-12s imported: %4s  weight: %9s  %s\n",
          $def,
          $Net::Dev::Tools::MIB::MIBLoadOrder::DEFINITIONS{$def}{type}   || '-',
          $Net::Dev::Tools::MIB::MIBLoadOrder::DEFINITIONS{$def}{import} || 0,
          $Net::Dev::Tools::MIB::MIBLoadOrder::DEFINITIONS{$def}{weight} || 0,
          $Net::Dev::Tools::MIB::MIBLoadOrder::DEFINITIONS{$def}{file}   || 'noFile',
    
       );
       # show the imports for current definition
       if ($track == 1) {
          foreach ( @{$Net::Dev::Tools::MIB::MIBLoadOrder::DEFINITIONS{$def}{imports}} ) {
             printf("%52s %-23s %9s imported\n",
                '',
                $_,
                $Net::Dev::Tools::MIB::MIBLoadOrder::DEFINITIONS{$_}{weight}|| '0',
             );
          }
          printf("\n");
       }
    
       # show trace for current definition
       if ($track == 2) {
           foreach $trace (@{$Net::Dev::Tools::MIB::MIBLoadOrder::TRACK_HASH{$def}} )
               {printf("\t    trace:  index %-9s event: %s\n", $trace->[0], $trace->[1]);}
           }
    }
    
    exit(0);

Determine Load Order, use reference to variables

    #!/usr/bin/perl
    #
    # Net::Dev::Tools::MIB::MIBLoadOrder example using functions
    # to access data
    #
    
    use strict;
    use Net::Dev::Tools::MIB::MIBLoadOrder;
    
    our $MIBLOAD;
    
    my $track    = 2;
    my $prio     = 0;
    my $maxloop  = 100;
    my $debug    = 0;
    
    my ($error, $warn, $def, $file, $trace,
        $modName_href,
        $warn_aref,
        $trace_href,
    );
    
    # set location of mibs
    # standard mib files
    my @standard_mibs   = ('./mibs/std');
    # enterprise mib files
    my @enterprise_mibs = ('./mibs/fore',
                           './mibs/marconi'
    );
    # set desired extensions
    my @extensions      = ('mib', 'txt');
    
    # determine load order
    ($MIBLOAD, $warn, $error) = mib_load(
       StandardMIBs   => \@standard_mibs,
       EnterpriseMIBs => \@enterprise_mibs,
       Extensions     => \@extensions,
       track          => $track,
       prioritize     => $prio,
       maxloops       => $maxloop,
       debug          => $debug,
    );
    
    # check for failure
    unless ($MIBLOAD) {
       printf("mib_load function failed: %s\n",  $error);
       exit(1);
    }
    
    $modName_href   = &mib_load_definitions;
    $warn_aref      = &mib_load_warnings;
    $trace_href     = &mib_load_trace;
    
    # check for warinings
    if ($warn) {
       printf("Warnings\n");
       foreach (@{$warn_aref})
          {printf("   %-20s  %s\n", $_->[0], $_->[1]);}
    }
    print "="x79, "\n\n";
    
    # print load order
    printf("Load Order:\n");
    foreach $def (@{$MIBLOAD}) {
       printf("   %-35s  %-12s imported: %4s  weight: %9s  %s\n",
          $def,
          $modName_href->{$def}{type}   || '-',
          $modName_href->{$def}{import} || 0,
          $modName_href->{$def}{weight} || 0,
          $modName_href->{$def}{file}   || 'noFile',
    
       );
       # show the imports for current definition
       if ($track == 1) {
          foreach ( @{$modName_href->{$def}{imports}} ) {
             printf("%52s %-23s %9s imported\n",
                '',
                $_,
                $modName_href->{$_}{weight}|| '0',
             );
          }
          printf("\n");
       }
    
       # show trace for current definition
       if ($track == 2) {
           foreach $trace (@{$trace_href->{$def}} )
               {printf("\t    trace:  index %-9s event: %s\n", $trace->[0], $trace->[1]);}
           }
    }
    exit(0);

AUTHOR

    perlnetdev@netscape.net

COPYRIGHT

    Copyright (c) 2004 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.