NetSNMP::agent

PerlSNMPエージェントを簡単に動かせないかなぁと思ってたら、それらしいモジュール NetSNMP::agent があった。だけど動かなかった。色々試した結果、net-snmpの設定ファイルを作る必要があるのね。とりあえずセキュリティはザルで動いた。

hello.conf

com2sec testcommunitysec default testcommunity
group testcommunitygroup v2c testcommunitysec
view all included .1 80
access testcommunitygroup "" any noauth exact all none none

NSNMP-agent.pl

#!/usr/bin/perl
use strict;
use warnings;
use NetSNMP::agent (':all');
use NetSNMP::ASN qw(ASN_OCTET_STR);

use constant CONF_BASE_NAME   => 'hello';
use constant HANDLER_REG_NAME => CONF_BASE_NAME;
use constant REG_OID          => '.1.3.6.1.4.1.8872.9999.9999';

$ENV{SNMPCONFPATH} = "./:";

my $my_oid1 = REG_OID . ".1.0";                # "hello world" OID
my $my_oid2 = REG_OID . ".2.0";                # "hello again world" OID

my $agent = new NetSNMP::agent( 'Name' => CONF_BASE_NAME, 'AgentX' => 0 );
my $regoid = new NetSNMP::OID(REG_OID);
$agent->register( HANDLER_REG_NAME, $regoid, \&my_snmp_handler );

my $running = 1;
while ($running) {
    $agent->agent_check_and_process(1);
}
$agent->shutdown();

sub my_snmp_handler {
    my ( $handler, $registration_info, $request_info, $requests ) = @_;

    for ( my $request = $requests; $request; $request = $request->next() ) {
        if ( $request_info->getMode() == MODE_GET ) {
            if ( $request->getOID() == new NetSNMP::OID($my_oid1) ) {
                $request->setValue( ASN_OCTET_STR, "hello world" );
                last;
            }
            elsif ( $request->getOID() == new NetSNMP::OID($my_oid2) ) {
                $request->setValue( ASN_OCTET_STR, "hello again world" );
                last;
            }
        }
    }
}

Net-SNMP.pl

#!/usr/bin/perl
use strict;
use warnings;
use Net::SNMP qw(:snmp);

use constant REG_OID => '.1.3.6.1.4.1.8872.9999.9999';

my ( $session, $error ) = Net::SNMP->session(
    -version   => 'snmpv2c',
    -hostname  => shift || 'localhost',
    -community => shift || 'testcommunity',
    -port      => shift || 161
);
if ( !defined($session) ) {
    print "ERROR: $error\n";
    exit 1;
}

my $my_oid1 = REG_OID . ".1.0";    # "hello world" OID
my $my_oid2 = REG_OID . ".2.0";    # "hello again world" OID

for my $oid ($my_oid1, $my_oid2) {
    my $result = $session->get_request( -varbindlist => [$oid] );
    if ( !defined($result) ) {
        print "ERROR: ", $session->error, "\n";
        $session->close;
        exit 1;
    }
    print $oid, " : ", $result->{$oid}, "\n";
}

$session->close;

結果。

マネージャ

$ perl Net-SNMP.pl
.1.3.6.1.4.1.8872.9999.9999.1.0 : hello world
.1.3.6.1.4.1.8872.9999.9999.2.0 : hello again world

SNMPエージェントは、Well-knownポートで動くからroot権限必要。ポート番号も設定で変えられるけど。

エージェント

$ sudo perl NSNMP-agent.pl
Connection from UDP: [127.0.0.1]:33046
Connection from UDP: [127.0.0.1]:33046