Ejemplo n.º 1
0
        public DnsResponseMessage GetResponseMessage(ArraySegment <byte> responseData)
        {
            var reader = new DnsDatagramReader(responseData);

            var id              = reader.ReadUInt16NetworkOrder();
            var flags           = reader.ReadUInt16NetworkOrder();
            var questionCount   = reader.ReadUInt16NetworkOrder();
            var answerCount     = reader.ReadUInt16NetworkOrder();
            var nameServerCount = reader.ReadUInt16NetworkOrder();
            var additionalCount = reader.ReadUInt16NetworkOrder();

            var header   = new DnsResponseHeader(id, flags, questionCount, answerCount, additionalCount, nameServerCount);
            var response = new DnsResponseMessage(header, responseData.Count);

            for (var questionIndex = 0; questionIndex < questionCount; questionIndex++)
            {
                var questionQueryString = reader.ReadQuestionQueryString();
                var queryTypeValue      = reader.ReadUInt16NetworkOrder();
                var queryClass          = reader.ReadUInt16NetworkOrder();
                if (!_queryTypes.TryGetValue(queryTypeValue, out var queryType))
                {
                    queryType = new PseudoResourceRecordType(
                        abbreviation: "Unknown",
                        value: queryTypeValue
                        );
                }
                var question = new DnsQuestion(questionQueryString, queryType, (QueryClass)queryClass);
                response.AddQuestion(question);
            }

            for (var answerIndex = 0; answerIndex < answerCount; answerIndex++)
            {
                var info   = ReadRecordInfo(reader);
                var record = _dnsRecordFactory.GetRecord(info, reader);
                response.AddAnswer(record);
            }

            for (var serverIndex = 0; serverIndex < nameServerCount; serverIndex++)
            {
                var info   = ReadRecordInfo(reader);
                var record = _dnsRecordFactory.GetRecord(info, reader);
                response.AddAuthority(record);
            }

            for (var additionalIndex = 0; additionalIndex < additionalCount; additionalIndex++)
            {
                var info   = ReadRecordInfo(reader);
                var record = _dnsRecordFactory.GetRecord(info, reader);
                response.AddAdditional(record);
            }

            return(response);
        }
Ejemplo n.º 2
0
        public ICollection <ArraySegment <byte> > ReadLabels()
        {
            var result = new List <ArraySegment <byte> >(10);

            // read the length byte for the label, then get the content from offset+1 to length
            // proceed till we reach zero length byte.
            byte length;

            while ((length = ReadByte()) != 0)
            {
                // respect the reference bit and lookup the name at the given position
                // the reader will advance only for the 2 bytes read.
                if ((length & ReferenceByte) != 0)
                {
                    int subIndex = (length & 0x3f) << 8 | ReadByte();
                    if (subIndex >= _data.Array.Length - 1)
                    {
                        // invalid length pointer, seems to be actual length of a label which exceeds 63 chars...
                        // get back one and continue other labels
                        _index--;
                        result.Add(_data.SubArray(_index, length));
                        Advance(length);
                        continue;
                    }

                    var subReader = new DnsDatagramReader(_data.SubArrayFromOriginal(subIndex));
                    var newLabels = subReader.ReadLabels();
                    result.AddRange(newLabels); // add range actually much faster than concat and equal to or faster than for-each.. (array copy would work maybe)
                    return(result);
                }

                if (_index + length >= _count)
                {
                    throw new DnsResponseParseException(
                              "Found invalid label position.", _data.ToArray(), _index, length);
                }

                var label = _data.SubArray(_index, length);

                // maybe store original bytes in this instance too?
                result.Add(label);

                Advance(length);
            }

            return(result);
        }
Ejemplo n.º 3
0
        public virtual DnsResponseMessage GetResponseMessage(ArraySegment <byte> responseData)
        {
            var reader  = new DnsDatagramReader(responseData);
            var factory = new DnsRecordFactory(reader);

            var id              = reader.ReadUInt16NetworkOrder();
            var flags           = reader.ReadUInt16NetworkOrder();
            var questionCount   = reader.ReadUInt16NetworkOrder();
            var answerCount     = reader.ReadUInt16NetworkOrder();
            var nameServerCount = reader.ReadUInt16NetworkOrder();
            var additionalCount = reader.ReadUInt16NetworkOrder();

            var header   = new DnsResponseHeader(id, flags, questionCount, answerCount, additionalCount, nameServerCount);
            var response = new DnsResponseMessage(header, responseData.Count);

            for (int questionIndex = 0; questionIndex < questionCount; questionIndex++)
            {
                var question = new DnsQuestion(reader.ReadQuestionQueryString(), (QueryType)reader.ReadUInt16NetworkOrder(), (QueryClass)reader.ReadUInt16NetworkOrder());
                response.AddQuestion(question);
            }

            for (int answerIndex = 0; answerIndex < answerCount; answerIndex++)
            {
                var info   = factory.ReadRecordInfo();
                var record = factory.GetRecord(info);
                response.AddAnswer(record);
            }

            for (int serverIndex = 0; serverIndex < nameServerCount; serverIndex++)
            {
                var info   = factory.ReadRecordInfo();
                var record = factory.GetRecord(info);
                response.AddAuthority(record);
            }

            for (int additionalIndex = 0; additionalIndex < additionalCount; additionalIndex++)
            {
                var info   = factory.ReadRecordInfo();
                var record = factory.GetRecord(info);
                response.AddAdditional(record);
            }

            return(response);
        }
Ejemplo n.º 4
0
        private DnsResourceRecord ResolveTXTRecord(ResourceRecordInfo info)
        {
            int pos = _reader.Index;

            var values     = new List <string>();
            var utf8Values = new List <string>();

            while ((_reader.Index - pos) < info.RawDataLength)
            {
                var length  = _reader.ReadByte();
                var bytes   = _reader.ReadBytes(length);
                var escaped = DnsDatagramReader.ParseString(bytes);
                var utf     = DnsDatagramReader.ReadUTF8String(bytes);
                values.Add(escaped);
                utf8Values.Add(utf);
            }

            return(new TxtRecord(info, values.ToArray(), utf8Values.ToArray()));
        }
Ejemplo n.º 5
0
        public static string ParseString(DnsDatagramReader reader, int length)
        {
            if (reader._count < reader._index + length)
            {
                throw new DnsResponseParseException("Cannot parse string.", reader._data.ToArray(), reader._index, length);
            }

            var builder = StringBuilderObjectPool.Default.Get();

            for (var i = 0; i < length; i++)
            {
                byte b = reader.ReadByte();
                char c = (char)b;

                if (b < 32 || b > 126)
                {
                    builder.Append("\\" + b.ToString("000"));
                }
                else if (c == ';')
                {
                    builder.Append("\\;");
                }
                else if (c == '\\')
                {
                    builder.Append("\\\\");
                }
                else if (c == '"')
                {
                    builder.Append("\\\"");
                }
                else
                {
                    builder.Append(c);
                }
            }

            var value = builder.ToString();

            StringBuilderObjectPool.Default.Return(builder);
            return(value);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Reads a <see cref="ResourceRecord"/> from this <see cref="DnsDatagramReader"/>.
        /// </summary>
        private ResourceRecord ReadRecordInfo(DnsDatagramReader reader)
        {
            var queryString = reader.ReadQuestionQueryString();
            var type        = reader.ReadUInt16NetworkOrder();

            if (!_resourceRecordTypes.TryGetValue(type, out var resourceRecordType))
            {
                resourceRecordType = new PseudoResourceRecordType(
                    abbreviation: "Unknown - machine generated",
                    value: type
                    );
            }
            var queryClass = reader.ReadUInt16NetworkOrder();
            var ttl        = reader.ReadUInt32NetworkOrder();
            var rdLength   = reader.ReadUInt16NetworkOrder();

            return(new ResourceRecord(
                       queryString,            // name
                       resourceRecordType,     // type
                       (QueryClass)queryClass, // class
                       (int)ttl,               // ttl - 32bit!!
                       rdLength));             // RDLength
        }
Ejemplo n.º 7
0
        public static string ParseString(DnsDatagramReader reader, int length)
        {
            var builder = StringBuilderObjectPool.Default.Get();

            for (var i = 0; i < length; i++)
            {
                byte b = reader.ReadByte();
                char c = (char)b;

                if (b < 32 || b > 126)
                {
                    builder.Append("\\" + b.ToString("000"));
                }
                else if (c == ';')
                {
                    builder.Append("\\;");
                }
                else if (c == '\\')
                {
                    builder.Append("\\\\");
                }
                else if (c == '"')
                {
                    builder.Append("\\\"");
                }
                else
                {
                    builder.Append(c);
                }
            }

            var value = builder.ToString();

            StringBuilderObjectPool.Default.Return(builder);
            return(value);
        }
Ejemplo n.º 8
0
 public DnsRecordFactory(DnsDatagramReader reader)
 {
     _reader = reader ?? throw new ArgumentNullException(nameof(reader));
 }