public Response ParseResponse(byte[] recvBytes)
        {
            var memoryStream = new MemoryStream(recvBytes);
            var flagBytesBuffer = new byte[2];
            var transactionIdBuffer = new byte[2];
            var questionsBuffer = new byte[2];
            var answerRRsBuffer = new byte[2];
            var authorityRRsBuffer = new byte[2];
            var additionalRRCountBytesBuffer = new byte[2];
            var nsTypeBuffer = new byte[2];
            var nsClassBuffer = new byte[2];

            var bytesReceived = recvBytes.Length;

            // Parse DNS Response
            memoryStream.Read(transactionIdBuffer, 0, 2);
            memoryStream.Read(flagBytesBuffer, 0, 2);
            memoryStream.Read(questionsBuffer, 0, 2);
            memoryStream.Read(answerRRsBuffer, 0, 2);
            memoryStream.Read(authorityRRsBuffer, 0, 2);
            memoryStream.Read(additionalRRCountBytesBuffer, 0, 2);

            // Parse Header
            var transactionId = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(transactionIdBuffer, 0));
            var flags = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(flagBytesBuffer, 0));
            var queryResponse = (QueryResponse)(flags & (ushort)FlagMasks.QueryResponseMask);
            var opCode = (OpCode)(flags & (ushort)FlagMasks.OpCodeMask);
            var nsFlags = (NsFlags)(flags & (ushort)FlagMasks.NsFlagMask);
            var rCode = (RCode)(flags & (ushort)FlagMasks.RCodeMask);

            // Parse Questions Section
            var questions = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(questionsBuffer, 0));
            var answerRRs = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(answerRRsBuffer, 0));
            var authorityRRs = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(authorityRRsBuffer, 0));
            var additionalRRCount = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(additionalRRCountBytesBuffer, 0));
            var additionalRecords = new List<Record>();
            var answers = new Record[answerRRs];
            var authoritiveNameServers = new Record[authorityRRs];

            var name = _recordNameParser.ParseName(ref memoryStream);

            // Read dnsType
            memoryStream.Read(nsTypeBuffer, 0, 2);

            // Read dnsClass
            memoryStream.Read(nsClassBuffer, 0, 2);

            var nsType = (NsType)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsTypeBuffer, 0));
            var nsClass = (NsClass)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsClassBuffer, 0));

            var headerParser = new RecordHeaderParser(_recordNameParser);
            
            // Read in Answer Blocks
            for (var i = 0; i < answerRRs; i++)
            {
                var header = headerParser.Parse(ref memoryStream);
                var parser = _parserFactory.Get(header.NsType);
                answers[i] = parser.ParseRecord(header, ref memoryStream);
            }

            // Parse Authority Records
            for (var i = 0; i < authorityRRs; i++)
            {
                var header = headerParser.Parse(ref memoryStream);
                var parser = _parserFactory.Get(header.NsType);
                authoritiveNameServers[i] = parser.ParseRecord(header, ref memoryStream);
            }

            // Parse Additional Records
            for (var i = 0; i < additionalRRCount; i++)
            {
                var header = headerParser.Parse(ref memoryStream);
                var parser = _parserFactory.Get(header.NsType);
                additionalRecords.Add(parser.ParseRecord(header, ref memoryStream));
            }

            return new Response(transactionId, flags, queryResponse, opCode, nsFlags, rCode, questions, answerRRs, authorityRRs, name, nsType, nsClass, additionalRecords, bytesReceived, answers, authoritiveNameServers);
        }
        public Response ParseResponse(byte[] recvBytes)
        {
            var memoryStream                 = new MemoryStream(recvBytes);
            var flagBytesBuffer              = new byte[2];
            var transactionIdBuffer          = new byte[2];
            var questionsBuffer              = new byte[2];
            var answerRRsBuffer              = new byte[2];
            var authorityRRsBuffer           = new byte[2];
            var additionalRRCountBytesBuffer = new byte[2];
            var nsTypeBuffer                 = new byte[2];
            var nsClassBuffer                = new byte[2];

            var bytesReceived = recvBytes.Length;

            // Parse DNS Response
            memoryStream.Read(transactionIdBuffer, 0, 2);
            memoryStream.Read(flagBytesBuffer, 0, 2);
            memoryStream.Read(questionsBuffer, 0, 2);
            memoryStream.Read(answerRRsBuffer, 0, 2);
            memoryStream.Read(authorityRRsBuffer, 0, 2);
            memoryStream.Read(additionalRRCountBytesBuffer, 0, 2);

            // Parse Header
            var transactionId = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(transactionIdBuffer, 0));
            var flags         = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(flagBytesBuffer, 0));
            var queryResponse = (QueryResponse)(flags & (ushort)FlagMasks.QueryResponseMask);
            var opCode        = (OpCode)(flags & (ushort)FlagMasks.OpCodeMask);
            var nsFlags       = (NsFlags)(flags & (ushort)FlagMasks.NsFlagMask);
            var rCode         = (RCode)(flags & (ushort)FlagMasks.RCodeMask);

            // Parse Questions Section
            var questions              = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(questionsBuffer, 0));
            var answerRRs              = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(answerRRsBuffer, 0));
            var authorityRRs           = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(authorityRRsBuffer, 0));
            var additionalRRCount      = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(additionalRRCountBytesBuffer, 0));
            var additionalRecords      = new List <Record>();
            var answers                = new Record[answerRRs];
            var authoritiveNameServers = new Record[authorityRRs];

            var name = _recordNameParser.ParseName(ref memoryStream);

            // Read dnsType
            memoryStream.Read(nsTypeBuffer, 0, 2);

            // Read dnsClass
            memoryStream.Read(nsClassBuffer, 0, 2);

            var nsType  = (NsType)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsTypeBuffer, 0));
            var nsClass = (NsClass)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsClassBuffer, 0));

            var headerParser = new RecordHeaderParser(_recordNameParser);

            // Read in Answer Blocks
            for (var i = 0; i < answerRRs; i++)
            {
                var header = headerParser.Parse(ref memoryStream);
                var parser = _parserFactory.Get(header.NsType);
                answers[i] = parser.ParseRecord(header, ref memoryStream);
            }

            // Parse Authority Records
            for (var i = 0; i < authorityRRs; i++)
            {
                var header = headerParser.Parse(ref memoryStream);
                var parser = _parserFactory.Get(header.NsType);
                authoritiveNameServers[i] = parser.ParseRecord(header, ref memoryStream);
            }

            // Parse Additional Records
            for (var i = 0; i < additionalRRCount; i++)
            {
                var header = headerParser.Parse(ref memoryStream);
                var parser = _parserFactory.Get(header.NsType);
                additionalRecords.Add(parser.ParseRecord(header, ref memoryStream));
            }

            return(new Response(transactionId, flags, queryResponse, opCode, nsFlags, rCode, questions, answerRRs, authorityRRs, name, nsType, nsClass, additionalRecords, bytesReceived, answers, authoritiveNameServers));
        }