2016-08-09 15 views
1

SNMP4Jを使ってsnmpv3のGET PDUをシミュレートすると、存在しないOIDを変数バインディングリストに追加しても、有効な応答が得られることがわかりました。
しかし、プロトコルのバージョンがv1,の場合は、エラーコード2が表示されますが、「そのような名前はありません」という意味です。
プロトコルバージョンがV2Cあるとき、私はERRORを取得し、VBリストのサイズを返されませんでしたが1であり、リスト(0)変数の結合構文は、 『そのようなオブジェクト』を意味しない例外です。
だから私はv1またはv2cのを使用している場合、それが存在するかどうかを把握することができますが、それはV3だとき、私は次の応答を得た:snmpv3が存在しないOIDで正常にPDUを返すのはなぜですか?

SNMP-USER-BASED-SM-MIB::usmStatsUnknownEngineIDs.0 = Counter32: xx 

** XX番号です。

コードは次のとおりです。

 import org.snmp4j.*; 
     import org.snmp4j.event.ResponseEvent; 
     import org.snmp4j.mp.SnmpConstants; 
     import org.snmp4j.security.*; 
     import org.snmp4j.smi.*; 
     import org.snmp4j.transport.DefaultUdpTransportMapping; 

      import static org.snmp4j.mp.MPv3.createLocalEngineID; 

    /** 
    * 
    * Following syntax may helpfull: SMIConstants 
    * public static final int EXCEPTION_NO_SUCH_OBJECT = BER.NOSUCHOBJECT; 
    * public static final int EXCEPTION_NO_SUCH_INSTANCE = BER.NOSUCHINSTANCE; 
    * public static final int EXCEPTION_END_OF_MIB_VIEW = BER.ENDOFMIBVIEW; 
    * 
    * give a string and test whether it exists or not 
    * 
    * Conclusions: 
    * (1)When the op is GET, 
    * V1: 
    * errorcode at pdu, AND IS 2, MEANS "no such name" 
    * V2C: 
    * NOT GET ERROR, and returned vb list size is 1, and the list(0) Null.isExceptionSyntax(vb.getSyntax()) == true // means "no such object" 
    * V3: 
    * NOT GET ERROR, like this : SNMP-USER-BASED-SM-MIB::usmStatsUnknownEngineIDs.0 = Counter32: 23 
    * returned varbingds : 1.3.6.1.6.3.15.1.1.3.0 = xxx 
    * (2)When the op is GETNEXT: 
    *  V1: 
    *  errorcode at pdu, AND IS 2, MEANS "no such name" 
    *  V2C: 
    *  NOT GET ERROR, and returned vb list size is 1, and the list(0) Null.isExceptionSyntax(vb.getSyntax()) == true // means "endOfMibView" 
    *  V3: 
    *  NOT GET ERROR, like this : SNMP-USER-BASED-SM-MIB::usmStatsUnknownEngineIDs.0 = Counter32: 23 
    * (3)When the op is GETBULK: 
    * 
    * Created by edward.gao on 8/9/16. 
    */ 
    public class TestOidExists { 

    private static final String _V1_OR_V2_COMMUNITYNAME= "public"; 
    private static final String _V3_USERNAME = "edward"; 
    /** 
    * authentication protocol MD5 or SHA 
    */ 
    private static final String _V3_AUTHENTICATION_PASSPHRASE = "auth12345678"; 

    /** 
    * privacy protocol DES OR AES 
    */ 
    private static final String _V3_PRIVACY_PASSPHRASE = "encry12345678"; 

    public static void main(String[] args) throws Exception{ 

     final String addrString= "udp:192.168.170.150/161"; 
     byte [] localEngineID = createLocalEngineID(); 
     //version3 need usm 
     USM usm = new USM(SecurityProtocols.getInstance(),new OctetString(localEngineID), 0); 
     SecurityModels.getInstance().addSecurityModel(usm); 
     Snmp snmp = new Snmp(new DefaultUdpTransportMapping()); 

     snmp.listen(); 


     String [] oids = new String[] {/*".1.3.6.1.2.1.1.5.0", ".1.3.6.1.2.1.25.6.3.1.2", ".1.3.6.1.2.1.1.5",*/ ".1.3.999"}; 
     String [] types = new String[]{ "get","getnext", "getbulk"}; 
     for (String oid : oids) 
     { 
      for (String type : types) { 
       System.out.println(String.format("VERSION IS 3, oid:%s result: %d", oid, typeOfOID(oid, snmp, SnmpConstants.version3, type))); 
       System.out.println(String.format("VERSION IS 2, oid:%s result: %d", oid, typeOfOID(oid, snmp, SnmpConstants.version2c, type))); 
       System.out.println(String.format("VERSION IS 1, oid:%s result: %d", oid, typeOfOID(oid, snmp, SnmpConstants.version1, type))); 
      } 
     } 
    } 

    /** 
    * get the type of matched oid string 
    * @param oid 
    * @param snmp 
    * @return -1 : not exist , 0, leaf, 1, tree 
    */ 
    public static int typeOfOID(String oid , Snmp snmp, int version, String typeString) throws Exception 
    { 


     boolean isv3 = version == SnmpConstants.version3; 
     //build a client 
     Address addr = GenericAddress.parse("192.168.170.150/161"); 
     Target target = null; 
     if (isv3) { 
      UsmUser usmUser = new UsmUser(new OctetString(_V3_USERNAME), 
        AuthMD5.ID, 
        new OctetString(_V3_AUTHENTICATION_PASSPHRASE), 
        PrivDES.ID, 
        new OctetString(_V3_PRIVACY_PASSPHRASE) 
      ); 
      snmp.getUSM().addUser(usmUser); 
      target = new UserTarget(); 
     } 
     else 
     { 
      target = new CommunityTarget(); 
      //the default version is 3 
      if (version == SnmpConstants.version2c) 
      { 
       target.setVersion(SnmpConstants.version2c); 
      } 
      else 
      { 
       target.setVersion(SnmpConstants.version1); 
      } 
      ((CommunityTarget)target).setCommunity(new OctetString("public")); 
     } 


     target.setAddress(addr); 
     target.setRetries(2); 
     target.setTimeout(30000); 

     int type = typeString.equalsIgnoreCase("get") ? PDU.GET : (typeString.equalsIgnoreCase("getnext") ? PDU.GETNEXT : PDU.GETBULK); 
     System.out.println("Using version " + (version == SnmpConstants.version1 ? "v1" :(version == SnmpConstants.version2c ? "v2c " : "v3 ")) + " type:" + typeString); 
     PDU pdu = version == SnmpConstants.version3 ? new ScopedPDU() : new PDU(); 
     pdu.setType(type); 
     pdu.add(new VariableBinding(new OID(oid))); 
     pdu.setRequestID(new Integer32(0)); 
     ResponseEvent responseEvent = snmp.send(pdu, target); 
     if (responseEvent.getError() == null) 
     { 
      PDU responsePdu = responseEvent.getResponse(); 
      if (responsePdu.getErrorStatus() == 0) 
      { 
       responsePdu.getVariableBindings().forEach(vb ->System.out.print(vb + " " + Null.isExceptionSyntax(vb.getSyntax()))); 
       System.out.println(); 
       //leaf get only one, other get more than one 
       return responsePdu.getVariableBindings().size() == 1 ? 0 : 1; 
      } 
      else 
      { 
       System.out.println("error code at pdu," + responsePdu.getErrorStatus() + " text:" + responsePdu.getErrorStatusText() + " index:" + responsePdu.getErrorIndex()); 
      } 
     } 
     else 
     { 
      System.out.println("error happend,"); 
      responseEvent.getError().printStackTrace(); 
     } 
     return -1; 
    } 

} 

だから私の質問は次のとおりです。
(1)正しく実装V3のこの振る舞いですか?なぜ私は何らかのエラーを起こさなかったのですか?
(2)SNMP4Jを使用してOIDが存在するかどうかをテストするにはどうすればよいですか?

答えて

1

SNMP REPORT PDUと表示されています。エージェントがマネージャから要求PDUを受信し、engine_id,engine_bootsおよびengine_timeのような重要なセキュリティ属性が欠落していると判断し、その旨をマネージャに通知するためにREPORTを返すことが起こります。マネージャは、https://tools.ietf.org/html/rfc5343で詳細に説明されている、いわゆるSNMPエンジンディスカバリ手順に従って完全にレポートPDUを処理する必要があります。

0

質問1の場合、userTargetのsecurityName & securityLevelを設定すると、正常に機能しました。

 userTarget.setSecurityName(new OctetString(_V3_USERNAME)); 
     userTarget.setSecurityLevel(SecurityLevel.AUTH_PRIV); 

それで質問2の場合は、バージョン今1 &図2cと同じです。

参照:RFC3414:

3) securityParametersでmsgAuthoritativeEngineIDフィールドの値が不明である場合は、次の発見は 任意に新しいエントリを作成できる行う A)非正式のSNMPエンジンローカルコンフィグレーションで データストア(LCD)を呼び出し、処理を続行します。 又はB)usmStatsUnknownEngineIDsカウンタをインクリメントカウンタのOIDと 値を呼び出す モジュールに戻されると共にをインクリメントし、 エラー表示(unknownEngineID)されます。

関連する問題