Commit 6703c3cd authored by Brickner_cp's avatar Brickner_cp

DNS

parent 82914442
......@@ -554,6 +554,11 @@ namespace PcapDotNet.Base
return ((long)this).ToString(CultureInfo.InvariantCulture);
}
public string ToString(string format)
{
return ((long)this).ToString(format);
}
private UInt48(long value)
{
_mostSignificant = (ushort)(value >> 32);
......
......@@ -77,6 +77,7 @@
<Compile Include="MoreTcpOption.cs" />
<Compile Include="WiresharkDatagramComparer.cs" />
<Compile Include="WiresharkDatagramComparerArp.cs" />
<Compile Include="WiresharkDatagramComparerDns.cs" />
<Compile Include="WiresharkDatagramComparerEthernet.cs" />
<Compile Include="WiresharkDatagramComparerGre.cs" />
<Compile Include="WiresharkDatagramComparerHttp.cs" />
......
......@@ -7,6 +7,7 @@ using System.Linq;
using System.Xml.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PcapDotNet.Packets;
using PcapDotNet.Packets.Dns;
using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.Gre;
using PcapDotNet.Packets.Http;
......@@ -30,7 +31,7 @@ namespace PcapDotNet.Core.Test
private const bool IsRetry
// = true;
= false;
private const byte RetryNumber = 190;
private const byte RetryNumber = 27;
/// <summary>
/// Gets or sets the test context which provides
......@@ -135,12 +136,24 @@ namespace PcapDotNet.Core.Test
Gre,
Udp,
Tcp,
Dns,
Http,
}
private static Packet CreateRandomPacket(Random random)
{
PacketType packetType = random.NextEnum<PacketType>();
// BUG: Limited timestamp due to Windows bug: https://connect.microsoft.com/VisualStudio/feedback/details/559198/net-4-datetime-tolocaltime-is-sometimes-wrong
Packet packet;
do
{
packet = CreateRandomPacket(random, packetType);
} while (packet.Length > 65536);
return packet;
}
private static Packet CreateRandomPacket(Random random, PacketType packetType)
{
DateTime packetTimestamp =
random.NextDateTime(new DateTime(2010,1,1), new DateTime(2010,12,31)).ToUniversalTime().ToLocalTime();
//random.NextDateTime(PacketTimestamp.MinimumPacketTimestamp, PacketTimestamp.MaximumPacketTimestamp).ToUniversalTime().ToLocalTime();
......@@ -149,7 +162,7 @@ namespace PcapDotNet.Core.Test
IpV4Layer ipV4Layer = random.NextIpV4Layer();
PayloadLayer payloadLayer = random.NextPayloadLayer(random.Next(100));
switch (random.NextEnum<PacketType>())
switch (packetType)
// switch (PacketType.Icmp)
{
case PacketType.Ethernet:
......@@ -201,6 +214,21 @@ namespace PcapDotNet.Core.Test
ipV4Layer.Fragmentation = IpV4Fragmentation.None;
return PacketBuilder.Build(packetTimestamp, ethernetLayer, ipV4Layer, random.NextTcpLayer(), payloadLayer);
case PacketType.Dns:
ethernetLayer.EtherType = EthernetType.None;
ipV4Layer.Protocol = null;
if (random.NextBool())
ipV4Layer.Fragmentation = IpV4Fragmentation.None;
UdpLayer udpLayer = random.NextUdpLayer();
DnsLayer dnsLayer = random.NextDnsLayer();
if (dnsLayer.IsQuery)
udpLayer.DestinationPort = 53;
else
udpLayer.SourcePort = 53;
return PacketBuilder.Build(packetTimestamp, ethernetLayer, ipV4Layer, udpLayer, dnsLayer);
case PacketType.Http:
ethernetLayer.EtherType = EthernetType.None;
ipV4Layer.Protocol = null;
......@@ -223,7 +251,10 @@ namespace PcapDotNet.Core.Test
private static IEnumerable<Packet> CreateRandomPackets(Random random, int numPackets)
{
for (int i = 0; i != numPackets; ++i)
yield return CreateRandomPacket(random);
{
Packet packet = CreateRandomPacket(random);
yield return packet;
}
}
private static void ComparePacketsToWireshark(params Packet[] packets)
......
......@@ -67,6 +67,9 @@ namespace PcapDotNet.Core.Test
case "tcp":
return new WiresharkDatagramComparerTcp();
case "dns":
return new WiresharkDatagramComparerDns();
case "http":
return new WiresharkDatagramComparerHttp();
......
......@@ -5,39 +5,41 @@ namespace PcapDotNet.Core.Test
{
public static class WiresharkStringExtensions
{
public static string ToWiresharkLiteral(this string value)
public static string ToWiresharkLiteral(this string value, bool putLeadingZerosInHexAndBackslashesBeforeSpecialCharacters = true)
{
StringBuilder result = new StringBuilder();
for (int i = 0; i != value.Length; ++i)
{
char currentChar = value[i];
if (currentChar == '\0')
return result.ToString();
if (putLeadingZerosInHexAndBackslashesBeforeSpecialCharacters)
{
switch (currentChar)
{
case '\\':
case '"':
result.Append('\\');
result.Append(currentChar);
break;
continue;
case '\r':
result.Append(@"\r");
break;
continue;
case '\n':
result.Append(@"\n");
break;
continue;
}
}
default:
if (currentChar >= 0x7F || currentChar < 0x20)
{
result.Append(@"\x");
result.Append(((int)currentChar).ToString("x2"));
break;
result.Append(((int)currentChar).ToString("x" + (putLeadingZerosInHexAndBackslashesBeforeSpecialCharacters ? "2" : "")));
}
else
result.Append(currentChar);
break;
}
}
return result.ToString();
......
......@@ -24,7 +24,7 @@ namespace PcapDotNet.Core.Test
{
XAttribute attribute = element.Attribute(attributeName);
if (attribute == null)
throw new ArgumentException("element " + element.Name + " doesn't contain attribute " + attributeName, "attributeName");
return string.Empty;
return attribute.Value;
}
......@@ -168,5 +168,15 @@ namespace PcapDotNet.Core.Test
{
element.AssertValue(expectedValue.ToString("x8"));
}
public static void AssertValue(this XElement element, UInt48 expectedValue)
{
element.AssertValue(expectedValue.ToString("x12"));
}
public static void AssertValue(this XElement element, SerialNumber32 expectedValue)
{
element.AssertValue(expectedValue.Value);
}
}
}
\ No newline at end of file
......@@ -95,31 +95,31 @@ namespace PcapDotNet.Packets.Test
dnsLayer.Additionals = new List<DnsDataResourceRecord>();
TestDomainNameCompression(0, dnsLayer);
dnsLayer.Queries.Add(new DnsQueryResourceRecord(new DnsDomainName(""), DnsType.All, DnsClass.In));
dnsLayer.Queries.Add(new DnsQueryResourceRecord(new DnsDomainName(""), DnsType.Any, DnsClass.In));
TestDomainNameCompression(0, dnsLayer);
dnsLayer.Answers.Add(new DnsDataResourceRecord(new DnsDomainName(""), DnsType.All, DnsClass.In, 100, new DnsResourceDataAnything(DataSegment.Empty)));
dnsLayer.Answers.Add(new DnsDataResourceRecord(new DnsDomainName(""), DnsType.Any, DnsClass.In, 100, new DnsResourceDataAnything(DataSegment.Empty)));
TestDomainNameCompression(0, dnsLayer);
dnsLayer.Answers.Add(new DnsDataResourceRecord(new DnsDomainName("abc"), DnsType.All, DnsClass.In, 100, new DnsResourceDataAnything(DataSegment.Empty)));
dnsLayer.Answers.Add(new DnsDataResourceRecord(new DnsDomainName("abc"), DnsType.Any, DnsClass.In, 100, new DnsResourceDataAnything(DataSegment.Empty)));
TestDomainNameCompression(0, dnsLayer);
dnsLayer.Answers.Add(new DnsDataResourceRecord(new DnsDomainName("abc"), DnsType.All, DnsClass.In, 100, new DnsResourceDataAnything(DataSegment.Empty)));
dnsLayer.Answers.Add(new DnsDataResourceRecord(new DnsDomainName("abc"), DnsType.Any, DnsClass.In, 100, new DnsResourceDataAnything(DataSegment.Empty)));
TestDomainNameCompression(3, dnsLayer);
dnsLayer.Answers.Add(new DnsDataResourceRecord(new DnsDomainName("def.abc"), DnsType.All, DnsClass.In, 100, new DnsResourceDataAnything(DataSegment.Empty)));
dnsLayer.Answers.Add(new DnsDataResourceRecord(new DnsDomainName("def.abc"), DnsType.Any, DnsClass.In, 100, new DnsResourceDataAnything(DataSegment.Empty)));
TestDomainNameCompression(6, dnsLayer);
dnsLayer.Answers.Add(new DnsDataResourceRecord(new DnsDomainName("abc.def"), DnsType.All, DnsClass.In, 100, new DnsResourceDataAnything(DataSegment.Empty)));
dnsLayer.Answers.Add(new DnsDataResourceRecord(new DnsDomainName("abc.def"), DnsType.Any, DnsClass.In, 100, new DnsResourceDataAnything(DataSegment.Empty)));
TestDomainNameCompression(6, dnsLayer);
dnsLayer.Authorities.Add(new DnsDataResourceRecord(new DnsDomainName("abc.def"), DnsType.All, DnsClass.In, 100, new DnsResourceDataAnything(DataSegment.Empty)));
dnsLayer.Authorities.Add(new DnsDataResourceRecord(new DnsDomainName("abc.def"), DnsType.Any, DnsClass.In, 100, new DnsResourceDataAnything(DataSegment.Empty)));
TestDomainNameCompression(13, dnsLayer);
dnsLayer.Authorities.Add(new DnsDataResourceRecord(new DnsDomainName("abd.def"), DnsType.All, DnsClass.In, 100, new DnsResourceDataAnything(DataSegment.Empty)));
dnsLayer.Authorities.Add(new DnsDataResourceRecord(new DnsDomainName("abd.def"), DnsType.Any, DnsClass.In, 100, new DnsResourceDataAnything(DataSegment.Empty)));
TestDomainNameCompression(16, dnsLayer);
dnsLayer.Additionals.Add(new DnsDataResourceRecord(new DnsDomainName("hello.abd.def"), DnsType.All, DnsClass.In, 100, new DnsResourceDataAnything(DataSegment.Empty)));
dnsLayer.Additionals.Add(new DnsDataResourceRecord(new DnsDomainName("hello.abd.def"), DnsType.Any, DnsClass.In, 100, new DnsResourceDataAnything(DataSegment.Empty)));
TestDomainNameCompression(23, dnsLayer);
}
......
......@@ -14,6 +14,8 @@ namespace PcapDotNet.Packets.TestUtils
{
public static DnsLayer NextDnsLayer(this Random random)
{
const int MaxRecordsPerSection = 5;
DnsLayer dnsLayer = new DnsLayer();
dnsLayer.Id = random.NextUShort();
dnsLayer.IsQuery = random.NextBool();
......@@ -22,25 +24,26 @@ namespace PcapDotNet.Packets.TestUtils
dnsLayer.IsTruncated = random.NextBool();
dnsLayer.IsRecusionDesired = random.NextBool();
dnsLayer.IsRecusionAvailable = random.NextBool();
dnsLayer.FutureUse = random.NextByte(DnsDatagram.MaxFutureUse + 1);
dnsLayer.ResponseCode = random.NextEnum<DnsResponseCode>();
dnsLayer.FutureUse = random.NextBool();
dnsLayer.ResponseCode = random.NextEnum(DnsResponseCode.BadVersOrBadSig, DnsResponseCode.BadKey, DnsResponseCode.BadTime, DnsResponseCode.BadMode,
DnsResponseCode.BadName, DnsResponseCode.BadAlg, DnsResponseCode.BadTrunc);
dnsLayer.DomainNameCompressionMode = random.NextEnum<DnsDomainNameCompressionMode>();
int numQueries = random.Next(10);
int numQueries = random.Next(MaxRecordsPerSection + 1);
List<DnsQueryResourceRecord> queries = new List<DnsQueryResourceRecord>();
for (int i = 0; i != numQueries; ++i)
queries.Add(random.NextDnsQueryResourceRecord());
dnsLayer.Queries = queries;
int numAnswers = random.Next(10);
int numAnswers = random.Next(MaxRecordsPerSection + 1);
List<DnsDataResourceRecord> answers = new List<DnsDataResourceRecord>();
for (int i = 0; i != numAnswers; ++i)
answers.Add(random.NextDnsDataResourceRecord());
dnsLayer.Answers = answers;
int numAuthorities = random.Next(10);
int numAuthorities = random.Next(MaxRecordsPerSection + 1);
List<DnsDataResourceRecord> authorities = new List<DnsDataResourceRecord>();
for (int i = 0; i != numAuthorities; ++i)
authorities.Add(random.NextDnsDataResourceRecord());
dnsLayer.Authorities = authorities;
int numAdditionals = random.Next(10);
int numAdditionals = random.Next(MaxRecordsPerSection + 1);
List<DnsDataResourceRecord> additionals = new List<DnsDataResourceRecord>();
for (int i = 0; i != numAdditionals; ++i)
additionals.Add(random.NextDnsDataResourceRecord());
......@@ -179,7 +182,8 @@ namespace PcapDotNet.Packets.TestUtils
random.NextDataSegment(random.Next(100)));
case DnsType.Key:
return new DnsResourceDataKey(random.NextBool(), random.NextBool(), random.NextEnum<DnsKeyNameType>(), random.NextFlags<DnsKeySignatory>(),
return new DnsResourceDataKey(random.NextBool(), random.NextBool(), random.NextBool(), random.NextBool(), random.NextBool(),
random.NextBool(), random.NextEnum<DnsKeyNameType>(), random.NextFlags<DnsKeySignatory>(),
random.NextEnum<DnsKeyProtocol>(), random.NextEnum<DnsAlgorithm>(),
random.NextBool() ? (ushort?)random.NextUShort() : null, random.NextDataSegment(random.Next(100)));
......@@ -275,7 +279,8 @@ namespace PcapDotNet.Packets.TestUtils
return new DnsResourceDataNextDomainSecure(random.NextDnsDomainName(), random.NextDnsTypeArray(random.Next(100)));
case DnsType.DnsKey:
return new DnsResourceDataDnsKey(random.NextBool(), random.NextBool(), random.NextByte(), random.NextEnum<DnsAlgorithm>(), random.NextDataSegment(random.Next(100)));
return new DnsResourceDataDnsKey(random.NextBool(), random.NextBool(), random.NextBool(), random.NextByte(), random.NextEnum<DnsAlgorithm>(),
random.NextDataSegment(random.Next(100)));
case DnsType.NSec3:
return new DnsResourceDataNextDomainSecure3(random.NextEnum<DnsSecNSec3HashAlgorithm>(), random.NextFlags<DnsSecNSec3Flags>(),
......
......@@ -57,6 +57,11 @@ namespace PcapDotNet.Packets
public byte Last { get { return this[Length - 1]; } }
public DataSegment SubSegment(int offset, int length)
{
return SubSegment(ref offset, length);
}
/// <summary>
/// Returns the Segment's bytes as a read only MemoryStream with a non-public buffer.
/// </summary>
......@@ -177,11 +182,6 @@ namespace PcapDotNet.Packets
return subSegemnt;
}
internal DataSegment SubSegment(int offset, int length)
{
return SubSegment(ref offset, length);
}
internal bool ReadBool(int offset, byte mask)
{
return (this[offset] & mask) == mask;
......
......@@ -33,6 +33,11 @@ namespace PcapDotNet.Packets.Dns
}
}
public bool IsRoot
{
get { return NumLabels == 0; }
}
public int NonCompressedLength
{
get
......@@ -43,9 +48,9 @@ namespace PcapDotNet.Packets.Dns
public override string ToString()
{
if (_ascii == null)
_ascii = _labels.Select(label => label.ToString(Encoding.UTF8)).SequenceToString('.') + ".";
return _ascii;
if (_utf8 == null)
_utf8 = _labels.Select(label => label.ToString(Encoding.UTF8)).SequenceToString('.') + ".";
return _utf8;
}
public bool Equals(DnsDomainName other)
......@@ -160,6 +165,6 @@ namespace PcapDotNet.Packets.Dns
private static readonly DnsDomainName _root = new DnsDomainName("");
private readonly List<DataSegment> _labels;
private string _ascii;
private string _utf8;
}
}
\ No newline at end of file
......@@ -30,7 +30,11 @@ namespace PcapDotNet.Packets.Dns
public bool IsRecusionAvailable { get; set;}
public byte FutureUse { get; set; }
public bool FutureUse { get; set; }
public bool IsAuthenticData { get; set; }
public bool IsCheckingDisabled { get; set; }
public DnsResponseCode ResponseCode { get; set; }
......@@ -77,8 +81,8 @@ namespace PcapDotNet.Packets.Dns
protected override void Write(byte[] buffer, int offset)
{
DnsDatagram.Write(buffer, offset,
Id, IsResponse, Opcode, IsAuthoritiveAnswer, IsTruncated, IsRecusionDesired, IsRecusionAvailable, FutureUse, ResponseCode,
Queries, Answers, Authorities, Additionals, DomainNameCompressionMode);
Id, IsResponse, Opcode, IsAuthoritiveAnswer, IsTruncated, IsRecusionDesired, IsRecusionAvailable, FutureUse, IsAuthenticData,
IsCheckingDisabled, ResponseCode, Queries, Answers, Authorities, Additionals, DomainNameCompressionMode);
}
/// <summary>
......@@ -99,15 +103,17 @@ namespace PcapDotNet.Packets.Dns
public bool Equals(DnsLayer other)
{
return other != null &&
Id == other.Id &&
IsQuery == other.IsQuery &&
Opcode == other.Opcode &&
IsAuthoritiveAnswer == other.IsAuthoritiveAnswer &&
IsTruncated == other.IsTruncated &&
IsRecusionDesired == other.IsRecusionDesired &&
IsRecusionAvailable == other.IsRecusionAvailable &&
FutureUse == other.FutureUse &&
ResponseCode == other.ResponseCode &&
Id.Equals(other.Id) &&
IsQuery.Equals(other.IsQuery) &&
Opcode.Equals(other.Opcode) &&
IsAuthoritiveAnswer.Equals(other.IsAuthoritiveAnswer) &&
IsTruncated.Equals(other.IsTruncated) &&
IsRecusionDesired.Equals(other.IsRecusionDesired) &&
IsRecusionAvailable.Equals(other.IsRecusionAvailable) &&
FutureUse.Equals(other.FutureUse) &&
IsAuthenticData.Equals(other.IsAuthenticData) &&
IsCheckingDisabled.Equals(other.IsCheckingDisabled) &&
ResponseCode.Equals(other.ResponseCode) &&
(Queries.IsNullOrEmpty() && other.Queries.IsNullOrEmpty() || Queries.SequenceEqual(other.Queries)) &&
(Answers.IsNullOrEmpty() && other.Answers.IsNullOrEmpty() || Answers.SequenceEqual(other.Answers)) &&
(Authorities.IsNullOrEmpty() && other.Authorities.IsNullOrEmpty() || Authorities.SequenceEqual(other.Authorities)) &&
......
......@@ -89,7 +89,7 @@ namespace PcapDotNet.Packets.Dns
internal static bool TryParseBase(DnsDatagram dns, int offsetInDns,
out DnsDomainName domainName, out DnsType type, out DnsClass dnsClass, out int numBytesRead)
{
type = DnsType.All;
type = DnsType.Any;
dnsClass = DnsClass.Any;
if (!DnsDomainName.TryParse(dns, offsetInDns, dns.Length - offsetInDns, out domainName, out numBytesRead))
return false;
......
......@@ -178,7 +178,7 @@
Sig = 24,
/// <summary>
/// RFCs 2535, 3755, 4034.
/// RFCs 2065, 2535, 3755, 4034.
/// For security key.
/// Payload type: DnsResourceDataKey.
/// </summary>
......@@ -340,7 +340,7 @@
NSec = 47,
/// <summary>
/// RFCs 3755, 4034.
/// RFCs 3755, 4034, 5011.
/// DNSKEY.
/// Represents the public key.
/// Payload type: DnsResourceDataDnsKey.
......@@ -483,7 +483,7 @@
/// A request for all records
/// Query Type.
/// </summary>
All = 255,
Any = 255,
/// <summary>
/// Faltstrom.
......
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