示例#1
0
 internal int Init(DnsPacket packet, int offset)
 {
     name   = packet.ReadName(ref offset);
     type   = (DnsQType)packet.ReadUInt16(ref offset);
     _class = (DnsQClass)packet.ReadUInt16(ref offset);
     return(offset);
 }
示例#2
0
		internal int Init (DnsPacket packet, int offset)
		{
			name = packet.ReadName (ref offset);
			type = (DnsQType) packet.ReadUInt16 (ref offset);
			_class = (DnsQClass) packet.ReadUInt16 (ref offset);
			return offset;
		}
示例#3
0
        public DnsQuery(string name, DnsQType qtype, DnsQClass qclass)
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            int length = DnsUtil.GetEncodedLength(name);

            if (length == -1)
            {
                throw new ArgumentException("Invalid DNS name", "name");
            }

            length  += 12 + 2 + 2;            // Header + qtype + qclass
            packet   = new byte [length];
            header   = new DnsHeader(packet, 0);
            position = 12;
            WriteDnsName(name);
            WriteUInt16((ushort)qtype);
            WriteUInt16((ushort)qclass);
            Header.QuestionCount    = 1;
            Header.IsQuery          = true;
            Header.RecursionDesired = true;
        }
示例#4
0
 /// <summary>
 /// Shallow copies the data members from the source message passed
 /// to this instance.
 /// </summary>
 /// <param name="source">The source message.</param>
 protected void CopyFrom(DnsMessage source)
 {
     this.qid         = source.qid;
     this.flags       = source.flags;
     this.qname       = source.qname;
     this.qtype       = source.qtype;
     this.qclass      = source.qclass;
     this.answers     = source.answers;
     this.authorities = source.authorities;
     this.additional  = source.additional;
 }
示例#5
0
        private Dictionary <string, int> namePtrs;              // Set of existing name compression pointers

        /// <summary>
        /// This constructor initializes the message fields to default values.
        /// </summary>
        public DnsMessage()
        {
            this.qid         = 0;
            this.flags       = 0;
            this.qname       = null;
            this.qtype       = DnsQType.NULL;
            this.qclass      = DnsQClass.IN;
            this.answers     = null;
            this.authorities = null;
            this.additional  = null;
            this.namePtrs    = null;
        }
示例#6
0
        /// <summary>
        /// Connstructs a typical Internet class DNS request.
        /// </summary>
        /// <param name="flags">Additional flag bits (the QR and OPCODE sections will be set automatically).</param>
        /// <param name="qname">The query name.</param>
        /// <param name="qtype">The query type.</param>
        /// <remarks>
        /// <para>
        /// By default, this constructor initializes the OPCODE section of the message flags to
        /// <see cref="DnsOpcode.QUERY" />, the query ID to zero, and the query class to
        /// <see cref="DnsQClass.IN" />.  These properties can be modified directly after
        /// construction if necessary.  Note that the <see cref="DnsResolver" /> class
        /// handles the assignment of a unique query ID so it generally not necessary
        /// to explicitly set this property.
        /// </para>
        /// </remarks>
        public DnsRequest(DnsFlag flags, string qname, DnsQType qtype)
            : base()
        {
            if (!qname.EndsWith("."))
            {
                throw new ArgumentException("Domain names must end with [.]", "qname");
            }

            this.Flags  = flags;
            this.QName  = qname;
            this.QType  = qtype;
            this.QClass = DnsQClass.IN;
        }
示例#7
0
		public DnsQuery (string name, DnsQType qtype, DnsQClass qclass)
		{
			if (String.IsNullOrEmpty (name))
				throw new ArgumentNullException ("name");

			int length = DnsUtil.GetEncodedLength (name);
			if (length == -1)
				throw new ArgumentException ("Invalid DNS name", "name");

			length += 12 + 2 + 2; // Header + qtype + qclass
			packet = new byte [length];
			header = new DnsHeader (packet, 0);
			position = 12;
			WriteDnsName (name);
			WriteUInt16 ((ushort) qtype);
			WriteUInt16 ((ushort) qclass);
			Header.QuestionCount = 1;
			Header.IsQuery = true;
			Header.RecursionDesired = true;
		}
示例#8
0
		static DnsQuery GetQuery (string host, DnsQType q, DnsQClass c)
		{
			return new DnsQuery (host, q, c);
		}
        /// <summary>
        /// Gets DNSType
        /// </summary>
        /// <param name="uri"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public string GetDnsRecord(string uri, DnsQType type)
        {
            string   result = string.Empty;
            Request  req    = new Request();
            Question q      = new Question(uri, type, DnsClass.IN);

            req.AddQuestion(q);
            try
            {
                Response r = Resolver.Lookup(req, GetDnsServer());
                foreach (Answer a in r.Answers)
                {
                    switch (a.Type)
                    {
                    case DnsType.A:
                        result += string.Format("{0} has IPv4 address {1} (ttl: {2}){3}",
                                                a.Domain, a.Record, a.Ttl, Environment.NewLine);
                        break;

                    case DnsType.NS:
                        result += string.Format("{0} nameserver {1}; ttl: {2}{3}",
                                                a.Domain, a.Record, a.Ttl, Environment.NewLine);
                        break;

                    case DnsType.CNAME:
                        result += string.Format("{0} alias of {1} (ttl: {2}){3}",
                                                a.Domain, a.Record, a.Ttl, Environment.NewLine);
                        break;

                    case DnsType.SOA:
                        result += string.Format("typeid:\t\t{0}\nttl:\t\t{1}\ndata:\t\t{2}\ndomain:\t\t{3}\nserial:\t\t{4}\nrefresh:\t\t{5}\nretry:" +
                                                "\t\t{6}\nexpiry:\t\t{7}\nminttl:\t\t{8}\nresponsible:\t{9}\n\n", a.Type, a.Ttl,
                                                ((Bdev.Net.Dns.Records.SoaRecord)a.Record).PrimaryNameServer, uri,
                                                ((Bdev.Net.Dns.Records.SoaRecord)a.Record).Serial, ((Bdev.Net.Dns.Records.SoaRecord)a.Record).Refresh,
                                                ((Bdev.Net.Dns.Records.SoaRecord)a.Record).Retry, ((Bdev.Net.Dns.Records.SoaRecord)a.Record).Expire,
                                                ((Bdev.Net.Dns.Records.SoaRecord)a.Record).DefaultTtl, ((Bdev.Net.Dns.Records.SoaRecord)a.Record).ResponsibleMailAddress);
                        break;

                    case DnsType.MX:
                        result += string.Format("\n{0} mailserver {1} (pri={2}); ttl: {3}", a.Domain,
                                                ((Bdev.Net.Dns.Records.MXRecord)a.Record).DomainName, ((Bdev.Net.Dns.Records.MXRecord)a.Record).Preference, a.Ttl);
                        break;

                    case DnsType.TXT:
                        result += string.Format("{0}:\t{1} (ttl: {2}){3}",
                                                a.Domain, a.Record, a.Ttl, Environment.NewLine);
                        break;

                    case DnsType.AAAA:
                        result += string.Format("{0} has IPv6 address {1} (ttl: {2}){3}",
                                                a.Domain, a.Record, a.Ttl, Environment.NewLine);
                        break;

                    case DnsType.SRV:
                        result += string.Format("{0}:\t{1} (ttl: {2}){3}",
                                                a.Domain, a.Record, a.Ttl, Environment.NewLine);
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                if (type == DnsQType.A)
                {
                    return(GetDnsRecord(uri, DnsQType.CNAME));
                }

                return(uri + ": " + ex.Message + Environment.NewLine);
            }
            return(result);
        }
示例#10
0
 /// <summary>
 /// Compares the message's query type and qname to the parameters passed.
 /// </summary>
 /// <param name="qtype">The query type to be matched.</param>
 /// <param name="qname">The query name to be matched.</param>
 /// <returns><c>true</c> if both parameters match the values stored in the message.</returns>
 public bool Match(DnsQType qtype, string qname)
 {
     return(this.QType == qtype && String.Compare(this.QName, qname, true) == 0);
 }
示例#11
0
        /// <summary>
        /// This method parses the raw DNS message packet passed and initializes
        /// the message properties.
        /// </summary>
        /// <param name="packet">The raw DNS packet received.</param>
        /// <param name="cbPacket">Number of bytes in that packet.</param>
        /// <returns>True on success.</returns>
        public bool ParsePacket(byte[] packet, int cbPacket)
        {
            uint qdCount;
            uint anCount;
            uint nsCount;
            uint arCount;
            int  pos;

            // Read the message header

            pos      = 0;
            this.qid = (ushort)Helper.ReadInt16(packet, ref pos); if (pos > cbPacket)
            {
                return(false);
            }
            this.flags = (DnsFlag)Helper.ReadInt16(packet, ref pos); if (pos > cbPacket)
            {
                return(false);
            }
            qdCount = (ushort)Helper.ReadInt16(packet, ref pos); if (pos > cbPacket)
            {
                return(false);
            }
            anCount = (ushort)Helper.ReadInt16(packet, ref pos); if (pos > cbPacket)
            {
                return(false);
            }
            nsCount = (ushort)Helper.ReadInt16(packet, ref pos); if (pos > cbPacket)
            {
                return(false);
            }
            arCount = (ushort)Helper.ReadInt16(packet, ref pos); if (pos > cbPacket)
            {
                return(false);
            }

            Assertion.Test(pos == 12);

            // Check for unsupported packets

            if ((this.flags & DnsFlag.TC) != 0)     // truncation bit is set
            {
                return(false);
            }

            if (this.Opcode != DnsOpcode.QUERY)     // only accept standard queries
            {
                return(false);
            }

            if (qdCount != 1)                       // only supporting one question
            {
                return(false);
            }

            // Parse the question

            if (!ReadName(packet, ref pos, out this.qname))
            {
                return(false);
            }

            if (pos > cbPacket)
            {
                return(false);
            }

            this.qtype = (DnsQType)Helper.ReadInt16(packet, ref pos); if (pos > cbPacket)
            {
                return(false);
            }
            this.qclass = (DnsQClass)Helper.ReadInt16(packet, ref pos); if (pos > cbPacket)
            {
                return(false);
            }

            // We're only going to accept Internet queries

            if (this.qclass != DnsQClass.IN)
            {
                return(false);
            }

            // Parse the answer records

            for (int i = 0; i < anCount; i++)
            {
                var rr = DnsRR.Parse(this, packet, ref pos);

                if (rr == null || pos > cbPacket)
                {
                    return(false);
                }

                this.Answers.Add(rr);
            }

            // Parse the authority records

            for (int i = 0; i < nsCount; i++)
            {
                var rr = DnsRR.Parse(this, packet, ref pos);

                if (rr == null || pos > cbPacket)
                {
                    return(false);
                }

                this.Authorities.Add(rr);
            }

            // Parse the additional records

            for (int i = 0; i < arCount; i++)
            {
                var rr = DnsRR.Parse(this, packet, ref pos);

                if (rr == null || pos > cbPacket)
                {
                    return(false);
                }

                this.Additional.Add(rr);
            }

            // $todo(jeff.lill):
            //
            // Delete this once we've figured out why the DNS server
            // sometimes get requests with NULL QNAME properties.

            if (this.QName == null)
            {
                var packetBytes     = Helper.Extract(packet, cbPacket);
                var hexDump         = Helper.HexDump(packetBytes, 16, HexDumpOption.ShowAll);
                var diagnostics     = GetTraceDetails(IPAddress.Any);
                var extendedLogInfo = new StringSysLogEntryExtension(diagnostics + "\r\n\r\nPacket:\r\n\r\n" + hexDump);

                SysLog.LogWarning(extendedLogInfo, "DNS Packet with QNAME=NULL");
            }

            return(true);
        }
示例#12
0
        void ProcessResponse(SimpleResolverEventArgs args, DnsResponse response, EndPoint server_ep)
        {
            DnsRCode status = response.Header.RCode;

            if (status != 0)
            {
                if (args.PTRAddress != null)
                {
                    // PTR query failed -> no error, we have the IP
                    return;
                }
                args.ResolverError = (ResolverError)status;
                return;
            }

            // TODO: verify IP of the server is in our list and the same one that got the query
            IPEndPoint ep = (IPEndPoint)server_ep;

            if (ep.Port != 53)
            {
                args.ResolverError = ResolverError.ResponseHeaderError;
                args.ErrorMessage  = "Port";
                return;
            }

            DnsHeader header = response.Header;

            if (!header.IsQuery)
            {
                args.ResolverError = ResolverError.ResponseHeaderError;
                args.ErrorMessage  = "IsQuery";
                return;
            }

            // TODO: handle Truncation. Retry with bigger buffer?

            if (header.QuestionCount > 1)
            {
                args.ResolverError = ResolverError.ResponseHeaderError;
                args.ErrorMessage  = "QuestionCount";
                return;
            }
            ReadOnlyCollection <DnsQuestion> q = response.GetQuestions();

            if (q.Count != 1)
            {
                args.ResolverError = ResolverError.ResponseHeaderError;
                args.ErrorMessage  = "QuestionCount 2";
                return;
            }
            DnsQuestion question = q [0];

            /* The answer might have dot at the end, etc...
             * if (String.Compare (question.Name, args.HostName) != 0) {
             *      args.ResolverError = ResolverError.ResponseHeaderError;
             *      args.ErrorMessage = "HostName - " + question.Name + " != " + args.HostName;
             *      return;
             * }
             */

            DnsQType t = question.Type;

            if (t != DnsQType.A && t != DnsQType.AAAA && t != DnsQType.PTR)
            {
                args.ResolverError = ResolverError.ResponseHeaderError;
                args.ErrorMessage  = "QType " + question.Type;
                return;
            }

            if (question.Class != DnsQClass.IN)
            {
                args.ResolverError = ResolverError.ResponseHeaderError;
                args.ErrorMessage  = "QClass " + question.Class;
                return;
            }

            ReadOnlyCollection <DnsResourceRecord> records = response.GetAnswers();

            if (records.Count == 0)
            {
                if (args.PTRAddress != null)
                {
                    // PTR query failed -> no error
                    return;
                }
                args.ResolverError = ResolverError.NameError;                 // is this ok?
                args.ErrorMessage  = "NoAnswers";
                return;
            }

            List <string>    aliases   = null;
            List <IPAddress> addresses = null;

            foreach (DnsResourceRecord r in records)
            {
                if (r.Class != DnsClass.IN)
                {
                    continue;
                }
                if (r.Type == DnsType.A || r.Type == DnsType.AAAA)
                {
                    if (addresses == null)
                    {
                        addresses = new List <IPAddress> ();
                    }
                    addresses.Add(((DnsResourceRecordIPAddress)r).Address);
                }
                else if (r.Type == DnsType.CNAME)
                {
                    if (aliases == null)
                    {
                        aliases = new List <string> ();
                    }
                    aliases.Add(((DnsResourceRecordCName)r).CName);
                }
                else if (r.Type == DnsType.PTR)
                {
                    args.HostEntry.HostName    = ((DnsResourceRecordPTR)r).DName;
                    args.HostEntry.Aliases     = aliases == null ? EmptyStrings : aliases.ToArray();
                    args.HostEntry.AddressList = EmptyAddresses;
                    return;
                }
            }

            IPHostEntry entry = args.HostEntry ?? new IPHostEntry();

            if (entry.HostName == null && aliases != null && aliases.Count > 0)
            {
                entry.HostName = aliases [0];
                aliases.RemoveAt(0);
            }
            entry.Aliases     = aliases == null ? EmptyStrings : aliases.ToArray();
            entry.AddressList = addresses == null ? EmptyAddresses : addresses.ToArray();
            args.HostEntry    = entry;
            if ((question.Type == DnsQType.A || question.Type == DnsQType.AAAA) && entry.AddressList == EmptyAddresses)
            {
                args.ResolverError = ResolverError.NameError;
                args.ErrorMessage  = "No addresses in response";
            }
            else if (question.Type == DnsQType.PTR && entry.HostName == null)
            {
                args.ResolverError = ResolverError.NameError;
                args.ErrorMessage  = "No PTR in response";
            }
        }
示例#13
0
 static DnsQuery GetQuery(string host, DnsQType q, DnsQClass c)
 {
     return(new DnsQuery(host, q, c));
 }