Esempio n. 1
0
        /// <summary>
        /// Parse an EdnsOption based on the given type and array offset
        /// </summary>
        /// <param name="optionType"></param>
        /// <param name="optionLength"></param>
        /// <param name="array"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public static EdnsOption ParseOption(byte[] array, int offset, ref int bytesProcessed)
        {
            // 2 bytes ~ option code
            uint optionCode = DnsEncoder.ParseUint16(array, offset);

            offset += 2;

            // 2 bytes ~ option length
            uint optionLength = DnsEncoder.ParseUint16(array, offset);

            offset += 2;

            bytesProcessed += 4;

            EdnsOption option = null;

            // Load based on the option code
            switch ((EdnsOptionCode)optionCode)
            {
            case EdnsOptionCode.ClientSubnet:
                option = EdnsClientSubnetOption.Parse(array, offset, ref bytesProcessed);
                break;
            }

            return(option);
        }
Esempio n. 2
0
        /// <summary>
        /// Parse the DnsEdnsRequestMessage from the given byte array
        /// </summary>
        /// <param name="array"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public static EdnsQuestion Parse(byte[] array, int offset, ref int bytesProcessed)
        {
            // Check the length
            if (offset + 10 >= array.Length)
            {
                return(null);
            }

            // domain
            var domain = array[offset++];

            // 2 bytes - Question type
            var type = (DnsZoneType)DnsEncoder.ParseUint16(array, offset);

            offset += 2;

            // 2 bytes - requestor UDP size
            // TODO: save this, should be useful
            var requestorUdpSize = DnsEncoder.ParseUint16(array, offset);

            if (requestorUdpSize < 512)
            {
                requestorUdpSize = 512; // Don't allow smaller than 512 bytes
            }
            else if (requestorUdpSize > 4096)
            {
                requestorUdpSize = 4096; // Don't allow smaller than 4096 bytes
            }
            offset += 2;

            // extended RCODE and flags ~ skip
            offset += 4;

            // Domain must be 0, type must be OPT
            if (domain != 0 || type != DnsZoneType.OPT)
            {
                return(null);
            }

            // Read the RDATA length
            var rdataLength = DnsEncoder.ParseUint16(array, offset);

            offset += 2;

            // Validate length
            if (offset + rdataLength > array.Length)
            {
                return(null);
            }

            // Create a new question
            var ednsQuestion = new EdnsQuestion();

            // Read the options
            int dataBytesProcessed = 0;

            while (dataBytesProcessed < rdataLength)
            {
                // Load the option based on type
                var option = EdnsOption.ParseOption(array, offset + dataBytesProcessed, ref dataBytesProcessed);
                if (option != null)
                {
                    ednsQuestion.Options.Add(option);
                }
            }

            // Save the bytes processed
            bytesProcessed = 10 + dataBytesProcessed;

            return(ednsQuestion);
        }