Exemple #1
0
            static IReadOnlyList <DnsResourceRecord>?ParseSection(ref DnsParseContext context, int count)
            {
                if (count == 0)
                {
                    return(null);
                }

                var result = new DnsResourceRecord[count];

                foreach (ref var record in result.AsSpan())
                {
                    string           name   = context.ReadDomainName();
                    DnsRecordType    qtype  = (DnsRecordType)context.ReadUInt16();
                    DnsEndpointClass qclass = (DnsEndpointClass)context.ReadUInt16();
                    int    ttl      = context.ReadInt32();
                    ushort rdlength = context.ReadUInt16();

                    record = qtype switch
                    {
                        DnsRecordType.A or DnsRecordType.AAAA => new IPRecord(),
                                                         DnsRecordType.TXT => new TxtRecord(),
                                                         DnsRecordType.CNAME => new DomainNameRecord(),
                                                         DnsRecordType.MX => new MXRecord(),
                                                         DnsRecordType.SOA => new SoaRecord(),
                                                         _ => new UnknownRecord()
                    };
                    record.Name          = name;
                    record.Type          = qtype;
                    record.EndpointClass = qclass;
                    record.AliveSeconds  = ttl;

                    record.ReadData(ref context, rdlength);
                }

                return(result);
            }

            var queries = queryCount == 0 ? Array.Empty <DnsQuery>() : new DnsQuery[queryCount];

            foreach (ref var query in queries.AsSpan())
            {
                string           name   = context.ReadDomainName();
                DnsRecordType    qtype  = (DnsRecordType)context.ReadUInt16();
                DnsEndpointClass qclass = (DnsEndpointClass)context.ReadUInt16();
                query = new(name, qtype, qclass);
            }

            message.Queries = queries;
            message.Answers = ParseSection(ref context, answerCount);
            message.NameServerAuthorities = ParseSection(ref context, serverCount);
            message.AdditionalRecords     = ParseSection(ref context, additionalCount);

            bytesConsumed = context.BytesConsumed;
            return(message);
        }
Exemple #2
0
        public static DnsMessage ParseMessage(ReadOnlySpan <byte> span, out int bytesConsumed)
        {
            var context = new DnsParseContext(span);

            var message = new DnsMessage
            {
                QueryId = context.ReadUInt16(),
            };
            ushort flags           = context.ReadUInt16();
            int    queryCount      = context.ReadUInt16();
            int    answerCount     = context.ReadUInt16();
            int    serverCount     = context.ReadUInt16();
            int    additionalCount = context.ReadUInt16();

            message.IsResponse            = (flags & ResponseFlag) != 0;
            message.Operation             = (DnsOperation)((flags & OpCodeMask) >> OpCodeShift);
            message.IsAuthoritativeAnswer = (flags & AuthoritativeMask) != 0;
            message.IsTruncated           = (flags & TruncationMask) != 0;
            message.IsRecursionDesired    = (flags & RecursionDesiredMask) != 0;
            message.IsRecursionAvailable  = (flags & RecursionAvailableMask) != 0;
            message.ResponseCode          = (DnsResponseCode)(flags & ResponseCodeMask);