/// <summary>
 /// Construct the question reading from a DNS Server response. Consult RFC1035 4.1.2
 /// for byte-wise details of this structure in byte array form
 /// </summary>
 /// <param name="pointer">a logical pointer to the Question in byte array form</param>
 internal Question(Pointer pointer)
 {
     // extract from the message
     _domain = pointer.ReadDomain();
     _dnsType = (DnsType)pointer.ReadShort();
     _dnsClass = (DnsClass)pointer.ReadShort();
 }
		/// <summary>
		/// Construct a resource record from a pointer to a byte array
		/// </summary>
		/// <param name="pointer">the position in the byte array of the record</param>
		internal ResourceRecord(Pointer pointer) {
			// extract the domain, question type, question class and Ttl
			_domain = pointer.ReadDomain();
			_dnsType = (DnsType)pointer.ReadShort();
			_dnsClass = (DnsClass)pointer.ReadShort();
			_Ttl = pointer.ReadInt();

			// the next short is the record length, we only use it for unrecognised record types
			int recordLength = pointer.ReadShort();

			// and create the appropriate RDATA record based on the dnsType
			switch(_dnsType) {
				case DnsType.NS:
					_record = new NSRecord(pointer);
					break;
				case DnsType.MX:
					_record = new MXRecord(pointer);
					break;
				case DnsType.ANAME:
					_record = new ANameRecord(pointer);
					break;
				case DnsType.SOA:
					_record = new SoaRecord(pointer);
					break;
				default:
					{
						// move the pointer over this unrecognised record
						pointer += recordLength;
						break;
					}
			}
		}
		/// <summary>
		/// Constructs an ANAME record by reading bytes from a return message
		/// </summary>
		/// <param name="pointer">A logical pointer to the bytes holding the record</param>
		internal ANameRecord(Pointer pointer) {
			byte b1 = pointer.ReadByte();
			byte b2 = pointer.ReadByte();
			byte b3 = pointer.ReadByte();
			byte b4 = pointer.ReadByte();

			// this next line's not brilliant - couldn't find a better way though
			_ipAddress = IPAddress.Parse(string.Format("{0}.{1}.{2}.{3}", b1, b2, b3, b4));
		}
		/// <summary>
		/// Constructs an SOA record by reading bytes from a return message
		/// </summary>
		/// <param name="pointer">A logical pointer to the bytes holding the record</param>
		internal SoaRecord(Pointer pointer) {
			// read all fields RFC1035 3.3.13
			_primaryNameServer = pointer.ReadDomain();
			_responsibleMailAddress = pointer.ReadDomain();
			_serial = pointer.ReadInt();
			_refresh = pointer.ReadInt();
			_retry = pointer.ReadInt();
			_expire = pointer.ReadInt();
			_defaultTtl = pointer.ReadInt();
		}
        /// <summary>
        /// Construct a Response object from the supplied byte array
        /// </summary>
        /// <param name="message">a byte array returned from a DNS server query</param>
        internal Response(byte[] message)
        {
            // the bit flags are in bytes 2 and 3
            byte flags1 = message[2];
            byte flags2 = message[3];

            // get return code from lowest 4 bits of byte 3
            int returnCode = flags2 & 15;

            // if its in the reserved section, set to other
            if (returnCode > 6) returnCode = 6;
            _returnCode = (ReturnCode)returnCode;

            // other bit flags
            _authoritativeAnswer = ((flags1 & 4) != 0);
            _recursionAvailable = ((flags2 & 128) != 0);
            _truncated = ((flags1 & 2) != 0);

            // create the arrays of response objects
            _questions = new Question[GetShort(message, 4)];
            _answers = new Answer[GetShort(message, 6)];
            _nameServers = new NameServer[GetShort(message, 8)];
            _additionalRecords = new AdditionalRecord[GetShort(message, 10)];

            // need a pointer to do this, position just after the header
            Pointer pointer = new Pointer(message, 12);

            // and now populate them, they always follow this order
            for (int index = 0; index < _questions.Length; index++)
            {
                try
                {
                    // try to build a quesion from the response
                    _questions[index] = new Question(pointer);
                }
                catch (Exception ex)
                {
                    Terminals.Logging.Error("DNS Response Question Failure", ex);
                    // something grim has happened, we can't continue
                    throw new InvalidResponseException(ex);
                }
            }
            for (int index = 0; index < _answers.Length; index++)
            {
                _answers[index] = new Answer(pointer);
            }
            for (int index = 0; index < _nameServers.Length; index++)
            {
                _nameServers[index] = new NameServer(pointer);
            }
            for (int index = 0; index < _additionalRecords.Length; index++)
            {
                _additionalRecords[index] = new AdditionalRecord(pointer);
            }
        }
Exemple #6
0
 /// <summary>
 /// Constructs a NS record by reading bytes from a return message
 /// </summary>
 /// <param name="pointer">A logical pointer to the bytes holding the record</param>
 internal NSRecord(Pointer pointer)
 {
     _domainName = pointer.ReadDomain();
 }
        /// <summary>
        /// Construct a Response object from the supplied byte array
        /// </summary>
        /// <param name="message">a byte array returned from a DNS server query</param>
        internal Response(byte[] message)
        {
            if (message == null) throw new ArgumentNullException("message");

            // the bit flags are in bytes 2 and 3
            byte flags1 = message[2];
            byte flags2 = message[3];

            // get return code from lowest 4 bits of byte 3
            int returnCode = flags2 & 15;

            // if its in the reserved section, set to other
            if (returnCode > 6) returnCode = 6;
            _returnCode = (ReturnCode) returnCode;

            // other bit flags
            _authoritativeAnswer = ((flags1 & 4) != 0);
            _recursionAvailable = ((flags2 & 128) != 0);
            _messageTruncated = ((flags1 & 2) != 0);

            // create the arrays of response objects
            _questions = new Question[GetShort(message, 4)];
            _answers = new Answer[GetShort(message, 6)];
            _nameServers = new NameServer[GetShort(message, 8)];
            _additionalRecords = new AdditionalRecord[GetShort(message, 10)];

            // need a pointer to do this, position just after the header
            var pointer = new Pointer(message, 12);

            ReadQuestions(pointer);
            ReadAnswers(pointer);
            ReadNameServers(pointer);
            ReadAdditionalRecords(pointer);
        }
 private void ReadAdditionalRecords(Pointer pointer)
 {
     for (int index = 0; index < _additionalRecords.Length; index++)
     {
         _additionalRecords[index] = new AdditionalRecord(pointer);
     }
 }
 private void ReadNameServers(Pointer pointer)
 {
     for (int index = 0; index < _nameServers.Length; index++)
     {
         _nameServers[index] = new NameServer(pointer);
     }
 }
 private void ReadAnswers(Pointer pointer)
 {
     for (int index = 0; index < _answers.Length; index++)
     {
         _answers[index] = new Answer(pointer);
     }
 }
 internal NameServer(Pointer pointer) : base(pointer)
 {
 }
		internal NameServer(Pointer pointer) : base(pointer) {
		}
 /// <summary>
 /// Constructs an MX record by reading bytes from a return message
 /// </summary>
 /// <param name="pointer">A logical pointer to the bytes holding the record</param>
 internal MXRecord(Pointer pointer)
 {
     _preference = pointer.ReadShort();
     _domainName = pointer.ReadDomain();
 }
Exemple #14
0
 /// <summary>
 /// Constructs a NS record by reading bytes from a return message
 /// </summary>
 /// <param name="pointer">A logical pointer to the bytes holding the record</param>
 internal NSRecord(Pointer pointer)
 {
     _domainName = pointer.ReadDomain();
 }
 internal AdditionalRecord(Pointer pointer) : base(pointer)
 {
 }
		internal Answer(Pointer pointer) : base(pointer) {
		}
 private void ReadQuestions(Pointer pointer)
 {
     for (int index = 0; index < _questions.Length; index++)
     {
         try
         {
             // try to build a quesion from the response
             _questions[index] = new Question(pointer);
         }
         catch (Exception ex)
         {
             // something grim has happened, we can't continue
             throw new InvalidResponseException(ex);
         }
     }
 }
		internal AdditionalRecord(Pointer pointer) : base(pointer) {
		}
 internal Answer(Pointer pointer) : base(pointer)
 {
 }