/// <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(); }
// these fields constitute an SOA RR /// <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 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> /// 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(); Type = (DnsType)pointer.ReadShort(); Class = (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> /// 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> /// Reads a domain name from the byte array. The method by which this works is described /// in RFC1035 - 4.1.4. Essentially to minimise the size of the message, if part of a domain /// name already been seen in the message, rather than repeating it, a pointer to the existing /// definition is used. Each word in a domain name is a label, and is preceded by its length /// /// eg. bigdevelopments.co.uk /// /// is [15] (size of bigdevelopments) + "bigdevelopments" /// [2] "co" /// [2] "uk" /// [1] 0 (NULL) /// </summary> /// <returns>the byte at the pointer</returns> public string ReadDomain() { var domain = new StringBuilder(); int length; // get the length of the first label while ((length = ReadByte()) != 0) { // top 2 bits set denotes domain name compression and to reference elsewhere if ((length & 0xc0) == 0xc0) { // work out the existing domain name, copy this pointer Pointer newPointer = Copy(); // and move it to where specified here newPointer.SetPosition((length & 0x3f) << 8 | ReadByte()); // repeat call recursively domain.Append(newPointer.ReadDomain()); return(domain.ToString()); } // if not using compression, copy a char at a time to the domain name while (length > 0) { domain.Append(ReadChar()); length--; } // if size of next label isn't null (end of domain name) add a period ready for next label if (Peek() != 0) { domain.Append('.'); } } // and return return(domain.ToString()); }
/// <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> /// 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(); }
// the fields exposed outside the assembly // expose this domain name address r/o to the world /// <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(); }