Commit 23a7ca2c authored by Brickner_cp's avatar Brickner_cp

DNS

parent a8a38234
...@@ -160,6 +160,12 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -160,6 +160,12 @@ namespace PcapDotNet.Packets.TestUtils
(ulong)(random.Next(10) * Math.Pow(10, random.Next(10))), (ulong)(random.Next(10) * Math.Pow(10, random.Next(10))),
random.NextUInt(), random.NextUInt(), random.NextUInt()); random.NextUInt(), random.NextUInt(), random.NextUInt());
case DnsType.Nxt:
byte[] typeBitMap = random.NextBytes(random.Next(DnsResourceDataNextDomain.MaxTypeBitMapLength + 1));
if (typeBitMap.Length > 0 && typeBitMap[typeBitMap.Length - 1] == 0)
typeBitMap[typeBitMap.Length - 1] = random.NextByte(1, 256);
return new DnsResourceDataNextDomain(random.NextDnsDomainName(), new DataSegment(typeBitMap));
default: default:
return new DnsResourceDataAnything(random.NextDataSegment(random.Next(100))); return new DnsResourceDataAnything(random.NextDataSegment(random.Next(100)));
} }
......
...@@ -53,6 +53,8 @@ namespace PcapDotNet.Packets ...@@ -53,6 +53,8 @@ namespace PcapDotNet.Packets
get { return Buffer[StartOffset + offset]; } get { return Buffer[StartOffset + offset]; }
} }
public byte Last { get { return this[Length - 1]; } }
/// <summary> /// <summary>
/// Returns the Segment's bytes as a read only MemoryStream with a non-public buffer. /// Returns the Segment's bytes as a read only MemoryStream with a non-public buffer.
/// </summary> /// </summary>
......
...@@ -2246,8 +2246,14 @@ namespace PcapDotNet.Packets.Dns ...@@ -2246,8 +2246,14 @@ namespace PcapDotNet.Packets.Dns
byte version = data[Offset.Version]; byte version = data[Offset.Version];
ulong size = ReadSize(data[Offset.Size]); ulong size = ReadSize(data[Offset.Size]);
if (size > MaxSizeValue)
return null;
ulong horizontalPrecision = ReadSize(data[Offset.HorizontalPrecision]); ulong horizontalPrecision = ReadSize(data[Offset.HorizontalPrecision]);
if (horizontalPrecision > MaxSizeValue)
return null;
ulong verticalPrecision = ReadSize(data[Offset.VerticalPrecision]); ulong verticalPrecision = ReadSize(data[Offset.VerticalPrecision]);
if (verticalPrecision > MaxSizeValue)
return null;
uint latitude = data.ReadUInt(Offset.Latitude, Endianity.Big); uint latitude = data.ReadUInt(Offset.Latitude, Endianity.Big);
uint longitude = data.ReadUInt(Offset.Longitude, Endianity.Big); uint longitude = data.ReadUInt(Offset.Longitude, Endianity.Big);
uint altitude = data.ReadUInt(Offset.Altitude, Endianity.Big); uint altitude = data.ReadUInt(Offset.Altitude, Endianity.Big);
...@@ -2291,4 +2297,139 @@ namespace PcapDotNet.Packets.Dns ...@@ -2291,4 +2297,139 @@ namespace PcapDotNet.Packets.Dns
return (ulong)((value >> 4) * Math.Pow(10, value & 0x0F)); return (ulong)((value >> 4) * Math.Pow(10, value & 0x0F));
} }
} }
/// <summary>
/// <pre>
/// +------------------+
/// | next domain name |
/// | |
/// +------------------+
/// | type bit map |
/// | |
/// +------------------+
/// </summary>
[DnsTypeRegistration(Type = DnsType.Nxt)]
public sealed class DnsResourceDataNextDomain : DnsResourceData, IEquatable<DnsResourceDataNextDomain>
{
public const int MaxTypeBitMapLength = 16;
public const DnsType MaxTypeBitMapDnsType = (DnsType)(8 * MaxTypeBitMapLength);
public DnsResourceDataNextDomain()
: this(DnsDomainName.Root, DataSegment.Empty)
{
}
public DnsResourceDataNextDomain(DnsDomainName nextDomainName, DataSegment typeBitMap)
{
if (typeBitMap.Length > MaxTypeBitMapLength)
throw new ArgumentOutOfRangeException("typeBitMap", typeBitMap.Length, string.Format("Cannot be longer than {0} bytes.", MaxTypeBitMapLength));
if (typeBitMap.Length > 0 && typeBitMap.Last == 0)
throw new ArgumentOutOfRangeException("typeBitMap", typeBitMap, "Last byte cannot be 0x00");
NextDomainName = nextDomainName;
TypeBitMap = typeBitMap;
}
/// <summary>
/// The next domain name according to the canonical DNS name order.
/// </summary>
public DnsDomainName NextDomainName { get; private set; }
/// <summary>
/// One bit per RR type present for the owner name.
/// A one bit indicates that at least one RR of that type is present for the owner name.
/// A zero indicates that no such RR is present.
/// All bits not specified because they are beyond the end of the bit map are assumed to be zero.
/// Note that bit 30, for NXT, will always be on so the minimum bit map length is actually four octets.
/// Trailing zero octets are prohibited in this format.
/// The first bit represents RR type zero (an illegal type which can not be present) and so will be zero in this format.
/// This format is not used if there exists an RR with a type number greater than 127.
/// If the zero bit of the type bit map is a one, it indicates that a different format is being used which will always be the case if a type number greater than 127 is present.
/// </summary>
public DataSegment TypeBitMap { get; private set; }
public bool IsTypePresentForOwner(DnsType dnsType)
{
if (dnsType >= MaxTypeBitMapDnsType)
throw new ArgumentOutOfRangeException("dnsType", dnsType, string.Format("Cannot be bigger than {0}.", MaxTypeBitMapDnsType));
int byteOffset;
byte mask;
DnsTypeToByteOffsetAndMask(out byteOffset, out mask, dnsType);
if (byteOffset > TypeBitMap.Length)
return false;
return TypeBitMap.ReadBool(byteOffset, mask);
}
public static DataSegment CreateTypeBitMap(IEnumerable<DnsType> typesPresentForOwner)
{
DnsType maxDnsType = typesPresentForOwner.Max();
int length = (ushort)(maxDnsType + 7) / 8;
if (length == 0)
return DataSegment.Empty;
byte[] typeBitMapBuffer = new byte[length];
foreach (DnsType dnsType in typesPresentForOwner)
{
int byteOffset;
byte mask;
DnsTypeToByteOffsetAndMask(out byteOffset, out mask, dnsType);
typeBitMapBuffer[byteOffset] |= mask;
}
return new DataSegment(typeBitMapBuffer);
}
public bool Equals(DnsResourceDataNextDomain other)
{
return other != null &&
NextDomainName.Equals(other.NextDomainName) &&
TypeBitMap.Equals(other.TypeBitMap);
}
public override bool Equals(DnsResourceData other)
{
return Equals(other as DnsResourceDataNextDomain);
}
internal override int GetLength(DnsDomainNameCompressionData compressionData, int offsetInDns)
{
return NextDomainName.GetLength(compressionData, offsetInDns) + TypeBitMap.Length;
}
internal override int WriteData(byte[] buffer, int dnsOffset, int offsetInDns, DnsDomainNameCompressionData compressionData)
{
int numBytesWritten = NextDomainName.Write(buffer, dnsOffset, compressionData, offsetInDns);
TypeBitMap.Write(buffer, dnsOffset + offsetInDns + numBytesWritten);
return numBytesWritten + TypeBitMap.Length;
}
internal override DnsResourceData CreateInstance(DnsDatagram dns, int offsetInDns, int length)
{
DnsDomainName nextDomainName;
int nextDomainNameLength;
if (!DnsDomainName.TryParse(dns, offsetInDns, length, out nextDomainName, out nextDomainNameLength))
return null;
offsetInDns += nextDomainNameLength;
length -= nextDomainNameLength;
if (length > MaxTypeBitMapLength)
return null;
DataSegment typeBitMap = dns.SubSegment(offsetInDns, length);
if (length != 0 && typeBitMap.Last == 0)
return null;
return new DnsResourceDataNextDomain(nextDomainName, typeBitMap);
}
private static void DnsTypeToByteOffsetAndMask(out int byteOffset, out byte mask, DnsType dnsType)
{
byteOffset = (ushort)dnsType / 8;
mask = (byte)(1 << ((ushort)dnsType % 8));
}
}
} }
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