[SNMP4J] PDU setNonRepeaters problem?

Chris Richmond crichmond at referentia.com
Sat Sep 17 09:40:50 CEST 2011


We have been using the Snmp4j v2.0 library for a while now in testing 
and have begun to do some error condition handling when I came across 
something which seems either wrong or confusing to me

I noticed that when performing a bulk request and setting the 
PDU.setNonRepeaters() method that no matter what, the PDU always had an 
error code that made no sense even though the call worked just fine.

I narrowed the error state change down to this granularity, where the 
pdu is the snmp4j PDU instance

       System.err.println("pdu error string: " + getErrorString());
         pdu.setNonRepeaters(nonRepeaters);
       System.err.println("pdu error string: " + pdu.getErrorStatusText());


And this would always return

Success
<Some error message based on the number of repeaters I set>


The API documentation states that:


      setNonRepeaters

public void*setNonRepeaters*(int nonRepeaters)

    Sets the number of non repeater variable bindings in a GETBULK PDU.

    *Parameters:*
        |nonRepeaters| - an integer value >= 0 and <= |size()|
        <http://www.snmp4j.org/doc/org/snmp4j/PDU.html#size%28%29>

I ensured there was no variable list size problem, and I downloaded the 
source to see what was happening inside the PDU class.

Here is the method inside the PDU class from source

   /**
    * Sets the number of non repeater variable bindings in a GETBULK PDU.
    * @param nonRepeaters
    *    an integer value >= 0 and <= {@link #size()}
    */
   public void setNonRepeaters(int nonRepeaters) {
     this.errorStatus.setValue(nonRepeaters);
   }


Now I am confused.  It simply takes the number of repeaters and sets it 
directly to the error status, with no @link #size() logical check of any 
kind.  This integer for the number of non repeaters is then used 
directly by the method:

   /**
    * Gets a textual description of the error status.
    * @return
    *    a String containing an element of the
    *    {@link SnmpConstants#SNMP_ERROR_MESSAGES} array for a valid 
error status.
    *    "Unknown error: <errorStatusNumber>" is returned for any other 
value.
    */
   public String getErrorStatusText() {
     return toErrorStatusText(errorStatus.getValue());
   }

with the internal method toErrorStatusText simply mapping whatever 
integer to the SnmpConstants.SNMP_ERROR_MESSAGES index

   public static final String toErrorStatusText(int errorStatus) {
     try {
       return SnmpConstants.SNMP_ERROR_MESSAGES[errorStatus];
     }
     catch (ArrayIndexOutOfBoundsException iobex) {
       return "Unknown error: "+errorStatus;
     }
   }

   public static final String[] SNMP_ERROR_MESSAGES = {
       "Success",
       "PDU encoding too big",
       "No such name",
       "Bad value",
       "Variable is read-only",
       "General variable binding error",
       "No access",
       "Wrong type",
       "Variable binding data with incorrect length",
       "Variable binding data with wrong encoding",
       "Wrong value",
       "Unable to create object",
       "Inconsistent value",
       "Resource unavailable",
       "Commit failed",
       "Undo failed",
       "Authorization error",
       "Not writable",
       "Inconsistent naming used"


So I ran another test, and sure enough whatever value I pass in for the 
number of non-repeaters, simply equates directly to some error status on 
the PDU object with no other mitigating logic.

I also downloaded the latest snapshot 2.3 and this code is the same.

This seems like a pretty straightforward bug, but am I missing something?

Thanks,
Chris




More information about the SNMP4J mailing list