コード例 #1
0
        public static Int32 ParsePduInt32(Byte[] packet, UInt32 offset, UInt32 length)
        {
            UInt32 initialOffset = offset;

            //
            // Varbind
            //
            if (packet[offset] != Asn1.TYPE_SEQUENCE)
            {
                throw new FormatException(String.Format(
                                              "Expected varbind to be of type Sequence but is {0}", Asn1.GetTypeOrNumberString(packet[offset])));
            }
            offset++;

            UInt32 varbindLength = Asn1.ParseDefiniteLength(packet, ref offset);

            if (packet.Length - offset < varbindLength)
            {
                throw new FormatException(String.Format(
                                              "Failed to parse snmp packet because it was truncated from {0} bytes to {1}",
                                              varbindLength + (offset - initialOffset), packet.Length - initialOffset));
            }

            //
            // Skip the bound variable
            //
            offset++; // Skip the type
            UInt32 boundVariableLength = Asn1.ParseDefiniteLength(packet, ref offset);

            offset += boundVariableLength;

            //
            // Parse the integer
            //
            if (packet[offset] != Asn1.TYPE_INTEGER)
            {
                throw new FormatException(String.Format(
                                              "Expected value to be of type Integer but is {0}", Asn1.GetTypeOrNumberString(packet[offset])));
            }
            offset++;
            return(Asn1.ParseIntegerToInt32(packet, ref offset));
        }
コード例 #2
0
        // 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));
            }
        }