Commit d1cd96f5 authored by Brickner_cp's avatar Brickner_cp

DNS

parent eff86bb1
...@@ -130,7 +130,7 @@ namespace PcapDotNet.Packets.Test ...@@ -130,7 +130,7 @@ namespace PcapDotNet.Packets.Test
// new DnsResourceDataUnknown(new DataSegment(Encoding.ASCII.GetBytes("abcd")))), // new DnsResourceDataUnknown(new DataSegment(Encoding.ASCII.GetBytes("abcd")))),
// new DnsDataResourceRecord(new DnsDomainName("abc.def."), DnsType.A, DnsClass.In, 100, // new DnsDataResourceRecord(new DnsDomainName("abc.def."), DnsType.A, DnsClass.In, 100,
// new DnsResourceDataUnknown(new DataSegment(Encoding.ASCII.GetBytes("abce")))), // new DnsResourceDataUnknown(new DataSegment(Encoding.ASCII.GetBytes("abce")))),
new DnsDataResourceRecord(new DnsDomainName(""), DnsType.A, DnsClass.Any, 1, new DnsResourceDataUnknown(new DataSegment(new byte[0]))) new DnsDataResourceRecord(new DnsDomainName(""), DnsType.A, DnsClass.Any, 1, new DnsResourceDataIpV4(new IpV4Address("1.2.3.4")))
}.ToList(), }.ToList(),
// Authorities = // Authorities =
// new[] // new[]
......
...@@ -1002,7 +1002,8 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -1002,7 +1002,8 @@ namespace PcapDotNet.Packets.TestUtils
public static DnsDataResourceRecord NextDnsDataResourceRecord(this Random random) public static DnsDataResourceRecord NextDnsDataResourceRecord(this Random random)
{ {
DnsDataResourceRecord record = new DnsDataResourceRecord(random.NextDnsDomainName(), random.NextEnum<DnsType>(), random.NextEnum<DnsClass>(), random.Next(), random.NextDnsResourceData()); DnsType type = random.NextEnum<DnsType>();
DnsDataResourceRecord record = new DnsDataResourceRecord(random.NextDnsDomainName(), type, random.NextEnum<DnsClass>(), random.Next(), random.NextDnsResourceData(type));
return record; return record;
} }
...@@ -1021,10 +1022,15 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -1021,10 +1022,15 @@ namespace PcapDotNet.Packets.TestUtils
return new DnsDomainName(string.Join(".", labels)); return new DnsDomainName(string.Join(".", labels));
} }
public static DnsResourceData NextDnsResourceData(this Random random) public static DnsResourceData NextDnsResourceData(this Random random, DnsType type)
{ {
DnsResourceData resourceData = new DnsResourceDataUnknown(new DataSegment(random.NextBytes(random.Next(100)))); switch (type)
return resourceData; {
case DnsType.A:
return new DnsResourceDataIpV4(random.NextIpV4Address());
default:
return new DnsResourceDataUnknown(new DataSegment(random.NextBytes(random.Next(100))));
}
} }
// HTTP // HTTP
......
...@@ -220,7 +220,7 @@ namespace PcapDotNet.Packets ...@@ -220,7 +220,7 @@ namespace PcapDotNet.Packets
/// <param name="offset">The offset in the segment to start reading.</param> /// <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> /// <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> /// <returns>The value converted from the read bytes according to the endianity.</returns>
protected IpV4Address ReadIpV4Address(int offset, Endianity endianity) internal IpV4Address ReadIpV4Address(int offset, Endianity endianity)
{ {
return Buffer.ReadIpV4Address(StartOffset + offset, endianity); return Buffer.ReadIpV4Address(StartOffset + offset, endianity);
} }
......
...@@ -68,7 +68,7 @@ namespace PcapDotNet.Packets.Dns ...@@ -68,7 +68,7 @@ namespace PcapDotNet.Packets.Dns
numBytesRead += MinimumLengthAfterBase; numBytesRead += MinimumLengthAfterBase;
if (offsetInDns + numBytesRead + dataLength > dns.Length) if (offsetInDns + numBytesRead + dataLength > dns.Length)
return null; return null;
DnsResourceData data = DnsResourceData.Read(dns, offsetInDns + numBytesRead, dataLength); DnsResourceData data = DnsResourceData.Read(type, dnsClass, dns.SubSegment(offsetInDns + numBytesRead, dataLength));
if (data == null) if (data == null)
return null; return null;
numBytesRead += dataLength; numBytesRead += dataLength;
......
namespace PcapDotNet.Packets.Dns using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using PcapDotNet.Base;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Dns
{ {
public abstract class DnsResourceData internal class DnsTypeRegistrationAttribute : Attribute
{
public DnsType Type { get; set; }
}
public abstract class DnsResourceData : IEquatable<DnsResourceData>
{ {
internal static DnsResourceData Read(DnsDatagram dns, int offsetInDns, int dataLength) public abstract bool Equals(DnsResourceData other);
public sealed override bool Equals(object obj)
{ {
return new DnsResourceDataUnknown(dns.SubSegment(offsetInDns, dataLength)); return Equals(obj as DnsResourceData);
} }
internal abstract int GetLength(DnsDomainNameCompressionData compressionData, int offsetInDns); internal abstract int GetLength(DnsDomainNameCompressionData compressionData, int offsetInDns);
...@@ -18,5 +33,109 @@ ...@@ -18,5 +33,109 @@
} }
internal abstract int WriteData(byte[] buffer, int dnsOffset, int offsetInDns, DnsDomainNameCompressionData compressionData); internal abstract int WriteData(byte[] buffer, int dnsOffset, int offsetInDns, DnsDomainNameCompressionData compressionData);
internal static DnsResourceData Read(DnsType type, DnsClass dnsClass, DataSegment data)
{
DnsResourceData prototype = TryGetPrototype(type, dnsClass);
if (prototype != null)
return prototype.CreateInstance(data);
return new DnsResourceDataUnknown(data);
}
internal abstract DnsResourceData CreateInstance(DataSegment data);
private static DnsResourceData TryGetPrototype(DnsType type, DnsClass dnsClass)
{
DnsResourceData prototype;
if (!_prototypes.TryGetValue(type, out prototype))
return null;
return prototype;
}
private static Dictionary<DnsType, DnsResourceData> InitializePrototypes()
{
var prototypes =
from type in Assembly.GetExecutingAssembly().GetTypes()
where typeof(DnsResourceData).IsAssignableFrom(type) &&
type.GetCustomAttributes<DnsTypeRegistrationAttribute>(false).Any()
select new
{
type.GetCustomAttributes<DnsTypeRegistrationAttribute>(false).First().Type,
Prototype = (DnsResourceData)Activator.CreateInstance(type),
};
return prototypes.ToDictionary(prototype => prototype.Type, prototype => prototype.Prototype);
}
private static readonly Dictionary<DnsType, DnsResourceData> _prototypes = InitializePrototypes();
}
public abstract class DnsResourceDataNoCompression : DnsResourceData
{
internal sealed override int GetLength(DnsDomainNameCompressionData compressionData, int offsetInDns)
{
return GetLength();
}
internal sealed override int WriteData(byte[] buffer, int dnsOffset, int offsetInDns, DnsDomainNameCompressionData compressionData)
{
return WriteData(buffer, dnsOffset + offsetInDns);
}
internal abstract int GetLength();
internal abstract int WriteData(byte[] buffer, int offset);
}
public abstract class DnsResourceDataSimple : DnsResourceDataNoCompression
{
internal sealed override int WriteData(byte[] buffer, int offset)
{
WriteDataSimple(buffer, offset);
return GetLength();
}
internal abstract void WriteDataSimple(byte[] buffer, int offset);
}
[DnsTypeRegistration(Type = DnsType.A)]
public class DnsResourceDataIpV4 : DnsResourceDataSimple, IEquatable<DnsResourceDataIpV4>
{
public DnsResourceDataIpV4()
{
}
public DnsResourceDataIpV4(IpV4Address data)
{
Data = data;
}
public IpV4Address Data { get; private set; }
public bool Equals(DnsResourceDataIpV4 other)
{
return other != null && Data.Equals(other.Data);
}
public sealed override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataIpV4);
}
internal sealed override int GetLength()
{
return IpV4Address.SizeOf;
}
internal sealed override void WriteDataSimple(byte[] buffer, int offset)
{
buffer.Write(offset, Data, Endianity.Big);
}
internal sealed override DnsResourceData CreateInstance(DataSegment data)
{
return new DnsResourceDataIpV4(data.ReadIpV4Address(0, Endianity.Big));
}
} }
} }
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
namespace PcapDotNet.Packets.Dns namespace PcapDotNet.Packets.Dns
{ {
public class DnsResourceDataUnknown : DnsResourceData, IEquatable<DnsResourceDataUnknown> public class DnsResourceDataUnknown : DnsResourceDataSimple, IEquatable<DnsResourceDataUnknown>
{ {
public DnsResourceDataUnknown(DataSegment data) public DnsResourceDataUnknown(DataSegment data)
{ {
...@@ -16,20 +16,24 @@ namespace PcapDotNet.Packets.Dns ...@@ -16,20 +16,24 @@ namespace PcapDotNet.Packets.Dns
return other != null && Data.Equals(other.Data); return other != null && Data.Equals(other.Data);
} }
public override bool Equals(object obj) public sealed override bool Equals(DnsResourceData other)
{ {
return Equals(obj as DnsResourceDataUnknown); return Equals(other as DnsResourceDataUnknown);
} }
internal override int GetLength(DnsDomainNameCompressionData compressionData, int offsetInDns) internal override int GetLength()
{ {
return Data.Length; return Data.Length;
} }
internal override int WriteData(byte[] buffer, int dnsOffset, int offsetInDns, DnsDomainNameCompressionData compressionData) internal override void WriteDataSimple(byte[] buffer, int offset)
{ {
Data.Write(buffer, dnsOffset + offsetInDns); Data.Write(buffer, offset);
return Data.Length; }
internal override DnsResourceData CreateInstance(DataSegment data)
{
return new DnsResourceDataUnknown(data);
} }
} }
} }
\ No newline at end of file
...@@ -6,7 +6,7 @@ using PcapDotNet.Base; ...@@ -6,7 +6,7 @@ using PcapDotNet.Base;
namespace PcapDotNet.Packets namespace PcapDotNet.Packets
{ {
internal static class OptionComplexFactory<TOptionType>// : OptionComplexFactoryBase internal static class OptionComplexFactory<TOptionType>
{ {
/// <summary> /// <summary>
/// The header length in bytes for the option (type and size). /// The header length in bytes for the option (type and size).
......
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