Beispiel #1
0
        /*
        All communications inside of the domain protocol are carried in a single
        format called a message.  The top level format of message is divided
        into 5 sections (some of which are empty in certain cases) shown below:
        +---------------------+
        |        Header       |
        +---------------------+
        |       Question      | the question for the name server
        +---------------------+
        |        Answer       | RRs answering the question
        +---------------------+
        |      Authority      | RRs pointing toward an authority
        +---------------------+
        |      Additional     | RRs holding additional information
        +---------------------+
         */
        public static byte[] EncodeDnsMessage(DnsMessage message)
        {
            MemoryStream stream = new MemoryStream(512);
            BinaryWriter writer = new BinaryWriter(stream);

            byte[] header = EncodeHeader(message);
            writer.Write(header);

            foreach (DnsQuery query in message.Querys)
            {
                writer.Write(EncodeDnsQuery(query));
            }

            foreach (DnsResource answer in message.Answers)
            {
                writer.Write(EncodeDnsResource(answer));
            }

            foreach (DnsResource record in message.AuthorityRecords)
            {
                writer.Write(EncodeDnsResource(record));
            }

            foreach (DnsResource record in message.AdditionalRecords)
            {
                writer.Write(EncodeDnsResource(record));
            }

            return stream.ToArray();
        }
Beispiel #2
0
        /*
         * Header Structure, the bit labeled 0 is the most significant bit.
         *
         * 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
         +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
         |                      ID                       |
         +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
         |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
         +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
         |                    QDCOUNT                    |
         +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
         |                    ANCOUNT                    |
         +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
         |                    NSCOUNT                    |
         +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
         |                    ARCOUNT                    |
         +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
         */
        public static byte[] EncodeHeader(DnsMessage message)
        {
            MemoryStream stream = new MemoryStream(12);
            BinaryWriter writer = new BinaryWriter(stream);

            WriteUInt16BE(writer, message.ID);

            int fields = (int)message.ResponseCode;

            if (message.IsRecursionAvailable)
            {
                fields |= 0x80;
            }
            if (message.IsRecursionDesired)
            {
                fields |= 0x100;
            }
            if (message.IsTruncated)
            {
                fields |= 0x200;
            }
            if (message.IsRecursionAvailable)
            {
                fields |= 0x400;
            }

            fields |= (int)message.QueryKind << 11; //Opcode

            if (message.Type == MessageType.Response)
            {
                fields |= 0x8000;
            }

            WriteUInt16BE(writer, (UInt16)fields);
            WriteUInt16BE(writer, (UInt16)message.Querys.Count);
            WriteUInt16BE(writer, (UInt16)message.Answers.Count);
            WriteUInt16BE(writer, (UInt16)message.AuthorityRecords.Count);
            WriteUInt16BE(writer, (UInt16)message.AdditionalRecords.Count);

            return(stream.ToArray());
        }
Beispiel #3
0
        /*
         * Header Structure, the bit labeled 0 is the most significant bit.
          
          0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
         +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
         |                      ID                       |
         +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
         |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
         +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
         |                    QDCOUNT                    |
         +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
         |                    ANCOUNT                    |
         +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
         |                    NSCOUNT                    |
         +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
         |                    ARCOUNT                    |
         +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
        */
        public static byte[] EncodeHeader(DnsMessage message)
        {
            MemoryStream stream = new MemoryStream(12);
            BinaryWriter writer = new BinaryWriter(stream);

            WriteUInt16BE(writer, message.ID);

            int fields = (int)message.ResponseCode;
            if (message.IsRecursionAvailable)
            {
                fields |= 0x80;
            }
            if (message.IsRecursionDesired)
            {
                fields |= 0x100;
            }
            if (message.IsTruncated)
            {
                fields |= 0x200;
            }
            if (message.IsRecursionAvailable)
            {
                fields |= 0x400;
            }

            fields |= (int)message.QueryKind << 11; //Opcode

            if (message.Type == MessageType.Response)
            {
                fields |= 0x8000;
            }

            WriteUInt16BE(writer, (UInt16)fields);
            WriteUInt16BE(writer, (UInt16)message.Querys.Count);
            WriteUInt16BE(writer, (UInt16)message.Answers.Count);
            WriteUInt16BE(writer, (UInt16)message.AuthorityRecords.Count);
            WriteUInt16BE(writer, (UInt16)message.AdditionalRecords.Count);

            return stream.ToArray();
        }
Beispiel #4
0
        public static DnsMessage DecodeDnsMessage(byte[] msgData)
        {
            DnsMessage message = new DnsMessage();

            message.ID           = (UInt16)(msgData[0] << 8 | msgData[1]);
            message.Type         = (MessageType)(msgData[2] >> 7);
            message.QueryKind    = (QueryKind)((msgData[2] >> 3) & 15);
            message.ResponseCode = (ResponseCode)(msgData[3] & 15);

            MemoryStream stream = new MemoryStream(msgData);

            stream.Position = 4;
            BinaryReader reader = new BinaryReader(stream);

            int queryCount  = ReadUInt16BE(reader);
            int answerCount = ReadUInt16BE(reader);
            int nsCount     = ReadUInt16BE(reader);
            int arCount     = ReadUInt16BE(reader);

            for (int i = 0; i < queryCount; i++)
            {
                message.Querys.Add(ReadDnsQuery(reader));
            }
            for (int i = 0; i < answerCount; i++)
            {
                message.Answers.Add(ReadResourceRecord(reader));
            }
            for (int i = 0; i < nsCount; i++)
            {
                message.AuthorityRecords.Add(ReadResourceRecord(reader));
            }
            for (int i = 0; i < arCount; i++)
            {
                message.AdditionalRecords.Add(ReadResourceRecord(reader));
            }

            return(message);
        }
Beispiel #5
0
        public static DnsMessage DecodeDnsMessage(byte[] msgData)
        {
            DnsMessage message = new DnsMessage();
            message.ID = (UInt16)(msgData[0] << 8 | msgData[1]);
            message.Type = (MessageType)(msgData[2] >> 7);
            message.QueryKind = (QueryKind)((msgData[2] >> 3) & 15);
            message.ResponseCode = (ResponseCode)(msgData[3] & 15);

            MemoryStream stream = new MemoryStream(msgData);
            stream.Position = 4;
            BinaryReader reader = new BinaryReader(stream);

            int queryCount = ReadUInt16BE(reader);
            int answerCount = ReadUInt16BE(reader);
            int nsCount = ReadUInt16BE(reader);
            int arCount = ReadUInt16BE(reader);

            for (int i = 0; i < queryCount; i++)
            {
                message.Querys.Add(ReadDnsQuery(reader));
            }
            for (int i = 0; i < answerCount; i++)
            {
                message.Answers.Add(ReadResourceRecord(reader));
            }
            for (int i = 0; i < nsCount; i++)
            {
                message.AuthorityRecords.Add(ReadResourceRecord(reader));
            }
            for (int i = 0; i < arCount; i++)
            {
                message.AdditionalRecords.Add(ReadResourceRecord(reader));
            }

            return message;
        }
Beispiel #6
0
 private static IPAddress[] GetAddressList(DnsMessage answer, List<string> authorities)
 {
     List<IPAddress> serverAddresses = new List<IPAddress>();
     foreach (DnsResource resource in answer.AdditionalRecords)
     {
         if (resource.QueryType == QueryType.Address)
         {
             if (authorities.Contains(resource.Name))
             {
                 IPAddress serverIP = new IPAddress((byte[])resource.Content);
                 serverAddresses.Add(serverIP);
             }
         }
     }
     return serverAddresses.ToArray();
 }
Beispiel #7
0
 private static IPAddress[] GetAuthorityServers(DnsMessage answer)
 {
     List<string> authorities = new List<string>();
     foreach (DnsResource resource in answer.AuthorityRecords)
     {
         if (resource.QueryType == QueryType.NameServer)
         {
             string nameServer = (string)resource.Content;
             authorities.Add(nameServer);
         }
     }
     if (answer.AdditionalRecords.Count > 0)
     {
         return GetAddressList(answer, authorities);
     }
     else
     {
         List<IPAddress> serverAddresses = new List<IPAddress>();
         foreach (string authority in authorities)
         {
             serverAddresses.AddRange(System.Net.Dns.GetHostAddresses(authority));
         }
         return serverAddresses.ToArray();
     }
 }
Beispiel #8
0
 private static string[] GetMailExchangeAliases(string domainName, DnsMessage answer)
 {
     List<string> aliases = new List<string>();
     foreach (DnsResource resource in answer.Answers)
     {
         if (resource.QueryType == QueryType.MailExchange && resource.Name == domainName)
         {
             MailExchange mailExchange = (MailExchange)resource.Content;
             aliases.Add(mailExchange.HostName);
         }
     }
     return aliases.ToArray();
 }
Beispiel #9
0
 private static IPAddress[] GetAddressList(string domainName, DnsMessage answer)
 {
     List<IPAddress> addresseList = new List<IPAddress>();
     foreach (DnsResource resource in answer.Answers)
     {
         if (resource.QueryType == QueryType.Address && resource.Name == domainName)
         {
             IPAddress ipAddress = new IPAddress((byte[])resource.Content);
             addresseList.Add(ipAddress);
         }
     }
     return addresseList.ToArray();
 }
Beispiel #10
0
 public static DnsMessage InverseQuery()
 {
     DnsMessage message = new DnsMessage();
     message.ID = GenerateID();
     message.Type = MessageType.Query;
     message.QueryKind = QueryKind.InverseQuery;
     return message;
 }
Beispiel #11
0
 public static DnsMessage StandardQuery()
 {
     DnsMessage message = new DnsMessage();
     message.ID = GenerateID();
     message.Type = MessageType.Query;
     message.QueryKind = QueryKind.StandardQuery;
     return message;
 }