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

NAME

Net::SNMP::Util - Utility functions for Net::SNMP

SYNOPSIS

    @hosts = qw( host1 host2 host3 );
    %oids  = (
        'ifType'  =>   '1.3.6.1.2.1.2.2.1.3',
        'ifXData  => [ '1.3.6.1.2.1.31.1.1.1.1',    # ifName
                       '1.3.6.1.2.1.31.1.1.1.15' ], # ifHighSpeed
        'someMib' =>   '1.3.6.1.4.1.99999.12.3'
    );
    %snmpparams = (
        -version   => 2,
        -community => "comname"
    );

    # Blocking Function
    use Net::SNMP::Util;

    ($result,$error) = snmpawlk(
        hosts => \@hosts,
        oids  => \%oids,
        snmp  => \%snmpparams
    );
    die "[ERROR] $error\n" unless defined $result;

    # Non-blocking One
    use Net::SNMP::Util qw(:para);

    ($result,$error) = snmpparawalk(
        hosts => \@hosts,
        oids  => \%oids,
        snmp  => \%snmpparams
    );
    die "[ERROR] $error\n" unless defined $result;

    # output result sample
    foreach $host ( @hosts ){
        foreach $index ( sort keys %{$result->{$host}{ifType}} ){
            printf "$host - $index - type:%d - %s (%d kbps)\n",
                $result->{$host}{ifType}{$index},
                $result->{$host}{ifXData}[0]{$index},   # ifName
                $result->{$host}{ifXData}[1]{$index};   # ifHighSpeed
        }
    }

DESCRIPTION

This module, Net::SNMP::Util, gives you functions of SNMP getting operation interfaces using Net::SNMP communicating with multiple hosts and multi-OIDs.

OVERVIEW

Functions of Net::SNMP::Util are grouped by type whether using Blocking mode or Non-blocking mode.

Blocking Functions

Blocking functions, snmpget(), snmpwalk() and snmpbulk(), are exported by defalut. These functions use Net::SNMP blocking object and exchange SNMP messages serially.

Non-blocking Functions

Using tag ":para" or ":parallel", Non-Blocking functions which use Net::SNMP Non-blocking object are exported. These functions can exchange SNMP messages to multiple hosts and treat response MIB values in order of message receiving while the loop. These functions will apparently behave in parallel, so they have "para" in its own names.

Arguments

The way of passing arguments is unified whether function is Non-blocking or Blocking. Basically pass arguments with name and following value like hash pair below;

    $r = snmpwalk( hosts => $hostsval,
                   oids  => $oidval,
                   snmp  => $snmpval );

Mostly original Net::SNMP functions' arguments are able to be passed.

    $r = snmpparabulk(
        hosts => $hostsval, oids => $oidval, snmp => $snmpval
        -maxrepetitions => 20,
        -delay          => 2,
    );

But some original parameter, -callback, -nonrepeaters and -varbindlist are not supported by reason of a algorithm.

Argument "hosts"

By argument "hosts", specify hosts to communicate. This takes a hash or array reference or hostname.

When only hash reference using, it is possible to use prepared Net::SNMP object like below;

    # Using hash reference with prepared Net::SNMP object
    $session1 = Net::SNMP->session( -hostname=>"www.freshes.org", ... );
    $session2 = Net::SNMP->session( -hostname=>"192.168.10.8",    ... );
    $r = snmpwalk( hosts => {
                        "peach" => $session1,
                        "berry" => $session2
                   }, ...
    );

In this way, keys of hash are not specifying target hosts but just used to classfy result.

Except such way of using prepered object like above, a temporary Net::SNMP session object will be made, used and deleted internally and automaticaly. See the way below, this example will make temporary session with hash parameters of Net::SNMP->session();

    # Using hash reference with parameters
    $r = snmpwalk( hosts => {
                        "pine" => {
                            -hostname  => "192.168.10.9",
                        },
                        "passion" => {
                            -hostname  => "exchanger.local",
                            -port      => 10161,
                        }
                   }, ...
    );

More hash argument "snmp" are given, it will be used as common parameters for each temporary session making. This argument "snmp" hash is not only for hash but also for specifying by array rererence or hostname string.

    # hash "snmp" using examples
    $r = snmpwalk( hosts => {
                        "peach"   => { -hostname  => "www.freshes.org" },
                        "berry"   => { -hostname  => "192.168.10.8"    },
                        "pine"    => { -hostname  => "192.168.20.8",   },
                        "passion" => { -hostname  => "exchanger.local",
                                       -port      => 10161,            },
                   },
                   snmp  => { -community => "4leaf-clover",
                              -timeout   => 10,
                              -retries   => 2,
                   }, ...
    );

    # Using array reference or string
    $r5 = snmpwalk( hosts => [ "dream","rouge","lemonade","mint","aqua" ],
                    snmp  => { -version   => 1,
                               -community => "yes5",
                    }, ...
    );
    $r6 = snmpwalk( hosts => "milkyrose",
                    snmp  => { -version   => 2,
                               -community => "yes5gogo",
                    }, ...
    );

Note that values of arguments "host" in array reference case or hostname string are used as values of -hostname parameters for Net::SNMP, and at the same, time used as classfying key of result.

Arguments "oids"

Specify OIDs to investigate by hash reference argument named "oids". Keys of this hash will be used as just classfying of result. Values must be an array reference listing OIDs, or singular OID string. And this hash allows that these two types are mixed into it.

    $r = snmpwalk( hosts => \@hosts,
                   oids  => {
                        "system" =>   "1.3.6.1.2.1.1",
                        "ifInfo" => [ "1.3.6.1.2.1.2.2.1.3",        # ifType
                                      "1.3.6.1.2.1.31.1.1.1.1", ]   # ifName
                   }, ...
    );

Each value of this "oids" hash will make one Var Bindings. So singular OID value makes Var Bindings contains one OID, and multiple OID specified by array reference makes one contains several OIDs.

It is allowed to specify arguments "oids" as array reference. In this case, result content will not be classfied by keys of OID name but keys of suboids. See section of "Return Values" below.

Argument "snmp"

If argument "hosts" is specified, hash argument "snmp" will mean common parameters to Net::SNMP->session() mentioned above.

Well, it is possible to omit parameter "host". In this case, value of "snmp" will be used to specify the target. Same as argument "hosts", giving prepared Net::SNMP session object is allowed.

    # Prepared session
    $session = Net::SNMP->session( -hostname => "blossom", ... );
    $r = snmpwalk(  snmp => $session,
                    oids => \%oids,
                    ...
    );
    # Temporary session
    $r = snmpwalk( snmp => { -hostname  => "marine",
                             -community => "heartcatchers",
                   },
                   oids => \%oids,
                   ...
    );

Forbiddings

These case below causes an error;

  • Argument "snmp" with prepared Net::SNMP object and "hosts" are specified at the same time. Chomp "hosts" or let parameter "snmp" a hash reference.

        # NG
        $session = Net::SNMP->session( ... );
        $r = snmpwalk(  hosts => \%something,
                        snmp  => $session,
        );
  • Non-blocking prepared Net::SNMP object are given as "hosts" or "snmp" value to Blocking functions.

  • Blocking prepared Net::SNMP object are given as "hosts" or "snmp" value to Non-blocking functions.

Return Values

Errors

In list context, a hash reference result value and errors string will be returned. In scalar, only result value will be returned. In both case, critical errors will make result value undef and make errors string.

If several hosts checking and some errors occured while communicating, each error messages will be chained to errors string. For checking errors by host individually or in scalar context, use functions get_errhash(). This function will return a hash reference which contains error messages for each hosts.

Gained MIB Values

In success, gained MIB value will be packed into a hash and its reference will be returned.

For example, case of snmpget() and snmpparaget() operations;

    snmpget( oids => { sysContact =>   "1.3.6.1.2.1.1.4.0",
                       sysInfo    => [ "1.3.6.1.2.1.1.5.0",    # sysName
                                       "1.3.6.1.2.1.1.6.0"  ], # sysLocation
             }, ...
    );

yeilds;

    {
        sysContact => "Cure Flower <k.hanasaki@heartcatchers.com>",
        sysInfo    => [ "palace", "some place, some world" ],
    }

Other functions, value will be a more hash which contains pairs of key as sub OID and its values. For example;

    snmpwalk( oids => { "system" =>   "1.3.6.1.2.1.1",
                        "ifInfo" => [ "1.3.6.1.2.1.2.2.1.3",        # ifType
                                      "1.3.6.1.2.1.31.1.1.1.1", ]   # ifName
              }, ...
    );

yeilds;

    {
        "system"  => {
            "1.0" => "Testing system the fighters are strong enough",
            "2.0" => "1.3.6.1.4.1.99999.1",
            ... ,
        },
        "ifInfo" => [
            {
                "1"         => 62,          # 1.3.6.1.2.1.2.2.1.3.1
                "10101"     => 62,          # 1.3.6.1.2.1.2.2.1.3.10101
                ...
            },
            {
                "1"         => "mgmt",      # 1.3.6.1.2.1.31.1.1.1.1.1
                "10101"     => "1/1",       # 1.3.6.1.2.1.31.1.1.1.1.10101
                ...
            }
        ]
    }

As stated above, when OIDs are specified in an array, values also will be contained in an array.

If parameter "snmp" decides target host without "hosts", result data will be the same as above examples yields. If not so, parameter "hosts" is specified, result data of each host will be contained to parentally hash which key will be identified by hostname. For example;

    $r1 = snmpget(
        hosts => [ "bloom", "eaglet" ],
        oids => {
                system => [ "1.3.6.1.2.1.1.1.0", "1.3.6.1.2.1.1.3.0" ],
        }, ...
    );

    $r2 = snmpwalk(
        hosts => {
            "kaoru"   => { -hostname => '192.168.11.10', ... },
            "michiru" => { -hostname => '192.168.12.10', ... },
        },
        oids => { "system" =>   "1.3.6.1.2.1.1",
                  "ifInfo" => [ "1.3.6.1.2.1.2.2.1.3",        # ifType
                                "1.3.6.1.2.1.31.1.1.1.1", ]   # ifName
        }, ...
    );

returns hashref;

    # $r1
    {
        "bloom"  => {                       # hostname
            "system" => [ ...VALUES... ]
        },
        "eaglet" => {                       # hostname
            "system" => [ ...VALUES... ]
        }
    }

    # $r2
    {
        "system"  => { 
            "1.0" => "...", "2.0" => "...", ... 
        },
        "ifInfo" => [
            {
                "1"         => 62,          # 1.3.6.1.2.1.2.2.1.3.1
                "10101"     => 62,          # 1.3.6.1.2.1.2.2.1.3.10101
                ...
            },
            {
                "1"         => "mgmt",      # 1.3.6.1.2.1.31.1.1.1.1.1
                "10101"     => "1/1",       # 1.3.6.1.2.1.31.1.1.1.1.10101
                ...
            }
        ]
    }

If OIDs specifying by "oids" are not a hash but an array reference, values of gained data will be not hash but array. For example,

    snmpget( oids => [ "1.3.6.1.2.1.1.5.0",     # sysName
                       "1.3.6.1.2.1.1.6.0"  ],  # sysLocation
             }, ...
    );

yeilds;

    [ "takocafe",                               # string of sysName
      "Wakabadai-park, Tokyo" ],                # string of sysLocation

Callback function

Apart from original -callback option of functions of Net::SNMP, functions of Net::SNMP::Util provides another callback logic, by specifying common option, -mycallback. This option is possible to be used whether Non-blocking or Blocking.

This callback function will be called when each MIB value recieving with passing arguments; session object, host name, key name and reference to array of values.

For example, snmpget() and snmpparaget() operations, array contains values which order is same as a member of parameter "oids" specifys.

    snmpget(
        hosts => \%hosts,
        oids  => { someMIB1 => $oid1,
                   someMIB2 => [ $oid2, $oid3, $oid4 ]
        },
        -mycallback => sub {
            ($session, $host, $key, $valref) = @_;
            # $valref will be;
            #   [ $val1 ]                   when $key is "someMIB1"
            # or 
            #   [ $val2, $val3, $val4 ]     when $key is "someMIB2"
        }
    );

Other functions, passing array reference will contain more array references which will have two value, sub OID and value. Values ordering rule is, same as above, a member of parameter "oids" specifys.

    snmpwalk(
        hosts => \%hosts,
        oids  => { someMIB1 => $oid1,
                   someMIB2 => [ $oid2, $oid3, $oid4 ]
        },
        -mycallback => sub {
            ($session, $host, $key, $valref) = @_;
            # $valref will be;
            #   [ [ $suboid1, $val1 ] ]             when $key is "someMIB1"
            # or 
            #   [ [ $suboid2,$val2 ], [ $suboid3,$val3 ], [ $suboid4,$val4 ] ]
            #                                       when $key is "someMIB2"
        }
    );

BLOCKING FUNCTIONS

Net::SNMP::Util exports bloking functions defalut.

snmpget()

snmpget() is a Blocking function which gather MIB values with SNMP GetRequest operation via Net::SNMP->get_request().

snmpwalk()

snmpwalk() is a Blocking function which gather MIB values with SNMP GetNextRequest operation via Net::SNMP->get_next_request().

snmpbulk()

snmpbulk() is a Blocking function which gather MIB values with SNMP GetBulkRequest operation via Net::SNMP->get_bulk_request(). So using this function needs that target devices are acceptable for SNMP version 2c or more.

Note that -maxrepetitions should be passed with some value. Net::SNMP will set this parameter 0 by defalut. Also note that reason of algorithm, -nonrepeaters is not supported.

snmpbulkwalk()

An alias of snmpbulk().

NON-BLOCKING FUNCTIONS

Net::SNMP::Util gives some Non-blocking functions. Use these Non-blocking functions, import them with ":para" tag at use pragma.

snmpparaget()

snmpparaget() is a Non-blocking function which gather MIB values with SNMP GetRequest operation via Net::SNMP->get_request().

snmpparawalk()

snmpparawalk() is a Non-blocking function which gather MIB values with SNMP GetNextRequest operation via Net::SNMP->get_next_request().

snmpparabulk()

snmpparabulk() is a Non-blocking function which gather MIB values with SNMP GetBulkRequest operation via Net::SNMP->get_bulk_request(). So using this function needs that target devices are acceptable for SNMP version 2c or more.

Note that -maxrepetitions should be passwd with some value. Net::SNMP will set this parameter 0 by defalut. Also note that reason of algorithm, -nonrepeaters is not supported.

snmpparabulkwalk()

An alias of snmpparabulk().

OTHER FUNCTIONS

get_errstr()

    $lasterror = get_errstr();

get_errstr() returns last error message string that is chained all of error messages for each hosts.

get_errhash()

    $lasterror = get_errhash();

get_errhash() returns hash reference which contains last error messages identified by host names.

APPENDIX

Net::SNMP::Util has sub modules; Net::SNMP::Util::OID and Net::SNMP::Util::TC.

Net::SNMP::Util::OID gives MIBname-OID converter utilities. For example, you can specify basic OIDs when call function like below;

    use Net::SNMP::Util::OID qw(if*);   # import if* MIB name maps

    %oids  = (
        sysInfo => [
            oid( "ifDescr", "ifType" )  # equals '1.3.6.1.2.1.2.2.1.2','1.3.6.1.2.1.2.2.1.3'
        ],
        oidm("ifName")                  # equals "ifName" => "1.3.6.1.2.1.31.1.1.1.1"
    );
    ($result,$error) = snmpparaawlk(
        hosts => \@hosts,
        oids  => \%oids,
        snmp  => \%snmpparams
    );

Net::SNMP::Util::TC gives MIBEnumValue-Text convertor utilities. For example, you can convert value of ifAdminStatus, ifOperStatus and ifType like below;

    use Net::SNMP::Util::TC;

    $tc = Net::SNMP::Util::TC->new;
    $astat  = $tc->ifAdminStatus( $value_admin_stat );  # "up", "down" or etc.
    $ostat  = $tc->ifOperStatus( $value_oper_stat  );
    $iftype = $tc->ifType( $value_iftype  );            # "ethernet-csmacd" or etc.

PRACTICAL EXAMPLES

1. Check system information simply

This example get some system entry MIB values from several hosts with snmpget().

    #!/usr/local/bin/perl
    use strict;
    use warnings;
    use Getopt::Std;
    use Net::SNMP::Util;

    my %opt;
    getopts('hv:c:r:t:', \%opt);

    sub HELP_MESSAGE {
        print "Usage: $0 [-v VERSION] [-c COMMUNITY_NAME] ".
              "[-r RETRIES] [-t TIMEOUT] HOST [,HOST2 ...]\n";
        exit 1;
    }
    HELP_MESSAGE() if ( !@ARGV || $opt{h} );

    (my $version = ($opt{v}||2)) =~ tr/1-3//cd; # now "2c" is ok
    my ($ret, $err) = snmpget(
        hosts => \@ARGV,
        snmp  => { -version   => $version,
                   -timeout   => $opt{t} || 5,
                   -retries   => $opt{r} || 1,
                   -community => $opt{c} || "public" },
        oids  => { descr    => '1.3.6.1.2.1.1.1.0',
                   uptime   => '1.3.6.1.2.1.1.3.0',
                   name     => '1.3.6.1.2.1.1.5.0',
                   location => '1.3.6.1.2.1.1.6.0',
        }
    );
    die "[ERROR] $err\n" unless defined $ret;

    foreach my $h ( @ARGV ){
        if ( $ret->{$h} ){
            printf "%s @%s (up %s) - %s\n",
                 map { $ret->{$h}{$_} or 'N/A' } qw(name location uptime descr);
        } else {
            printf "%s [ERROR]%s\n", $h, $err->{$h};
        }
    }

    __END__

2. Realtime monitor of host interfaces (SNMPv2c)

This program shows realtime traffic throughput of interfaces of a host on your console with using snmpwalk() and callbacking.

Notice: This program is for devices which can deal SNMP version 2c.

    #!/usr/local/bin/perl

    use strict;
    use warnings;
    use Getopt::Std;
    use Term::ANSIScreen qw/:color :screen :constants/;
    use Net::SNMP::Util;

    my %opt;
    getopts('hv:c:w:x:', \%opt);
    my $host = shift @ARGV;

    sub HELP_MESSAGE {
        print "Usage: $0 [-c COMMUNITY_NAME] [-w WAIT] [-x REGEXP] HOST\n";
        exit 1;
    }
    HELP_MESSAGE() if ( !$host || $opt{h} );

    my ($wait,$regexp) = ($opt{w}||5, $opt{x}? qr/$opt{x}/: '');
    my $console = Term::ANSIScreen->new();
    local $| = 1;

    # make session
    my ($ses, $err) = Net::SNMP->session(
        -hostname  => $host,
        -version   => "2",
        -community => ($opt{c} || "public")
    );
    die "[ERROR] $err\n" unless defined $ses;

    # main loop
    my (%pdata, %cdata);  # flag, previous and current octets data
    my $first = 1;
    while ( 1 ){
        %cdata = ();
        (my $ret, $err) = snmpwalk(
            snmp => $ses,
            oids => {
                sysUpTime => '1.3.6.1.2.1.1.3',
                ifTable => [
                    '1.3.6.1.2.1.31.1.1.1.1',  # [0] ifName
                    '1.3.6.1.2.1.2.2.1.7',     # [1] ifAdminStatus
                    '1.3.6.1.2.1.2.2.1.8',     # [2] ifOperStatus
                    '1.3.6.1.2.1.31.1.1.1.6',  # [3] ifHCInOctets
                    '1.3.6.1.2.1.31.1.1.1.10', # [4] ifHCOutOctets
                    '1.3.6.1.2.1.31.1.1.1.15', # [5] ifHighSpeed
                ] },
            -mycallback => sub {
                my ($s, $host, $key, $val) = @_;
                return 1 if $key ne 'ifTable';
                my $name = $val->[0][1];
                return 0 if ( $regexp && $name !~ /$regexp/ );
                # storing current octets data
                $cdata{$name}{t} = time;
                $cdata{$name}{i} = $val->[3][1];
                $cdata{$name}{o} = $val->[4][1];
                return 1;
            }
        );
        die "[ERROR] $err\n" unless $ret;

        # header
        $console->Cls();
        $console->Cursor(0, 0);

        printf "%s, up %s - %s\n\n",
            BOLD.$host.CLEAR, $ret->{sysUpTime}{0}, scalar(localtime(time));

        # matrix
        printf "%s%-30s (%-10s) %2s %2s %10s %10s %10s%s\n",
            UNDERSCORE, qw/ifName ifIndex Ad Op BW(Mbps) InBps(M) OutBps(M)/, CLEAR;

        my $iftable = $ret->{ifTable};
        foreach my $i ( sort { $a <=> $b } keys %{$iftable->[1]} )
        {
            my ($name, $astat, $ostat, $bw)
                = map { $iftable->[$_]{$i} } qw( 0 1 2 5 );
            if ( $first ){
                printf "%-30s (%-10d) %2d %2d %10.1f %10s %10s\n",
                    $name, $i, $astat, $ostat, $bw/1000, '-', '-';
                next;   # skip first
            }

            # calculate (k)bps
            my $td = $cdata{$name}{t} - $pdata{$name}{t};
            my ($inbps, $outbps) = map {
                my $delta = $cdata{$name}{$_} - $pdata{$name}{$_};
                $delta<0? 0: $delta / $td / 1000; # Kbps
            } qw( i o );

            printf "%-30s (%-10d) %2d %2d %10.1f %10.1f %10.1f\n",
                $name, $i, $astat, $ostat, map { $_/1000 } ($bw, $inbps, $outbps);
        }

        %pdata = %cdata;
        $first = 0;
        sleep $wait;
    }

    __END__

3. Tiny MRTG with RRDTool (SNMPv2c)

With installing Tobias Oetiker's RRDTool and RRD::Simple, this sample will do like MRTG. (It is better to execute this by cron.)

If Environmental variables, PATH2DATADIR and URL2HTMLDIR, are defined, files will be stored under PATH2DATADIR and URL pathes will include URL2HTMLDIR in html. Or Modify $datadir and $htmldir to decide these path and URL where browser can access through your http service.

Notice: This program is for devices which can deal SNMP version 2c.

    #!/usr/local/bin/perl
    use strict;
    use warnings;
    use Getopt::Std;
    use CGI qw(:html);
    use RRD::Simple;        # install the "RRDTool" and RRD::Simple
    use Net::SNMP::Util qw(:para);

    my %opt;
    getopts('hc:x:', \%opt);
    my @hosts = @ARGV;

    sub HELP_MESSAGE {
        print "Usage: $0 [-c COMMUNITY_NAME] [-x REGEXP] HOST [HOST [...]]\n";
        exit 1;
    }
    HELP_MESSAGE() if ( !@hosts || $opt{h} );

    my $datadir = $ENV{PATH2DATADIR} || "/path/to/datadir";   # !!! Modify !!!
    my $htmldir = $ENV{URL2HTMLDIR}  || "/path/to/htmldir";   # !!! Modify !!!
    my $regexp  = $opt{x}? qr/$opt{x}/: '';
    my %sesopts = ( -version => 2, -community=> ($opt{c} || 'public') );

    sub escname {
        my $n = shift;
        $n =~ tr/\\\/\*\?\|"<>:,;%/_/;
        return $n;
    }

    # gather traffic data and store to RRD
    my ($result, $error) = snmpparawalk(
        hosts => \@hosts,
        snmp  => \%sesopts,
        oids  => {
            ifData => [ '1.3.6.1.2.1.31.1.1.1.1',   # ifName
                        '1.3.6.1.2.1.31.1.1.1.6',   # ifHCInOctets
                        '1.3.6.1.2.1.31.1.1.1.10' ] # ifHCOutOctets
        },

        # this callback will work everything of necessary
        -mycallback => sub {
            my ($s, $host, $key, $val) = @_;
            # val=[[index,name], [index,inOcts], [index,outOcts]]
            my ($index, $name) = @{$val->[0]};

            # check necessarity by ifName
            return 0 if ( $regexp && $name !~ /$regexp/ );

            my $basename = "$host.".escname($name);
            my $rrdfile  = "$datadir/$basename.rrd";

            # treat RRD
            my $rrd = RRD::Simple->new( file => $rrdfile );

            #eval { # wanna catch an error, uncomment here.

            $rrd->create($rrdfile, 'mrtg',
                'in'  => 'COUNTER', 'out' => 'COUNTER'
            ) unless -e $rrdfile;

            $rrd->update( $rrdfile, time,
                'in'  => $val->[1][1], 'out' => $val->[2][1]
            );

            $rrd->graph( $rrdfile,
                destination => $datadir,
                basename    => $basename,
                title       => "$host :: $name",
                sources          => [ qw( in       out      ) ],
                source_labels    => [ qw( incoming outgoing ) ],
                source_colors    => [ qw( 00cc00   0000ff   ) ],
                source_drawtypes => [ qw( AREA     LINE1    ) ]
            );

            #}; warn "[EVAL ERROR] $@" if $@;

            return 1;
        }
    );
    die "[ERROR] $error\n" unless $result;

    # make html
    sub mkimgtag {
        my ($host, $name, $type) = @_;
        my $basename = escname($name);
        img({ -src   => "$htmldir/$host.$basename-$type.png",
              -alt   => "$host $name $type",
              -title => "$type graph of $host $name",
              -border=> 0 });
    }

    open(HTML,"> $datadir/index.html") or die "$!";
    print HTML start_html(
        -title=> 'Traffic Monitor',
        -head => meta({ -http_equiv => 'refresh',
                        -content    => 300 })
    ), h1('Traffic Monitor');

    foreach my $host ( sort @hosts ){
        print HTML h2($host);
        foreach my $i ( sort keys %{$result->{$host}{ifData}[0]} ){
            my $name     = $result->{$host}{ifData}[0]{$i};
            my $subhtml  = "$host.".escname($name).".html";

            printf HTML a( {-href=>"$htmldir/$subhtml"},
                mkimgtag($host, $name, 'daily')
            );

            if ( open(HTML2,"> $datadir/$subhtml") ){
                print HTML2 start_html(
                        -title=> 'Traffic Monitor',
                        -head => meta({ -http_equiv => 'refresh',
                                        -content    => 300 }) ),
                    h1("$host $name"),
                    (map { h2($_).p(mkimgtag($host, $name, $_)) }
                        qw(daily weekly monthly annual)),
                    end_html();
                close(HTML2);
            } else {
                warn "$!";
            }
        }
    }

    print HTML end_html();
    close(HTML);

    __END__

REQUIREMENTS

See Net::SNMP.

AUTHOR

t.onodera, <cpan :: garakuta.net>

TO DO

- Implementation of simple trapping functions

SEE ALSO

  • Net::SNMP - Core module of Net::SNMP::Util which brings us good SNMP implementations.

  • Net::SNMP::Util::OID - Sub module of Net::SNMP::Util which provides easy and simple functions to treat OID.

  • Net::SNMP::Util::TC - Sub module of Net::SNMP::Util which provides easy and simple functions to treat textual conversion.

LICENSE AND COPYRIGHT

Copyright(C) 2011- Takahiro Ondoera.

This program is free software; you may redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.