[SNMP4J] PDU setNonRepeaters problem?

Chris Richmond crichmond at referentia.com
Sat Sep 17 12:34:12 CEST 2011


As a followup...I notice by looking through the responsePDU in the 
source code that the error code is never set to anything but 0 for any 
response, such as in the Snmp class:

     protected void sendInformResponse(CommandResponderEvent event) throws
         MessageException {
       PDU responsePDU = (PDU) event.getPDU().clone();
       responsePDU.setType(PDU.RESPONSE);
       responsePDU.setErrorStatus(PDU.noError);

where PDU.noError simply maps to the Snmp error constant 0

I find only one other place in the code where setErrorStatus on PDU is 
called and it is set to 0.

I did find that I should be examing the response event's pdu for this 
instead of looking at my request pdu after I make a request, however 
after looking through the code, can the error response be used for non 
bulk requests either?

Thanks,

Chris



On 9/16/2011 12:17 PM, Frank Fock wrote:
> Hi Chris,
>
> It's not a bug, it's a feature. The SNMP standard(s) have
> caused that. The nonRepeaters field is the same as
> the errorStatus field on the wire (repeaters = error index).
>
> That works, because when you send a GETBULK request,
> an error condition does not make sense (for the agent).
> The repsonse then contains the error status and index
> which is "overwritten" by the agent.
>
> Best regards,
> Frank
>
>
> Am 17.09.2011 09:40, schrieb Chris Richmond:
>> 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
>>
>> _______________________________________________
>> SNMP4J mailing list
>> SNMP4J at agentpp.org
>> http://lists.agentpp.org/mailman/listinfo/snmp4j
> _______________________________________________
> SNMP4J mailing list
> SNMP4J at agentpp.org
> http://lists.agentpp.org/mailman/listinfo/snmp4j




More information about the SNMP4J mailing list