public void ParseByteTests() { Byte[] buffer = new Byte[3]; // Test valid octet lengths buffer[0] = 1; for (int i = 0; i < 255; i++) { buffer[1] = (Byte)i; UInt32 offset = 0; Byte parsedValue = Asn1.ParseIntegerToByte(buffer, ref offset); Assert.AreEqual(2U, offset); Assert.AreEqual((Byte)i, parsedValue); } // Test invalid octet lengths buffer[0] = 0; try { UInt32 offset = 0; Asn1.ParseIntegerToByte(buffer, ref offset); Assert.Fail("Expected exception that did not occur"); } catch (Exception e) { Console.WriteLine("Caught expected exception: {0}", e.Message); } // Test invalid octet lengths buffer[0] = 2; try { UInt32 offset = 0; Asn1.ParseIntegerToByte(buffer, ref offset); Assert.Fail("Expected exception that did not occur"); } catch (Exception e) { Console.WriteLine("Caught expected exception: {0}", e.Message); } }
// returns offset of varbind list public UInt32 Deserialize(Byte[] packet, UInt32 offset) { this.packetBytes = packet; UInt32 initialOffset = offset; // // SNMP Message Type // if (packet[offset] != Asn1.TYPE_SEQUENCE) { throw new FormatException(String.Format( "Expected snmp packet to be of type Sequence but is {0}", Asn1.GetTypeOrNumberString(packet[offset]))); } offset++; UInt32 sequenceLength = Asn1.ParseDefiniteLength(packet, ref offset); UInt32 sequenceOffsetLimit = offset + sequenceLength; if (packet.Length - offset < sequenceLength) { throw new FormatException(String.Format( "Failed to parse snmp packet because it was truncated from {0} bytes to {1}", sequenceLength + (offset - initialOffset), packet.Length - initialOffset)); } // // Version // if (packet[offset] != Asn1.TYPE_INTEGER) { throw new FormatException(String.Format( "Expected snmp version to be of type Integer but is {0}", Asn1.GetTypeOrNumberString(packet[offset]))); } offset++; this.version = Asn1.ParseIntegerToByte(packet, ref offset); if (this.version != 0) { throw new NotImplementedException(String.Format("Snmp version {0} (binary code {1}) is not implemented yet", this.version + 1, this.version)); } // // Community // if (packet[offset] != Asn1.TYPE_OCTET_STRING) { throw new FormatException(String.Format( "Expected snmp community to be of type OctetString but is '{0}'", Asn1.GetTypeOrNumberString(packet[offset]))); } offset++; Int32 communityLength = (Byte)Asn1.ParseDefiniteLength(packet, ref offset); if (communityLength < 0) { throw new FormatException(String.Format("Expected community octet string length to be positive but is {0}", communityLength)); } offset += (UInt32)communityLength; // // PDU Type // Byte pduTypeByte = packet[offset]; offset++; if (pduTypeByte < 0xA0) { throw new FormatException(String.Format("Expected SNMP pdu type to be >= 0xA0 but is {0:2X}", pduTypeByte)); } // // Use similar logic to parse similar types // Get, GetNext, GetResponse, Set if (pduTypeByte <= 0xA3) { SnmpPduType pduType = (SnmpPduType)(pduTypeByte - 0xA0); UInt32 pduLength = Asn1.ParseDefiniteLength(packet, ref offset); if (offset + pduLength != sequenceOffsetLimit) { throw new FormatException(String.Format( "Snmp packet is malformed, the pdu which ends at {0} does not end at the same place as the sequence at {1}", offset + pduLength, sequenceOffsetLimit)); } // // Request ID // if (packet[offset] != Asn1.TYPE_INTEGER) { throw new FormatException(String.Format( "Expected Snmp{0}Pdu to start with the Integer type but started with '{1}'", pduType, Asn1.GetTypeOrNumberString(packet[offset]))); } offset++; this.requestID = Asn1.ParseIntegerToInt32(packet, ref offset); // // Error Status // if (packet[offset] != Asn1.TYPE_INTEGER) { throw new FormatException(String.Format( "Expected Snmp{0}Pdu ErrorStatus to be an Integer type but is '{1}'", pduType, Asn1.GetTypeOrNumberString(packet[offset]))); } offset++; this.errorStatus = (SnmpErrorStatus)Asn1.ParseIntegerToInt32(packet, ref offset); // // Error Index // if (packet[offset] != Asn1.TYPE_INTEGER) { throw new FormatException(String.Format( "Expected Snmp{0}Pdu ErrorIndex to be an Integer type but is '{1}'", pduType, Asn1.GetTypeOrNumberString(packet[offset]))); } offset++; this.errorIndex = Asn1.ParseIntegerToInt32(packet, ref offset); // // Varbind List // if (packet[offset] != Asn1.TYPE_SEQUENCE) { throw new FormatException(String.Format( "Expected varbind list to be of type Sequence but is {0}", Asn1.GetTypeOrNumberString(packet[offset]))); } offset++; UInt32 varbindListLength = Asn1.ParseDefiniteLength(packet, ref offset); if (offset + varbindListLength != sequenceOffsetLimit) { throw new FormatException(String.Format( "Snmp packet is malformed, the varbind list which ends at {0} does not end at the same place as the sequence at {1}", offset + varbindListLength, sequenceOffsetLimit)); } return(offset); // return the offset to the varbind variables } else { throw new NotImplementedException(String.Format("Snmp pdu type {0} is not implemented yet", pduTypeByte)); } }