GET request throwing MPv3 parse error - reason: statusInfo=noError, status=-1408

Hello,

I’m trying to send a GET request to a device and I’m getting the following DEBUG output:

Initialized Salt to 18981ce190da4167.
UDP receive buffer size for socket 0.0.0.0/0 is set to: 65507
Adding user JGB = UsmUser[secName=JGB,authProtocol=1.3.6.1.6.3.10.1.1.2,authPassphrase=Whats_My_Name,privProtocol=1.3.6.1.4.1.4976.2.2.1.2.2,privPassphrase=Francis123,localizationEngineID=null]
RFC3414 §3.1.4.b Outgoing message is not encrypted
Adding cache entry: StateReference[msgID=49808,pduHandle=PduHandle[1841946943],securityEngineID=,securityModel=org.snmp4j.security.USM@5b37e0d2,securityName=JGB,securityLevel=1,contextEngineID=,contextName=,retryMsgIDs=null]
Running pending sync request with handle PduHandle[1841946943] and retry count left 0
Sending message to 192.168.0.23/161 with length 60: 30:3a:02:01:03:30:10:02:03:00:c2:90:02:03:00:ff:ff:04:01:04:02:01:03:04:10:30:0e:04:00:02:01:00:02:01:00:04:00:04:00:04:00:30:11:04:00:04:00:a0:0b:02:01:00:02:01:00:02:01:00:30:00
Received message from /192.168.0.23/161 with length 106: 30:68:02:01:03:30:12:02:04:00:00:c2:90:02:04:00:00:04:00:04:01:00:02:01:03:04:21:30:1f:04:0b:80:00:42:c7:03:54:10:ec:ca:34:a7:02:04:00:00:00:04:02:04:00:04:5e:d7:04:00:04:00:04:00:30:2c:04:00:04:00:a8:82:00:24:02:04:00:00:00:00:02:01:00:02:01:00:30:82:00:14:30:12:06:0a:2b:06:01:06:03:0f:01:01:04:00:41:04:00:00:08:53
SNMPv3 header decoded: msgId=49808, msgMaxSize=1024, msgFlags=00, secModel=3
MPv3 parse error: The actual length of the SEQUENCE object org.snmp4j.mp.MPv3$HeaderData is 15, but 18 was expected
java.io.IOException: The actual length of the SEQUENCE object org.snmp4j.mp.MPv3$HeaderData is 15, but 18 was expected
	at org.snmp4j.asn1.BER.checkSequenceLength(BER.java:967)
	at org.snmp4j.mp.MPv3$HeaderData.decodeBER(MPv3.java:739)
	at org.snmp4j.mp.MPv3.prepareDataElements(MPv3.java:1137)
	at org.snmp4j.MessageDispatcherImpl.dispatchMessage(MessageDispatcherImpl.java:278)
	at org.snmp4j.MessageDispatcherImpl.processMessage(MessageDispatcherImpl.java:390)
	at org.snmp4j.MessageDispatcherImpl.processMessage(MessageDispatcherImpl.java:350)
	at org.snmp4j.transport.AbstractTransportMapping.fireProcessMessage(AbstractTransportMapping.java:76)
	at org.snmp4j.transport.DefaultUdpTransportMapping$ListenThread.run(DefaultUdpTransportMapping.java:430)
	at java.lang.Thread.run(Thread.java:748)
Message from 192.168.0.23/161 not dispatched, reason: statusInfo=noError, status=-1408
Request timed out: 1841946943
Removed pending request with handle: PduHandle[1841946943]
Removed cache entry: StateReference[msgID=49808,pduHandle=null,securityEngineID=,securityModel=org.snmp4j.security.USM@5b37e0d2,securityName=JGB,securityLevel=1,contextEngineID=,contextName=,retryMsgIDs=null]
ResponsePDU: null

Can you please advise on how to troubleshoot this issue?

Thanks.

Have you modified the SNMP34J you are using or is it an old version?

The latest version (3.4.0) parses the response (an unknownEngineIDs REPORT PDU) correctly: The header length is given in hex “12” which is decimal 18 and that is the correct length of the dumped packet:
30:68:02:01:03:30:12:02:04:00:00:c2:90:02:04:00:00:04:00:04:01:00:02:01:03:04:21:30:1f:04:0b:80:00:42:c7:03:54:10:ec:ca:34:a7:02:04:00:00:00:04:02:04:00:04:5e:d7:04:00:04:00:04:00:30:2c:04:00:04:00:a8:82:00:24:02:04:00:00:00:00:02:01:00:02:01:00:30:82:00:14:30:12:06:0a:2b:06:01:06:03:0f:01:01:04:00:41:04:00:00:08:53

MIB Explorer Pro has a packet analyzer that can read a packet dump or a whole log file and display the BER structure even of encrypted packets (if you have stored the security name and passwords in the USM of MIB Explorer). The helps debugging such issues:

I’m using snmp4j version 2.8.1. Unfortunately I only have Java 8 available to me so I don’t think I can upgrade to 3.4.0.

I don’t have MIB Explorer Pro, but I was able to use Wireshark to view the packets.

Do you have any suggestions on how I can resolve the issue?

Thanks.

Ok, I found the cause for this exception:

  1. The exception is thrown, because BER.isCheckSequenceLength() is true. You can set this boolean to false to suppress length checks at all.
  2. The msgID and msgMaxSize are encoded by the remote agent with more bytes than necessary. This is allowed by the standard but unusual and waste of bandwidth.

Most of the length checks are in SNMP4J are already immune against this encoding anomaly but not the check for the SNMPv3 header.
Changing MPv3.Header.decodeBER to the following code will fix the issue (this fix will be included in the next releases of the 3.x and 2.x branch):

    public void decodeBER(BERInputStream message) throws IOException {
        BER.MutableByte type = new BER.MutableByte();
        int length = BER.decodeHeader(message, type);
        if (type.getValue() != BER.SEQUENCE) {
            throw new IOException("Unexpected sequence header type: " +
                    type.getValue());
        }
        long startPos = message.getPosition();
        msgID.decodeBER(message);
        msgMaxSize.decodeBER(message);
        if (msgMaxSize.getValue() < 484) {
            throw new IOException("Invalid msgMaxSize: " + msgMaxSize);
        }
        msgFlags.decodeBER(message);
        if (msgFlags.length() != 1) {
            throw new IOException("Message flags length != 1: " + msgFlags.length());
        }
        securityModel.decodeBER(message);
        if (logger.isDebugEnabled()) {
            logger.debug("SNMPv3 header decoded: msgId=" + msgID +
                    ", msgMaxSize=" + msgMaxSize +
                    ", msgFlags=" + msgFlags.toHexString() +
                    ", secModel=" + securityModel);
        }
        BER.checkSequenceLength(length, (int) (message.getPosition() - startPos),this);
    }

That fixed it for me, thanks for your help!