Commit c9141cab authored by Brickner_cp's avatar Brickner_cp

DNS

parent ce1f95a8
namespace PcapDotNet.Packets.Dns
{
public class DnsDataResourceRecord : DnsResourceRecord
{
private static class OffsetAfterBase
{
public const int Ttl = 0;
public const int DataLength = 4;
public const int Data = 6;
}
private const int MinimumLengthAfterBase = 6;
public DnsDataResourceRecord(DnsDomainName domainName, DnsType type, DnsClass dnsClass, int ttl, DnsResourceData data)
: base(domainName, type, dnsClass)
{
Ttl = ttl;
Data = data;
}
/// <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 override int Ttl { get; protected set; }
/// <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.
/// For example, the if the TYPE is A and the CLASS is IN, the RDATA field is a 4 octet ARPA Internet address.
/// </summary>
public override DnsResourceData Data { get; protected set; }
public override string ToString()
{
return base.ToString() + " " + Ttl + " " + Data;
}
internal static DnsDataResourceRecord Parse(DnsDatagram dns, int offsetInDns, out int numBytesRead)
{
DnsDomainName domainName;
DnsType type;
DnsClass dnsClass;
if (!TryParseBase(dns, offsetInDns, out domainName, out type, out dnsClass, out numBytesRead))
return null;
if (offsetInDns + numBytesRead + MinimumLengthAfterBase > dns.Length)
return null;
int ttl = dns.ReadInt(offsetInDns + numBytesRead + OffsetAfterBase.Ttl, Endianity.Big);
ushort dataLength = dns.ReadUShort(offsetInDns + numBytesRead + OffsetAfterBase.DataLength, Endianity.Big);
numBytesRead += MinimumLengthAfterBase;
if (offsetInDns + numBytesRead + dataLength > dns.Length)
return null;
DnsResourceData data = DnsResourceData.Read(dns, offsetInDns + numBytesRead, dataLength);
if (data == null)
return null;
numBytesRead += dataLength;
return new DnsDataResourceRecord(domainName, type, dnsClass, ttl, data);
}
internal override int GetLengthAfterBase(DnsDomainNameCompressionData compressionData, int offsetInDns)
{
return MinimumLengthAfterBase + Data.GetLength(compressionData, offsetInDns);
}
internal override int Write(byte[] buffer, int dnsOffset, DnsDomainNameCompressionData compressionData, int offsetInDns)
{
int length = base.Write(buffer, dnsOffset, compressionData, offsetInDns);
buffer.Write(dnsOffset + offsetInDns + length, Ttl, Endianity.Big);
length += sizeof(uint);
length += Data.Write(buffer, dnsOffset, offsetInDns + length, compressionData);
return length;
}
}
}
\ No newline at end of file
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using PcapDotNet.Base;
namespace PcapDotNet.Packets.Dns
{
public class ListSegment<T> : IList<T>
{
public ListSegment(IList<T> data, int startIndex, int count)
{
_data = data;
_startIndex = startIndex;
Count = count;
}
public ListSegment(IList<T> data, int startIndex)
: this(data, startIndex, data.Count - startIndex)
{
}
public IEnumerator<T> GetEnumerator()
{
for (int i = 0; i != Count; ++i)
yield return this[i];
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(T item)
{
throw new NotSupportedException("ListSegment<T> is read-only");
}
public void Clear()
{
throw new NotSupportedException("ListSegment<T> is read-only");
}
public bool Contains(T item)
{
return Enumerable.Contains(this, item);
}
public void CopyTo(T[] array, int arrayIndex)
{
foreach (T value in this)
array[arrayIndex++] = value;
}
public bool Remove(T item)
{
throw new NotSupportedException("ListSegment<T> is read-only");
}
public int Count { get; private set; }
public bool IsReadOnly
{
get { return true; }
}
public int IndexOf(T item)
{
if (ReferenceEquals(item, null))
{
for (int i = 0; i != Count; ++i)
{
if (ReferenceEquals(this[i], null))
return i;
}
return -1;
}
for (int i = 0; i != Count; ++i)
{
if (item.Equals(this[i]))
return i;
}
return -1;
}
public void Insert(int index, T item)
{
throw new NotSupportedException("ListSegment<T> is read-only");
}
public void RemoveAt(int index)
{
throw new NotSupportedException("ListSegment<T> is read-only");
}
public T this[int index]
{
get { return _data[_startIndex + index]; }
set { throw new NotSupportedException("ListSegment<T> is read-only"); }
}
public ListSegment<T> SubSegment(int startIndex, int count)
{
return new ListSegment<T>(_data, _startIndex + startIndex, count);
}
public ListSegment<T> SubSegment(int startIndex)
{
return SubSegment(startIndex, Count - startIndex);
}
private readonly IList<T> _data;
private readonly int _startIndex;
}
internal class DnsDomainNameCompressionData
{
// private class LabelNode
// {
// public int? DnsOffset { get; private set; }
//
// public bool TryGetOffset(ListSegment<DataSegment> labels, out int offsetInDns)
// {
// if (labels.Count == 0)
// {
// offsetInDns = DnsOffset.GetValueOrDefault();
// return DnsOffset.HasValue;
// }
// LabelNode nextNode;
// if (!_nextLabels.TryGetValue(labels[0], out nextNode))
// {
// offsetInDns = 0;
// return false;
// }
// offsetInDns = nextNode.DnsOffset.Value;
// int nextNodeOffset;
// return nextNode.TryGetOffset(labels.SubSegment(1), out nextNodeOffset);
// }
//
// public void AddLabels(ListSegment<DataSegment> labels, int dnsOffset)
// {
// if (labels.Count == 0)
// {
// DnsOffset = dnsOffset;
// return;
// }
// DataSegment firstLabel = labels[0];
// LabelNode node;
// if (!_nextLabels.TryGetValue(firstLabel, out node))
// {
// node = new LabelNode();
// _nextLabels.Add(firstLabel, node);
// }
// node.AddLabels(labels.SubSegment(1), dnsOffset);
// }
//
// private readonly Dictionary<DataSegment, LabelNode> _nextLabels = new Dictionary<DataSegment, LabelNode>();
// }
public DnsDomainNameCompressionData(DnsDomainNameCompressionMode domainNameCompressionMode)
{
DomainNameCompressionMode = domainNameCompressionMode;
......
using System;
namespace PcapDotNet.Packets.Dns
{
public class DnsQueryResourceRecord : DnsResourceRecord
{
public DnsQueryResourceRecord(DnsDomainName domainName, DnsType type, DnsClass dnsClass)
: base(domainName, type, dnsClass)
{
}
public override int Ttl
{
get { throw new InvalidOperationException("No TTL in queries"); }
protected set { throw new InvalidOperationException("No TTL in queries"); }
}
public override DnsResourceData Data
{
get { throw new InvalidOperationException("No Resource Data in queries"); }
protected set { throw new InvalidOperationException("No Resource Data in queries"); }
}
internal static DnsQueryResourceRecord Parse(DnsDatagram dns, int offsetInDns, out int numBytesRead)
{
DnsDomainName domainName;
DnsType type;
DnsClass dnsClass;
if (!TryParseBase(dns, offsetInDns, out domainName, out type, out dnsClass, out numBytesRead))
return null;
return new DnsQueryResourceRecord(domainName, type, dnsClass);
}
internal override int GetLengthAfterBase(DnsDomainNameCompressionData compressionData, int offsetInDns)
{
return 0;
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
public abstract class DnsResourceData
{
internal static DnsResourceData Read(DnsDatagram dns, int offsetInDns, int dataLength)
{
return new DnsResourceDataUnknown(dns.SubSegment(offsetInDns, dataLength));
}
internal abstract int GetLength(DnsDomainNameCompressionData compressionData, int offsetInDns);
internal int Write(byte[] buffer, int dnsOffset, int offsetInDns, DnsDomainNameCompressionData compressionData)
{
int length = WriteData(buffer, dnsOffset, offsetInDns + sizeof(ushort), compressionData);
buffer.Write(dnsOffset + offsetInDns, (ushort)length, Endianity.Big);
length += sizeof(ushort);
return length;
}
internal abstract int WriteData(byte[] buffer, int dnsOffset, int offsetInDns, DnsDomainNameCompressionData compressionData);
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Dns
{
public class DnsResourceDataUnknown : DnsResourceData
{
public DnsResourceDataUnknown(DataSegment data)
{
Data = data;
}
public DataSegment Data { get; private set; }
internal override int GetLength(DnsDomainNameCompressionData compressionData, int offsetInDns)
{
return Data.Length;
}
internal override int WriteData(byte[] buffer, int dnsOffset, int offsetInDns, DnsDomainNameCompressionData compressionData)
{
Data.Write(buffer, dnsOffset + offsetInDns);
return Data.Length;
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
namespace PcapDotNet.Packets.Dns
{
// public enum DnsSection
// {
// Query,
// Answer,
// Authority,
// Additional,
// }
/// <summary>
/// RFC 1035.
/// All RRs have the same top level format shown below:
......@@ -51,8 +42,6 @@ namespace PcapDotNet.Packets.Dns
DnsClass = dnsClass;
}
// public abstract DnsSection Section { get; }
/// <summary>
/// An owner name, i.e., the name of the node to which this resource record pertains.
/// </summary>
......@@ -123,158 +112,4 @@ namespace PcapDotNet.Packets.Dns
return length;
}
}
public class DnsQueryResourceRecord : DnsResourceRecord
{
public DnsQueryResourceRecord(DnsDomainName domainName, DnsType type, DnsClass dnsClass)
: base(domainName, type, dnsClass)
{
}
public override int Ttl
{
get { throw new InvalidOperationException("No TTL in queries"); }
protected set { throw new InvalidOperationException("No TTL in queries"); }
}
public override DnsResourceData Data
{
get { throw new InvalidOperationException("No Resource Data in queries"); }
protected set { throw new InvalidOperationException("No Resource Data in queries"); }
}
internal static DnsQueryResourceRecord Parse(DnsDatagram dns, int offsetInDns, out int numBytesRead)
{
DnsDomainName domainName;
DnsType type;
DnsClass dnsClass;
if (!TryParseBase(dns, offsetInDns, out domainName, out type, out dnsClass, out numBytesRead))
return null;
return new DnsQueryResourceRecord(domainName, type, dnsClass);
}
internal override int GetLengthAfterBase(DnsDomainNameCompressionData compressionData, int offsetInDns)
{
return 0;
}
}
public class DnsDataResourceRecord : DnsResourceRecord
{
private static class OffsetAfterBase
{
public const int Ttl = 0;
public const int DataLength = 4;
public const int Data = 6;
}
private const int MinimumLengthAfterBase = 6;
public DnsDataResourceRecord(DnsDomainName domainName, DnsType type, DnsClass dnsClass, int ttl, DnsResourceData data)
: base(domainName, type, dnsClass)
{
Ttl = ttl;
Data = data;
}
/// <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 override int Ttl { get; protected set; }
/// <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.
/// For example, the if the TYPE is A and the CLASS is IN, the RDATA field is a 4 octet ARPA Internet address.
/// </summary>
public override DnsResourceData Data { get; protected set; }
public override string ToString()
{
return base.ToString() + " " + Ttl + " " + Data;
}
internal static DnsDataResourceRecord Parse(DnsDatagram dns, int offsetInDns, out int numBytesRead)
{
DnsDomainName domainName;
DnsType type;
DnsClass dnsClass;
if (!TryParseBase(dns, offsetInDns, out domainName, out type, out dnsClass, out numBytesRead))
return null;
if (offsetInDns + numBytesRead + MinimumLengthAfterBase > dns.Length)
return null;
int ttl = dns.ReadInt(offsetInDns + numBytesRead + OffsetAfterBase.Ttl, Endianity.Big);
ushort dataLength = dns.ReadUShort(offsetInDns + numBytesRead + OffsetAfterBase.DataLength, Endianity.Big);
numBytesRead += MinimumLengthAfterBase;
if (offsetInDns + numBytesRead + dataLength > dns.Length)
return null;
DnsResourceData data = DnsResourceData.Read(dns, offsetInDns + numBytesRead, dataLength);
if (data == null)
return null;
numBytesRead += dataLength;
return new DnsDataResourceRecord(domainName, type, dnsClass, ttl, data);
}
internal override int GetLengthAfterBase(DnsDomainNameCompressionData compressionData, int offsetInDns)
{
return MinimumLengthAfterBase + Data.GetLength(compressionData, offsetInDns);
}
internal override int Write(byte[] buffer, int dnsOffset, DnsDomainNameCompressionData compressionData, int offsetInDns)
{
int length = base.Write(buffer, dnsOffset, compressionData, offsetInDns);
buffer.Write(dnsOffset + offsetInDns + length, Ttl, Endianity.Big);
length += sizeof(uint);
length += Data.Write(buffer, dnsOffset, offsetInDns + length, compressionData);
return length;
}
}
public abstract class DnsResourceData
{
internal static DnsResourceData Read(DnsDatagram dns, int offsetInDns, int dataLength)
{
return new DnsResourceDataUnknown(dns.SubSegment(offsetInDns, dataLength));
}
internal abstract int GetLength(DnsDomainNameCompressionData compressionData, int offsetInDns);
internal int Write(byte[] buffer, int dnsOffset, int offsetInDns, DnsDomainNameCompressionData compressionData)
{
int length = WriteData(buffer, dnsOffset, offsetInDns + sizeof(ushort), compressionData);
buffer.Write(dnsOffset + offsetInDns, (ushort)length, Endianity.Big);
length += sizeof(ushort);
return length;
}
internal abstract int WriteData(byte[] buffer, int dnsOffset, int offsetInDns, DnsDomainNameCompressionData compressionData);
}
public class DnsResourceDataUnknown : DnsResourceData
{
public DnsResourceDataUnknown(DataSegment data)
{
Data = data;
}
public DataSegment Data { get; private set; }
internal override int GetLength(DnsDomainNameCompressionData compressionData, int offsetInDns)
{
return Data.Length;
}
internal override int WriteData(byte[] buffer, int dnsOffset, int offsetInDns, DnsDomainNameCompressionData compressionData)
{
Data.Write(buffer, dnsOffset + offsetInDns);
return Data.Length;
}
}
}
\ No newline at end of file
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace PcapDotNet.Packets.Dns
{
public class ListSegment<T> : IList<T>
{
public ListSegment(IList<T> data, int startIndex, int count)
{
_data = data;
_startIndex = startIndex;
Count = count;
}
public ListSegment(IList<T> data, int startIndex)
: this(data, startIndex, data.Count - startIndex)
{
}
public IEnumerator<T> GetEnumerator()
{
for (int i = 0; i != Count; ++i)
yield return this[i];
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(T item)
{
throw new NotSupportedException("ListSegment<T> is read-only");
}
public void Clear()
{
throw new NotSupportedException("ListSegment<T> is read-only");
}
public bool Contains(T item)
{
return Enumerable.Contains(this, item);
}
public void CopyTo(T[] array, int arrayIndex)
{
foreach (T value in this)
array[arrayIndex++] = value;
}
public bool Remove(T item)
{
throw new NotSupportedException("ListSegment<T> is read-only");
}
public int Count { get; private set; }
public bool IsReadOnly
{
get { return true; }
}
public int IndexOf(T item)
{
if (ReferenceEquals(item, null))
{
for (int i = 0; i != Count; ++i)
{
if (ReferenceEquals(this[i], null))
return i;
}
return -1;
}
for (int i = 0; i != Count; ++i)
{
if (item.Equals(this[i]))
return i;
}
return -1;
}
public void Insert(int index, T item)
{
throw new NotSupportedException("ListSegment<T> is read-only");
}
public void RemoveAt(int index)
{
throw new NotSupportedException("ListSegment<T> is read-only");
}
public T this[int index]
{
get { return _data[_startIndex + index]; }
set { throw new NotSupportedException("ListSegment<T> is read-only"); }
}
public ListSegment<T> SubSegment(int startIndex, int count)
{
return new ListSegment<T>(_data, _startIndex + startIndex, count);
}
public ListSegment<T> SubSegment(int startIndex)
{
return SubSegment(startIndex, Count - startIndex);
}
private readonly IList<T> _data;
private readonly int _startIndex;
}
}
\ No newline at end of file
......@@ -94,15 +94,20 @@
<Compile Include="DataLinkKind.cs" />
<Compile Include="DataSegment.cs" />
<Compile Include="Dns\DnsClass.cs" />
<Compile Include="Dns\DnsDataResourceRecord.cs" />
<Compile Include="Dns\DnsDomainName.cs" />
<Compile Include="Dns\DnsDatagram.cs" />
<Compile Include="Dns\DnsDomainNameCompressionData.cs" />
<Compile Include="Dns\DnsDomainNameCompressionMode.cs" />
<Compile Include="Dns\DnsLayer.cs" />
<Compile Include="Dns\DnsOpcode.cs" />
<Compile Include="Dns\DnsQueryResourceRecord.cs" />
<Compile Include="Dns\DnsResourceData.cs" />
<Compile Include="Dns\DnsResourceDataUnknown.cs" />
<Compile Include="Dns\DnsResourceRecord.cs" />
<Compile Include="Dns\DnsResponseCode.cs" />
<Compile Include="Dns\DnsType.cs" />
<Compile Include="Dns\ListSegment.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