//////////////////////////////////////////////////////////////////////////////////////////////////// /// <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); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <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()); }