/* * Each resource record has the following format: * 1 1 1 1 1 1 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | | | / / | / NAME / | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | TYPE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | CLASS | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | TTL | | | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | RDLENGTH | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| | / RDATA / | / / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ */ //////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Encode DNS resource. </summary> /// /// <param name="record"> The record. </param> /// /// <returns> A byte[]. </returns> //////////////////////////////////////////////////////////////////////////////////////////////////// /// public static byte[] EncodeDnsResource(DnsResource record) { MemoryStream stream = new MemoryStream(); BinaryWriter writer = new BinaryWriter(stream); // Name string[] labels = record.Name.Split('.'); foreach (string label in labels) { writer.Write((byte)label.Length); writer.Write(Encoding.ASCII.GetBytes(label)); } writer.Write((byte)0); //TYPE WriteUInt16BE(writer, (UInt16)record.QueryType); //CLASS WriteUInt16BE(writer, (UInt16)record.QueryClass); //TTL WriteInt32BE(writer, record.TimeToLive); //RDLENGTH WriteUInt16BE(writer, record.DataLength); //RDATA writer.Write(record.Data); return(stream.ToArray()); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Reads resource record. </summary> /// /// <exception cref="Exception"> Thrown when an exception error condition occurs. </exception> /// /// <param name="reader"> The reader. </param> /// /// <returns> The resource record. </returns> //////////////////////////////////////////////////////////////////////////////////////////////////// public static DnsResource ReadResourceRecord(BinaryReader reader) { DnsResource record = new DnsResource(); record.Name = ReadDomainName(reader); record.QueryType = (QueryType)ReadUInt16BE(reader); record.QueryClass = (QueryClass)ReadUInt16BE(reader); record.TimeToLive = ReadUInt16BE(reader); record.DataLength = ReadUInt16BE(reader); long pos = reader.BaseStream.Position; DecodeRecordContent(record, reader); if (reader.BaseStream.Position != pos + record.DataLength) { throw new Exception("Error in decoding content of ResourceRecord"); } return(record); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Decode record content. </summary> /// /// <param name="record"> The record. </param> /// <param name="reader"> The reader. </param> //////////////////////////////////////////////////////////////////////////////////////////////////// private static void DecodeRecordContent(DnsResource record, BinaryReader reader) { switch (record.QueryType) { case QueryType.Address: record.Content = reader.ReadBytes(4); break; case QueryType.NameServer: case QueryType.CanonicalName: record.Content = ReadDomainName(reader); break; case QueryType.MailExchange: record.Content = ReadMailExchange(reader); break; default: record.Data = reader.ReadBytes(record.DataLength); break; } }