Пример #1
0
        public static QueryHeader ParseQueryHeader(byte[] buffer)
        {
            //https://tools.ietf.org/html/rfc1035#section-4.1.1
            var header = new QueryHeader();

            //this is the first place I was bitten by endianness
            header.ID = endianBitConverter.ToUInt16(buffer, 0); //first 2 bytes is the ID

            //and this is the second
            BitArray byteTwo = new BitArray(new byte[] { buffer[2] });
            byteTwo.Reverse();

            BitArray byteThree = new BitArray(new byte[] { buffer[3] });
            byteThree.Reverse();

            header.QueryResponse = byteTwo[0]; //Query Response bit

            //chop up the next nybble as we'll use it to get the opcode itself
            var opcodeArray = new BitArray(4);
            opcodeArray[0] = byteTwo[1];
            opcodeArray[1] = byteTwo[2];
            opcodeArray[2] = byteTwo[3];
            opcodeArray[3] = byteTwo[4];

            //Look away, children!
            //I'm converting the BitArray to a string (1010), then to a short, then to my OpCode value
            //todo: use bitmasking to do this
            header.OPCODE = (OpCode)Convert.ToInt16(opcodeArray.ToBitString(), 2);

            //this takes us to position 5 of the second byte
            header.AuthoritativeAnswer = byteTwo[5];
            header.Truncation = byteTwo[6];
            header.RecursionDesired = byteTwo[7];

            //next!
            header.RecursionAvailable = byteThree[0];
            header.Z = byteThree[1];
            //header.ResponseCode //bits two through 5

            header.QuestionCount = endianBitConverter.ToUInt16(buffer, 4);
            header.AnswerCount = endianBitConverter.ToUInt16(buffer, 6);
            header.NameServerCount = endianBitConverter.ToUInt16(buffer, 8);
            header.AdditonalRecordCount = endianBitConverter.ToUInt16(buffer, 10); //wtf happened with endianness here?
            return header;
        }