243 lines
10 KiB
C#
243 lines
10 KiB
C#
/**********************************************************************
|
|
* Copyright (c) 2010, j. montgomery *
|
|
* All rights reserved. *
|
|
* *
|
|
* Redistribution and use in source and binary forms, with or without *
|
|
* modification, are permitted provided that the following conditions *
|
|
* are met: *
|
|
* *
|
|
* + Redistributions of source code must retain the above copyright *
|
|
* notice, this list of conditions and the following disclaimer. *
|
|
* *
|
|
* + Redistributions in binary form must reproduce the above copyright*
|
|
* notice, this list of conditions and the following disclaimer *
|
|
* in the documentation and/or other materials provided with the *
|
|
* distribution. *
|
|
* *
|
|
* + Neither the name of j. montgomery's employer nor the names of *
|
|
* its contributors may be used to endorse or promote products *
|
|
* derived from this software without specific prior written *
|
|
* permission. *
|
|
* *
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS*
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *
|
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,*
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR *
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,*
|
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) *
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED*
|
|
* OF THE POSSIBILITY OF SUCH DAMAGE. *
|
|
**********************************************************************/
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.IO;
|
|
using System.Net;
|
|
|
|
using DnDns.Enums;
|
|
|
|
namespace DnDns.Records
|
|
{
|
|
/// <summary>
|
|
/// The DnsRecordHeader class contains fields, properties and
|
|
/// parsing cababilities within the DNS Record except the the
|
|
/// RDATA. The Name, Type, Class, TTL, and RDLength.
|
|
///
|
|
/// This class is used in the DnsRecordFactory to instantiate
|
|
/// concrete DnsRecord Classes.
|
|
///
|
|
/// RFC 1035
|
|
///
|
|
/// 3.2.1. Format
|
|
///
|
|
/// All RRs have the same top level format shown below:
|
|
///
|
|
/// 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 |
|
|
/// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
|
|
///
|
|
/// where:
|
|
///
|
|
/// NAME an owner name, i.e., the name of the node to which this
|
|
/// resource record pertains.
|
|
///
|
|
/// TYPE two octets containing one of the RR TYPE codes.
|
|
///
|
|
/// CLASS two octets containing one of the RR CLASS codes.
|
|
///
|
|
/// TTL a 32 bit signed integer that specifies the time interval
|
|
/// that the resource record may be cached before the source
|
|
/// of the information should again be consulted. Zero
|
|
/// values are interpreted to mean that the RR can only be
|
|
/// used for the transaction in progress, and should not be
|
|
/// cached. For example, SOA records are always distributed
|
|
/// with a zero TTL to prohibit caching. Zero values can
|
|
/// also be used for extremely volatile data.
|
|
///
|
|
/// RDLENGTH an unsigned 16 bit integer that specifies the length in
|
|
/// octets of the RDATA field.
|
|
///
|
|
/// </summary>
|
|
public class RecordHeader
|
|
{
|
|
#region Fields
|
|
// NAME an owner name, i.e., the name of the node to which this
|
|
// resource record pertains.
|
|
private string _name;
|
|
// TYPE two octets containing one of the RR TYPE codes.
|
|
private NsType _nsType;
|
|
// CLASS - two octets containing one of the RR CLASS codes.
|
|
private NsClass _nsClass;
|
|
// TTL - a 32 bit signed integer that specifies the time interval
|
|
// that the resource record may be cached before the source
|
|
// of the information should again be consulted. Zero
|
|
// values are interpreted to mean that the RR can only be
|
|
// used for the transaction in progress, and should not be
|
|
// cached. For example, SOA records are always distributed
|
|
// with a zero TTL to prohibit caching. Zero values can
|
|
/// also be used for extremely volatile data.
|
|
private int _timeToLive;
|
|
// RDLENGTH - an unsigned 16 bit integer that specifies the length in
|
|
// octets of the RDATA field.
|
|
private short _dataLength;
|
|
|
|
/// <summary>
|
|
/// Initalise the <see cref="RecordHeader"/>
|
|
/// </summary>
|
|
/// <param name="name">The header name</param>
|
|
/// <param name="nsType">The resource type</param>
|
|
/// <param name="nsClass">The class type</param>
|
|
/// <param name="timeToLive">The time to live</param>
|
|
public RecordHeader(string name, NsType nsType, NsClass nsClass, int timeToLive)
|
|
{
|
|
_name = name;
|
|
_nsType = nsType;
|
|
_nsClass = nsClass;
|
|
_timeToLive = timeToLive;
|
|
}
|
|
|
|
public RecordHeader()
|
|
{
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
/// <summary>
|
|
/// NAME - an owner name, i.e., the name of the node to which this
|
|
/// resource record pertains.
|
|
/// </summary>
|
|
public string Name
|
|
{
|
|
get { return _name; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// TYPE two octets containing one of the RR TYPE codes.
|
|
/// </summary>
|
|
public NsType NsType
|
|
{
|
|
get { return _nsType; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// CLASS - two octets containing one of the RR CLASS codes.
|
|
/// </summary>
|
|
public NsClass NsClass
|
|
{
|
|
get { return _nsClass; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// TTL - a 32 bit signed integer that specifies the time interval
|
|
/// that the resource record may be cached before the source
|
|
/// of the information should again be consulted. Zero
|
|
/// values are interpreted to mean that the RR can only be
|
|
/// used for the transaction in progress, and should not be
|
|
/// cached. For example, SOA records are always distributed
|
|
/// with a zero TTL to prohibit caching. Zero values can
|
|
/// also be used for extremely volatile data.
|
|
/// </summary>
|
|
public int TimeToLive
|
|
{
|
|
get { return _timeToLive; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// RDLENGTH - an unsigned 16 bit integer that specifies the length in
|
|
/// octets of the RDATA field.
|
|
/// </summary>
|
|
public short DataLength
|
|
{
|
|
get { return _dataLength; }
|
|
}
|
|
#endregion
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="ms"></param>
|
|
public void ParseRecordHeader(ref MemoryStream ms)
|
|
{
|
|
byte[] nsType = new byte[2];
|
|
byte[] nsClass = new byte[2];
|
|
byte[] nsTTL = new byte[4];
|
|
byte[] nsDataLength = new byte[2];
|
|
|
|
// Read the name
|
|
_name = DnsRecordBase.ParseName(ref ms);
|
|
|
|
// Read the data header
|
|
ms.Read(nsType, 0, 2);
|
|
ms.Read(nsClass, 0, 2);
|
|
ms.Read(nsTTL, 0, 4);
|
|
ms.Read(nsDataLength, 0, 2);
|
|
_nsType = (NsType)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsType, 0));
|
|
_nsClass = (NsClass)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsClass, 0));
|
|
|
|
_timeToLive = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(nsTTL, 0));
|
|
_dataLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsDataLength, 0));
|
|
}
|
|
|
|
internal byte[] GetMessageBytes()
|
|
{
|
|
MemoryStream memoryStream = new MemoryStream();
|
|
|
|
byte[] data = DnsHelpers.CanonicaliseDnsName(_name, false);
|
|
memoryStream.Write(data,0,data.Length);
|
|
|
|
data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)_nsType) >> 16));
|
|
memoryStream.Write(data, 0, data.Length);
|
|
|
|
data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)_nsClass) >> 16));
|
|
memoryStream.Write(data, 0, data.Length);
|
|
|
|
data = BitConverter.GetBytes((uint)(IPAddress.HostToNetworkOrder((ushort)_timeToLive) >> 32));
|
|
memoryStream.Write(data, 0, data.Length);
|
|
|
|
data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)_dataLength) >> 16));
|
|
memoryStream.Write(data, 0, data.Length);
|
|
|
|
return memoryStream.ToArray();
|
|
}
|
|
}
|
|
}
|