private DnsServerResponse ParseQuery(byte[] reply,int queryID)
{
//--- Parse headers ------------------------------------//
/* RFC 1035 4.1.1. Header section format
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
QDCOUNT
an unsigned 16 bit integer specifying the number of
entries in the question section.
ANCOUNT
an unsigned 16 bit integer specifying the number of
resource records in the answer section.
NSCOUNT
an unsigned 16 bit integer specifying the number of name
server resource records in the authority records section.
ARCOUNT
an unsigned 16 bit integer specifying the number of
resource records in the additional records section.
*/
// Get reply code
int id = (reply[0] << 8 | reply[1]);
OPCODE opcode = (OPCODE)((reply[2] >> 3) & 15);
RCODE replyCode = (RCODE)(reply[3] & 15);
int queryCount = (reply[4] << 8 | reply[5]);
int answerCount = (reply[6] << 8 | reply[7]);
int authoritiveAnswerCount = (reply[8] << 8 | reply[9]);
int additionalAnswerCount = (reply[10] << 8 | reply[11]);
//---- End of headers ---------------------------------//
// Check that it's query what we want
if(queryID != id){
throw new Exception("This isn't query with ID what we expected");
}
int pos = 12;
//----- Parse question part ------------//
for(int q=0;q<queryCount;q++){
string dummy = "";
GetQName(reply,ref pos,ref dummy);
//qtype + qclass
pos += 4;
}
//--------------------------------------//
// 1) parse answers
// 2) parse authoritive answers
// 3) parse additional answers
ArrayList answers = ParseAnswers(reply,answerCount,ref pos);
ArrayList authoritiveAnswers = ParseAnswers(reply,authoritiveAnswerCount,ref pos);
ArrayList additionalAnswers = ParseAnswers(reply,additionalAnswerCount,ref pos);
return new DnsServerResponse(true,replyCode,answers,authoritiveAnswers,additionalAnswers);
}