SNMP MIB browser in Perl and JavaScript

What to do at work if you don't know what else to do? Of course, write to Habr!





Thanks to our valiant legislators, further business development on our own is unprofitable and we are leaving under a larger operator. So I have such a situation that there is no point in modifying, rewriting and correcting my old projects - no, the "big man" has all its services. I sit and smoke . And then I think, why sit, I'll write to Habr . The article was moderated, "And then Ostap suffered ...".





So what this article will be about. Anyone who is involved in networking, sooner or later comes across the MIB . For those who are too lazy to follow the link, this is a database containing information about an object, in our case, a network device. There were several articles on HabrΓ© devoted to working with the MIB and the questions arising from this. I liked the article SNMP MIBs and How to Prepare Them, where the author used a tool from D-Link - the D-View utility to work with the MIB. I must say right away, knowing the quality of the MIB from this vendor - I do not recommend using D-View in real projects. However, it does give an idea of ​​the typical interface of such software. Oddly enough, there are not so many programs for working directly with the MIB, similar in functionality to at least D-View. I would even say very little . I am not going to describe all their pros and cons. Here I want to show my implementation, probably not the best one, but it was written "for myself" and the functionality was added as needed.





So, the whole server side will be based on Perl and the SNMP.pm library . Perhaps I will split the article into two parts - the second will be a description of the client side. Let's start by loading the MIBs we need:





sub load_mibs {
    my ($attr, $Nms) = @_;
    # MIB     ,  
    #(    -   ),   
    my $MIB_search_path = '../modules/Nms/mibs';
    
    #      
    SNMP::addMibDirs($MIB_search_path);
    SNMP::addMibDirs($MIB_search_path . '/private');
    
    #     ,      -
    #    .
    if ( $attr->{ALL} ) {
        SNMP::addMibFiles( glob( $MIB_search_path . '/private' . '/*' ) );
        SNMP::initMib();
    }
    #   DES3200-28
    elsif ( $attr->{SYS_ID} ) {
        my @mods = ('EQUIPMENT-MIB', 'DES3200-28-L3MGMT-MIB', 'CABLE-DIAG-MIB');
        #,     ,    MIB
        SNMP::loadModules(@mods);
        SNMP::initMib();
    }
    
    return 1;
}
      
      



Several explanations at once: - first, loading only the necessary modules, significantly speeds up further work with the OID tree; - second, it is not necessary to indicate all the necessary modules, in a properly "prepared" MIB links to the necessary modules are used, and they will be loaded automatically, for example:





IMPORTS
    MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE,
    OBJECT-IDENTITY, Counter32, Gauge32, Integer32, mib-2
        FROM SNMPv2-SMI
    DisplayString, TimeStamp, TimeInterval, TestAndIncr,
      AutonomousType, TEXTUAL-CONVENTION
        FROM SNMPv2-TC
    MODULE-COMPLIANCE, OBJECT-GROUP
        FROM SNMPv2-CONF;
      
      



that is, it specifies what and where to import.





, OID %SNMP::MIB. , , - JS . , - . jsTree, :





sub mibs_tree {

    my ($attr) = @_;

    my %labels;
    my @tree_arr;
    
    foreach my $oid ( sort keys(%SNMP::MIB) ) {
    		#  ,  .
        my $prev_id =
              ( $SNMP::MIB{$oid}{parent} )
              ? $SNMP::MIB{$oid}{parent}{objectID}
              : '#';
        
        #      OID     jsTree
        my $icon = '';        
        my %type;
        if ( $SNMP::MIB{$oid}{children}[0]{indexes}[0] ) {
        	$type{type} = 'table';
        }
        elsif ($SNMP::MIB{$oid}{parent} && $SNMP::MIB{$oid}{parent}{indexes}[0]){
        		$type{type} = 'row';
        }
        elsif ( $SNMP::MIB{$oid}{type} ) {
        		$type{type} = 'scalar';
        }
        elsif ( $SNMP::MIB{$oid}{indexes}[0] ) {
        		$type{type} = 'indexes';
        }
        else {
        		$type{type} = 'folder';
        }
        push @tree_arr,
              (
                {
                    id     => $SNMP::MIB{$oid}{objectID},
                    text   => $SNMP::MIB{$oid}{label},
                    parent => $prev_id,
                    %type
                }
              );
        }
    }

    my %types = (
        table   => { icon => 'fa fa-table' },
        row     => { icon => 'fa fa-columns' },
        scalar  => { icon => 'fa fa-paragraph' },
        indexes => { icon => 'fa fa-list-ul' },
        folder  => { icon => 'fa fa-folder-o' },
    );
    
    return make_tree(
        {
            plugins => [ 'types', 'search', 'contextmenu' ],
            contextmenu => { items => '*customMenu*' },
            types       => \%types,
            core        => { data  => \@tree_arr }
        }
    );
}
      
      



, JS HTML. , :





, , . github. , , Perl, .












All Articles