SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

net-snmpについて

net-snmpについて(独自監視項目の追加) - 後編

net-snmpによる拡張MIBの設定方法について(後編)

  • このエントリーをはてなブックマークに追加

ダウンロード snmp_mibfile_2nd.lzh (4.5 KB)

snmpは広く知られた監視用のプロトコルです。しかし実際は“シンプル”ではなく、複雑な仕様、深いMIB-Tree、異なるバージョンなど、理解が困難と思われます。本レポートでは、前半で作成した拡張MIBから生成したソースファイルの編集ポイント、およびソースファイルからエージェントの取り込み方を述べて行きます。

  • このエントリーをはてなブックマークに追加

はじめに

 この連載では監視用プロトコルとして広く知られているSNMPについて設定方法などを交えて説明していきます。今回は前半で作成したMIBファイルを基に生成したソースファイルの編集ポイント、およびエージェントの作成方法を述べます。

 構築環境はFedora7(2.6.23.17-88.fc7)、32bit、glibc-2.6-4、gcc-4.1.2を使用しています。

これまでの記事

7. 拡張MIBと独自エージェントの実装

 今まで取得してきた情報は、既にnet-snmpが用意したものです。

 しかし自分たちが作成したソフトの挙動を監視する際、その監視項目は当然ですがnet-snmpにはありませんし、他のsnmpソフトにもありません。

 ではどうするか、自分たちで監視したい項目をnet-snmpに追加することで対応します。

 具体的な方法は下記の通りです。

  • 企業拡張番号の払い出し
  • MIBファイルの作成
  • MIBファイルの登録
  • mib2cによるソースファイルの生成
  • ソースファイルの修正・改良
  • ソースファイルから拡張MIB対応エージェントの構築

 今回は、前回作成したMIBファイルから自動生成されたソースファイルの編集ポイント、および実際にエージェントを作成する手順について述べて行きます。

7.5 ソースコードの説明

 mib2cによって生成されたソースファイルは、それだけでは使用はおろか、makeも通りません。get-requestに対してどんな情報を出力するか、set-requestに対して、どんなチェックをして、どんな値の時に何をするか、仕様を決めてプログラムに落とし込む必要があります。

 今回はmib2cによって生成されたファイルに対して編集したファイルをダウンロードできるようにUpしましたので、そちらを参考にしながら説明をします(と言っても大したことはしておりませんが)。

7.5.1 init_matsutest

 いわゆる初期化処理です。編集しなくともコンパイルは通ります。

 一回しか呼ばれないので、大域変数や、他のアプリケーションの情報が格納されたファイルなどを開いて、そのディスクリプタを保存しておくなどの初期化処理を追加します。

7.5.2 handle_mtuObject1

 文字列を作成後、snmp_set_var_typed_valueに渡しています。

プログラムの追加
sprintf( buf, "matsutest1, pid:[%d] timer:%s:[%d] call_count:[%d]",
    getpid( ), status, timered_count, func_call_cnt );
snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
    (u_char *)buf, strlen( buf ));

7.5.3 handle_mtuObject2

 自身が呼ばれた回数をカウントし、その数値をsnmp_set_var_typed_value に渡しています。

プログラムの追加
int func_call_cnt;
snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
    (u_char *)&func_call_cnt, sizeof( func_call_cnt ));

7.5.4 handle_mtuTrap

 set-request/get-request両方に対応しなくてはいけないため、やや複雑です。get-requestで呼ばれたときは、reqinfo->mode == MODE_GETが実行されるだけなので、数値(trap_status)を返して終了しています。

プログラムの追加
snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
    (u_char *)&trap_status, sizeof( trap_status ));

 set-requestで呼ばれた時、reqinfo->modeは下記の順で呼ばれます(つまり最低4回、handle_mtuTrapが呼ばれます)。

MODE_SET_RESERVE1 → NG → MODE_SET_FREE
     ↓OK
MODE_SET_RESERVE2 → NG → MODE_SET_FREE
     ↓OK
MODE_SET_ACTION   → NG → MODE_SET_UNDO
     ↓OK
MODE_SET_COMMIT

 今回はMODE_SET_ACTIONの時に値を判定し、条件を満たす場合、Trap関数(send_mtuStatusTrap_trap)を発行しています。それ以外の場所では何もしてません(OKを返しているだけです)。
今回は生成されたプログラムを極力編集しないようにしたので、MODE_SET_ACTION以外の所では、本当は消すところを、"if( 0 )"とか、ありえない記述をしていますが、ご容赦ください。

 入力された値は、requests->requestvb->val.*に入っています。さらにこの領域はポインタなので、実際に変数に確保するには下記の通り行ってください。

数値(int)の時
    int p    = *( requests->requestvb->val.integer );
数値(float)の時
    float p  = *( requests->requestvb->val.floatVal );
数値(double)の時
    double p = *( requests->requestvb->val.doubleVal );
文字列(char *)の時
    char * p = strdup( requests->requestvb->val.string );
set-requestされた文字列の長さ
    int strlen = request->requestvb->val_len;
注意事項
 個人的な見解ですが、set-requestで取得した文字列を「静的な」配列にコピーするのは避けた方が良いです。
実はつい最近まで、上記が原因となるバッファオーバーフローバグなどがnet-snmpに存在してました。デーモンとして動作するnet-snmpにとって脆弱性を突かれると管理者権限が奪われます。
安全を期すために、「動的に」取得した配列で処理するか、コピー先の配列の大きさ分しかコピーしない等とした対策をとった方が良いでしょう。

7.5.5 handle_mtuTimer

 これも set-request/get-request 両方で呼ばれます。
get-requestで呼ばれたときは、reqinfo->mode == MODE_GETの時なので、数値(timer_status)を返して終了しています。
set-requestで呼ばれたときは、MODE_SET_ACTIONの時、入力された値によってタイマーの登録・解除を行っています。

  • タイマー登録:snmp_alarm_register
  • タイマー解除:snmp_alarm_unregister

 今回は自作の関数timer_matsutestを設定し、そこで30秒経過するとTrap関数(send_mtuTimerTrap_trap)を発行、タイマーを解除しています。

 snmp_alarm_register/snmp_alarm_unregisterは、net-snmpにおける組み込み関数です。詳細は7.6章で説明します。

7.5.6 send_mtuStatusTrap_trap

 実はTrap用のソースファイルは、編集しなくてもMakeは通ります。このままでも行けるんですが、イベント内容(独自に送信したい情報)は空になるので、トラップ送信回数とTrapのステータス情報を送信するようにしました。送信したい内容は引数を通して取得しています。

7.5.7 send_mtuTimerTrap_trap

 上記同様、イベント内容を送信するために編集しています。タイマーによるトラップのカウント値とhandle_mtuObject1で作成した文字列を返すように編集しました。具体的にはこれらの値をsend_mtuTimerTrap_trapの引数として渡し、使用するようにしました。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
アラーム関係の関数について

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
net-snmpについて連載記事一覧

もっと読む

この記事の著者

赤松 エイト(エイト)

(株)DTSに勤てます。WebアプリやJavaやLL等の上位アプリ環境を密かに憧れつつも、ず~っとLinuxとかHP-UXばかり、ここ数年はカーネル以上アプリ未満のあたりを行ったり来たりしています。mixiもやってまして、こちらは子育てとか日々の日記メインです。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/2991 2008/09/24 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング