/** * Decodes a <code>Variable</code> from an <code>InputStream</code>. * * @param inputStream an <code>InputStream</code> containing a BER encoded byte stream. * @throws IOException */ @Override public void decodeBER(BERInputStream inputStream) throws IOException { MutableByte pduType = new MutableByte(); int length = BER.decodeHeader(inputStream, pduType); int pduStartPos = (int) inputStream.getPosition(); switch (pduType.getValue()) { case PDU.SET: case PDU.GET: case PDU.GETNEXT: case PDU.V1TRAP: case PDU.RESPONSE: break; // The following PDU types are not supported by the SNMPv1 standard! case PDU.NOTIFICATION: case PDU.INFORM: if (SNMP4JSettings.isAllowSNMPv2InV1()) { break; } // fall through default: throw new IOException("Unsupported PDU type: " + pduType.getValue()); } this.setType(pduType.getValue()); if (getType() == PDU.V1TRAP) { enterprise.decodeBER(inputStream); agentAddress.decodeBER(inputStream); genericTrap.decodeBER(inputStream); specificTrap.decodeBER(inputStream); timestamp.decodeBER(inputStream); } else { requestID.decodeBER(inputStream); errorStatus.decodeBER(inputStream); errorIndex.decodeBER(inputStream); } // reusing pduType here to save memory ;-) pduType = new BER.MutableByte(); int vbLength = BER.decodeHeader(inputStream, pduType); if (pduType.getValue() != BER.SEQUENCE) { throw new IOException("Encountered invalid tag, SEQUENCE expected: " + pduType.getValue()); } // rest read count int startPos = (int) inputStream.getPosition(); variableBindings = new Vector<>(); while (inputStream.getPosition() - startPos < vbLength) { VariableBinding vb = new VariableBinding(); vb.decodeBER(inputStream); if (!isVariableV1(vb.getVariable())) { throw new MessageException("Counter64 encountered in SNMPv1 PDU " + "(RFC 2576 §4.1.2.1)"); } variableBindings.add(vb); } if (BER.isCheckSequenceLength()) { BER.checkSequenceLength(vbLength, (int) inputStream.getPosition() - startPos, this); BER.checkSequenceLength(length, (int) inputStream.getPosition() - pduStartPos, this); } }
/** * Check if the given variable can be encoded into a SNMPv1 PDU. * * @param v a variable value (must not be <code>null</code>). * @return <code>true</code> if the variable is SNMPv1 compatible (or {@link * org.snmp4j.SNMP4JSettings#isAllowSNMPv2InV1()} is true), <code>false</code> otherwise, i.e. * if <code>v</code> is an instance of {@link Counter64}. * @since 1.9.1c */ protected boolean isVariableV1(Variable v) { return !(v instanceof Counter64) || SNMP4JSettings.isAllowSNMPv2InV1(); }