231 lines
4.3 KiB
C#
231 lines
4.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using skyscraper5.DNS.Protocol.Utils;
|
|
|
|
namespace skyscraper5.DNS.Protocol
|
|
{
|
|
[Marshalling.Endian(Marshalling.Endianness.Big)]
|
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
public struct Header
|
|
{
|
|
public const int SIZE = 12;
|
|
|
|
public static Header FromArray(byte[] header)
|
|
{
|
|
if (header.Length < SIZE)
|
|
{
|
|
Header dummy = new Header();
|
|
dummy.Response = false;
|
|
return dummy;
|
|
}
|
|
|
|
return Marshalling.Struct.GetStruct<Header>(header, 0, SIZE);
|
|
}
|
|
|
|
private ushort id;
|
|
|
|
private byte flag0;
|
|
private byte flag1;
|
|
|
|
// Question count: number of questions in the Question section
|
|
private ushort qdCount;
|
|
|
|
// Answer record count: number of records in the Answer section
|
|
private ushort anCount;
|
|
|
|
// Authority record count: number of records in the Authority section
|
|
private ushort nsCount;
|
|
|
|
// Additional record count: number of records in the Additional section
|
|
private ushort arCount;
|
|
|
|
public int Id
|
|
{
|
|
get { return id; }
|
|
set { id = (ushort)value; }
|
|
}
|
|
|
|
public int QuestionCount
|
|
{
|
|
get { return qdCount; }
|
|
set { qdCount = (ushort)value; }
|
|
}
|
|
|
|
public int AnswerRecordCount
|
|
{
|
|
get { return anCount; }
|
|
set { anCount = (ushort)value; }
|
|
}
|
|
|
|
public int AuthorityRecordCount
|
|
{
|
|
get { return nsCount; }
|
|
set { nsCount = (ushort)value; }
|
|
}
|
|
|
|
public int AdditionalRecordCount
|
|
{
|
|
get { return arCount; }
|
|
set { arCount = (ushort)value; }
|
|
}
|
|
|
|
public bool Response
|
|
{
|
|
get { return Qr == 1; }
|
|
set { Qr = Convert.ToByte(value); }
|
|
}
|
|
|
|
public OperationCode OperationCode
|
|
{
|
|
get { return (OperationCode)Opcode; }
|
|
set { Opcode = (byte)value; }
|
|
}
|
|
|
|
public bool AuthorativeServer
|
|
{
|
|
get { return Aa == 1; }
|
|
set { Aa = Convert.ToByte(value); }
|
|
}
|
|
|
|
public bool Truncated
|
|
{
|
|
get { return Tc == 1; }
|
|
set { Tc = Convert.ToByte(value); }
|
|
}
|
|
|
|
public bool RecursionDesired
|
|
{
|
|
get { return Rd == 1; }
|
|
set { Rd = Convert.ToByte(value); }
|
|
}
|
|
|
|
public bool RecursionAvailable
|
|
{
|
|
get { return Ra == 1; }
|
|
set { Ra = Convert.ToByte(value); }
|
|
}
|
|
|
|
public bool AuthenticData
|
|
{
|
|
get { return Ad == 1; }
|
|
set { Ad = Convert.ToByte(value); }
|
|
}
|
|
|
|
public bool CheckingDisabled
|
|
{
|
|
get { return Cd == 1; }
|
|
set { Cd = Convert.ToByte(value); }
|
|
}
|
|
|
|
public ResponseCode ResponseCode
|
|
{
|
|
get { return (ResponseCode)RCode; }
|
|
set { RCode = (byte)value; }
|
|
}
|
|
|
|
public int Size
|
|
{
|
|
get { return Header.SIZE; }
|
|
}
|
|
|
|
public byte[] ToArray()
|
|
{
|
|
return Marshalling.Struct.GetBytes(this);
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return ObjectStringifier.New(this)
|
|
.AddAll()
|
|
.Remove(nameof(Size))
|
|
.ToString();
|
|
}
|
|
|
|
// Query/Response Flag
|
|
private byte Qr
|
|
{
|
|
get { return Flag0.GetBitValueAt(7, 1); }
|
|
set { Flag0 = Flag0.SetBitValueAt(7, 1, value); }
|
|
}
|
|
|
|
// Operation Code
|
|
private byte Opcode
|
|
{
|
|
get { return Flag0.GetBitValueAt(3, 4); }
|
|
set { Flag0 = Flag0.SetBitValueAt(3, 4, value); }
|
|
}
|
|
|
|
// Authorative Answer Flag
|
|
private byte Aa
|
|
{
|
|
get { return Flag0.GetBitValueAt(2, 1); }
|
|
set { Flag0 = Flag0.SetBitValueAt(2, 1, value); }
|
|
}
|
|
|
|
// Truncation Flag
|
|
private byte Tc
|
|
{
|
|
get { return Flag0.GetBitValueAt(1, 1); }
|
|
set { Flag0 = Flag0.SetBitValueAt(1, 1, value); }
|
|
}
|
|
|
|
// Recursion Desired
|
|
private byte Rd
|
|
{
|
|
get { return Flag0.GetBitValueAt(0, 1); }
|
|
set { Flag0 = Flag0.SetBitValueAt(0, 1, value); }
|
|
}
|
|
|
|
// Recursion Available
|
|
private byte Ra
|
|
{
|
|
get { return Flag1.GetBitValueAt(7, 1); }
|
|
set { Flag1 = Flag1.SetBitValueAt(7, 1, value); }
|
|
}
|
|
|
|
// Zero (Reserved)
|
|
private byte Z
|
|
{
|
|
get { return Flag1.GetBitValueAt(6, 1); }
|
|
set { }
|
|
}
|
|
|
|
// Authentic Data
|
|
private byte Ad
|
|
{
|
|
get { return Flag1.GetBitValueAt(5, 1); }
|
|
set { Flag1 = Flag1.SetBitValueAt(5, 1, value); }
|
|
}
|
|
|
|
// Checking Disabled
|
|
private byte Cd
|
|
{
|
|
get { return Flag1.GetBitValueAt(4, 1); }
|
|
set { Flag1 = Flag1.SetBitValueAt(4, 1, value); }
|
|
}
|
|
|
|
// Response Code
|
|
private byte RCode
|
|
{
|
|
get { return Flag1.GetBitValueAt(0, 4); }
|
|
set { Flag1 = Flag1.SetBitValueAt(0, 4, value); }
|
|
}
|
|
|
|
private byte Flag0
|
|
{
|
|
get { return flag0; }
|
|
set { flag0 = value; }
|
|
}
|
|
|
|
private byte Flag1
|
|
{
|
|
get { return flag1; }
|
|
set { flag1 = value; }
|
|
}
|
|
}
|
|
}
|