flodhest network


29th August 2006

YAPC::Europe::2006


Speeding up SNMP queries


by


Jan Henning Thorsen


Table of Contents

1.Summary 3

2.Introduction 3

2.1.Preface 3

2.2.Requirements 3

2.3.Pro / cons about the module 4

3.A bit about the module “SNMP” 4

3.1.Description from the SNMP POD 4

3.2.SNMP + SNMP::Effective 4

4.The interface of SNMP::Effective 5

4.1.SNMP::Effective->new( ... ); 5

4.2.$snmp_effective->add( ... ); 5

4.3.$snmp_effective->execute; 5

5.The inner workings of SNMP::Effective 5

5.1.Introduction 5

5.2.SNMP/Effective.pm methods 6

5.3.SNMP/Effective/Dispatch.pm 6

5.4.SNMP/Effective/Var.pm 7

6.SNMP::Effective's callback method 7

7.Debugging 8

8.References 9

1.Summary

“Speeding up SNMP queries” tells you about a new module called SNMP::Effective. The module is written with one main goal: It has to be fast.

This paper does not dig into how the SNMP protocol works. It contains information about the module's interface and also some of the inner workings. It covers what the SNMP module offers, and how the two modules interact.

2.Introduction

2.1.Preface

SNMP is a protocol for querying network components. It features great flexibility and is quite simple to understand how to use it. I needed a Perl module that could query many hosts in a short period of time.

I searched CPAN for a module that could do this and found SNMP::Multi. It looked promising, but it didn't exactly fit my needs, so I decided to make my own module instead.

The module is written from scratch by me, but some parts are inspired by SNMP::Multi.

2.2.Requirements

The module had to meet these requirements:

2.3.Pro / cons about the module

3.A bit about the module “SNMP”

3.1.Description from the SNMP POD

The basic operations of the SNMP protocol are provided by this module through an object oriented interface for modularity and ease of use. The primary class is SNMP::Session which encapsulates the persistent aspects of a connection between the management application and the managed agent. Internally the class is implemented as a blessed hash reference. This class supplies get, getnext, set, fget, and fgetnext method calls. The methods take a variety of input argument formats and support both synchronous and asynchronous operation through a polymorphic API.

3.2.SNMP + SNMP::Effective

SNMP::Effective creates a SNMP-object, using the SNMP::Session->new() constructor. It passes on arguments defined by the user or default arguments defined in either SNMP::Session or SNMP::Effective.

Later it use the SNMP::Session object to call get(), set() or getnext() asynchronously. Calling them asynchronously allows SNMP::Effective to do multiple things at the same time, which then again saves time and increases the efficiency. After SNMP is done with the request, it calls a callback method inside SNMP::Effective, which then stores the retrieved data.

SNMP::MainLoop is a subroutine that starts the asynchronous calls. If you specify MasterTimeout in SNMP::Effective, it will call SNMP::MainLoop with a timeout and a callback. The callback method calls SNMP::finish, which stops SNMP::MainLoop.

SNMP::Effective will call SNMP::finish when it has no more hosts to query. It must do so, since SNMP::finish is the only thing that can stop SNMP::MainLoop from looping forever.

4.The interface of SNMP::Effective

4.1.SNMP::Effective->new( ... );

This method returns a SNMP::Effective object (refered to as $snmp_effective later in this document) . Arguments to the constructor can be:

MaxSessions   => int # maximum number of simultainious SNMP session
MasterTimeout => int # maximum number of seconds before killing execute

All other arguments are passed on to SNMP::Effective::Var::new, which from a users views is the same as calling $snmp_effective->add( [args] ).

4.2.$snmp_effective->add( ... );

Arguments to this method can be:

DestHost => []     # an array-ref that contains a list of hosts, in this format:
                   # xxx.xxx.xxx.xxx or a hostname
Arg      => {}     # arguments passed on to SNMP::Session
Callback => sub {} # the callback method whick handles the received data
get      => []     # an array-ref that contains a list of OIDs to get
walk     => []     # an array-ref that contains a list of OIDs “trees” to get
set      => []     # an array-ref that contains a list of OIDs to set

This can be called with many different combinations, such as:

4.3.$snmp_effective->execute;

5.The inner workings of SNMP::Effective

5.1.Introduction

The module consists of three separate files / perl modules. It's kind of “unorthodox” set up, since SNMP::Effective inherit from SNMP::Effective::Dispatch and SNMP::Effective::Var, instead of the other way around – like it's normally done. (Example: CD::Burner::Wui inherit from CD::Burner...) Comments are welcome, but It's done this way, because the programmer likes to separate blocks of code into different files.

5.2.SNMP/Effective.pm methods

5.3.SNMP/Effective/Dispatch.pm

5.4.SNMP/Effective/Var.pm

This part of the module is kind of hard to explain, since it contains tied and overloaded variables, but here is a short summary of the classes:

6.SNMP::Effective's callback method

When SNMP is done collecting data from a host, it calls a callback method, provided by the Callback => sub{} argument. Here is an example on a callback method:

my my_callback {

    my $host  = shift;
    my $error = shift;

    if($error) {
        warn “$host failed with this error: $error”;
        return;
    }
    
    my $data = $host->data;

    PRINT_DATA:
    for my $oid (%$data) {
        print “$host returned oid “$oid” with this data:\n”;
        print join “\n\t”, map {
            "$_ => $data->{$oid}{$_}”;
        } keys %{ $data->{$oid} };
        print "\n";
    }
}

Example output:

10.2.10.3 returned oid “1.3.6.1.2.1.1.1” with this data: 1 =>
C12-MM4-CS, Hardware V4 <<VENDOR: BigBand; BOOTR: >>
(ser#0600012893, part#90000046000, rev#A2, opt#c02), v6.0.1(14) ,
Release6.0_Integration Built 2006_03_29_153010

7.Debugging

By setting $SNMP::Effective::DEBUG you will get a debugging information printed to STDERR. There are no strict debugging levels (yet), but setting it to “100” will output a lot of information.

8.References