/// <summary> /// Decode BER encoded <see cref="ScopedPdu"/> values. This method does not perform SNMP v3 privacy operations /// and is not aware of privacy requirements. /// /// To decode a privacy protected SNMP v3 packet, you will need to a) extract <see cref="OctetString"/> value /// holding encrypted <see cref="ScopedPdu"/> data, b) decrypt the encrypted ScopedPdu data into an unecrypted /// byte array, c) pass unencrypted <see cref="ScopedPdu"/> and BER encoded byte array to this method for /// final data conversion from BER into individual sequences and variables. /// </summary> /// <param name="buffer">Buffer holding BER encoded <see cref="ScopedPdu"/> data</param> /// <param name="offset">Offset within the buffer BER encoded <see cref="ScopedPdu"/> data begins.</param> /// <returns>Offset position after parsed ScopedPdu</returns> /// <exception cref="SnmpDecodingException">Error was encountered when decoding the PDU</exception> /// <exception cref="OverflowException">Thrown when buffer is too short to contain the PDU</exception> public override int decode(byte[] buffer, int offset) { int length; byte sequenceType = ParseHeader(buffer, ref offset, out length); if (sequenceType != SnmpConstants.SMI_SEQUENCE) { throw new SnmpDecodingException("Invalid ScopedPdu sequence detected. Invalid ScopedPdu encoding."); } // verify packet can match parsed length if (length > (buffer.Length - offset)) { throw new OverflowException("SNMP packet too short."); } // Reset scoped pdu specific variables _contextEngineId.Reset(); _contextName.Reset(); // parse scoped pdu specific variables offset = _contextEngineId.decode(buffer, offset); offset = _contextName.decode(buffer, offset); // decode base pdu offset = base.decode(buffer, offset); return(offset); }
/// <summary>BER encode security model field.</summary> /// <remarks> /// USM security model is a SEQUENCE encoded inside a OCTETSTRING. To encode it, first encode the sequence /// of class values then "wrap" it inside a OCTETSTRING field /// </remarks> /// <param name="buffer">Buffer to store encoded USM security model header</param> public override void encode(MutableByte buffer) { MutableByte tmp = new MutableByte(); // First encode all the values that will form the sequence _engineId.encode(tmp); // Encode engine boots _engineBoots.encode(tmp); // encode engine time _engineTime.encode(tmp); _securityName.encode(tmp); if (_authentication != AuthenticationDigests.None) { if (_authenticationParameters.Length <= 0) { // If authentication is used, set authentication parameters field to 12 bytes set to 0x00 _authenticationParameters.Set(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); } } else { _authenticationParameters.Reset(); } _authenticationParameters.encode(tmp); if (_privacy != PrivacyProtocols.None) { if (_privacyParameters.Length <= 0) { IPrivacyProtocol privProto = PrivacyProtocol.GetInstance(_privacy); if (privProto != null) { byte[] parameter = new byte[privProto.PrivacyParametersLength]; for (int i = 0; i < privProto.PrivacyParametersLength; i++) { parameter[i] = 0x00; // This is not necessary since all array members are, by default, initialized to 0 } _privacyParameters.Set(parameter); } else { throw new SnmpException(SnmpException.UnsupportedPrivacyProtocol, "Unrecognized privacy protocol specified."); } } } else { _privacyParameters.Reset(); } _privacyParameters.encode(tmp); MutableByte tmp1 = new MutableByte(); BuildHeader(tmp1, SnmpConstants.SMI_SEQUENCE, tmp.Length); tmp1.Append(tmp); BuildHeader(buffer, OCTETSTRING, tmp1.Length); buffer.Append(tmp1); }