private byte[] CreateQuery(int ID,string qname,QTYPE qtype,int qclass)
{
byte[] query = new byte[512];
//---- Create header --------------------------------------------//
// Header is first 12 bytes of query
/* 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 |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
QR A one bit field that specifies whether this message is a
query (0), or a response (1).
OPCODE A four bit field that specifies kind of query in this
message. This value is set by the originator of a query
and copied into the response. The values are:
0 a standard query (QUERY)
1 an inverse query (IQUERY)
2 a server status request (STATUS)
*/
//--------- Header part -----------------------------------//
query[0] = (byte) (ID >> 8); query[1] = (byte) (ID & 0xFF);
query[2] = (byte) 1; query[3] = (byte) 0;
query[4] = (byte) 0; query[5] = (byte) 1;
query[6] = (byte) 0; query[7] = (byte) 0;
query[8] = (byte) 0; query[9] = (byte) 0;
query[10] = (byte) 0; query[11] = (byte) 0;
//---------------------------------------------------------//
//---- End of header --------------------------------------------//
//----Create query ------------------------------------//
/* Rfc 1035 4.1.2. Question section format
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ QNAME /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QTYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QCLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
QNAME
a domain name represented as a sequence of labels, where
each label consists of a length octet followed by that
number of octets. The domain name terminates with the
zero length octet for the null label of the root. Note
that this field may be an odd number of octets; no
padding is used.
*/
string[] labels = qname.Split(new char[] {'.'});
int position = 12;
// Copy all domain parts(labels) to query
// eg. lumisoft.ee = 2 labels, lumisoft and ee.
// format = label.length + label(bytes)
foreach(string label in labels){
// add label lenght to query
query[position++] = (byte)(label.Length);
// convert label string to byte array
byte[] b = Encoding.ASCII.GetBytes(label);
b.CopyTo(query,position);
// Move position by label length
position += b.Length;
}
// Terminate domain (see note above)
query[position++] = (byte) 0;
// Set QTYPE
query[position++] = (byte) 0;
query[position++] = (byte)qtype;
// Set QCLASS
query[position++] = (byte) 0;
query[position++] = (byte)qclass;
//-------------------------------------------------------//
return query;
}