////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Reads DNS query. </summary>
        ///
        /// <param name="reader">   The reader. </param>
        ///
        /// <returns>   The DNS query. </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        public static DnsQuery ReadDnsQuery(BinaryReader reader)
        {
            String     domainName = ReadDomainName(reader);
            QueryType  qtype      = (QueryType)ReadUInt16BE(reader);
            QueryClass qclass     = (QueryClass)ReadUInt16BE(reader);

            DnsQuery query = new DnsQuery(domainName, qtype, qclass);

            return(query);
        }
Beispiel #2
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Get IPHostEntry for given domainName. </summary>
        ///
        /// <param name="domainName">   domainName. </param>
        /// <param name="queryType">    QueryType.Address or QueryType.MailExchange. </param>
        /// <param name="dnsServer">    dnsServer. </param>
        ///
        /// <returns>   The IP host entry. </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        public static IPHostEntry GetIPHostEntry(string domainName, QueryType queryType, IPAddress dnsServer)
        {
            DnsMessage message = DnsMessage.StandardQuery();
            DnsQuery   query   = new DnsQuery(domainName, queryType);

            message.Querys.Add(query);
            byte[] msgData = DnsMessageCoder.EncodeDnsMessage(message);
            try
            {
                byte[] reply = QueryServer(msgData, dnsServer);
                if (reply != null)
                {
                    DnsMessage answer = DnsMessageCoder.DecodeDnsMessage(reply);
                    if (answer.ID == message.ID)
                    {
                        if (answer.Answers.Count > 0)
                        {
                            IPHostEntry host = new IPHostEntry();
                            host.HostName = domainName;
                            if (queryType == QueryType.Address)
                            {
                                host.AddressList = GetAddressList(domainName, answer);
                            }
                            else if (queryType == QueryType.MailExchange)
                            {
                                host.Aliases     = GetMailExchangeAliases(domainName, answer);
                                host.AddressList = GetAddressList(answer, new List <string>(host.Aliases));
                            }
                            return(host);
                        }
                        else if (answer.AuthorityRecords.Count > 0)
                        {
                            IPAddress[] serverAddresses = GetAuthorityServers(answer);
                            // depth first search
                            foreach (IPAddress serverIP in serverAddresses)
                            {
                                IPHostEntry host = GetIPHostEntry(domainName, queryType, serverIP);
                                if (host != null)
                                {
                                    return(host);
                                }
                            }
                        }
                    }
                }
            }
            catch { }
            return(null);
        }
        /*  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.
         */

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>   Encode DNS query. </summary>
        ///
        /// <param name="query">    The query. </param>
        ///
        /// <returns>   A byte[]. </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        public static byte[] EncodeDnsQuery(DnsQuery query)
        {
            MemoryStream stream = new MemoryStream(256);
            BinaryWriter writer = new BinaryWriter(stream);

            //QNAME
            string[] labels = query.DomainName.Split('.');
            foreach (string label in labels)
            {
                writer.Write((byte)label.Length);
                writer.Write(Encoding.ASCII.GetBytes(label));
            }
            writer.Write((byte)0);

            //QTYPE
            WriteUInt16BE(writer, (UInt16)query.QueryType);

            //QCLASS
            WriteUInt16BE(writer, (UInt16)query.QueryClass);

            return(stream.ToArray());
        }