Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

24.6.5.2. Perl による Net-SNMP の拡張

extend ディレクティブを使用したシェルスクリプトの実行は、SNMP によるカスタムアプリケーションメトリックを公開する非常に限定的な方法です。Net-SNMP エージェントは、カスタムオブジェクトを公開するための埋め込み Perl インターフェースも提供します。net-snmp-perl パッケージは、Red Hat Enterprise Linuxnbsp;Hat Enterprise Linuxnbsp;Linux で組み込み Perl プラグインを作成するために使用される NetSNMP::agent Perl モジュールを提供します。
NetSNMP::agent Perl モジュールは、エージェントの OID ツリーの一部に対する要求を処理するために使用される agent オブジェクトを提供します。agent オブジェクトのコンストラクターには、エージェントを snmpd のサブエージェントまたはスタンドアロンエージェントとして実行するためのオプションがあります。埋め込みエージェントを作成するために必要な引数はありません。
use NetSNMP::agent (':all');

my $agent = new NetSNMP::agent();
agent オブジェクトには、コールバック関数を特定の OID に登録するために使用される register メソッドがあります。register 関数は、名前、OID、コールバック関数へのポインターを取ります。以下の例では、hello_handler という名前のコールバック関数を OID .1.3.6 .1.4.1.8072.9999.9999 で要求を処理する SNMP Agent に登録しています
$agent->register("hello_world", ".1.3.6.1.4.1.8072.9999.9999",
                 \&hello_handler);
ルート OID の取得
通常、OID .1.3.6.1.4.1.8072.9999.9999 (NET-SNMP-MIB::netSnmpPlaypen)はデモ目的でのみ使用されます。お客様の組織に root OID がない場合は、ISO Name Registration Authority (米国では ANSI) にご連絡いただくと取得できます。
ハンドラー関数は、HANDLERREGISTRATION_INFOREQUEST_INFO、および REQUESTS の 4 つのパラメーターで呼び出されます。REQUESTS パラメーターには、現在の呼び出しの要求一覧が含まれており、反復されデータが追加されるはずです。一覧の request オブジェクトには get メソッドおよび set メソッドがあるため、リクエストの OID および value を操作することができます。たとえば、以下の呼び出しは要求オブジェクトの値を文字列 hello world に設定します。
$request->setValue(ASN_OCTET_STR, "hello world");
ハンドラー関数は、GET 要求と GETNEXT 要求という 2 種類の SNMP 要求に応答できます。要求のタイプは、ハンドラー関数に第 3 のパラメーターとして渡される getMode オブジェクトの request_info メソッドを呼び出すことで決定されます。要求が GET 要求である場合、呼び出し元は、ハンドラーに要求の OID に応じて value オブジェクトの request を設定するよう求めます。要求が GETNEXT 要求である場合、呼び出し元は、ハンドラーに要求の OID をツリー内で次に利用可能な OID に設定するよう求めます。以下のコードは、この例を示しています。
my $request;
my $string_value = "hello world";
my $integer_value = "8675309";

for($request = $requests; $request; $request = $request->next()) {
  my $oid = $request->getOID();
  if ($request_info->getMode() == MODE_GET) {
    if ($oid == new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.0")) {
      $request->setValue(ASN_OCTET_STR, $string_value);
    }
    elsif ($oid == new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.1")) {
      $request->setValue(ASN_INTEGER, $integer_value);
    }
  } elsif ($request_info->getMode() == MODE_GETNEXT) {
    if ($oid == new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.0")) {
      $request->setOID(".1.3.6.1.4.1.8072.9999.9999.1.1");
      $request->setValue(ASN_INTEGER, $integer_value);
    }
    elsif ($oid < new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.0")) {
      $request->setOID(".1.3.6.1.4.1.8072.9999.9999.1.0");
      $request->setValue(ASN_OCTET_STR, $string_value);
    }
  }
}
getModeMODE_GET を返すと、ハンドラーは getOID オブジェクトの request 呼び出しの値を分析します。valuerequest は、OID が .1 .0 で終わる場合は string_value に、OID が .1.1 で終わる場合は integer_value に設定され ます。getModeMODE_GETNEXT を返す場合、ハンドラーは要求の OID が .1.0 かどうかを判断し、. 1.1 の OID と値を設定し ます。ツリーで要求が .1.0 を超える場合、.1.0 の OID および値が 設定 されます。実際、これはツリーの の値を返すため、snmpwalk のようなプログラムは構造に関する事前知識なくツリーをトラバースできます。
変数のタイプは NetSNMP::ASN からの定数を使用して設定されます。利用可能な定数の全一覧については、NetSNMP::ASNperldoc を参照してください。
この例の Perl プラグインのコード全一覧は、以下のとおりです:
#!/usr/bin/perl

use NetSNMP::agent (':all');
use NetSNMP::ASN qw(ASN_OCTET_STR ASN_INTEGER);

sub hello_handler {
  my ($handler, $registration_info, $request_info, $requests) = @_;
  my $request;
  my $string_value = "hello world";
  my $integer_value = "8675309";

  for($request = $requests; $request; $request = $request->next()) {
    my $oid = $request->getOID();
    if ($request_info->getMode() == MODE_GET) {
      if ($oid == new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.0")) {
        $request->setValue(ASN_OCTET_STR, $string_value);
      }
      elsif ($oid == new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.1")) {
        $request->setValue(ASN_INTEGER, $integer_value);
      }
    } elsif ($request_info->getMode() == MODE_GETNEXT) {
      if ($oid == new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.0")) {
        $request->setOID(".1.3.6.1.4.1.8072.9999.9999.1.1");
        $request->setValue(ASN_INTEGER, $integer_value);
      }
      elsif ($oid < new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.0")) {
        $request->setOID(".1.3.6.1.4.1.8072.9999.9999.1.0");
        $request->setValue(ASN_OCTET_STR, $string_value);
      }
    }
  }
}

my $agent = new NetSNMP::agent();
$agent->register("hello_world", ".1.3.6.1.4.1.8072.9999.9999",
                 \&hello_handler);
プラグインをテストするには、上記のプログラムを /usr/share/snmp/hello_world.pl にコピーし、以下の行を /etc/snmp/snmpd.conf 設定ファイルに追加します。
perl do "/usr/share/snmp/hello_world.pl"
新しい Perl プラグインをロードするためには、SNMP Agent Daemon を再起動する必要があります。再起動したら、snmpwalk が新しいデータを返すはずです。
~]$ snmpwalk localhost NET-SNMP-MIB::netSnmpPlaypen
NET-SNMP-MIB::netSnmpPlaypen.1.0 = STRING: "hello world"
NET-SNMP-MIB::netSnmpPlaypen.1.1 = INTEGER: 8675309
snmpget を使用すると、ハンドラーの他のモードを使用することも可能です。
~]$ snmpget localhost \
    NET-SNMP-MIB::netSnmpPlaypen.1.0 \
    NET-SNMP-MIB::netSnmpPlaypen.1.1
NET-SNMP-MIB::netSnmpPlaypen.1.0 = STRING: "hello world"
NET-SNMP-MIB::netSnmpPlaypen.1.1 = INTEGER: 8675309