You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
3.7 KiB
125 lines
3.7 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net;
|
|
using System.Text;
|
|
using Ubiety.Dns.Core.Common;
|
|
|
|
namespace Ubiety.Dns.Core
|
|
{
|
|
/// <summary>
|
|
/// DNS Question record
|
|
/// </summary>
|
|
public class Question
|
|
{
|
|
private string _questionName;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="Question" /> class
|
|
/// </summary>
|
|
/// <param name="questionName">Query name</param>
|
|
/// <param name="questionType">Question type</param>
|
|
/// <param name="questionClass">Question class</param>
|
|
public Question(string questionName, QuestionType questionType, QuestionClass questionClass)
|
|
{
|
|
QuestionName = questionName;
|
|
QuestionType = questionType;
|
|
QuestionClass = questionClass;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="Question" /> class
|
|
/// </summary>
|
|
/// <param name="rr"><see cref="RecordReader" /> of the record</param>
|
|
public Question(RecordReader rr)
|
|
{
|
|
QuestionName = rr.ReadDomainName();
|
|
QuestionType = (QuestionType)rr.ReadUInt16();
|
|
QuestionClass = (QuestionClass)rr.ReadUInt16();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the question name
|
|
/// </summary>
|
|
public String QuestionName
|
|
{
|
|
get => _questionName;
|
|
|
|
private set
|
|
{
|
|
_questionName = value;
|
|
if (!_questionName.EndsWith(".", StringComparison.InvariantCulture))
|
|
{
|
|
_questionName += ".";
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the query type
|
|
/// </summary>
|
|
public QuestionType QuestionType { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the query class
|
|
/// </summary>
|
|
public QuestionClass QuestionClass { get; }
|
|
|
|
/// <summary>
|
|
/// String representation of the question
|
|
/// </summary>
|
|
/// <returns>String of the question</returns>
|
|
public override String ToString()
|
|
{
|
|
return $"{QuestionName, -32}\t{QuestionClass}\t{QuestionType}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the question as a byte array
|
|
/// </summary>
|
|
/// <returns>Byte array of the question data</returns>
|
|
public IEnumerable<Byte> GetData()
|
|
{
|
|
var data = new List<Byte>();
|
|
data.AddRange(WriteName(QuestionName));
|
|
data.AddRange(WriteShort((UInt16)QuestionType));
|
|
data.AddRange(WriteShort((UInt16)QuestionClass));
|
|
return data.ToArray();
|
|
}
|
|
|
|
private static IEnumerable<Byte> WriteName(String src)
|
|
{
|
|
if (!src.EndsWith(".", StringComparison.InvariantCulture))
|
|
{
|
|
src += ".";
|
|
}
|
|
|
|
if (src == ".")
|
|
{
|
|
return new Byte[1];
|
|
}
|
|
|
|
var sb = new StringBuilder();
|
|
Int32 intI, intJ, intLen = src.Length;
|
|
sb.Append('\0');
|
|
for (intI = 0, intJ = 0; intI < intLen; intI++, intJ++)
|
|
{
|
|
sb.Append(src[intI]);
|
|
if (src[intI] != '.')
|
|
{
|
|
continue;
|
|
}
|
|
|
|
sb[intI - intJ] = (Char)(intJ & 0xff);
|
|
intJ = -1;
|
|
}
|
|
|
|
sb[sb.Length - 1] = '\0';
|
|
return Encoding.ASCII.GetBytes(sb.ToString());
|
|
}
|
|
|
|
private static Byte[] WriteShort(UInt16 value)
|
|
{
|
|
return BitConverter.GetBytes(IPAddress.HostToNetworkOrder((Int16)value));
|
|
}
|
|
}
|
|
}
|