Commit cd46a194 authored by Brickner_cp's avatar Brickner_cp

DNS

parent 3dafb585
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using PcapDotNet.Base;
using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets
{
public class DataSegment : IEquatable<DataSegment>, IEnumerable<byte>
{
/// <summary>
/// Take all the bytes as a segment.
/// </summary>
/// <param name="buffer">The buffer to take as a segment.</param>
public DataSegment(byte[] buffer)
{
if (buffer == null)
throw new ArgumentNullException("buffer");
Buffer = buffer;
StartOffset = 0;
Length = buffer.Length;
}
/// <summary>
/// Take only part of the bytes as a segment.
/// </summary>
/// <param name="buffer">The bytes to take the segment from.</param>
/// <param name="offset">The offset in the buffer to start taking the bytes from.</param>
/// <param name="length">The number of bytes to take.</param>
public DataSegment(byte[] buffer, int offset, int length)
{
Buffer = buffer;
StartOffset = offset;
Length = length;
}
/// <summary>
/// The number of bytes in this segment.
/// </summary>
public int Length { get; private set; }
/// <summary>
/// The value of the byte in the given offset in the segment.
/// </summary>
/// <param name="offset">The offset in the segment to take the byte from.</param>
public byte this[int offset]
{
get { return Buffer[StartOffset + offset]; }
}
/// <summary>
/// Returns the Segment's bytes as a read only MemoryStream with a non-public buffer.
/// </summary>
/// <returns>A read only MemoryStream containing the bytes of the segment.</returns>
public MemoryStream ToMemoryStream()
{
return new MemoryStream(Buffer, StartOffset, Length, false, false);
}
/// <summary>
/// Iterate through all the bytes in the segment.
/// </summary>
public IEnumerator<byte> GetEnumerator()
{
for (int i = 0; i != Length; ++i)
yield return this[i];
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// Two segments are equal if they have the same data.
/// </summary>
public bool Equals(DataSegment other)
{
if (other == null || Length != other.Length)
return false;
for (int i = 0; i != Length; ++i)
{
if (this[i] != other[i])
return false;
}
return true;
}
/// <summary>
/// Two segments are equal if they have the same data.
/// </summary>
public override bool Equals(object obj)
{
return Equals(obj as DataSegment);
}
/// <summary>
/// The hash code of a segment is the hash code of its length xored with all its bytes (each byte is xored with the next byte in the integer).
/// </summary>
public override int GetHashCode()
{
return Length.GetHashCode() ^ this.BytesSequenceGetHashCode();
}
/// <summary>
/// Converts the segment to a hexadecimal string representing every bytes as two hexadecimal digits.
/// </summary>
/// <returns>A hexadecimal string representing every bytes as two hexadecimal digits.</returns>
public override string ToString()
{
return Buffer.Range(StartOffset, Length).BytesSequenceToHexadecimalString();
}
/// <summary>
/// Converts the segment to a string using the given encoding.
/// </summary>
/// <param name="encoding">The encoding to use to convert the bytes sequence in the segment to a string.</param>
/// <returns>A string of the bytes in the segment converted using the given encoding.</returns>
public string ToString(Encoding encoding)
{
if (encoding == null)
throw new ArgumentNullException("encoding");
return encoding.GetString(Buffer, StartOffset, Length);
}
internal void Write(byte[] buffer, int offset)
{
Buffer.BlockCopy(StartOffset, buffer, offset, Length);
}
/// <summary>
/// The original buffer that holds all the data for the segment.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
internal byte[] Buffer { get; private set; }
/// <summary>
/// The offset of the first byte of the segment in the buffer.
/// </summary>
internal int StartOffset { get; private set; }
/// <summary>
/// Reads a requested number of bytes from a specific offset in the segment.
/// </summary>
/// <param name="offset">The offset in the segment to start reading.</param>
/// <param name="length">The number of bytes to read.</param>
/// <returns>The bytes read from the segment starting from the given offset and in the given length.</returns>
protected byte[] ReadBytes(int offset, int length)
{
return Buffer.ReadBytes(StartOffset + offset, length);
}
internal bool ReadBool(int offset, byte mask)
{
return (this[offset] & mask) == mask;
}
/// <summary>
/// Reads 2 bytes from a specific offset in the segment as a ushort with a given endianity.
/// </summary>
/// <param name="offset">The offset in the segment to start reading.</param>
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <returns>The value converted from the read bytes according to the endianity.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "ushort")]
internal ushort ReadUShort(int offset, Endianity endianity)
{
return Buffer.ReadUShort(StartOffset + offset, endianity);
}
/// <summary>
/// Reads 4 bytes from a specific offset in the segment as an int with a given endianity.
/// </summary>
/// <param name="offset">The offset in the segment to start reading.</param>
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <returns>The value converted from the read bytes according to the endianity.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "int")]
protected int ReadInt(int offset, Endianity endianity)
{
return Buffer.ReadInt(StartOffset + offset, endianity);
}
/// <summary>
/// Reads 4 bytes from a specific offset in the segment as a uint with a given endianity.
/// </summary>
/// <param name="offset">The offset in the segment to start reading.</param>
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <returns>The value converted from the read bytes according to the endianity.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "uint")]
protected uint ReadUInt(int offset, Endianity endianity)
{
return Buffer.ReadUInt(StartOffset + offset, endianity);
}
/// <summary>
/// Reads 6 bytes from a specific offset in the segment as a MacAddress with a given endianity.
/// </summary>
/// <param name="offset">The offset in the segment to start reading.</param>
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <returns>The value converted from the read bytes according to the endianity.</returns>
protected MacAddress ReadMacAddress(int offset, Endianity endianity)
{
return Buffer.ReadMacAddress(StartOffset + offset, endianity);
}
/// <summary>
/// Reads 4 bytes from a specific offset in the segment as an IpV4Address with a given endianity.
/// </summary>
/// <param name="offset">The offset in the segment to start reading.</param>
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <returns>The value converted from the read bytes according to the endianity.</returns>
protected IpV4Address ReadIpV4Address(int offset, Endianity endianity)
{
return Buffer.ReadIpV4Address(StartOffset + offset, endianity);
}
/// <summary>
/// Reads 4 bytes from a specific offset in the segment as an IpV4TimeOfDay with a given endianity.
/// </summary>
/// <param name="offset">The offset in the segment to start reading.</param>
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <returns>The value converted from the read bytes according to the endianity.</returns>
protected IpV4TimeOfDay ReadIpV4TimeOfDay(int offset, Endianity endianity)
{
return Buffer.ReadIpV4TimeOfDay(StartOffset + offset, endianity);
}
/// <summary>
/// Converts the given 16 bits sum to a checksum.
/// Sums the two 16 bits in the 32 bits value and if the result is bigger than a 16 bits value repeat.
/// The result is one's complemented and the least significant 16 bits are taken.
/// </summary>
/// <param name="sum"></param>
/// <returns></returns>
protected static ushort Sum16BitsToChecksum(uint sum)
{
// Take only 16 bits out of the 32 bit sum and add up the carrier.
// if the results overflows - do it again.
while (sum > 0xFFFF)
sum = (sum & 0xFFFF) + (sum >> 16);
// one's complement the result
sum = ~sum;
return (ushort)sum;
}
/// <summary>
/// Sums bytes in a buffer as 16 bits big endian values.
/// If the number of bytes is odd then a 0x00 value is assumed after the last byte.
/// Used to calculate checksum.
/// </summary>
/// <param name="buffer">The buffer to take the bytes from.</param>
/// <param name="offset">The offset in the buffer to start reading the bytes.</param>
/// <param name="length">The number of bytes to read.</param>
/// <returns>A value equals to the sum of all 16 bits big endian values of the given bytes.</returns>
protected static uint Sum16Bits(byte[] buffer, int offset, int length)
{
if (buffer == null)
throw new ArgumentNullException("buffer");
int endOffset = offset + length;
uint sum = 0;
while (offset < endOffset - 1)
sum += buffer.ReadUShort(ref offset, Endianity.Big);
if (offset < endOffset)
sum += (ushort)(buffer[offset] << 8);
return sum;
}
}
}
\ No newline at end of file
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using PcapDotNet.Base;
using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets
{
......@@ -14,33 +7,26 @@ namespace PcapDotNet.Packets
/// A datagram is part of the packet bytes that can be treated as a specific protocol data (usually header + payload).
/// Never copies the given buffer.
/// </summary>
public class Datagram : IEquatable<Datagram>, IEnumerable<byte>
public class Datagram : DataSegment, IEquatable<Datagram>
{
/// <summary>
/// Take all the bytes as a datagram.
/// </summary>
/// <param name="buffer">The buffer to take as a datagram.</param>
public Datagram(byte[] buffer)
: base(buffer)
{
if (buffer == null)
throw new ArgumentNullException("buffer");
Buffer = buffer;
StartOffset = 0;
Length = buffer.Length;
}
/// <summary>
/// Take only part of the bytes as a datagarm.
/// Take only part of the bytes as a datagram.
/// </summary>
/// <param name="buffer">The bytes to take the datagram from.</param>
/// <param name="offset">The offset in the buffer to start taking the bytes from.</param>
/// <param name="length">The number of bytes to take.</param>
public Datagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
Buffer = buffer;
StartOffset = offset;
Length = length;
}
/// <summary>
......@@ -52,29 +38,6 @@ namespace PcapDotNet.Packets
get { return _empty; }
}
/// <summary>
/// The number of bytes in this datagram.
/// </summary>
public int Length { get; private set; }
/// <summary>
/// The value of the byte in the given offset in the datagram.
/// </summary>
/// <param name="offset">The offset in the datagram to take the byte from.</param>
public byte this[int offset]
{
get { return Buffer[StartOffset + offset]; }
}
/// <summary>
/// Returns the Datagram's bytes as a read only MemoryStream with a non-public buffer.
/// </summary>
/// <returns>A read only MemoryStream containing the bytes of the Datagram.</returns>
public MemoryStream ToMemoryStream()
{
return new MemoryStream(Buffer, StartOffset, Length, false, false);
}
/// <summary>
/// A datagram is checked for validity according to the protocol.
/// </summary>
......@@ -100,90 +63,21 @@ namespace PcapDotNet.Packets
}
/// <summary>
/// Iterate through all the bytes in the datagram.
/// </summary>
public IEnumerator<byte> GetEnumerator()
{
for (int i = 0; i != Length; ++i)
yield return this[i];
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// Two datagrams are equal if the have the same data.
/// Two datagrams are equal if they have the same data.
/// </summary>
public bool Equals(Datagram other)
{
if (other == null || Length != other.Length)
return false;
for (int i = 0; i != Length; ++i)
{
if (this[i] != other[i])
return false;
}
return true;
return base.Equals(other);
}
/// <summary>
/// Two datagrams are equal if the have the same data.
/// Two datagrams are equal if they have the same data.
/// </summary>
public override bool Equals(object obj)
{
return Equals(obj as Datagram);
}
/// <summary>
/// The hash code of a datagram is the hash code of its length xored with all its bytes (each byte is xored with the next byte in the integer).
/// </summary>
public override int GetHashCode()
{
return Length.GetHashCode() ^ this.BytesSequenceGetHashCode();
}
/// <summary>
/// Converts the datagram to a hexadecimal string representing every bytes as two hexadecimal digits.
/// </summary>
/// <returns>A hexadecimal string representing every bytes as two hexadecimal digits.</returns>
public override string ToString()
{
return Buffer.Range(StartOffset, Length).BytesSequenceToHexadecimalString();
}
/// <summary>
/// Converts the datagram to a string using the given encoding.
/// </summary>
/// <param name="encoding">The encoding to use to convert the bytes sequence in the Datagram to a string.</param>
/// <returns>A string of the bytes in the Datagram converted using the given encoding.</returns>
public string ToString(Encoding encoding)
{
if (encoding == null)
throw new ArgumentNullException("encoding");
return encoding.GetString(Buffer, StartOffset, Length);
}
internal void Write(byte[] buffer, int offset)
{
Buffer.BlockCopy(StartOffset, buffer, offset, Length);
}
/// <summary>
/// The original buffer that holds all the data for the datagram.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
internal byte[] Buffer { get; private set; }
/// <summary>
/// The offset of the first byte of the datagram in the buffer.
/// </summary>
internal int StartOffset { get; private set; }
/// <summary>
/// The default validity check always returns true.
/// </summary>
......@@ -192,141 +86,7 @@ namespace PcapDotNet.Packets
return true;
}
/// <summary>
/// Reads a requested number of bytes from a specific offset in the datagram.
/// </summary>
/// <param name="offset">The offset in the datagram to start reading.</param>
/// <param name="length">The number of bytes to read.</param>
/// <returns>The bytes read from the datagram starting from the given offset and in the given length.</returns>
protected byte[] ReadBytes(int offset, int length)
{
return Buffer.ReadBytes(StartOffset + offset, length);
}
/// <summary>
/// Reads 2 bytes from a specific offset in the datagram as a ushort with a given endianity.
/// </summary>
/// <param name="offset">The offset in the datagram to start reading.</param>
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <returns>The value converted from the read bytes according to the endianity.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "ushort")]
internal ushort ReadUShort(int offset, Endianity endianity)
{
return Buffer.ReadUShort(StartOffset + offset, endianity);
}
/// <summary>
/// Reads 4 bytes from a specific offset in the datagram as an int with a given endianity.
/// </summary>
/// <param name="offset">The offset in the datagram to start reading.</param>
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <returns>The value converted from the read bytes according to the endianity.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "int")]
protected int ReadInt(int offset, Endianity endianity)
{
return Buffer.ReadInt(StartOffset + offset, endianity);
}
/// <summary>
/// Reads 4 bytes from a specific offset in the datagram as a uint with a given endianity.
/// </summary>
/// <param name="offset">The offset in the datagram to start reading.</param>
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <returns>The value converted from the read bytes according to the endianity.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "uint")]
protected uint ReadUInt(int offset, Endianity endianity)
{
return Buffer.ReadUInt(StartOffset + offset, endianity);
}
/*
/// <summary>
/// Reads 8 bytes from a specific offset in the datagram as a ulong with a given endianity.
/// </summary>
/// <param name="offset">The offset in the datagram to start reading.</param>
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <returns>The value converted from the read bytes according to the endianity.</returns>
// protected ulong ReadULong(int offset, Endianity endianity)
// {
// return Buffer.ReadULong(StartOffset + offset, endianity);
// }
*/
/// <summary>
/// Reads 6 bytes from a specific offset in the datagram as a MacAddress with a given endianity.
/// </summary>
/// <param name="offset">The offset in the datagram to start reading.</param>
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <returns>The value converted from the read bytes according to the endianity.</returns>
protected MacAddress ReadMacAddress(int offset, Endianity endianity)
{
return Buffer.ReadMacAddress(StartOffset + offset, endianity);
}
/// <summary>
/// Reads 4 bytes from a specific offset in the datagram as an IpV4Address with a given endianity.
/// </summary>
/// <param name="offset">The offset in the datagram to start reading.</param>
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <returns>The value converted from the read bytes according to the endianity.</returns>
protected IpV4Address ReadIpV4Address(int offset, Endianity endianity)
{
return Buffer.ReadIpV4Address(StartOffset + offset, endianity);
}
/// <summary>
/// Reads 4 bytes from a specific offset in the datagram as an IpV4TimeOfDay with a given endianity.
/// </summary>
/// <param name="offset">The offset in the datagram to start reading.</param>
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <returns>The value converted from the read bytes according to the endianity.</returns>
protected IpV4TimeOfDay ReadIpV4TimeOfDay(int offset, Endianity endianity)
{
return Buffer.ReadIpV4TimeOfDay(StartOffset + offset, endianity);
}
/// <summary>
/// Converts the given 16 bits sum to a checksum.
/// Sums the two 16 bits in the 32 bits value and if the result is bigger than a 16 bits value repeat.
/// The result is one's complemented and the least significant 16 bits are taken.
/// </summary>
/// <param name="sum"></param>
/// <returns></returns>
protected static ushort Sum16BitsToChecksum(uint sum)
{
// Take only 16 bits out of the 32 bit sum and add up the carrier.
// if the results overflows - do it again.
while (sum > 0xFFFF)
sum = (sum & 0xFFFF) + (sum >> 16);
// one's complement the result
sum = ~sum;
return (ushort)sum;
}
/// <summary>
/// Sums bytes in a buffer as 16 bits big endian values.
/// If the number of bytes is odd then a 0x00 value is assumed after the last byte.
/// Used to calculate checksum.
/// </summary>
/// <param name="buffer">The buffer to take the bytes from.</param>
/// <param name="offset">The offset in the buffer to start reading the bytes.</param>
/// <param name="length">The number of bytes to read.</param>
/// <returns>A value equals to the sum of all 16 bits big endian values of the given bytes.</returns>
protected static uint Sum16Bits(byte[] buffer, int offset, int length)
{
if (buffer == null)
throw new ArgumentNullException("buffer");
int endOffset = offset + length;
uint sum = 0;
while (offset < endOffset - 1)
sum += buffer.ReadUShort(ref offset, Endianity.Big);
if (offset < endOffset)
sum += (ushort)(buffer[offset] << 8);
return sum;
}
private static readonly Datagram _empty = new Datagram(new byte[0], 0, 0);
private static readonly Datagram _empty = new Datagram(new byte[0]);
private bool? _isValid;
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 1035.
/// CLASS fields appear in resource records.
/// </summary>
public enum DnsClass : ushort
{
/// <summary>
/// The Internet.
/// </summary>
In = 1,
/// <summary>
/// The CSNET class (Obsolete - used only for examples in some obsolete RFCs).
/// </summary>
Cs = 2,
/// <summary>
/// The CHAOS class.
/// </summary>
Ch = 3,
/// <summary>
/// Hesiod [Dyer 87].
/// </summary>
Hs = 4,
/// <summary>
/// *.
/// Any class.
/// Query Class.
/// </summary>
Any = 255,
}
}
\ No newline at end of file
using System.Collections.ObjectModel;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 1035.
/// All communications inside of the domain protocol are carried in a single format called a message.
/// The top level format of message is divided into 5 sections (some of which are empty in certain cases) shown below:
/// <pre>
/// +-----+----+--------+----+----+----+----+------+--------+
/// | bit | 0 | 1-4 | 5 | 6 | 7 | 8 | 9-11 | 12-15 |
/// +-----+----+--------+----+----+----+----+------+--------+
/// | 0 | ID |
/// +-----+----+--------+----+----+----+----+------+--------+
/// | 16 | QR | Opcode | AA | TC | RD | RA | Z | RCODE |
/// +-----+----+--------+----+----+----+----+------+--------+
/// | 32 | QDCOUNT |
/// +-----+-------------------------------------------------+
/// | 48 | ANCOUNT |
/// +-----+-------------------------------------------------+
/// | 64 | NSCOUNT |
/// +-----+-------------------------------------------------+
/// | 80 | ARCOUNT |
/// +-----+-------------------------------------------------+
/// | 96 | Question - the question for the name server |
/// +-----+-------------------------------------------------+
/// | | Answer - RRs answering the question |
/// +-----+-------------------------------------------------+
/// | | Authority - RRs pointing toward an authority |
/// +-----+-------------------------------------------------+
/// | | Additional - RRs holding additional information |
/// +-----+-------------------------------------------------+
/// </pre>
/// The header section is always present.
/// The header includes fields that specify which of the remaining sections are present,
/// and also specify whether the message is a query or a response, a standard query or some other opcode, etc.
/// The names of the sections after the header are derived from their use in standard queries.
/// The question section contains fields that describe a question to a name server.
/// These fields are a query type (QTYPE), a query class (QCLASS), and a query domain name (QNAME).
/// The last three sections have the same format: a possibly empty list of concatenated resource records (RRs).
/// The answer section contains RRs that answer the question; the authority section contains RRs that point toward an authoritative name server;
/// the additional records section contains RRs which relate to the query, but are not strictly answers for the question.
/// </summary>
public class DnsDatagram : Datagram
{
private static class Offset
{
public const int Id = 0;
public const int IsResponse = 2;
public const int Opcode = 2;
public const int IsAuthoritiveAnswer = 2;
public const int IsTruncated = 2;
public const int IsRecusionDesired = 2;
public const int IsRecusionAvailable = 3;
public const int FutureUse = 3;
public const int ResponseCode = 3;
public const int QueryCount = 4;
public const int AnswerCount = 6;
public const int AuthorityCount = 8;
public const int AdditionalCount = 10;
public const int Query = 12;
}
private static class Mask
{
public const byte IsResponse = 0x80;
public const byte Opcode = 0x78;
public const byte IsAuthoritiveAnswer = 0x04;
public const byte IsTruncated = 0x02;
public const byte IsRecusionDesired = 0x01;
public const byte IsRecusionAvailable = 0x80;
public const byte FutureUse = 0x70;
public const byte ResponseCode = 0x0F;
}
private static class Shift
{
public const int Opcode = 3;
public const int FutureUse = 4;
}
/// <summary>
/// The number of bytes the DNS header takes.
/// </summary>
public const int HeaderLength = 10;
public ushort Id
{
get { return ReadUShort(Offset.Id, Endianity.Big); }
}
public bool IsResponse
{
get { return ReadBool(Offset.IsResponse, Mask.IsResponse); }
}
public bool IsQuery
{
get { return !IsResponse; }
}
public byte Opcode
{
get { return (byte)((this[Offset.Opcode] & Mask.Opcode) >> Shift.Opcode); }
}
public bool IsAuthoritiveAnswer
{
get { return ReadBool(Offset.IsAuthoritiveAnswer, Mask.IsAuthoritiveAnswer); }
}
public bool IsTruncated
{
get { return ReadBool(Offset.IsTruncated, Mask.IsTruncated); }
}
public bool IsRecusionDesired
{
get { return ReadBool(Offset.IsRecusionDesired, Mask.IsRecusionDesired); }
}
public bool IsRecusionAvailable
{
get { return ReadBool(Offset.IsRecusionAvailable, Mask.IsRecusionAvailable); }
}
public byte FutureUse
{
get { return (byte)((this[Offset.FutureUse] & Mask.FutureUse) >> Shift.FutureUse); }
}
public byte ResponseCode
{
get { return (byte)(this[Offset.ResponseCode] & Mask.ResponseCode); }
}
public ushort QueryCount
{
get { return ReadUShort(Offset.QueryCount, Endianity.Big); }
}
public ushort AnswerCount
{
get { return ReadUShort(Offset.AnswerCount, Endianity.Big); }
}
public ushort AuthorityCount
{
get { return ReadUShort(Offset.AuthorityCount, Endianity.Big); }
}
public ushort AdditionalCount
{
get { return ReadUShort(Offset.AdditionalCount, Endianity.Big); }
}
/*
public ReadOnlyCollection<DnsResourceRecord> Query
{
}
*/
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
/*
public override ILayer ExtractLayer()
{
return new ArpLayer
{
SenderHardwareAddress = SenderHardwareAddress,
SenderProtocolAddress = SenderProtocolAddress,
TargetHardwareAddress = TargetHardwareAddress,
TargetProtocolAddress = TargetProtocolAddress,
ProtocolType = ProtocolType,
Operation = Operation,
};
}
*/
/*
protected override bool CalculateIsValid()
{
return Length >= HeaderBaseLength && Length == HeaderLength;
}
*/
internal DnsDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// A domain name represented as a series of labels, and terminated by a label with zero length.
/// </summary>
public class DnsDomainName
{
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 1035.
/// All RRs have the same top level format shown below:
/// <pre>
/// +------+------------------------+
/// | byte | 0-1 |
/// +------+------------------------+
/// | 0 | Name |
/// | ... | |
/// +------+------------------------+
/// | | Type |
/// +------+------------------------+
/// | | Class |
/// +------+------------------------+
/// | | TTL |
/// | | |
/// +------+------------------------+
/// | | Resource Data Length |
/// +------+------------------------+
/// | | Resource Data |
/// | ... | |
/// +------+------------------------+
/// </pre>
public class DnsResourceRecord
{
public DnsResourceRecord(DnsDomainName domainName, DnsType type, DnsClass dnsClass, int ttl, DataSegment data)
{
DomainName = domainName;
Type = type;
DnsClass = dnsClass;
Ttl = ttl;
Data = data;
}
/// <summary>
/// An owner name, i.e., the name of the node to which this resource record pertains.
/// </summary>
public DnsDomainName DomainName { get; private set; }
/// <summary>
/// Two octets containing one of the RR TYPE codes.
/// </summary>
public DnsType Type { get; private set;}
public DnsClass DnsClass { get; private set; }
/// <summary>
/// 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 Ttl { get; private set; }
public ushort DataLength { get { return (ushort)Data.Length; } }
/// <summary>
/// A variable length string of octets that describes the resource.
/// The format of this information varies according to the TYPE and CLASS of the resource record.
/// </summary>
public DataSegment Data { get; private set; }
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
/// <summary>
/// RFC 1035.
/// Type fields are used in resource records.
/// </summary>
public enum DnsType : ushort
{
/// <summary>
/// A host address.
/// </summary>
A = 1,
/// <summary>
/// An authoritative name server.
/// </summary>
Ns = 2,
/// <summary>
/// A mail destination (Obsolete - use MX).
/// </summary>
Md = 3,
/// <summary>
/// A mail forwarder (Obsolete - use MX).
/// </summary>
Mf = 4,
/// <summary>
/// The canonical name for an alias.
/// </summary>
CName = 5,
/// <summary>
/// Marks the start of a zone of authority.
/// </summary>
Soa = 6,
/// <summary>
/// A mailbox domain name (EXPERIMENTAL).
/// </summary>
Mb = 7,
/// <summary>
/// A mail group member (EXPERIMENTAL).
/// </summary>
Mg = 8,
/// <summary>
/// A mail rename domain name (EXPERIMENTAL).
/// </summary>
Mr = 9,
/// <summary>
/// A null RR (EXPERIMENTAL).
/// </summary>
Null = 10,
/// <summary>
/// A well known service description..
/// </summary>
Wks = 11,
/// <summary>
/// A domain name pointer.
/// </summary>
Ptr = 12,
/// <summary>
/// Host information.
/// </summary>
HInfo = 13,
/// <summary>
/// mailbox or mail list information.
/// </summary>
MInfo = 14,
/// <summary>
/// Mail exchange.
/// </summary>
Mx = 15,
/// <summary>
/// Text strings.
/// </summary>
Txt = 16,
/// <summary>
/// A request for a transfer of an entire zone.
/// Query Type.
/// </summary>
Axfr = 252,
/// <summary>
/// A request for mailbox-related records (MB, MG or MR).
/// Query Type.
/// </summary>
MailB = 253,
/// <summary>
/// A request for mail agent RRs (Obsolete - see MX).
/// Query Type.
/// </summary>
MailA = 254,
/// <summary>
/// *.
/// A request for all records
/// Query Type.
/// </summary>
All = 255,
}
}
\ No newline at end of file
......@@ -92,6 +92,12 @@
<Compile Include="Datagram.cs" />
<Compile Include="DataLink.cs" />
<Compile Include="DataLinkKind.cs" />
<Compile Include="DataSegment.cs" />
<Compile Include="Dns\DnsClass.cs" />
<Compile Include="Dns\DnsDomain.cs" />
<Compile Include="Dns\DnsDatagram.cs" />
<Compile Include="Dns\DnsResourceRecord.cs" />
<Compile Include="Dns\DnsType.cs" />
<Compile Include="Endianity.cs" />
<Compile Include="Ethernet\EthernetLayer.cs" />
<Compile Include="Ethernet\EthernetDatagram.cs" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment