3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

net-snmpと、PINGとPONGをやり取りする仲になる

Posted at

net-snmpのpass_persistを使って、
自作したsnmp agentで応答を返す。

以下自作agent。

a.cpp

# include <iostream>
# include <string>

void getnext_request( std::string &oid ) {

        if(
                oid == ".1.3.6.1.4.1.99999" ||
                oid == ".1.3.6.1.4.1.99999.1"
        ) {

                std::cout
                        << ".1.3.6.1.4.1.99999.1.0" << std::endl
                        << "integer" << std::endl
                        << 42 << std::endl
                ;

        } else {

                // 該当する内容が無い場合、NONE\nを返す
                std::cout << "NONE" << std::endl;

        }

}

void get_request( std::string &oid ) {

        if( oid == ".1.3.6.1.4.1.99999.1.0" ) {

                std::cout
                        << oid << std::endl
                        << "integer" << std::endl
                        << 42 << std::endl
                ;

        } else {

                // 該当する内容が無い場合、NONE\nを返す
                std::cout << "NONE" << std::endl;

        }

}

int main( int argc, char **argv ) {

        while( 1 ) {

                std::string line;
                std::cin >> line;

                if( line.empty() ) {

                        break;

                } else if( line == "PING" ) {

                        std::cout << "PONG" << std::endl;

                } else if( line == "get" ) {

                        std::string oid;
                        std::cin >> oid;

                        get_request( oid );

                } else if( line == "getnext" ) {

                        std::string oid;
                        std::cin >> oid;

                        getnext_request( oid );

                } else {

                        // unk.
                        break;

                }

        }

}

このサンプルでは、getで.1.3.6.1.4.1.99999.1.0しか応答しない。
もしこれを元にagentを作成する場合は、
getnext_requestとget_requestの部分を、相当作りこむ必要がある。

上記ソースをコンパイルする。
実行ファイルは/root/a.outとする。

snmpd.confを以下のようにする。



#
syslocation     あなたの心の中
syscontact      todanano

#               sec.name        source          community
com2sec         Net-Local       0.0.0.0         public

#               groupName       securityModel   securityName
group           Net-Group       v1              Net-Local
group           Net-Group       v2c             Net-Local

#               name            incl/excl       subtree         mask(optional)
view            all             included        .1

#               group           context sec.model       sec.level       prefix  read    write   notif
access          Net-Group       ""      any             noauth          exact   all     none    none
access          Net-Group       ""      any             priv            exact   all     none    none

pass_persist .1.3.6.1.4.1.99999 /root/a.out

pass_persist .1.3.6.1.4.1.99999 /root/a.outの部分が、
作成した自作エージェントを設定している箇所。
.1.3.6.1.4.1.99999以下のリクエストが来た場合、
/root/a.outに渡すようになる。

それ以外は、色々書いてあるが、最低限、応答が返せる内容であれば
何でも良い。

snmpd.confを書き換えたら、snmpdを再起動する。


[root@localhost ~]# /etc/init.d/snmpd restart
Stopping snmpd:                                            [  OK  ]
Starting snmpd:                                            [  OK  ]
[root@localhost ~]#

snmpgetかsnmpwalkを使って、.1.3.6.1.4.1.99999.1.0が応答することを確認する。
※snmpgetの場合、oidを間違えないこと。間違えた場合、エラーとなる。


[root@localhost ~]# snmpget -v 1 -c public localhost .1.3.6.1.4.1.99999.1.0
SNMPv2-SMI::enterprises.99999.1.0 = INTEGER: 42
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.99999
SNMPv2-SMI::enterprises.99999.1.0 = INTEGER: 42
[root@localhost ~]#
[root@localhost ~]# snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.99999.1
SNMPv2-SMI::enterprises.99999.1.0 = INTEGER: 42
[root@localhost ~]#
[root@localhost ~]# snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.99999.1.0
SNMPv2-SMI::enterprises.99999.1.0 = INTEGER: 42
[root@localhost ~]#
[root@localhost ~]#

先にも書いたが、上記サンプルでは、.1.3.6.1.4.1.99999.1.0しか応答を返せないので、
もしこれ以外の内容を返したい場合は、作りこむ必要がある。
(特にgetnextの内容は、相当考える必要がある。矛盾無く、次のoidを返せる仕組みが必要)

また、pass_persistによって呼び出されるプロセスは、
一度実行された後は、起動し続ける。
これは、snmpwalkなど、連続で問い合わせを受ける場合、
応答速度の面で恩恵がある。
また、前回値と今回値の差分値を返す場合、
プロセスが起動し続けているため、
シンプルな実装が可能となる(一時ファイル等を使う必要が無い)。

該当するoidにリクエストが来たタイミングで、対象のプロセスが動作していない場合、
snmpdはプロセスの実行を試みる。
すでに動作している場合は、そのままやり取りをする。

一度起動したプロセスは、snmpdの停止(再起動)によって、停止する。


[root@localhost ~]# /etc/init.d/snmpd restart
Stopping snmpd:                                            [  OK  ]
Starting snmpd:                                            [  OK  ]
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# ps aux | grep a.out
root     15833  0.0  0.0  61176   748 pts/0    S+   10:09   0:00 grep a.out
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.99999.1.0
SNMPv2-SMI::enterprises.99999.1.0 = INTEGER: 42
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# ps aux | grep a.out
root     15839  0.0  0.0  11564  1008 ?        S    10:09   0:00 /root/a.out
root     15843  0.0  0.0  61176   748 pts/0    S+   10:09   0:00 grep a.out
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# /etc/init.d/snmpd restart
Stopping snmpd:                                            [  OK  ]
Starting snmpd:                                            [  OK  ]
[root@localhost ~]#
[root@localhost ~]# ps aux | grep a.out
root     15865  0.0  0.0  61176   748 pts/0    S+   10:09   0:00 grep a.out
[root@localhost ~]#
[root@localhost ~]#

仮に指定したプロセスが、起動し続けるような実装になっていない場合でも、
単にいなければ実行してからやり取りをするだけなので、とりあえず動作する。

ただ、起動し続けるプログラムよりも、オーバーヘッドが大きくなるため、
pass_persistで設定する意味は無い。

実行したら終了したい場合は、pass_persistではなく、passを使ったほうが良い。
passであれば、PING、PONGのやり取りをせずに、そのままリクエストを受け取れるため、
実装もシンプルになるだろう。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?