Ejemplo n.º 1
0
        public DnsHeader(Byte[] bytes, UInt32 offset)
        {
            id = (UInt16)((bytes[offset] << 8) |
                          (bytes[offset + 1]));


            thirdByte  = bytes[offset + 2];
            fourthByte = bytes[offset + 3];

            isResponseFlag = (bytes[offset + 2] & 0x80) != 0;

            opCode = (DnsOpCode)((bytes[offset + 2] >> 3) & 0xF);

            rCode = (DnsRCode)(bytes[offset + 3] & 0xF);

            qdCount = (UInt16)((bytes[offset + 4] << 8) |
                               (bytes[offset + 5]));
            anCount = (UInt16)((bytes[offset + 6] << 8) |
                               (bytes[offset + 7]));
            nsCount = (UInt16)((bytes[offset + 8] << 8) |
                               (bytes[offset + 9]));
            arCount = (UInt16)((bytes[offset + 10] << 8) |
                               (bytes[offset + 11]));
        }
Ejemplo n.º 2
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";
            }
        }