/// <summary>Encode Pdu class to BER byte buffer</summary> /// <remarks> /// Encodes the protocol data unit using the passed encoder and stores /// the results in the passed buffer. An exception is thrown if an /// error occurs with the encoding of the information. /// </remarks> /// <param name="buffer">The buffer to write the encoded information.</param> public override void Encode(MutableByte buffer) { MutableByte tmpBuffer = new MutableByte(); // if request id is 0, get a random value if (requestId.Value == 0) { requestId.SetRandom(); } requestId.Encode(tmpBuffer); errorStatus.Encode(tmpBuffer); errorIndex.Encode(tmpBuffer); // if V2TRAP PDU type, add sysUpTime and trapObjectID OIDs before encoding VarBind if (Type == EPduType.V2Trap || Type == EPduType.Inform) { if (VbList.Count == 0) { // add sysUpTime and trapObjectID to the VbList VbList.Add(SnmpConstants.SysUpTime, TrapSysUpTime); VbList.Add(SnmpConstants.TrapObjectId, trapObjectID); } else { // Make sure user didn't manually add sysUpTime and trapObjectID values // to the pdu // if we have more then one item in the VarBinds array check for sysUpTime if (VbList.Count > 0) { // if the first Vb in the VarBinds array is not sysUpTime append it in the // encoded byte array if (!VbList[0].Oid.Equals(SnmpConstants.SysUpTime)) { Vb sysUpTimeVb = new Vb(SnmpConstants.SysUpTime, TrapSysUpTime); VbList.Insert(0, sysUpTimeVb); } } // if we have 2 or more Vbs in the VarBinds array check for trapObjectID Vb if (VbList.Count > 1) { // if second Vb in the VarBinds array is not trapObjectId encode the value if (!VbList[1].Oid.Equals(SnmpConstants.TrapObjectId)) { Vb trapObjectIdVb = new Vb(SnmpConstants.TrapObjectId, trapObjectID); VbList.Insert(1, trapObjectIdVb); } } } } // encode variable bindings VbList.Encode(tmpBuffer); // Now encode the header for the PDU BuildHeader(buffer, (byte)Type, tmpBuffer.Length); buffer.Append(tmpBuffer); }
/// <summary>Copy values from another Pdu class.</summary> /// <param name="value"><see cref="Pdu"/> cast as AsnType</param> /// <exception cref="ArgumentNullException">Thrown when received argument is null</exception> public void Set(AsnType value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } if (value is Pdu pdu) { Type = pdu.Type; requestId.Value = pdu.RequestId; if (Type == EPduType.GetBulk) { NonRepeaters = pdu.NonRepeaters; MaxRepetitions = pdu.MaxRepetitions; } else { ErrorStatus = pdu.ErrorStatus; ErrorIndex = pdu.ErrorIndex; } VbList.Clear(); foreach (Vb v in pdu.VbList) { VbList.Add((Vb)v.Clone()); } } else { throw new ArgumentNullException(nameof(value), "Argument is not an Oid class"); } }
/// <summary>Delete VB from the specified location in the VarBind list</summary> /// <param name="pos">0 based VB location</param> public void DeleteVb(int pos) { if (pos >= 0 && pos <= VbList.Count) { VbList.RemoveAt(pos); } }
/// <summary>Decode BER encoded SNMP version 1 trap packet</summary> /// <param name="buffer">BER encoded buffer</param> /// <param name="offset">Offset in the packet to start decoding from</param> /// <returns>Buffer position after the decoded value.</returns> /// <exception cref="SnmpException">Invalid SNMP Pdu type received. Not an SNMP version 1 Trap PDU.</exception> /// <exception cref="SnmpException">Invalid Variable Binding list encoding.</exception> public override int Decode(byte[] buffer, int offset) { byte asnType = ParseHeader(buffer, ref offset, out int headerLength); if (asnType != (byte)PduType.Trap) { throw new SnmpException("Invalid PDU type."); } if (headerLength > buffer.Length - offset) { throw new OverflowException("Packet is too short."); } offset = _enterprise.Decode(buffer, offset); offset = _agentAddr.Decode(buffer, offset); offset = _generic.Decode(buffer, offset); offset = _specific.Decode(buffer, offset); offset = _timeStamp.Decode(buffer, offset); // clean out the current variables VbList.Clear(); offset = VbList.Decode(buffer, offset); return(offset); }
/// <summary>Set VbList</summary> /// <remarks> /// Copy variable bindings from argument <see cref="VbCollection"/> into this classes variable /// binding collection /// </remarks> /// <param name="value"><see cref="VbCollection"/> to copy variable bindings from</param> public void SetVbList(VbCollection value) { VbList.Clear(); foreach (Vb v in value) { VbList.Add(v); } }
/// <summary> /// Check class equality with argument. /// /// Accepted argument types are: /// * Integer32 - compared against the request id /// * Pdu - compared against PduType, request id and contents of VarBind list /// </summary> /// <param name="obj">Integer32 or Pdu to compare</param> /// <returns>True if equal, otherwise false</returns> public override bool Equals(object obj) { if (obj == null) { return(false); } if (obj is Integer32) { if (((Integer32)obj) == _requestId) { return(true); } return(false); } else if (obj is Pdu p) { if (p.Type != Type) { return(false); } if (p.RequestId != RequestId) { return(false); } if (p.VbCount != VbCount) { return(false); } foreach (Vb v in VbList) { if (!p.VbList.ContainsOid(v.Oid)) { return(false); } } foreach (Vb v in p.VbList) { if (!VbList.ContainsOid(v.Oid)) { return(false); } } return(true); } return(false); }
/// <summary>Decode BER encoded Pdu</summary> /// <remarks> /// Decodes the protocol data unit from the passed buffer. If an error /// occurs during the decoding sequence then an AsnDecodingException is /// thrown by the method. The value is decoded using the AsnEncoder /// passed to the object. /// </remarks> /// <param name="buffer">BER encoded buffer</param> /// <param name="offset">The offset byte to begin decoding</param> /// <returns>Buffer position after the decoded value</returns> /// <exception cref="OverflowException">Thrown when header points to more data then is available.</exception> public override int Decode(byte[] buffer, int offset) { byte asnType = ParseHeader(buffer, ref offset, out int headerLength); if (offset + headerLength > buffer.Length) { throw new OverflowException("Insufficient data in packet"); } base.Type = asnType; // request id offset = requestId.Decode(buffer, offset); // error status offset = errorStatus.Decode(buffer, offset); // error index offset = errorIndex.Decode(buffer, offset); // clean out the current variables VbList.Clear(); // decode the Variable binding collection offset = VbList.Decode(buffer, offset); // if Pdu is an SNMP version 2 TRAP, remove sysUpTime and trapObjectID from the VarBinds array if (Type == EPduType.V2Trap || Type == EPduType.Inform) { if (VbList.Count > 0) { if (VbList[0].Oid.Equals(SnmpConstants.SysUpTime)) { TrapSysUpTime.Set(VbList[0].Value); VbList.RemoveAt(0); // remove sysUpTime } } if (VbList.Count > 0) { if (VbList[0].Oid.Equals(SnmpConstants.TrapObjectId)) { trapObjectID.Set((Oid)VbList[0].Value); VbList.RemoveAt(0); // remove sysUpTime } } } return(offset); }
/// <summary>Reset VbList.</summary> /// <remarks>Remove all entries in the VbList collections.</remarks> public void Reset() { VbList.Clear(); errorStatus.Value = 0; errorIndex.Value = 0; if (requestId.Value == int.MaxValue) { requestId.Value = 1; } else { requestId.Value = requestId.Value + 1; } trapObjectID.Reset(); TrapSysUpTime.Value = 0; }
/// <summary>Access variable bindings using Vb Oid value</summary> /// <param name="oid">Required Oid value</param> /// <returns>Variable binding with the Oid matching the parameter, otherwise null</returns> public Vb this[Oid oid] { get { if (!VbList.ContainsOid(oid)) { return(null); } foreach (Vb v in VbList) { if (v.Oid.Equals(oid)) { return(v); } } return(null); } }
/// <summary>ASN.1 encode SNMP version 1 trap</summary> /// <param name="buffer"><see cref="MutableByte"/> buffer to the end of which encoded values are appended.</param> public override void Encode(MutableByte buffer) { MutableByte trapBuffer = new MutableByte(); // encode the enterprise id & address _enterprise.Encode(trapBuffer); _agentAddr.Encode(trapBuffer); _generic.Encode(trapBuffer); _specific.Encode(trapBuffer); _timeStamp.Encode(trapBuffer); VbList.Encode(trapBuffer); MutableByte tmpBuffer = new MutableByte(); BuildHeader(tmpBuffer, (byte)PduType.Trap, trapBuffer.Length); trapBuffer.Prepend(tmpBuffer); buffer.Append(trapBuffer); }
/// <summary> /// Initialize the class with values from another <see cref="TrapPdu"/> class. /// </summary> /// <param name="second">TrapPdu class whose values are used to initialize this class.</param> public void Set(TrapPdu second) { if (second != null) { _enterprise.Set(second._enterprise); _agentAddr.Set(second._agentAddr); _generic.Value = second.Generic; _specific.Value = second.Specific; _timeStamp.Value = second.TimeStamp; VbList.Clear(); for (int x = 0; x < second.VbList.Count; x++) { VbList = (VbCollection)second.VbList.Clone(); } } else { throw new ArgumentException("Invalid argument type.", "value"); } }
/// <summary> /// Check class equality with argument. /// /// Accepted argument types are: /// * Integer32 - compared against the request id /// * Pdu - compared against PduType, request id and contents of VarBind list /// </summary> /// <param name="obj">Integer32 or Pdu to compare</param> /// <returns>True if equal, otherwise false</returns> public bool Equals(Pdu obj) { if (obj == null) { return(false); } Pdu p = (Pdu)obj; if (p.Type != this.Type) { return(false); } if (p.RequestId != this.RequestId) { return(false); } if (p.VbCount != this.VbCount) { return(false); } foreach (Vb v in VbList) { if (!p.VbList.ContainsOid(v.Oid)) { return(false); } } foreach (Vb v in p.VbList) { if (!VbList.ContainsOid(v.Oid)) { return(false); } } return(true); }
/// <summary>Get VarBind collection enumerator.</summary> /// <returns>Enumerator</returns> public IEnumerator <Vb> GetEnumerator() { return(VbList.GetEnumerator()); }