2010年07月23日
実践SNMP+Java - SNMP Inform
SNMP4Jを利用したSNMPv2 Informの送信について説明します。
これまでに説明したSNMPv1 Trap, SNMPv2 Trapを使うと、SNMPマネージャにアラームを通知することが出来ますが、Trapの場合、それだけではマネージャ側が受信したか否かを送信(SNMPエージェント)側で知ることは出来ません。
ですから、重要なアラームであるほど通知先(相手)が受信したことを知りたい、という実践(運用)上の矛盾が生じます。
SNMPv1,v2トラップの場合、僕の知っている限りでは、通知元(SNMPエージェント)でSNMP Setリクエストを受信できるようにしておき、ある特定のSetリクエストをもって、相手が受信したと判断することが多いようです。
(Setリクエストを受信できない場合、ある一定の間隔で、トラップを送信し続ける)
この方法は送信側でSNMPエージェントがサービスしている場合には良いですが、アラーム通知だけしたいアプリケーションを作る場合には面倒です。
そこでInformという事になります。
Informを利用すると受信側がレスポンスを戻すので、送信側が受信を確認することが出来ます。
では、Javaコードから見ていきましょう。
<Javaコード>
- // SNMP通信パラメータを設定するクラス。
- CommunityTarget comTgt = new CommunityTarget();
- String managerUdpAddr = "localhost/162"; // SNMPマネージャのUDPアドレス
- comTgt.setAddress( new UdpAddress(managerUdpAddr) );
- comTgt.setCommunity( new OctetString("public") ); // SNMPコミュニティ名
- comTgt.setVersion(SnmpConstants.version2c); // SNMPバージョン
- final String sysObjectID = ".1.3.6.1.4.1.99999.1.1.100"; // sysObjectID
- /*
- * SNMPv2-MIB::snmpTrapOID(RFC1907)
- * The authoritative identification of the notification
- * currently being sent. This variable occurs as the second
- * varbind in every SNMPv2-Trap-PDU and InformRequest-PDU.
- *
- * <standard>
- * coldStart -> .1.3.6.1.6.3.1.1.5.1
- * warmStart -> .1.3.6.1.6.3.1.1.5.2
- * authenticationFailure -> .1.3.6.1.6.3.1.1.5.5
- *
- * <private>
- * Generally, set the value that added '0' and specific trap type of SNMPv1 trap to sysObjectID.
- */
- final String mySnmpTrapOID = sysObjectID + ".0.1"; // dummy snmpTrapOID
- final String varBindOID1 = ".1.3.6.1.4.1.99999.1.2.1.0"; // my varbind 1
- final String varBindOID2 = ".1.3.6.1.4.1.99999.1.2.2.0"; // my varbind 2
- // SNMPv2 Trap PDU
- PDU v2pdu = new PDU();
- // set pdu type
- v2pdu.setType(PDU.INFORM);
- // add varbind1: sysUpTime default 0.
- long sysUpTime = 8640000;
- v2pdu.add(new VariableBinding(SnmpConstants.sysUpTime, new TimeTicks(sysUpTime)));
- // add varbind 2: snmpTrapOID
- // SnmpConstants.snmpTrapOID -> .1.3.6.1.6.3.1.1.4.1.0
- v2pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OID(mySnmpTrapOID)));
- // add varbind 3: my payload 1
- v2pdu.add( new VariableBinding(new OID(varBindOID1), new OctetString("NETBUFFALO SNMPv2 Inform - my varbind 1")) );
- // add varbind 4: my payload 2
- v2pdu.add( new VariableBinding(new OID(varBindOID2), new OctetString("NETBUFFALO SNMPv2 Inform - my varbind 2")) );
- // SNMP操作の基本になるクラス。
- Snmp snmp = null;
- // DefaultTcpTransportMappingクラスもあります
- DefaultUdpTransportMapping utm = null;
- try {
- utm = new DefaultUdpTransportMapping();
- snmp = new Snmp(utm);
- snmp.listen(); // snmp.listen();しないと必ずfailedです。
- // Inform
- ResponseEvent event = snmp.send(v2pdu, comTgt);
- PDU responsePDU = event.getResponse();
- if (responsePDU == null) {
- System.out.println("failed: SNMPv2 Inform");
- } else {
- System.out.println("succeed: SNMPv2 Inform");
- }
- snmp.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
<実行結果>
OpUtilsで受信した結果です。
succeed: SNMPv2 Inform
<説明>
1)送信準備
1~38行目までは、SNMPv2トラップと基本的に同じです。
送信先ポートは162、SNMPバージョンはv2cにしてください。
あと、28行目でPDUタイプをINFORMに設定しています。
2)送信と結果の応答確認
まず、46行目でsnmp.listen()しています。InformではSNMPマネージャの
応答を待つので、snmp.listen()が必要です。これをしないと、送信は出来ますが、
応答を待つので、snmp.listen()が必要です。これをしないと、送信は出来ますが、
レスポンスがnullになってしまいます。
48~54行目で受信確認しています。
responsePDUがnullの場合、タイムアウトですから、受信確認は失敗です。
逆の場合は、SNMPマネージャからレスポンスがあった事を意味しています。
失敗した場合は、暫く経ってから再送するロジックを実装します。
応答データって具体的に何が送られてくるのですか?、と思う方もいるかも知れません。
その答えは、SNMPマネージャ(Inform/トラップの受信)の実装でご説明します。
#ここで受信したPDUの中身を見ても分かります。
ダグラス・R. マウロ ケビン・J. シュミット
オライリー・ジャパン
売り上げランキング: 257,278
オライリー・ジャパン
売り上げランキング: 257,278
Java ネットワーク プログラミング 基礎からわかる 完全入門
posted with amazlet at 13.01.12
永嶋 浩
技術評論社
売り上げランキング: 228,941
技術評論社
売り上げランキング: 228,941
Posted by netbuffalo at 14:49│TrackBack(0)│
│実践SNMP+Java