Commit b9a4771a authored by Brickner_cp's avatar Brickner_cp

WinPcap 4.1.3.

Wireshark 1.12.1.
Add TcpDatagram.IsNonceSum property.
Fix IPv4 and IPv6 QuickStart Option so that Nonce doesn't include the reserved bits.
Fix IpV6MobilityOptionContextRequest to include the reserved field.
Fix UInt128 Parsing from hexa and ToString() to hexa to handle the extra 0 used in BigInteger correctly.
Fix RFC reference in IpV6MobilityOptionIpV6AddressPrefix.
parent 106d239c
......@@ -254,9 +254,17 @@ namespace PcapDotNet.Base.Test
[TestMethod]
public void ToStringTest()
{
const string ValueString = "0123456789ABCDEFFEDCBA9876543210";
const string ValueString = "1234567890abcdeffedcba0987654321";
UInt128 value = UInt128.Parse(ValueString, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
Assert.AreEqual(ValueString, value.ToString("x32"));
}
[TestMethod]
public void ToStringTestFirstBitIsOne()
{
const string ValueString = "fedcba9876543210fedcba9876543210";
UInt128 value = UInt128.Parse(ValueString, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
Assert.AreEqual(ValueString, value.ToString("X32"));
Assert.AreEqual(ValueString, value.ToString("x32"));
}
}
}
\ No newline at end of file
......@@ -223,6 +223,10 @@ namespace PcapDotNet.Base
/// </remarks>
public static UInt128 Parse(string value, NumberStyles style, IFormatProvider provider)
{
if (value == null)
throw new ArgumentNullException("value");
if ((style & NumberStyles.HexNumber) == NumberStyles.HexNumber)
value = "0" + value;
BigInteger bigIntegerValue = BigInteger.Parse(value, style, provider);
if (bigIntegerValue < 0 || bigIntegerValue > MaxValue)
throw new OverflowException("Value was either too large or too small for an UInt128.");
......@@ -523,6 +527,28 @@ namespace PcapDotNet.Base
return new UInt128(value1._mostSignificant & value2._mostSignificant, value1._leastSignificant & value2._leastSignificant);
}
/// <summary>
/// Bitwise ors between two values.
/// </summary>
/// <param name="value1">The first value to do bitwise or.</param>
/// <param name="value2">The second value to do bitwise or.</param>
/// <returns>The two values after they were bitwise ored.</returns>
public static UInt128 operator |(UInt128 value1, UInt128 value2)
{
return BitwiseOr(value1, value2);
}
/// <summary>
/// Bitwise ors between two values.
/// </summary>
/// <param name="value1">The first value to do bitwise or.</param>
/// <param name="value2">The second value to do bitwise or.</param>
/// <returns>The two values after they were bitwise ored.</returns>
public static UInt128 BitwiseOr(UInt128 value1, UInt128 value2)
{
return new UInt128(value1._mostSignificant | value2._mostSignificant, value1._leastSignificant | value2._leastSignificant);
}
/// <summary>
/// Sums the given values and returns the sum.
/// </summary>
......@@ -616,7 +642,10 @@ namespace PcapDotNet.Base
/// </remarks>
public string ToString(string format, IFormatProvider formatProvider)
{
return ((BigInteger)this).ToString(format, formatProvider);
string bigIntegerString = ((BigInteger)this).ToString(format, formatProvider);
if (_mostSignificant >> 63 == 1 && bigIntegerString[0] == '0')
return bigIntegerString.Substring(1);
return bigIntegerString;
}
/// <summary>
......
......@@ -10,150 +10,6 @@ namespace PcapDotNet.Core.Test
{
internal static class IpV4OptionExtensions
{
public static string GetWiresharkString(this IpV4Option option)
{
switch (option.OptionType)
{
case IpV4OptionType.EndOfOptionList:
return "End of Option List (EOL)";
case IpV4OptionType.NoOperation:
return "No-Operation (NOP)";
case IpV4OptionType.BasicSecurity:
return "Security";
case IpV4OptionType.LooseSourceRouting:
return "Loose source route (" + option.Length + " bytes)";
case IpV4OptionType.StrictSourceRouting:
return "Strict source route (" + option.Length + " bytes)";
case IpV4OptionType.RecordRoute:
return "Record route (" + option.Length + " bytes)";
case IpV4OptionType.StreamIdentifier:
return "Stream identifier: " + ((IpV4OptionStreamIdentifier)option).Identifier;
case IpV4OptionType.InternetTimestamp:
return "Time stamp" + (option.Length < 5 ? " (with option length = " + option.Length + " bytes; should be >= 5)" : ":");
case IpV4OptionType.TraceRoute:
return "Unknown (0x52) (12 bytes)";
case IpV4OptionType.RouterAlert:
ushort routerAlertValue = ((IpV4OptionRouterAlert)option).Value;
return "Router Alert: " + ((routerAlertValue != 0)
? "Unknown (" + routerAlertValue + ")"
: "Every router examines packet");
case IpV4OptionType.QuickStart:
IpV4OptionQuickStart quickStart = (IpV4OptionQuickStart)option;
StringBuilder quickStartWireshark = new StringBuilder("Quick-Start: ");
quickStartWireshark.Append(quickStart.QuickStartFunction == IpV4OptionQuickStartFunction.RateRequest ? "Rate request" : "Rate report");
quickStartWireshark.Append(", ");
if (quickStart.RateKbps == 0)
quickStartWireshark.Append("0 bit/s");
else if (quickStart.RateKbps < 1024)
quickStartWireshark.Append(quickStart.RateKbps + " kbit/s");
else if (quickStart.RateKbps < 1024 * 1024)
quickStartWireshark.Append(((double)quickStart.RateKbps / 1000).ToString(CultureInfo.InvariantCulture) + " Mbit/s");
else
quickStartWireshark.Append(((double)quickStart.RateKbps / 1000000).ToString(CultureInfo.InvariantCulture) + " Gbit/s");
if (quickStart.QuickStartFunction == IpV4OptionQuickStartFunction.RateRequest)
quickStartWireshark.Append(", QS TTL " + quickStart.Ttl);
return quickStartWireshark.ToString();
case (IpV4OptionType)134:
return "Commercial IP security option" + (option.Length >= 10
? string.Empty
: " (with option length = " + option.Length + " bytes; should be >= 10)");
default:
if (typeof(IpV4OptionType).GetEnumValues<IpV4OptionType>().Contains(option.OptionType))
throw new InvalidOperationException("Invalid option type " + option.OptionType);
return "Unknown (0x" + ((byte)option.OptionType).ToString("x2") + ") (" + option.Length + " bytes)";
}
}
public static IEnumerable<string> GetWiresharkSubfieldStrings(this IpV4Option option)
{
switch (option.OptionType)
{
case IpV4OptionType.EndOfOptionList:
case IpV4OptionType.NoOperation:
case IpV4OptionType.StreamIdentifier:
case IpV4OptionType.RouterAlert:
case IpV4OptionType.QuickStart:
break;
case IpV4OptionType.LooseSourceRouting:
case IpV4OptionType.StrictSourceRouting:
case IpV4OptionType.RecordRoute:
IpV4OptionRoute routeOption = (IpV4OptionRoute)option;
yield return "Pointer: " + (routeOption.PointedAddressIndex * 4 + 4);
for (int i = 0; i != routeOption.Route.Count; ++i)
yield return routeOption.Route[i] + (routeOption.PointedAddressIndex == i ? " <- (current)" : string.Empty);
break;
case IpV4OptionType.InternetTimestamp:
IpV4OptionTimestamp timestampOption = (IpV4OptionTimestamp)option;
if (timestampOption.CountTimestamps == 0)
break;
yield return "Pointer: " + (timestampOption.PointedIndex * 4 + 5);
yield return "Overflow: " + timestampOption.Overflow;
switch (timestampOption.TimestampType)
{
case IpV4OptionTimestampType.TimestampOnly:
yield return "Flag: Time stamps only";
IpV4OptionTimestampOnly timestampOnlyOption = (IpV4OptionTimestampOnly)option;
foreach (IpV4TimeOfDay timeOfDay in timestampOnlyOption.Timestamps)
yield return "Time stamp = " + timeOfDay.MillisecondsSinceMidnightUniversalTime;
break;
case IpV4OptionTimestampType.AddressAndTimestamp:
yield return "Flag: Time stamp and address";
IpV4OptionTimestampAndAddress timestampAndAddressOption = (IpV4OptionTimestampAndAddress)option;
foreach (IpV4OptionTimedAddress timedAddress in timestampAndAddressOption.TimedRoute)
{
yield return "Address = " + timedAddress.Address + ", " +
"time stamp = " + timedAddress.TimeOfDay.MillisecondsSinceMidnightUniversalTime;
}
break;
case IpV4OptionTimestampType.AddressPrespecified:
yield return "Flag: Time stamps for prespecified addresses";
IpV4OptionTimestampAndAddress timestampPrespecifiedOption = (IpV4OptionTimestampAndAddress)option;
foreach (IpV4OptionTimedAddress timedAddress in timestampPrespecifiedOption.TimedRoute)
{
yield return string.Format("Address = {0}, time stamp = {1}",
timedAddress.Address,
timedAddress.TimeOfDay.MillisecondsSinceMidnightUniversalTime);
}
break;
default:
throw new InvalidOperationException("Illegal timestamp type " + timestampOption.TimestampType);
}
break;
// ReSharper disable RedundantCaseLabel
case IpV4OptionType.BasicSecurity:
// ReSharper restore RedundantCaseLabel
default:
if (typeof(IpV4OptionType).GetEnumValues<IpV4OptionType>().Contains(option.OptionType))
throw new InvalidOperationException("Invalid option type " + option.OptionType);
break;
}
}
public static bool IsBadForWireshark(this IpV4Options options)
{
// TODO: This shouldn't be a factor once https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7043 is fixed.
......
......@@ -76,7 +76,10 @@ namespace PcapDotNet.Core.Test
}
#pragma warning restore 162
Random random = new Random();
int seed = new Random().Next();
Console.WriteLine("Seed: " + seed);
Random random = new Random(seed);
for (int i = 0; i != 10; ++i)
{
// Create packets
......@@ -436,7 +439,9 @@ namespace PcapDotNet.Core.Test
{
// Wireshark's preferences file is %APPDATA%\Wireshark\preferences
FileName = WiresharkTsharkPath,
Arguments = "-o udp.check_checksum:TRUE " +
Arguments = "-o ip.check_checksum:TRUE " +
"-o ipv6.use_geoip:FALSE " +
"-o udp.check_checksum:TRUE " +
"-o tcp.relative_sequence_numbers:FALSE " +
"-o tcp.analyze_sequence_numbers:FALSE " +
"-o tcp.track_bytes_in_flight:FALSE " +
......@@ -447,13 +452,20 @@ namespace PcapDotNet.Core.Test
WorkingDirectory = WiresharkDiretory,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};
Console.WriteLine("Starting process " + process.StartInfo.FileName + " " + process.StartInfo.Arguments);
process.Start();
Assert.IsTrue(process.Start());
string output = process.StandardOutput.ReadToEnd();
string errorOutput = process.StandardError.ReadToEnd();
process.WaitForExit();
Console.WriteLine(errorOutput);
File.WriteAllText(documentFilename, output);
// TODO: Remove this when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10651 is fixed.
if (process.ExitCode == 3)
return;
Assert.AreEqual(0, process.ExitCode);
}
// Fix pdml file
......@@ -533,7 +545,8 @@ namespace PcapDotNet.Core.Test
break;
default:
var comparer = WiresharkDatagramComparer.GetComparer(layer.Name(), layerNameToCount[layerName], parentLayerSuccess);
var comparer = WiresharkDatagramComparer.GetComparer(layer.Name(), layerNameToCount[layerName], layersContainer.Name(),
parentLayerSuccess);
if (comparer == null)
return;
currentDatagram = comparer.Compare(layer, currentDatagram);
......
......@@ -57,7 +57,7 @@ namespace PcapDotNet.Core.Test
return success;
}
public static WiresharkDatagramComparer GetComparer(string name, int count, bool parentLayerSuccess)
public static WiresharkDatagramComparer GetComparer(string name, int count, string parentName, bool parentLayerSuccess)
{
switch (name)
{
......@@ -78,7 +78,11 @@ namespace PcapDotNet.Core.Test
case "ah":
if (parentLayerSuccess)
{
// TODO: Remove this condition when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10705 is fixed.
if (parentName == "ipv6")
return new WiresharkDatagramComparerIpV6AuthenticationHeader(count);
}
return null;
case "mipv6":
......
......@@ -14,6 +14,7 @@ namespace PcapDotNet.Core.Test
protected override bool CompareField(XElement field, Datagram datagram)
{
field.AssertNoFields();
ArpDatagram arpDatagram = (ArpDatagram)datagram;
switch (field.Name())
{
......@@ -22,7 +23,7 @@ namespace PcapDotNet.Core.Test
break;
case "arp.proto.type":
field.AssertShowHex((ushort)arpDatagram.ProtocolType);
field.AssertShowDecimal((ushort)arpDatagram.ProtocolType);
break;
case "arp.hw.size":
......@@ -65,6 +66,8 @@ namespace PcapDotNet.Core.Test
break;
case "arp.isgratuitous":
case "arp.dst.drarp_error_status":
// TODO: Support DRARP (RFC 1931).
break;
default:
......
......@@ -28,11 +28,11 @@ namespace PcapDotNet.Core.Test
switch (field.Name())
{
case "dns.id":
field.AssertShowHex(dnsDatagram.Id);
field.AssertShowDecimal(dnsDatagram.Id);
break;
case "dns.flags":
field.AssertShowHex(dnsDatagram.Subsegment(2, 2).ToArray().ReadUShort(0, Endianity.Big));
field.AssertShowDecimal(dnsDatagram.Subsegment(2, 2).ToArray().ReadUShort(0, Endianity.Big));
foreach (var flagField in field.Fields())
{
switch (flagField.Name())
......@@ -147,7 +147,7 @@ namespace PcapDotNet.Core.Test
{
XElement[] resourceRecordFieldsArray= resourceRecordFields.ToArray();
DnsResourceRecord[] resourceRecordsArray = resourceRecords.ToArray();
if (resourceRecordFieldsArray.Length != resourceRecordsArray.Length)
if (resourceRecordFieldsArray.Length > resourceRecordsArray.Length)
{
var queryNameField = resourceRecordFieldsArray[resourceRecordsArray.Length].Fields().First();
if (queryNameField.Name() == "dns.qry.name")
......@@ -155,6 +155,13 @@ namespace PcapDotNet.Core.Test
else
Assert.AreEqual("dns.resp.name", queryNameField.Name());
}
else if (resourceRecordFieldsArray.Length < resourceRecordsArray.Length)
{
// TODO: This case should never happen when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10615 is fixed.
XElement lastDnsType = resourceRecordFieldsArray.Last().Fields().Skip(1).First();
lastDnsType.AssertName("dns.resp.type");
lastDnsType.AssertShowDecimal((ushort)DnsType.NextDomain);
}
for (int i = 0; i != resourceRecordsArray.Length; ++i)
{
ResetRecordFields();
......@@ -170,15 +177,27 @@ namespace PcapDotNet.Core.Test
resourceRecordAttributeField.AssertNoFields();
break;
case "dns.qry.name.len":
// TODO: Remove the IsRoot condition when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10674 is fixed.
resourceRecordAttributeField.AssertShowDecimal(resourceRecord.DomainName.IsRoot ? 6 : resourceRecord.DomainName.NonCompressedLength - 2);
resourceRecordAttributeField.AssertNoFields();
break;
case "dns.count.labels":
// TODO: Remove the IsRoot condition when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10674 is fixed.
resourceRecordAttributeField.AssertShowDecimal(resourceRecord.DomainName.IsRoot ? 1 : resourceRecord.DomainName.LabelsCount);
resourceRecordAttributeField.AssertNoFields();
break;
case "dns.qry.type":
case "dns.resp.type":
resourceRecordAttributeField.AssertShowHex((ushort)resourceRecord.DnsType);
resourceRecordAttributeField.AssertShowDecimal((ushort)resourceRecord.DnsType);
resourceRecordAttributeField.AssertNoFields();
break;
case "dns.qry.class":
case "dns.resp.class":
resourceRecordAttributeField.AssertShowHex((ushort)resourceRecord.DnsClass);
resourceRecordAttributeField.AssertShowDecimal((ushort)resourceRecord.DnsClass);
resourceRecordAttributeField.AssertNoFields();
break;
......@@ -198,13 +217,13 @@ namespace PcapDotNet.Core.Test
case "dns.srv.service":
Assert.AreEqual(resourceRecord.DnsType, DnsType.ServerSelection);
resourceRecordAttributeField.AssertShow(resourceRecord.DomainName.IsRoot ? "Root>" : resourceRecord.DomainName.ToString().Split('.')[0].Substring(1));
resourceRecordAttributeField.AssertShow(resourceRecord.DomainName.IsRoot ? "<Root>" : resourceRecord.DomainName.ToString().Split('.')[0]);
resourceRecordAttributeField.AssertNoFields();
break;
case "dns.srv.proto":
Assert.AreEqual(resourceRecord.DnsType, DnsType.ServerSelection);
resourceRecordAttributeField.AssertShow(resourceRecord.DomainName.ToString().Split('.')[1].Substring(1));
resourceRecordAttributeField.AssertShow(resourceRecord.DomainName.ToString().Split('.')[1]);
resourceRecordAttributeField.AssertNoFields();
break;
......@@ -216,7 +235,8 @@ namespace PcapDotNet.Core.Test
break;
default:
CompareResourceRecordData(resourceRecordAttributeField, resourceRecord);
if (!CompareResourceRecordData(resourceRecordAttributeField, resourceRecord))
return;
break;
}
}
......@@ -228,13 +248,16 @@ namespace PcapDotNet.Core.Test
_hipRendezvousServersIndex = 0;
_wksBitmapIndex = 0;
_nxtTypeIndex = 0;
_spfTypeIndex = 0;
_txtTypeIndex = 0;
_nSecTypeIndex = 0;
_nSec3TypeIndex = 0;
_txtIndex = 0;
_aplItemIndex = 0;
_optOptionIndex = 0;
}
private void CompareResourceRecordData(XElement dataField, DnsResourceRecord resourceRecord)
private bool CompareResourceRecordData(XElement dataField, DnsResourceRecord resourceRecord)
{
var data = resourceRecord.Data;
string dataFieldName = dataField.Name();
......@@ -243,9 +266,10 @@ namespace PcapDotNet.Core.Test
switch (resourceRecord.DnsType)
{
case DnsType.A:
dataField.AssertNoFields();
switch (dataFieldName)
{
case "dns.resp.addr":
case "dns.a":
dataField.AssertShow(((DnsResourceDataIpV4)data).Data.ToString());
break;
......@@ -255,243 +279,322 @@ namespace PcapDotNet.Core.Test
break;
case DnsType.Ns:
dataField.AssertName("dns.resp.ns");
dataField.AssertNoFields();
switch (dataFieldName)
{
case "dns.ns":
dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
break;
default:
throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
}
break;
case DnsType.Mailbox:
dataField.AssertName("dns.mb");
dataField.AssertNoFields();
dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
break;
case DnsType.Md:
dataField.AssertName("dns.md");
dataField.AssertNoFields();
dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
break;
case DnsType.MailForwarder:
dataField.AssertName("dns.mf");
dataField.AssertNoFields();
dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
break;
case DnsType.Md: // 3.
case DnsType.MailForwarder: // 4.
case DnsType.Mailbox: // 7.
case DnsType.MailGroup: // 8.
dataField.AssertName("dns.mg");
dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
dataField.AssertNoFields();
break;
case DnsType.MailRename: // 9.
dataField.AssertName("");
dataField.AssertShow("Host: " + GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
dataField.AssertName("dns.mr");
dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
dataField.AssertNoFields();
break;
case DnsType.CName:
dataField.AssertName("dns.resp.primaryname");
dataField.AssertName("dns.cname");
dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
dataField.AssertNoFields();
break;
case DnsType.StartOfAuthority:
dataField.AssertName("");
var soaData = (DnsResourceDataStartOfAuthority)data;
switch (dataFieldShowUntilColon)
var startOfAuthority = (DnsResourceDataStartOfAuthority)data;
dataField.AssertNoFields();
switch (dataField.Name())
{
case "Primary name server":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(soaData.MainNameServer));
case "dns.soa.mname":
dataField.AssertShow(GetWiresharkDomainName(startOfAuthority.MainNameServer));
break;
case "Responsible authority's mailbox":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(soaData.ResponsibleMailbox));
case "dns.soa.rname":
dataField.AssertShow(GetWiresharkDomainName(startOfAuthority.ResponsibleMailbox));
break;
case "Serial number":
dataField.AssertShow(dataFieldShowUntilColon + ": " + soaData.Serial);
case "dns.soa.serial_number":
dataField.AssertShowDecimal(startOfAuthority.Serial.Value);
break;
case "Refresh interval":
dataField.AssertValue(soaData.Refresh);
case "dns.soa.refresh_interval":
dataField.AssertShowDecimal(startOfAuthority.Refresh);
break;
case "Retry interval":
dataField.AssertValue(soaData.Retry);
case "dns.soa.retry_interval":
dataField.AssertShowDecimal(startOfAuthority.Retry);
break;
case "Expiration limit":
dataField.AssertValue(soaData.Expire);
case "dns.soa.expire_limit":
dataField.AssertShowDecimal(startOfAuthority.Expire);
break;
case "Minimum TTL":
dataField.AssertValue(soaData.MinimumTtl);
case "dns.soa.mininum_ttl":
dataField.AssertShowDecimal(startOfAuthority.MinimumTtl);
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
}
dataField.AssertNoFields();
break;
case DnsType.Wks:
dataField.AssertName("");
var wksData = (DnsResourceDataWellKnownService)data;
switch (dataFieldShowUntilColon)
dataField.AssertNoFields();
switch (dataField.Name())
{
case "Addr":
dataField.AssertShow(dataFieldShowUntilColon + ": " + wksData.Address);
case "dns.wks.address":
dataField.AssertShow(wksData.Address.ToString());
break;
case "Protocol":
dataField.AssertValue((byte)wksData.Protocol);
case "dns.wks.protocol":
// TODO: Uncomment this when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10675 is fixed.
// dataField.AssertShowDecimal((byte)wksData.Protocol);
break;
case "Bits":
case "dns.wks.bits":
while (wksData.Bitmap[_wksBitmapIndex] == 0x00)
++_wksBitmapIndex;
dataField.AssertValue(wksData.Bitmap[_wksBitmapIndex++]);
dataField.AssertShowDecimal(wksData.Bitmap[_wksBitmapIndex++]);
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
}
dataField.AssertNoFields();
break;
case DnsType.Ptr:
dataField.AssertName("");
dataField.AssertShow("Domain name: " + GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
dataField.AssertName("dns.ptr.domain_name");
dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
dataField.AssertNoFields();
break;
case DnsType.HInfo:
dataField.AssertName("");
dataField.AssertNoFields();
var hInfoData = (DnsResourceDataHostInformation)data;
switch (dataFieldShowUntilColon)
switch (dataFieldName)
{
case "CPU":
dataField.AssertValue(new[] {(byte)hInfoData.Cpu.Length}.Concat(hInfoData.Cpu));
case "dns.hinfo.cpu_length":
dataField.AssertShowDecimal(hInfoData.Cpu.Length);
break;
case "dns.hinfo.cpu":
dataField.AssertValue(hInfoData.Cpu);
break;
case "OS":
dataField.AssertValue(new[] {(byte)hInfoData.Os.Length}.Concat(hInfoData.Os));
case "dns.hinfo.os_length":
dataField.AssertShowDecimal(hInfoData.Os.Length);
break;
case "dns.hinfo.os":
dataField.AssertValue(hInfoData.Os);
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.MInfo:
dataField.AssertName("");
dataField.AssertNoFields();
var mInfoData = (DnsResourceDataMailingListInfo)data;
switch (dataFieldShowUntilColon)
switch (dataFieldName)
{
case "Responsible Mailbox":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(mInfoData.MailingList));
case "dns.minfo.r":
dataField.AssertShow(GetWiresharkDomainName(mInfoData.MailingList));
break;
case "Error Mailbox":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(mInfoData.ErrorMailbox));
case "dns.minfo.e":
dataField.AssertShow(GetWiresharkDomainName(mInfoData.ErrorMailbox));
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.MailExchange:
var mxData = (DnsResourceDataMailExchange)data;
switch (dataFieldShowUntilColon)
dataField.AssertNoFields();
switch (dataFieldName)
{
case "Preference":
dataField.AssertShow(dataFieldShowUntilColon + ": " + mxData.Preference);
case "dns.mx.preference":
dataField.AssertShowDecimal(mxData.Preference);
break;
case "Mail exchange":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(mxData.MailExchangeHost));
case "dns.mx.mail_exchange":
dataField.AssertShow(GetWiresharkDomainName(mxData.MailExchangeHost));
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.Txt: // 16.
case DnsType.Spf: // 99.
var txtData = (DnsResourceDataText)data;
dataField.AssertShow("Text: " + txtData.Text[_txtIndex++].Decode(EncodingExtensions.Iso88591).ToWiresharkLiteral(false, false));
dataField.AssertNoFields();
switch (dataField.Name())
{
case "dns.txt.length":
dataField.AssertShowDecimal(txtData.Text[_txtTypeIndex].Length);
break;
case "dns.txt":
dataField.AssertValue(txtData.Text[_txtTypeIndex]);
++_txtTypeIndex;
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
}
break;
case DnsType.Spf: // 99.
var spfData = (DnsResourceDataText)data;
dataField.AssertNoFields();
switch (dataField.Name())
{
case "dns.spf.length":
dataField.AssertShowDecimal(spfData.Text[_spfTypeIndex].Length);
break;
case "dns.spf":
dataField.AssertValue(spfData.Text[_spfTypeIndex]);
++_spfTypeIndex;
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
}
break;
case DnsType.ResponsiblePerson:
dataField.AssertName("");
var rpData = (DnsResourceDataResponsiblePerson)data;
switch (dataFieldShowUntilColon)
dataField.AssertNoFields();
switch (dataFieldName)
{
case "Mailbox":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(rpData.Mailbox));
case "dns.rp.mailbox":
dataField.AssertShow(GetWiresharkDomainName(rpData.Mailbox));
break;
case "TXT RR":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(rpData.TextDomain));
case "dns.rp.txt_rr":
dataField.AssertShow(GetWiresharkDomainName(rpData.TextDomain));
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.AfsDatabase:
dataField.AssertName("");
var afsDbData = (DnsResourceDataAfsDatabase)data;
switch (dataFieldShowUntilColon)
dataField.AssertNoFields();
switch (dataFieldName)
{
case "Subtype":
dataField.AssertShow(dataFieldShowUntilColon + ": " + (ushort)afsDbData.Subtype);
case "dns.afsdb.subtype":
dataField.AssertShowDecimal((ushort)afsDbData.Subtype);
break;
case "Hostname":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(afsDbData.HostName));
case "dns.afsdb.hostname":
dataField.AssertShow(GetWiresharkDomainName(afsDbData.HostName));
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.X25:
dataField.AssertName("");
dataField.AssertShow("PSDN-Address: " + ((DnsResourceDataString)data).String.Decode(EncodingExtensions.Iso88591).ToWiresharkLiteral(false, false));
var x25 = (DnsResourceDataString)data;
dataField.AssertNoFields();
switch (dataFieldName)
{
case "dns.x25.length":
dataField.AssertShowDecimal(x25.String.Length);
break;
case "dns.x25.psdn_address":
dataField.AssertValue(x25.String);
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
}
break;
case DnsType.Isdn:
dataField.AssertName("");
var isdnData = (DnsResourceDataIsdn)data;
switch (dataFieldShowUntilColon)
dataField.AssertNoFields();
switch (dataFieldName)
{
case "ISDN Address":
dataField.AssertShow(dataFieldShowUntilColon + ": " +
isdnData.IsdnAddress.Decode(EncodingExtensions.Iso88591).ToWiresharkLiteral(false, false));
case "dns.idsn.length":
dataField.AssertShowDecimal(isdnData.IsdnAddress.Length);
break;
case "Subaddress":
dataField.AssertShow(dataFieldShowUntilColon + ": " +
isdnData.Subaddress.Decode(EncodingExtensions.Iso88591).ToWiresharkLiteral(false, false));
case "dns.idsn.address":
dataField.AssertValue(isdnData.IsdnAddress);
break;
case "dns.idsn.sa.length":
dataField.AssertShowDecimal(isdnData.Subaddress.Length);
break;
case "dns.idsn.sa.address":
// TODO: Uncomment when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10650 is fixed.
// dataField.AssertValue(isdnData.Subaddress);
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.RouteThrough:
dataField.AssertName("");
dataField.AssertNoFields();
var rtData = (DnsResourceDataRouteThrough)data;
switch (dataFieldShowUntilColon)
switch (dataFieldName)
{
case "Preference":
dataField.AssertShow(dataFieldShowUntilColon + ": " + rtData.Preference);
case "dns.rt.subtype":
dataField.AssertShowDecimal(rtData.Preference);
break;
case "Intermediate-Host":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(rtData.IntermediateHost));
case "dns.rt.intermediate_host":
dataField.AssertShow(GetWiresharkDomainName(rtData.IntermediateHost));
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.NetworkServiceAccessPoint:
......@@ -512,66 +615,52 @@ namespace PcapDotNet.Core.Test
break;
case DnsType.NetworkServiceAccessPointPointer:
dataField.AssertName("");
dataField.AssertShow("Owner: " + GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
dataField.AssertName("dns.nsap_ptr.owner");
dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
dataField.AssertNoFields();
break;
case DnsType.Key:
dataField.AssertName("");
var keyData = (DnsResourceDataKey)data;
switch (dataFieldShowUntilColon)
switch (dataFieldName)
{
case "Flags":
case "dns.key.flags":
foreach (var flagField in dataField.Fields())
{
flagField.AssertNoFields();
int flagCount = GetFlagCount(flagField);
switch (flagCount)
{
case 0:
flagField.AssertShow(keyData.AuthenticationProhibited
? "1... .... .... .... = Key prohibited for authentication"
: "0... .... .... .... = Key allowed for authentication");
flagField.AssertShowDecimal(keyData.AuthenticationProhibited);
break;
case 1:
flagField.AssertShow(keyData.ConfidentialityProhibited
? ".1.. .... .... .... = Key prohibited for confidentiality"
: ".0.. .... .... .... = Key allowed for confidentiality");
flagField.AssertShowDecimal(keyData.ConfidentialityProhibited);
break;
case 2:
flagField.AssertShow(keyData.Experimental
? "..1. .... .... .... = Key is experimental or optional"
: "..0. .... .... .... = Key is required");
flagField.AssertShowDecimal(keyData.Experimental);
break;
case 5:
flagField.AssertShow(keyData.UserAssociated
? ".... .1.. .... .... = Key is associated with a user"
: ".... .0.. .... .... = Key is not associated with a user");
flagField.AssertShowDecimal(keyData.UserAssociated);
break;
case 6:
flagField.AssertShow(keyData.NameType == DnsKeyNameType.NonZoneEntity
? ".... ..1. .... .... = Key is associated with the named entity"
: ".... ..0. .... .... = Key is not associated with the named entity");
flagField.AssertShowDecimal(keyData.NameType == DnsKeyNameType.NonZoneEntity);
break;
case 8:
flagField.AssertShow(keyData.IpSec
? ".... .... 1... .... = Key is valid for use with IPSEC"
: ".... .... 0... .... = Key is not valid for use with IPSEC");
flagField.AssertShowDecimal(keyData.IpSec);
break;
case 9:
flagField.AssertShow(keyData.Email
? ".... .... .1.. .... = Key is valid for use with MIME security multiparts"
: ".... .... .0.. .... = Key is not valid for use with MIME security multiparts");
flagField.AssertShowDecimal(keyData.Email);
break;
case 12:
Assert.AreEqual(flagField.Show().Substring(19), " = Signatory = " + (byte)keyData.Signatory);
flagField.AssertShowDecimal((byte)keyData.Signatory);
break;
default:
......@@ -580,22 +669,23 @@ namespace PcapDotNet.Core.Test
}
break;
case "Protocol":
dataField.AssertShow(dataFieldShowUntilColon + ": " + (byte)keyData.Protocol);
case "dns.key.protocol":
dataField.AssertNoFields();
dataField.AssertShowDecimal((byte)keyData.Protocol);
break;
case "Algorithm":
dataField.AssertValue((byte)keyData.Algorithm);
case "dns.key.algorithm":
dataField.AssertNoFields();
dataField.AssertShowDecimal((byte)keyData.Algorithm);
break;
case "Key id":
// TODO: Calculate key tag.
case "dns.key.key_id":
dataField.AssertNoFields();
// TODO: Calculate key tag.
break;
case "Public key":
case "dns.key.public_key":
dataField.AssertNoFields();
byte[] flagsExtension;
if (keyData.FlagsExtension == null)
{
......@@ -607,329 +697,309 @@ namespace PcapDotNet.Core.Test
flagsExtension.Write(0, keyData.FlagsExtension.Value, Endianity.Big);
}
dataField.AssertValue(flagsExtension.Concat(keyData.PublicKey));
dataField.AssertNoFields();
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
}
break;
case DnsType.Signature: // 24.
case DnsType.ResourceRecordSignature: // 46.
dataField.AssertName("");
dataField.AssertNoFields();
var sigData = (DnsResourceDataSignature)data;
switch (dataFieldShowUntilColon)
switch (dataFieldName)
{
case "Type covered":
dataField.AssertValue((ushort)sigData.TypeCovered);
case "dns.rrsig.type_covered":
dataField.AssertShowDecimal((ushort)sigData.TypeCovered);
break;
case "Algorithm":
dataField.AssertValue((byte)sigData.Algorithm);
case "dns.rrsig.algorithm":
dataField.AssertShowDecimal((byte)sigData.Algorithm);
break;
case "Labels":
dataField.AssertShow(dataFieldShowUntilColon + ": " + sigData.Labels);
case "dns.rrsig.labels":
dataField.AssertShowDecimal(sigData.Labels);
break;
case "Original TTL":
dataField.AssertValue(sigData.OriginalTtl);
case "dns.rrsig.original_ttl":
dataField.AssertShowDecimal(sigData.OriginalTtl);
break;
case "Signature expiration":
case "dns.rrsig.signature_expiration":
dataField.AssertValue(sigData.SignatureExpiration);
break;
case "Time signed":
case "dns.rrsig.signature_inception":
dataField.AssertValue(sigData.SignatureInception);
break;
case "Id of signing key(footprint)":
dataField.AssertShow(dataFieldShowUntilColon + ": " + sigData.KeyTag);
case "dns.rrsig.key_tag":
dataField.AssertShowDecimal(sigData.KeyTag);
break;
case "Signer's name":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(sigData.SignersName));
case "dns.rrsig.signers_name":
dataField.AssertShow(GetWiresharkDomainName(sigData.SignersName));
break;
case "Signature":
case "dns.rrsig.signature":
dataField.AssertValue(sigData.Signature);
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.PointerX400:
dataField.AssertName("");
var pxData = (DnsResourceDataX400Pointer)data;
switch (dataFieldShowUntilColon)
switch (dataField.Name())
{
case "Preference":
dataField.AssertShow(dataFieldShowUntilColon + ": " + pxData.Preference);
case "dns.px.preference":
dataField.AssertShowDecimal(pxData.Preference);
break;
case "MAP822":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(pxData.Map822));
case "dns.px.map822":
dataField.AssertShow(GetWiresharkDomainName(pxData.Map822));
break;
case "MAPX400":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(pxData.MapX400));
case "dns.px.map400":
dataField.AssertShow(GetWiresharkDomainName(pxData.MapX400));
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
}
dataField.AssertNoFields();
break;
case DnsType.GPos:
dataField.AssertName("");
dataField.AssertNoFields();
var gposData = (DnsResourceDataGeographicalPosition)data;
switch (dataFieldShowUntilColon)
switch (dataFieldName)
{
case "Longitude":
dataField.AssertShow(dataFieldShowUntilColon + ": " + gposData.Longitude);
break;
case "Latitude":
dataField.AssertShow(dataFieldShowUntilColon + ": " + gposData.Latitude);
break;
case "Altitude":
dataField.AssertShow(dataFieldShowUntilColon + ": " + gposData.Altitude);
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
}
dataField.AssertNoFields();
case "dns.gpos.longitude_length":
dataField.AssertShowDecimal(gposData.Longitude.Length);
break;
case DnsType.Aaaa:
dataField.AssertName("");
dataField.AssertShow("Addr: " + GetWiresharkIpV6(((DnsResourceDataIpV6)data).Data));
case "dns.gpos.longitude":
dataField.AssertShow(gposData.Longitude);
break;
case DnsType.Loc:
dataField.AssertName("");
var locData = (DnsResourceDataLocationInformation)data;
switch (dataFieldShowUntilColon)
{
case "Version":
dataField.AssertShow(dataFieldShowUntilColon + ": " + locData.Version);
case "dns.gpos.latitude_length":
dataField.AssertShowDecimal(gposData.Latitude.Length);
break;
case "Data":
dataField.AssertShow("Data");
case "dns.gpos.latitude":
dataField.AssertShow(gposData.Latitude);
break;
case "Size":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetPrecisionValueString(locData.Size));
case "dns.gpos.altitude_length":
dataField.AssertShowDecimal(gposData.Altitude.Length);
break;
case "Horizontal precision":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetPrecisionValueString(locData.HorizontalPrecision));
case "dns.gpos.altitude":
dataField.AssertShow(gposData.Altitude);
break;
case "Vertical precision":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetPrecisionValueString(locData.VerticalPrecision));
default:
throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
}
break;
case "Latitude":
dataField.AssertValue(locData.Latitude);
case DnsType.Aaaa:
dataField.AssertName("dns.aaaa");
dataField.AssertShow(GetWiresharkIpV6(((DnsResourceDataIpV6)data).Data));
dataField.AssertNoFields();
break;
case "Longitude":
dataField.AssertValue(locData.Longitude);
case DnsType.Loc:
var locData = (DnsResourceDataLocationInformation)data;
dataField.AssertNoFields();
switch (dataFieldName)
{
case "dns.loc.version":
dataField.AssertShowDecimal(locData.Version);
break;
case "Altitude":
dataField.AssertValue(locData.Altitude);
case "dns.loc.unknown_data":
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShowUntilColon);
throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.NextDomain:
dataField.AssertName("");
var nxtData = (DnsResourceDataNextDomain)data;
switch (dataFieldShowUntilColon)
switch (dataField.Name())
{
case "Next domain name":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(nxtData.NextDomainName));
case "dns.nxt.next_domain_name":
dataField.AssertShow(GetWiresharkDomainName(nxtData.NextDomainName));
break;
case "RR type in bit map":
DnsType actualType = nxtData.TypesExist.Skip(_nxtTypeIndex++).First();
DnsType expectedType;
if (!TryGetDnsType(dataFieldShow, out expectedType))
throw new InvalidOperationException(string.Format("Can't parse DNS field {0} : {1}", dataFieldShow, actualType));
Assert.AreEqual(expectedType, actualType);
break;
case "":
// TODO: Uncomment this when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10615 is fixed.
// DnsType actualType = nxtData.TypesExist.Skip(_nxtTypeIndex++).First();
// DnsType expectedType;
// if (!TryGetDnsType(dataFieldShow, out expectedType))
// throw new InvalidOperationException(string.Format("Can't parse DNS field {0} : {1}", dataFieldShow, actualType));
// Assert.AreEqual(expectedType, actualType);
return false;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
}
dataField.AssertNoFields();
break;
case DnsType.ServerSelection:
dataField.AssertName("");
dataField.AssertNoFields();
var srvData = (DnsResourceDataServerSelection)data;
switch (dataFieldShowUntilColon)
switch (dataFieldName)
{
case "Priority":
dataField.AssertShow(dataFieldShowUntilColon + ": " + srvData.Priority);
case "dns.srv.priority":
dataField.AssertShowDecimal(srvData.Priority);
break;
case "Weight":
dataField.AssertShow(dataFieldShowUntilColon + ": " + srvData.Weight);
case "dns.srv.weight":
dataField.AssertShowDecimal(srvData.Weight);
break;
case "Port":
dataField.AssertShow(dataFieldShowUntilColon + ": " + srvData.Port);
case "dns.srv.port":
dataField.AssertShowDecimal(srvData.Port);
break;
case "Target":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(srvData.Target));
case "dns.srv.target":
dataField.AssertShow(GetWiresharkDomainName(srvData.Target));
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShowUntilColon);
throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.NaPtr:
dataField.AssertName("");
var naPtrData = (DnsResourceDataNamingAuthorityPointer)data;
switch (dataFieldShowUntilColon)
dataField.AssertNoFields();
switch (dataFieldName)
{
case "Order":
dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Order);
case "dns.naptr.order":
dataField.AssertShowDecimal(naPtrData.Order);
break;
case "Preference":
dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Preference);
case "dns.naptr.preference":
dataField.AssertShowDecimal(naPtrData.Preference);
break;
case "Flags length":
dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Flags.Length);
case "dns.naptr.flags_length":
dataField.AssertShowDecimal(naPtrData.Flags.Length);
break;
case "Flags":
case "dns.naptr.flags":
dataField.AssertValue(naPtrData.Flags);
break;
case "Service length":
dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Services.Length);
case "dns.naptr.service_length":
dataField.AssertShowDecimal(naPtrData.Services.Length);
break;
case "Service":
case "dns.naptr.service":
dataField.AssertValue(naPtrData.Services);
break;
case "Regex length":
dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.RegularExpression.Length);
case "dns.naptr.regex_length":
dataField.AssertShowDecimal(naPtrData.RegularExpression.Length);
break;
case "Regex":
case "dns.naptr.regex":
dataField.AssertValue(naPtrData.RegularExpression);
break;
case "Replacement length":
dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Replacement.NonCompressedLength);
case "dns.naptr.replacement_length":
// TODO: Uncomment when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10700 is fixed.
// dataField.AssertShowDecimal(naPtrData.Replacement.NonCompressedLength);
break;
case "Replacement":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(naPtrData.Replacement));
case "dns.naptr.replacement":
dataField.AssertShow(GetWiresharkDomainName(naPtrData.Replacement));
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.KeyExchanger:
dataField.AssertName("");
dataField.AssertNoFields();
var kxData = (DnsResourceDataKeyExchanger)data;
switch (dataFieldShowUntilColon)
switch (dataFieldName)
{
case "Preference":
dataField.AssertShow(dataFieldShowUntilColon + ": 0");
dataField.AssertValue(kxData.Preference);
case "dns.kx.preference":
dataField.AssertShowDecimal(kxData.Preference);
break;
case "Key exchange":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(kxData.KeyExchangeHost));
case "dns.kx.key_exchange":
dataField.AssertShow(GetWiresharkDomainName(kxData.KeyExchangeHost));
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.Cert:
dataField.AssertName("");
dataField.AssertNoFields();
var certData = (DnsResourceDataCertificate)data;
switch (dataFieldShowUntilColon)
switch (dataFieldName)
{
case "Type":
dataField.AssertValue((ushort)certData.CertificateType);
case "dns.cert.type":
dataField.AssertShowDecimal((ushort)certData.CertificateType);
break;
case "Key footprint":
dataField.AssertValue(certData.KeyTag);
case "dns.cert.key_tag":
dataField.AssertShowDecimal(certData.KeyTag);
break;
case "Algorithm":
dataField.AssertValue((byte)certData.Algorithm);
case "dns.cert.algorithm":
dataField.AssertShowDecimal((byte)certData.Algorithm);
break;
case "Public key":
case "dns.cert.certificate":
dataField.AssertValue(certData.Certificate);
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.A6:
var a6Data = (DnsResourceDataA6)data;
switch (dataFieldShowUntilColon)
switch (dataFieldName)
{
case "Prefix len":
dataField.AssertShow(dataFieldShowUntilColon + ": " + a6Data.PrefixLength);
case "dns.a6.prefix_len":
dataField.AssertShowDecimal(a6Data.PrefixLength);
break;
case "Address suffix":
Assert.AreEqual(new IpV6Address(dataFieldShow.Substring(dataFieldShowUntilColon.Length + 2)), a6Data.AddressSuffix);
case "dns.a6.address_suffix":
// TODO: Uncomment when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10652 is fixed.
// Assert.AreEqual(new IpV6Address(dataFieldShow), a6Data.AddressSuffix);
break;
case "Prefix name":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(a6Data.PrefixName));
case "dns.a6.prefix_name":
dataField.AssertShow(GetWiresharkDomainName(a6Data.PrefixName));
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.DName:
dataField.AssertName("");
dataField.AssertShow("Target name: " + GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
dataField.AssertName("dns.dname");
dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
dataField.AssertNoFields();
break;
......@@ -938,53 +1008,90 @@ namespace PcapDotNet.Core.Test
var optData = (DnsResourceDataOptions)data;
switch (dataFieldName)
{
case "":
switch (dataFieldShowUntilColon)
{
case "UDP payload size":
dataField.AssertShow(dataFieldShowUntilColon + ": " + optResourceRecord.SendersUdpPayloadSize);
case "dns.rr.udp_payload_size":
_optOptionIndex = 0;
dataField.AssertNoFields();
dataField.AssertShowDecimal(optResourceRecord.SendersUdpPayloadSize);
break;
case "Higher bits in extended RCODE":
dataField.AssertValue(optResourceRecord.ExtendedReturnCode);
case "dns.resp.ext_rcode":
dataField.AssertNoFields();
dataField.AssertShowDecimal(optResourceRecord.ExtendedReturnCode);
break;
case "EDNS0 version":
dataField.AssertShow(dataFieldShowUntilColon + ": " + (byte)optResourceRecord.Version);
case "dns.resp.edns0_version":
dataField.AssertNoFields();
dataField.AssertShowDecimal((byte)optResourceRecord.Version);
break;
case "Z":
ushort flags = (ushort)optResourceRecord.Flags;
dataField.AssertValue(flags);
if (dataField.Fields().Any())
case "dns.resp.z":
DnsOptFlags flags = optResourceRecord.Flags;
dataField.AssertShowDecimal((ushort)flags);
foreach (XElement subfield in dataField.Fields())
{
dataField.AssertNumFields(2);
dataField.Fields().First().AssertShow("Bit 0 (DO bit): 1 (Accepts DNSSEC security RRs)");
// TODO - uncomment once https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7045 is fixed.
// dataField.Fields().Last().AssertShow("Bits 1-15: 0x" + (flags & 0x7FFF).ToString("x") + " (reserved)");
}
else
subfield.AssertNoFields();
switch (subfield.Name())
{
Assert.AreEqual<ushort>(0, (ushort)optResourceRecord.Flags);
case "dns.resp.z.do":
subfield.AssertShowDecimal((flags & DnsOptFlags.DnsSecOk) == DnsOptFlags.DnsSecOk);
break;
case "dns.resp.z.reserved":
subfield.AssertShowDecimal(0);
break;
default:
throw new InvalidOperationException("Invalid DNS data subfield name " + subfield.Name());
}
}
break;
case "Data":
Assert.AreEqual(dataField.Value().Length, 2 * optData.Options.Options.Sum(option => option.Length));
dataField.AssertNoFields();
case "dns.opt":
foreach (XElement subfield in dataField.Fields())
{
subfield.AssertNoFields();
DnsOption dnsOption = optData.Options.Options[_optOptionIndex];
switch (subfield.Name())
{
case "dns.opt.code":
subfield.AssertShowDecimal((ushort)dnsOption.Code);
break;
case "dns.opt.len":
subfield.AssertShowDecimal(dnsOption.DataLength);
break;
case "dns.opt.data":
switch (dnsOption.Code)
{
case DnsOptionCode.UpdateLease:
subfield.AssertValue((uint)((DnsOptionUpdateLease)dnsOption).Lease);
break;
case DnsOptionCode.LongLivedQuery:
byte[] expectedLongLivedQueryValue =
new byte[sizeof(ushort) + sizeof(ushort) + sizeof(ushort) + sizeof(ulong) + sizeof(uint)];
var longLivedQuery = (DnsOptionLongLivedQuery)dnsOption;
int offset = 0;
expectedLongLivedQueryValue.Write(ref offset, longLivedQuery.Version, Endianity.Big);
expectedLongLivedQueryValue.Write(ref offset, (ushort)longLivedQuery.OpCode, Endianity.Big);
expectedLongLivedQueryValue.Write(ref offset, (ushort)longLivedQuery.ErrorCode, Endianity.Big);
expectedLongLivedQueryValue.Write(ref offset, longLivedQuery.Id, Endianity.Big);
expectedLongLivedQueryValue.Write(ref offset, longLivedQuery.LeaseLife, Endianity.Big);
subfield.AssertValue(expectedLongLivedQueryValue);
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
subfield.AssertValue(((DnsOptionAnything)dnsOption).Data);
break;
}
++_optOptionIndex;
break;
case "dns.resp.len":
dataField.AssertShow("Data length: " + optData.Options.Options.Sum(option => option.DataLength));
dataField.AssertNoFields();
default:
throw new InvalidOperationException("Invalid DNS data subfield name " + subfield.Name());
}
}
break;
default:
......@@ -996,26 +1103,13 @@ namespace PcapDotNet.Core.Test
var aplData = (DnsResourceDataAddressPrefixList)data;
switch (dataFieldName)
{
case "":
switch (dataFieldShowUntilColon)
{
case "Address Family":
dataField.AssertValue((ushort)aplData.Items[_aplItemIndex++].AddressFamily);
break;
case "IPv4 address":
case "IPv6 address":
dataField.AssertValue(aplData.Items[_aplItemIndex - 1].AddressFamilyDependentPart);
break;
default:
throw new InvalidOperationException("Invalid DNS data field name " + dataFieldShowUntilColon);
}
case "dns.apl.address_family":
dataField.AssertNoFields();
dataField.AssertShowDecimal((ushort)aplData.Items[_aplItemIndex++].AddressFamily);
break;
case "dns.apl.coded.prefix":
case "dns.apl.coded_prefix":
dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].PrefixLength);
break;
......@@ -1027,6 +1121,11 @@ namespace PcapDotNet.Core.Test
dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].AddressFamilyDependentPart.Length);
break;
case "dns.apl.afdpart.data":
case "dns.apl.afdpart.ipv6":
dataField.AssertValue(aplData.Items[_aplItemIndex - 1].AddressFamilyDependentPart);
break;
default:
throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
}
......@@ -1035,50 +1134,42 @@ namespace PcapDotNet.Core.Test
case DnsType.DelegationSigner: // 43.
case DnsType.DnsSecLookAsideValidation: // 32769.
dataField.AssertName("");
dataField.AssertNoFields();
var dsData = (DnsResourceDataDelegationSigner)data;
switch (dataFieldShowUntilColon)
switch (dataFieldName)
{
case "Key id":
dataField.AssertShow(dataFieldShowUntilColon + ": " + dsData.KeyTag.ToString("0000"));
case "dns.ds.key_id":
dataField.AssertShowDecimal(dsData.KeyTag);
break;
case "Algorithm":
dataField.AssertValue((byte)dsData.Algorithm);
case "dns.ds.algorithm":
dataField.AssertShowDecimal((byte)dsData.Algorithm);
break;
case "Digest type":
dataField.AssertValue((byte)dsData.DigestType);
case "dns.ds.digest_type":
dataField.AssertShowDecimal((byte)dsData.DigestType);
break;
case "Public key":
case "dns.ds.digest":
dataField.AssertValue(dsData.Digest);
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.SshFingerprint:
var sshFpData = (DnsResourceDataSshFingerprint)data;
dataField.AssertNoFields();
switch (dataFieldName)
{
case "":
switch (dataFieldShowUntilColon)
{
case "Algorithm":
dataField.AssertValue((byte)sshFpData.Algorithm);
case "dns.sshfp.algorithm":
dataField.AssertShowDecimal((byte)sshFpData.Algorithm);
break;
case "Fingerprint type":
dataField.AssertValue((byte)sshFpData.FingerprintType);
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
}
case "dns.sshfp.fingerprint.type":
dataField.AssertShowDecimal((byte)sshFpData.FingerprintType);
break;
case "dns.sshfp.fingerprint":
......@@ -1088,66 +1179,55 @@ namespace PcapDotNet.Core.Test
default:
throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.IpSecKey:
dataField.AssertName("");
dataField.AssertNoFields();
var ipSecKeyData = (DnsResourceDataIpSecKey)data;
switch (dataFieldShowUntilColon)
switch (dataField.Name())
{
case "Gateway precedence":
dataField.AssertValue(ipSecKeyData.Precedence);
case "dns.ipseckey.gateway_precedence":
dataField.AssertShowDecimal(ipSecKeyData.Precedence);
break;
case "Algorithm":
dataField.AssertValue((byte)ipSecKeyData.Algorithm);
case "dns.ipseckey.gateway_type":
dataField.AssertShowDecimal((byte)ipSecKeyData.GatewayType);
break;
case "Gateway":
switch (ipSecKeyData.GatewayType)
{
case DnsGatewayType.None:
dataField.AssertShow(dataFieldShowUntilColon + ": no gateway");
case "dns.ipseckey.gateway_algorithm":
dataField.AssertShowDecimal((byte)ipSecKeyData.Algorithm);
break;
case DnsGatewayType.IpV4:
dataField.AssertShow(dataFieldShowUntilColon + ": " + ((DnsGatewayIpV4)ipSecKeyData.Gateway).Value);
case "dns.ipseckey.gateway_ipv4":
dataField.AssertShow(((DnsGatewayIpV4)ipSecKeyData.Gateway).Value.ToString());
break;
case DnsGatewayType.IpV6:
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkIpV6(((DnsGatewayIpV6)ipSecKeyData.Gateway).Value));
case "dns.ipseckey.gateway_ipv6":
dataField.AssertValue(((DnsGatewayIpV6)ipSecKeyData.Gateway).Value.ToValue());
break;
case DnsGatewayType.DomainName:
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(((DnsGatewayDomainName)ipSecKeyData.Gateway).Value));
case "dns.ipseckey.gateway_dns":
dataField.AssertShow(GetWiresharkDomainName(((DnsGatewayDomainName)ipSecKeyData.Gateway).Value));
break;
default:
throw new InvalidOperationException("Invalid Gateway Type " + ipSecKeyData.GatewayType);
}
break;
case "Public key":
case "dns.ipseckey.public_key":
dataField.AssertValue(ipSecKeyData.PublicKey);
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
}
dataField.AssertNoFields();
break;
case DnsType.NSec:
dataField.AssertName("");
var nSecData = (DnsResourceDataNextDomainSecure)data;
switch (dataFieldShowUntilColon)
switch (dataField.Name())
{
case "Next domain name":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(nSecData.NextDomainName));
case "dns.nsec.next_domain_name":
dataField.AssertShow(GetWiresharkDomainName(nSecData.NextDomainName));
break;
case "RR type in bit map":
case "":
DnsType actualType = nSecData.TypesExist[_nSecTypeIndex++];
DnsType expectedType;
if (!TryGetDnsType(dataFieldShow, out expectedType))
......@@ -1157,68 +1237,63 @@ namespace PcapDotNet.Core.Test
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
}
dataField.AssertNoFields();
break;
case DnsType.DnsKey:
dataField.AssertName("");
var dnsKeyData = (DnsResourceDataDnsKey)data;
switch (dataFieldShowUntilColon)
switch (dataFieldName)
{
case "Flags":
foreach (var flagField in dataField.Fields())
case "dns.dnskey.flags":
foreach (XElement subfield in dataField.Fields())
{
int flagCount = GetFlagCount(flagField);
switch (flagCount)
subfield.AssertNoFields();
switch (subfield.Name())
{
case 7:
flagField.AssertShow(dnsKeyData.ZoneKey
? ".... ...1 .... .... = This is the zone key for the specified zone"
: ".... ...0 .... .... = This is not a zone key");
case "dns.dnskey.flags.zone_key":
subfield.AssertShowDecimal(dnsKeyData.ZoneKey);
break;
case 8:
flagField.AssertShow(dnsKeyData.Revoke
? ".... .... 1... .... = Key is revoked"
: ".... .... 0... .... = Key is not revoked");
case "dns.dnskey.flags.key_revoked":
subfield.AssertShowDecimal(dnsKeyData.Revoke);
break;
case 15:
flagField.AssertShow(dnsKeyData.SecureEntryPoint
? ".... .... .... ...1 = Key is a Key Signing Key"
: ".... .... .... ...0 = Key is a Zone Signing Key");
case "dns.dnskey.flags.secure_entry_point":
subfield.AssertShowDecimal(dnsKeyData.SecureEntryPoint);
break;
default:
throw new InvalidOperationException("Invalid DNS data flag field " + flagField.Show());
}
}
case "dns.dnskey.flags.reserved":
subfield.AssertShowDecimal(0);
break;
case "Protocol":
dataField.AssertShow(dataFieldShowUntilColon + ": " + dnsKeyData.Protocol);
dataField.AssertNoFields();
case "dns.dnskey.protocol":
subfield.AssertShowDecimal(dnsKeyData.Protocol);
break;
case "Algorithm":
dataField.AssertValue((byte)dnsKeyData.Algorithm);
dataField.AssertNoFields();
case "dns.dnskey.algorithm":
subfield.AssertShowDecimal((byte)dnsKeyData.Algorithm);
break;
default:
throw new InvalidOperationException("Invalid DNS flags subfield name " + subfield.Name());
}
}
break;
case "Key id":
case "dns.dnskey.key_id":
// TODO: Calculate key tag.
dataField.AssertNoFields();
break;
case "Public key":
dataField.AssertValue(dnsKeyData.PublicKey);
case "dns.dnskey.public_key":
dataField.AssertNoFields();
dataField.AssertValue(dnsKeyData.PublicKey);
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS resource data field name " + dataFieldName);
}
break;
......@@ -1337,37 +1412,28 @@ namespace PcapDotNet.Core.Test
var hipData = (DnsResourceDataHostIdentityProtocol)data;
switch (dataFieldName)
{
case "":
switch (dataFieldShowUntilColon)
{
case "HIT length":
dataField.AssertShow(dataFieldShowUntilColon + ": " + hipData.HostIdentityTag.Length);
case "dns.hip.hit":
dataField.AssertShow(hipData.HostIdentityTag);
break;
case "PK algorithm":
dataField.AssertValue((byte)hipData.PublicKeyAlgorithm);
case "dns.hip.pk":
dataField.AssertShow(hipData.PublicKey);
break;
case "PK length":
dataField.AssertShow(dataFieldShowUntilColon + ": " + hipData.PublicKey.Length);
case "dns.hip.hit.length":
dataField.AssertShowDecimal(hipData.HostIdentityTag.Length);
break;
case "Rendezvous Server":
dataField.AssertShow(dataFieldShowUntilColon + ": " +
GetWiresharkDomainName(hipData.RendezvousServers[_hipRendezvousServersIndex++]));
case "dns.hip.hit.pk.algo":
dataField.AssertShowDecimal((byte)hipData.PublicKeyAlgorithm);
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
}
case "dns.hip.pk.length":
dataField.AssertShowDecimal(hipData.PublicKey.Length);
break;
case "dns.hip.hit":
dataField.AssertShow(hipData.HostIdentityTag);
break;
case "dns.hip.pk":
dataField.AssertShow(hipData.PublicKey);
case "dns.hip.rendezvous_server":
dataField.AssertShow(GetWiresharkDomainName(hipData.RendezvousServers[_hipRendezvousServersIndex++]));
break;
default:
......@@ -1377,50 +1443,49 @@ namespace PcapDotNet.Core.Test
break;
case DnsType.TKey:
dataField.AssertName("");
dataField.AssertNoFields();
var tKeyData = (DnsResourceDataTransactionKey)data;
switch (dataFieldShowUntilColon)
switch (dataFieldName)
{
case "Algorithm name":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(tKeyData.Algorithm));
case "dns.tkey.algo_name":
dataField.AssertShow(GetWiresharkDomainName(tKeyData.Algorithm));
break;
case "Signature inception":
case "dns.tkey.signature_inception":
dataField.AssertValue(tKeyData.Inception);
break;
case "Signature expiration":
case "dns.tkey.signature_expiration":
dataField.AssertValue(tKeyData.Expiration);
break;
case "Mode":
dataField.AssertValue((ushort)tKeyData.Mode);
case "dns.tkey.mode":
dataField.AssertShowDecimal((ushort)tKeyData.Mode);
break;
case "Error":
dataField.AssertValue((ushort)tKeyData.Error);
case "dns.tkey.error":
dataField.AssertShowDecimal((ushort)tKeyData.Error);
break;
case "Key Size":
dataField.AssertShow(dataFieldShowUntilColon + ": " + tKeyData.Key.Length);
case "dns.tkey.key_size":
dataField.AssertShowDecimal(tKeyData.Key.Length);
break;
case "Key Data":
case "dns.tkey.key_data":
dataField.AssertValue(tKeyData.Key);
break;
case "Other Size":
dataField.AssertShow(dataFieldShowUntilColon + ": " + tKeyData.Other.Length);
case "dns.tkey.other_size":
dataField.AssertShowDecimal(tKeyData.Other.Length);
break;
case "Other Data":
case "dns.tkey.other_data":
dataField.AssertValue(tKeyData.Other);
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
}
dataField.AssertNoFields();
break;
case DnsType.TransactionSignature:
......@@ -1459,8 +1524,7 @@ namespace PcapDotNet.Core.Test
dataField.AssertShow("");
Assert.AreEqual(1, dataField.Fields().Count());
var tsigSubfield = dataField.Fields().First();
tsigSubfield.AssertShow("No dissector for algorithm:" + GetWiresharkDomainName(tSigData.Algorithm));
tsigSubfield.AssertValue(tSigData.MessageAuthenticationCode);
tsigSubfield.AssertName("_ws.expert");
break;
case "dns.tsig.original_id":
......@@ -1483,12 +1547,80 @@ namespace PcapDotNet.Core.Test
dataField.AssertNoFields();
break;
case "dns.tsig.time_signed":
dataField.AssertValue(tSigData.TimeSigned);
dataField.AssertNoFields();
break;
case "_ws.expert":
break;
default:
throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
}
break;
case DnsType.Null: // 10.
case DnsType.Null:
dataField.AssertNoFields();
dataField.AssertName("dns.null");
dataField.AssertValue(((DnsResourceDataAnything)data).Data);
break;
case DnsType.CertificationAuthorityAuthorization:
var certificationAuthorityAuthorization = (DnsResourceDataCertificationAuthorityAuthorization)data;
switch (dataField.Name())
{
case "dns.caa.flags":
dataField.AssertShowDecimal((byte)certificationAuthorityAuthorization.Flags);
foreach (XElement subfield in dataField.Fields())
{
subfield.AssertNoFields();
switch (subfield.Name())
{
case "dns.caa.flags.issuer_critical":
subfield.AssertShowDecimal((certificationAuthorityAuthorization.Flags &
DnsCertificationAuthorityAuthorizationFlags.Critical) ==
DnsCertificationAuthorityAuthorizationFlags.Critical);
break;
default:
throw new InvalidOperationException("Invalid subfield " + subfield.Name());
}
}
break;
case "dns.caa.unknown":
case "dns.caa.issue":
foreach (XElement subfield in dataField.Fields())
{
subfield.AssertNoFields();
switch (subfield.Name())
{
case "dns.caa.tag_length":
subfield.AssertShowDecimal(certificationAuthorityAuthorization.Tag.Length);
break;
case "dns.caa.tag":
subfield.AssertValue(certificationAuthorityAuthorization.Tag);
break;
case "dns.caa.value":
subfield.AssertValue(certificationAuthorityAuthorization.Value);
break;
default:
throw new InvalidOperationException("Invalid subfield " + subfield.Name());
}
}
break;
default:
throw new InvalidOperationException("Invalid field " + dataField.Name());
}
break;
case DnsType.EId: // 31.
case DnsType.NimrodLocator: // 32.
case DnsType.AtmA: // 34.
......@@ -1507,14 +1639,20 @@ namespace PcapDotNet.Core.Test
case DnsType.MailA: // 254.
case DnsType.Any: // 255.
case DnsType.Uri: // 256.
case DnsType.CertificationAuthorityAuthorization: // 257.
case DnsType.TrustAnchor: // 32768.
default:
dataField.AssertName("");
dataField.AssertShow("Data");
dataField.AssertNoFields();
if (dataField.Name() == "_ws.expert")
{
dataField.AssertShowname("Expert Info (Note/Undecoded): Dissector for DNS Type (" + (ushort)resourceRecord.DnsType +
") code not implemented, Contact Wireshark developers if you want this supported");
}
else
{
dataField.AssertName("dns.data");
}
break;
}
return true;
}
private static string GetWiresharkDomainName(DnsDomainName domainName)
......@@ -1555,8 +1693,12 @@ namespace PcapDotNet.Core.Test
{"RRSIG", DnsType.ResourceRecordSignature}, // 46
{"DHCID", DnsType.DynamicHostConfigurationId}, // 49
{"NSEC3PARAM", DnsType.NSec3Parameters}, // 51
{"TALINK", DnsType.TrustAnchorLink}, // 58
{"UNSPEC", DnsType.Unspecified}, // 103
{"TSIG", DnsType.TransactionSignature}, // 250
{"*", DnsType.Any}, // 255
{"CAA", DnsType.CertificationAuthorityAuthorization}, // 257
{"TA", DnsType.TrustAnchor}, // 32768
{"DLV", DnsType.DnsSecLookAsideValidation}, // 32769
};
......@@ -1585,12 +1727,13 @@ namespace PcapDotNet.Core.Test
return true;
}
return _wiresharkDnsTypeToDnsType.TryGetValue(dataFieldShow.Split(new[] { ": " }, StringSplitOptions.None)[1].Split(' ')[0], out type);
string wiresharkDnsType = dataFieldShow.Split(new[] {": "}, StringSplitOptions.None)[1].Split(' ', '(')[0];
return _wiresharkDnsTypeToDnsType.TryGetValue(wiresharkDnsType, out type);
}
private static int GetFlagCount(XElement flagField)
{
return flagField.Show().Replace(" ", "").TakeWhile(c => c == '.').Count();
return flagField.Showname().Replace(" ", "").TakeWhile(c => c == '.').Count();
}
private static string GetPrecisionValueString(ulong value)
......@@ -1611,9 +1754,12 @@ namespace PcapDotNet.Core.Test
private int _hipRendezvousServersIndex;
private int _wksBitmapIndex;
private int _nxtTypeIndex;
private int _spfTypeIndex;
private int _txtTypeIndex;
private int _nSecTypeIndex;
private int _nSec3TypeIndex;
private int _txtIndex;
private int _aplItemIndex;
private int _optOptionIndex;
}
}
......@@ -26,7 +26,7 @@ namespace PcapDotNet.Core.Test
break;
case "eth.type":
field.AssertShowHex((ushort)ethernetDatagram.EtherType);
field.AssertShowDecimal((ushort)ethernetDatagram.EtherType);
break;
case "eth.trailer":
......@@ -53,11 +53,20 @@ namespace PcapDotNet.Core.Test
switch (field.Name())
{
case "eth.addr":
case "eth.dst_resolved":
case "eth.addr_resolved":
case "eth.src_resolved":
field.AssertShow(address.ToString().ToLower());
field.AssertNoFields();
break;
case "eth.ig":
case "eth.lg":
field.AssertNoFields();
break;
case "_ws.expert":
field.AssertNumFields(4);
break;
default:
......
......@@ -56,7 +56,7 @@ namespace PcapDotNet.Core.Test
break;
case "gre.checksum":
field.AssertShowHex(greDatagram.Checksum);
field.AssertShowDecimal(greDatagram.Checksum);
field.AssertNoFields();
break;
......@@ -138,12 +138,12 @@ namespace PcapDotNet.Core.Test
break;
case "gre.proto":
field.AssertShowHex((ushort)greDatagram.ProtocolType);
field.AssertShowDecimal((ushort)greDatagram.ProtocolType);
field.AssertNoFields();
break;
case "gre.key":
field.AssertShowHex(greDatagram.Key);
field.AssertShowDecimal(greDatagram.Key);
field.AssertNoFields();
break;
......
......@@ -54,13 +54,11 @@ namespace PcapDotNet.Core.Test
case "":
if (fieldShow == "HTTP chunked response")
{
throw new InvalidOperationException("HTTP chunked response");
}
if (fieldShow == @"\r\n" || fieldShow == "HTTP response 1/1" || fieldShow == "HTTP request 1/1")
break;
_data.Append(field.Value());
if (fieldShow == @"\r\n")
break;
if (_isFirstEmptyName)
{
......@@ -168,8 +166,16 @@ namespace PcapDotNet.Core.Test
}
break;
case "http.transfer_encoding":
case "http.request.line":
case "http.response.line":
if (_data.ToString().EndsWith(field.Value()))
break;
{
_data.Append(field.Value());
}
break;
case "http.transfer_encoding":
if (!IsBadHttp(httpDatagram))
{
Assert.AreEqual(fieldShow.ToWiresharkLowerLiteral(),
......@@ -192,20 +198,23 @@ namespace PcapDotNet.Core.Test
{
foreach (var field in httpFirstLineElement.Fields())
{
field.AssertNoFields();
switch (field.Name())
{
case "http.request.method":
field.AssertNoFields();
Assert.IsTrue(httpDatagram.IsRequest, field.Name() + " IsRequest");
field.AssertShow(((HttpRequestDatagram)httpDatagram).Method.Method);
break;
case "http.request.uri":
field.AssertNoFields();
Assert.IsTrue(httpDatagram.IsRequest, field.Name() + " IsRequest");
field.AssertShow(((HttpRequestDatagram)httpDatagram).Uri.ToWiresharkLiteral());
// TODO: Uncomment when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10681 is fixed.
// field.AssertShow(((HttpRequestDatagram)httpDatagram).Uri.ToWiresharkLiteral());
break;
case "http.request.version":
field.AssertNoFields();
if (httpDatagram.Version == null)
{
if (field.Show() != string.Empty)
......@@ -216,11 +225,13 @@ namespace PcapDotNet.Core.Test
break;
case "http.response.code":
field.AssertNoFields();
Assert.IsTrue(httpDatagram.IsResponse, field.Name() + " IsResponse");
field.AssertShowDecimal(IsBadHttp(httpDatagram) ? 0 : ((HttpResponseDatagram)httpDatagram).StatusCode.Value);
break;
case "http.response.phrase":
field.AssertNoFields();
Datagram reasonPhrase = ((HttpResponseDatagram)httpDatagram).ReasonPhrase;
if (reasonPhrase == null)
Assert.IsTrue(IsBadHttp(httpDatagram));
......@@ -228,6 +239,9 @@ namespace PcapDotNet.Core.Test
field.AssertValue(reasonPhrase);
break;
case "_ws.expert":
break;
default:
throw new InvalidOperationException("Invalid HTTP first line field " + field.Name());
}
......
......@@ -37,7 +37,7 @@ namespace PcapDotNet.Core.Test
break;
case "icmp.checksum":
field.AssertShowHex(icmpDatagram.Checksum);
field.AssertShowDecimal(icmpDatagram.Checksum);
field.AssertNoFields();
break;
......
......@@ -37,11 +37,11 @@ namespace PcapDotNet.Core.Test
break;
case "igmp.type":
field.AssertShowHex((byte)igmpDatagram.MessageType);
field.AssertShowDecimal((byte)igmpDatagram.MessageType);
break;
case "igmp.checksum":
field.AssertShowHex(igmpDatagram.Checksum);
field.AssertShowDecimal(igmpDatagram.Checksum);
break;
case "igmp.maddr":
......
using System;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PcapDotNet.Packets;
......@@ -21,6 +23,9 @@ namespace PcapDotNet.Core.Test
switch (field.Name())
{
case "ip.version":
// TODO: Remove this condition when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10706 is fixed.
if (field.Show() != ipV4Datagram.Version.ToString())
return false;
field.AssertShowDecimal(ipV4Datagram.Version);
field.AssertNoFields();
break;
......@@ -41,12 +46,12 @@ namespace PcapDotNet.Core.Test
break;
case "ip.id":
field.AssertShowHex(ipV4Datagram.Identification);
field.AssertShowDecimal(ipV4Datagram.Identification);
field.AssertNoFields();
break;
case "ip.flags":
field.AssertShowHex((byte)((ushort)ipV4Datagram.Fragmentation.Options >> 13));
field.AssertShowDecimal(((ushort)ipV4Datagram.Fragmentation.Options >> 13));
foreach (XElement subfield in field.Fields())
{
subfield.AssertNoFields();
......@@ -76,7 +81,18 @@ namespace PcapDotNet.Core.Test
case "ip.ttl":
field.AssertShowDecimal(ipV4Datagram.Ttl);
field.AssertNoFields();
foreach (XElement subfield in field.Fields())
{
switch (subfield.Name())
{
case "_ws.expert":
break;
default:
subfield.AssertNoFields();
throw new InvalidOperationException(string.Format("Invalid ip subfield {0}", subfield.Name()));
}
}
break;
case "ip.proto":
......@@ -85,7 +101,7 @@ namespace PcapDotNet.Core.Test
break;
case "ip.checksum":
field.AssertShowHex(ipV4Datagram.HeaderChecksum);
field.AssertShowDecimal(ipV4Datagram.HeaderChecksum);
if (field.Showname().EndsWith(" [not all data available]"))
{
Assert.IsFalse(ipV4Datagram.IsValid);
......@@ -96,17 +112,21 @@ namespace PcapDotNet.Core.Test
switch (checksumField.Name())
{
case "ip.checksum_good":
checksumField.AssertShowDecimal(ipV4Datagram.IsHeaderChecksumCorrect);
checksumField.AssertNoFields();
// TODO: Remove this case when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10579 is fixed.
if (field.Showname().EndsWith(" [in ICMP error packet]"))
break;
checksumField.AssertShowDecimal(ipV4Datagram.IsHeaderChecksumCorrect);
break;
case "ip.checksum_bad":
if (ipV4Datagram.Length < IpV4Datagram.HeaderMinimumLength ||
ipV4Datagram.Length < ipV4Datagram.HeaderLength)
ipV4Datagram.Length < ipV4Datagram.HeaderLength ||
// TODO: Remove this case when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10579 is fixed.
field.Showname().EndsWith(" [in ICMP error packet]"))
break;
checksumField.AssertShowDecimal(!ipV4Datagram.IsHeaderChecksumCorrect);
checksumField.AssertNoFields();
break;
}
}
......@@ -145,8 +165,13 @@ namespace PcapDotNet.Core.Test
field.AssertNoFields();
break;
case "ip.cur_rt":
case "ip.cur_rt_host":
field.AssertShow(ipV4Datagram.CurrentDestination.ToString());
break;
case "":
CompareIpV4Options(field, ipV4Datagram.Options);
CompareIpV4Options(field, ipV4Datagram, ipV4Datagram.Options);
break;
default:
......@@ -156,7 +181,7 @@ namespace PcapDotNet.Core.Test
return true;
}
private static void CompareIpV4Options(XElement element, IpV4Options options)
private static void CompareIpV4Options(XElement element, IpV4Datagram ipV4Datagram, IpV4Options options)
{
int currentOptionIndex = 0;
foreach (var field in element.Fields())
......@@ -179,19 +204,447 @@ namespace PcapDotNet.Core.Test
break;
}
IpV4Option option = options[currentOptionIndex++];
if (option.OptionType == IpV4OptionType.BasicSecurity ||
option.OptionType == IpV4OptionType.TraceRoute)
switch (option.OptionType)
{
case IpV4OptionType.NoOperation:
case IpV4OptionType.EndOfOptionList:
field.AssertShow(option.OptionType == IpV4OptionType.EndOfOptionList ? "End of Options List (EOL)" : "No Operation (NOP)");
foreach (var subfield in field.Fields())
{
if (HandleCommonOptionSubfield(subfield, option))
continue;
switch (subfield.Name())
{
default:
throw new InvalidOperationException("Invalid subfield " + subfield.Name());
}
}
break;
case IpV4OptionType.BasicSecurity:
field.AssertShow("Security (" + option.Length + " bytes)");
var basicSecurity = (IpV4OptionBasicSecurity)option;
int basicSecurityFlagsIndex = 0;
foreach (var subfield in field.Fields())
{
if (HandleCommonOptionSubfield(subfield, option))
continue;
switch (subfield.Name())
{
case "ip.opt.sec_cl":
subfield.AssertNoFields();
subfield.AssertShowDecimal((byte)basicSecurity.ClassificationLevel);
break;
case "ip.opt.sec_prot_auth_flags":
foreach (XElement flagField in subfield.Fields())
{
flagField.AssertNoFields();
switch (flagField.Name())
{
case "ip.opt.sec_prot_auth_genser":
flagField.AssertShowDecimal((basicSecurity.ProtectionAuthorities &
IpV4OptionSecurityProtectionAuthorities.Genser) ==
IpV4OptionSecurityProtectionAuthorities.Genser);
break;
case "ip.opt.sec_prot_auth_siop_esi":
flagField.AssertShowDecimal((basicSecurity.ProtectionAuthorities &
IpV4OptionSecurityProtectionAuthorities.
SingleIntegrationOptionalPlanExtremelySensitiveInformation) ==
IpV4OptionSecurityProtectionAuthorities.
SingleIntegrationOptionalPlanExtremelySensitiveInformation);
break;
case "ip.opt.sec_prot_auth_sci":
flagField.AssertShowDecimal((basicSecurity.ProtectionAuthorities &
IpV4OptionSecurityProtectionAuthorities.SensitiveCompartmentedInformation) ==
IpV4OptionSecurityProtectionAuthorities.SensitiveCompartmentedInformation);
break;
case "ip.opt.sec_prot_auth_nsa":
flagField.AssertShowDecimal((basicSecurity.ProtectionAuthorities & IpV4OptionSecurityProtectionAuthorities.Nsa) ==
IpV4OptionSecurityProtectionAuthorities.Nsa);
break;
case "ip.opt.sec_prot_auth_doe":
flagField.AssertShowDecimal((basicSecurity.ProtectionAuthorities &
IpV4OptionSecurityProtectionAuthorities.DepartmentOfEnergy) ==
IpV4OptionSecurityProtectionAuthorities.DepartmentOfEnergy);
break;
case "ip.opt.sec_prot_auth_unassigned":
flagField.AssertShowDecimal(0);
break;
case "ip.opt.sec_prot_auth_fti":
flagField.AssertShowDecimal(basicSecurity.Length - basicSecurityFlagsIndex > 4);
break;
default:
throw new InvalidOperationException("Invalid flag field " + flagField.Name());
}
}
++basicSecurityFlagsIndex;
break;
default:
throw new InvalidOperationException("Invalid subfield " + subfield.Name());
}
}
break;
case IpV4OptionType.StreamIdentifier:
field.AssertShow("Stream ID (" + option.Length + " bytes): " + ((IpV4OptionStreamIdentifier)option).Identifier);
var streamIdentifier = (IpV4OptionStreamIdentifier)option;
foreach (var subfield in field.Fields())
{
if (HandleCommonOptionSubfield(subfield, option))
continue;
switch (subfield.Name())
{
case "ip.opt.sid":
subfield.AssertNoFields();
subfield.AssertShowDecimal(streamIdentifier.Identifier);
break;
default:
throw new InvalidOperationException("Invalid subfield " + subfield.Name());
}
}
break;
case IpV4OptionType.LooseSourceRouting:
field.AssertShow("Loose Source Route (" + option.Length + " bytes)");
var looseSourceRouting = (IpV4OptionLooseSourceRouting)option;
int looseRouteIndex = 0;
foreach (var subfield in field.Fields())
{
if (HandleCommonOptionSubfield(subfield, option))
continue;
switch (subfield.Name())
{
case "ip.opt.ptr":
subfield.AssertShowDecimal(IpV4Address.SizeOf * (looseSourceRouting.PointedAddressIndex + 1));
subfield.AssertNoFields();
break;
case "ip.rec_rt":
case "ip.dst":
case "ip.addr":
case "ip.dst_host":
case "ip.src_rt":
subfield.AssertShow(looseSourceRouting.Route[looseRouteIndex].ToString());
subfield.AssertNoFields();
break;
case "ip.rec_rt_host":
case "ip.host":
case "ip.src_rt_host":
subfield.AssertShow(looseSourceRouting.Route[looseRouteIndex].ToString());
subfield.AssertNoFields();
++looseRouteIndex;
break;
default:
throw new InvalidOperationException("Invalid subfield " + subfield.Name());
}
}
break;
case IpV4OptionType.RecordRoute:
field.AssertShow("Record Route (" + option.Length + " bytes)");
var recordRoute = (IpV4OptionRecordRoute)option;
int recordRouteIndex = 0;
foreach (var subfield in field.Fields())
{
if (HandleCommonOptionSubfield(subfield, option))
continue;
switch (subfield.Name())
{
Assert.IsTrue(field.Show().StartsWith(option.GetWiresharkString()));
continue; // Wireshark doesn't support
case "ip.opt.ptr":
subfield.AssertShowDecimal(IpV4Address.SizeOf * (recordRoute.PointedAddressIndex + 1));
subfield.AssertNoFields();
break;
case "ip.rec_rt":
case "ip.empty_rt":
subfield.AssertShow(recordRoute.Route[recordRouteIndex].ToString());
subfield.AssertNoFields();
break;
case "ip.rec_rt_host":
case "ip.empty_rt_host":
subfield.AssertShow(recordRoute.Route[recordRouteIndex].ToString());
subfield.AssertNoFields();
++recordRouteIndex;
break;
default:
throw new InvalidOperationException("Invalid subfield " + subfield.Name());
}
}
field.AssertShow(option.GetWiresharkString());
break;
case IpV4OptionType.StrictSourceRouting:
field.AssertShow("Strict Source Route (" + option.Length + " bytes)");
if ((option is IpV4OptionUnknown))
var strictSourceRouting = (IpV4OptionStrictSourceRouting)option;
int strictSourceRoutingIndex = 0;
foreach (var subfield in field.Fields())
{
if (HandleCommonOptionSubfield(subfield, option))
continue;
switch (subfield.Name())
{
case "ip.opt.ptr":
subfield.AssertShowDecimal(IpV4Address.SizeOf * (strictSourceRouting.PointedAddressIndex + 1));
subfield.AssertNoFields();
break;
var optionShows = from f in field.Fields() select f.Show();
MoreAssert.AreSequenceEqual(optionShows, option.GetWiresharkSubfieldStrings());
case "ip.dst":
case "ip.addr":
case "ip.dst_host":
case "ip.rec_rt":
case "ip.src_rt":
subfield.AssertShow(strictSourceRouting.Route[strictSourceRoutingIndex].ToString());
subfield.AssertNoFields();
break;
case "ip.host":
case "ip.rec_rt_host":
case "ip.src_rt_host":
subfield.AssertShow(strictSourceRouting.Route[strictSourceRoutingIndex].ToString());
subfield.AssertNoFields();
++strictSourceRoutingIndex;
break;
default:
throw new InvalidOperationException("Invalid subfield " + subfield.Name());
}
}
break;
case IpV4OptionType.RouterAlert:
var routerAlert = (IpV4OptionRouterAlert)option;
field.AssertShow("Router Alert (" + option.Length + " bytes): " +
((routerAlert.Value != 0) ? "Reserved (" + routerAlert.Value + ")" : "Every router examines packet"));
foreach (var subfield in field.Fields())
{
if (HandleCommonOptionSubfield(subfield, option))
continue;
switch (subfield.Name())
{
case "ip.opt.ra":
subfield.AssertNoFields();
subfield.AssertShowDecimal(routerAlert.Value);
break;
default:
throw new InvalidOperationException("Invalid subfield " + subfield.Name());
}
}
break;
case IpV4OptionType.TraceRoute:
field.AssertShow("Traceroute (" + option.Length + " bytes)");
var traceRoute = (IpV4OptionTraceRoute)option;
foreach (var subfield in field.Fields())
{
if (HandleCommonOptionSubfield(subfield, option))
continue;
subfield.AssertNoFields();
switch (subfield.Name())
{
case "ip.opt.id_number":
subfield.AssertShowDecimal(traceRoute.Identification);
break;
case "ip.opt.ohc":
subfield.AssertShowDecimal(traceRoute.OutboundHopCount);
break;
case "ip.opt.rhc":
subfield.AssertShowDecimal(traceRoute.ReturnHopCount);
break;
case "ip.opt.originator":
subfield.AssertShow(traceRoute.OriginatorIpAddress.ToString());
break;
default:
throw new InvalidOperationException("Invalid subfield " + subfield.Name());
}
}
break;
case IpV4OptionType.InternetTimestamp:
field.AssertShow("Time Stamp (" + option.Length + " bytes)");
var timestamp = (IpV4OptionTimestamp)option;
int timestampIndex = 0;
foreach (var subfield in field.Fields())
{
if (HandleCommonOptionSubfield(subfield, option))
continue;
subfield.AssertNoFields();
switch (subfield.Name())
{
case "":
var subfieldParts = subfield.Show().Split(new[] { ':', '=', ',' }, StringSplitOptions.RemoveEmptyEntries);
string subfieldValue = subfieldParts[1].Trim();
switch (subfieldParts[0].Trim())
{
case "Pointer":
Assert.AreEqual(timestamp.PointedIndex, int.Parse(subfieldValue) / 4 - 1);
break;
case "Overflow":
Assert.AreEqual(timestamp.Overflow.ToString(), subfieldValue);
break;
case "Flag":
switch (timestamp.TimestampType)
{
case IpV4OptionTimestampType.AddressAndTimestamp:
Assert.AreEqual("Time stamp and address", subfieldValue);
break;
case IpV4OptionTimestampType.TimestampOnly:
Assert.AreEqual("Time stamps only", subfieldValue);
break;
case IpV4OptionTimestampType.AddressPrespecified:
Assert.AreEqual("Time stamps for prespecified addresses", subfieldValue);
break;
default:
throw new InvalidOperationException("Invalid timestamp type: " + timestamp.TimestampType);
}
break;
case "Time stamp":
var timestampOnly = (IpV4OptionTimestampOnly)timestamp;
Assert.AreEqual(timestampOnly.Timestamps[timestampIndex].MillisecondsSinceMidnightUniversalTime, uint.Parse(subfieldValue));
++timestampIndex;
break;
case "Address":
Assert.AreEqual(4, subfieldParts.Length);
var timestampAndAddress = (IpV4OptionTimestampAndAddress)timestamp;
Assert.AreEqual(timestampAndAddress.TimedRoute[timestampIndex].Address.ToString(), subfieldParts[1].Trim());
Assert.AreEqual("time stamp", subfieldParts[2].Trim());
Assert.AreEqual(timestampAndAddress.TimedRoute[timestampIndex].TimeOfDay.MillisecondsSinceMidnightUniversalTime,
uint.Parse(subfieldParts[3]));
++timestampIndex;
break;
default:
throw new InvalidOperationException("Invalid subfield " + subfield.Show());
}
break;
default:
throw new InvalidOperationException("Invalid subfield " + subfield.Name());
}
}
break;
case IpV4OptionType.QuickStart:
IpV4OptionQuickStart quickStart = (IpV4OptionQuickStart)option;
StringBuilder quickStartWireshark = new StringBuilder("Quick-Start (" + option.Length + " bytes): ");
quickStartWireshark.Append(quickStart.QuickStartFunction == IpV4OptionQuickStartFunction.RateRequest ? "Rate request" : "Rate report");
quickStartWireshark.Append(" (" + (byte)quickStart.QuickStartFunction + ")");
quickStartWireshark.Append(", ");
if (quickStart.RateKbps == 0)
quickStartWireshark.Append("0 bit/s");
else if (quickStart.RateKbps < 1024)
quickStartWireshark.Append(quickStart.RateKbps + " Kbit/s");
else if (quickStart.RateKbps < 1024 * 1024)
quickStartWireshark.Append(((double)quickStart.RateKbps / 1000).ToString(CultureInfo.InvariantCulture) + " Mbit/s");
else
quickStartWireshark.Append(((double)quickStart.RateKbps / 1000000).ToString(CultureInfo.InvariantCulture) + " Gbit/s");
if (quickStart.QuickStartFunction == IpV4OptionQuickStartFunction.RateRequest)
quickStartWireshark.Append(", QS TTL " + quickStart.Ttl + ", QS TTL diff " + (256 + ipV4Datagram.Ttl - quickStart.Ttl) % 256);
field.AssertShow(quickStartWireshark.ToString());
foreach (var subfield in field.Fields())
{
if (HandleCommonOptionSubfield(subfield, option))
continue;
subfield.AssertNoFields();
switch (subfield.Name())
{
case "ip.opt.qs_func":
subfield.AssertShowDecimal((byte)quickStart.QuickStartFunction);
break;
case "ip.opt.qs_rate":
subfield.AssertShowDecimal(quickStart.Rate);
break;
case "ip.opt.qs_ttl":
case "ip.opt.qs_unused":
subfield.AssertShowDecimal(quickStart.Ttl);
break;
case "ip.opt.qs_ttl_diff":
subfield.AssertShowDecimal((256 + ipV4Datagram.Ttl - quickStart.Ttl) % 256);
break;
case "ip.opt.qs_nonce":
subfield.AssertShowDecimal(quickStart.Nonce);
break;
case "ip.opt.qs_reserved":
subfield.AssertShowDecimal(0);
break;
default:
throw new InvalidOperationException("Invalid subfield " + subfield.Name());
}
}
break;
case (IpV4OptionType)11:
// TODO: Support 11.
field.AssertShow("MTU Probe (with option length = " + option.Length + " bytes; should be 4)");
break;
case (IpV4OptionType)133:
// TODO: Support 133.
field.AssertShow("Extended Security (" + option.Length + " bytes)");
break;
case (IpV4OptionType)134:
// TODO: Support 134.
field.AssertShow("Commercial Security" +
(option.Length >= 10 ? string.Empty : " (with option length = " + option.Length + " bytes; should be >= 10)"));
break;
case (IpV4OptionType)149:
// TODO: Support 149.
field.AssertShow("Selective Directed Broadcast (11 bytes)");
break;
default:
field.AssertShow("Unknown (0x" + ((byte)option.OptionType).ToString("x2") + ") (" + option.Length + " bytes)");
field.AssertNoFields();
break;
}
}
}
private static bool HandleCommonOptionSubfield(XElement subfield, IpV4Option option)
{
switch (subfield.Name())
{
case "ip.opt.type":
subfield.AssertShowDecimal((byte)option.OptionType);
return true;
case "ip.opt.len":
subfield.AssertShowDecimal(option.Length);
subfield.AssertNoFields();
return true;
default:
return false;
}
}
}
......
......@@ -46,12 +46,11 @@ namespace PcapDotNet.Core.Test
break;
case "ipv6.class":
field.AssertShowHex((uint)ipV6Datagram.TrafficClass);
//field.AssertNoFields();
field.AssertShowDecimal(ipV6Datagram.TrafficClass);
break;
case "ipv6.flow":
field.AssertShowHex((uint)ipV6Datagram.FlowLabel);
field.AssertShowDecimal(ipV6Datagram.FlowLabel);
field.AssertNoFields();
break;
......@@ -61,7 +60,7 @@ namespace PcapDotNet.Core.Test
break;
case "ipv6.nxt":
field.AssertShowHex((byte)ipV6Datagram.NextHeader);
field.AssertShowDecimal((byte)ipV6Datagram.NextHeader);
field.AssertNoFields();
break;
......@@ -111,7 +110,7 @@ namespace PcapDotNet.Core.Test
IpV6ExtensionHeaderHopByHopOptions hopByHopOptions =
(IpV6ExtensionHeaderHopByHopOptions)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex];
IncrementCurrentExtensionHeaderIndex(ipV6Datagram);
CompareOptions(field, ref optionsIndex, hopByHopOptions);
CompareOptions(field, ref optionsIndex, ipV6Datagram, hopByHopOptions);
}
break;
......@@ -119,35 +118,83 @@ namespace PcapDotNet.Core.Test
if (!ipV6Datagram.IsValid)
return false;
IpV6ExtensionHeaderRouting routing = (IpV6ExtensionHeaderRouting)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex];
IpV6ExtensionHeaderRoutingProtocolLowPowerAndLossyNetworks routingProtocolLowPowerAndLossyNetworks =
routing as IpV6ExtensionHeaderRoutingProtocolLowPowerAndLossyNetworks;
int routingProtocolLowPowerAndLossyNetworksAddressIndex = 0;
IncrementCurrentExtensionHeaderIndex(ipV6Datagram);
int sourceRouteAddressIndex = 0;
foreach (var headerField in field.Fields())
{
headerField.AssertNoFields();
switch (headerField.Name())
{
case "":
headerField.AssertNoFields();
ValidateExtensionHeaderUnnamedField(routing, headerField);
break;
case "ipv6.routing_hdr.type":
headerField.AssertNoFields();
headerField.AssertShowDecimal((byte)routing.RoutingType);
break;
case "ipv6.routing_hdr.left":
headerField.AssertNoFields();
headerField.AssertShowDecimal(routing.SegmentsLeft);
break;
case "ipv6.mipv6_home_address":
headerField.AssertNoFields();
IpV6ExtensionHeaderRoutingHomeAddress routingHomeAddress = (IpV6ExtensionHeaderRoutingHomeAddress)routing;
headerField.AssertShow(routingHomeAddress.HomeAddress.ToString("x"));
break;
case "ipv6.routing_hdr.addr":
headerField.AssertNoFields();
IpV6ExtensionHeaderRoutingSourceRoute routingSourceRoute = (IpV6ExtensionHeaderRoutingSourceRoute)routing;
headerField.AssertShow(routingSourceRoute.Addresses[sourceRouteAddressIndex++].ToString("x"));
break;
case "ipv6.routing_hdr.rpl.cmprI":
headerField.AssertNoFields();
headerField.AssertShowDecimal(routingProtocolLowPowerAndLossyNetworks.CommonPrefixLengthForNonLastAddresses);
break;
case "ipv6.routing_hdr.rpl.cmprE":
headerField.AssertNoFields();
headerField.AssertShowDecimal(routingProtocolLowPowerAndLossyNetworks.CommonPrefixLengthForLastAddress);
break;
case "ipv6.routing_hdr.rpl.pad":
headerField.AssertNoFields();
headerField.AssertShowDecimal(routingProtocolLowPowerAndLossyNetworks.PadSize);
break;
case "ipv6.routing_hdr.rpl.reserved":
headerField.AssertNoFields();
headerField.AssertShowDecimal(0);
break;
case "ipv6.routing_hdr.rpl.segments":
if (headerField.Fields().Any())
{
headerField.AssertNumFields(1);
headerField.Fields().First().AssertName("_ws.expert");
}
// TODO: Uncomment when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10560 is fixed.
// headerField.AssertShowDecimal(routingProtocolLowPowerAndLossyNetworks.Addresses.Count);
break;
case "ipv6.routing_hdr.rpl.address":
headerField.AssertNoFields();
// TODO: Implement when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10560 is fixed.
break;
case "ipv6.routing_hdr.rpl.full_address":
headerField.AssertNoFields();
// TODO: Implement when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10673 is fixed.
++routingProtocolLowPowerAndLossyNetworksAddressIndex;
break;
default:
throw new InvalidOperationException("Invalid IPv6 routing source route field " + headerField.Name());
}
......@@ -166,7 +213,7 @@ namespace PcapDotNet.Core.Test
}
IpV6ExtensionHeaderDestinationOptions destinationOptions = (IpV6ExtensionHeaderDestinationOptions)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex];
IncrementCurrentExtensionHeaderIndex(ipV6Datagram);
CompareOptions(field, ref optionsIndex, destinationOptions);
CompareOptions(field, ref optionsIndex, ipV6Datagram, destinationOptions);
break;
case "ipv6.shim6":
......@@ -205,7 +252,7 @@ namespace PcapDotNet.Core.Test
{
switch (headerField.Name())
{
case "":
case "ipv6.fragment.nxt":
headerField.AssertValue((byte)fragmentData.NextHeader.Value);
break;
......@@ -217,8 +264,13 @@ namespace PcapDotNet.Core.Test
headerField.AssertShowDecimal(fragmentData.MoreFragments);
break;
case "ipv6.framgent.id":
headerField.AssertShowHex(fragmentData.Identification);
case "ipv6.fragment.id":
headerField.AssertShowDecimal(fragmentData.Identification);
break;
case "ipv6.fragment.reserved_octet":
case "ipv6.fragment.reserved_bits":
headerField.AssertShowDecimal(0);
break;
default:
......@@ -239,39 +291,194 @@ namespace PcapDotNet.Core.Test
return true;
}
private void CompareOptions(XElement field, ref int optionsIndex, IpV6ExtensionHeaderOptions header)
private void CompareOptions(XElement field, ref int optionsIndex, IpV6Datagram ipV6Datagram, IpV6ExtensionHeaderOptions header)
{
foreach (var headerField in field.Fields())
{
headerField.AssertNoFields();
switch (headerField.Name())
{
case "":
ValidateExtensionHeaderUnnamedField(header, headerField, ref optionsIndex);
case "ipv6.nxt":
headerField.AssertNoFields();
headerField.AssertShowDecimal((byte)header.NextHeader);
break;
case "ipv6.opt.pad1":
if (header.Options.IsValid)
Assert.AreEqual(IpV6OptionType.Pad1, header.Options[optionsIndex++].OptionType);
case "ipv6.opt.length":
headerField.AssertNoFields();
headerField.AssertShowDecimal((header.Length - 8) / 8);
break;
case "ipv6.opt":
foreach (XElement headerSubfield in headerField.Fields())
{
IpV6Option option = header.Options[optionsIndex];
var optionCalipso = option as IpV6OptionCalipso;
var optionQuickStart = option as IpV6OptionQuickStart;
switch (headerSubfield.Name())
{
case "ipv6.opt.type":
headerSubfield.AssertNoFields();
headerSubfield.AssertShowDecimal((byte)option.OptionType);
break;
case "ipv6.opt.length":
headerSubfield.AssertNoFields();
headerSubfield.AssertShowDecimal(option.Length - 2);
break;
case "ipv6.opt.tel":
headerSubfield.AssertNoFields();
IpV6OptionTunnelEncapsulationLimit optionTunnelEncapsulationLimit = (IpV6OptionTunnelEncapsulationLimit)option;
headerSubfield.AssertShowDecimal(optionTunnelEncapsulationLimit.TunnelEncapsulationLimit);
++optionsIndex;
break;
case "ipv6.opt.rpl.flag":
IpV6OptionRoutingProtocolLowPowerAndLossyNetworks optionRoutingProtocolLowPowerAndLossyNetworks =
(IpV6OptionRoutingProtocolLowPowerAndLossyNetworks)option;
foreach (XElement optionSubfield in headerSubfield.Fields())
{
optionSubfield.AssertNoFields();
switch (optionSubfield.Name())
{
case "ipv6.opt.rpl.flag.o":
optionSubfield.AssertShowDecimal(optionRoutingProtocolLowPowerAndLossyNetworks.Down);
break;
case "ipv6.opt.rpl.flag.r":
optionSubfield.AssertShowDecimal(optionRoutingProtocolLowPowerAndLossyNetworks.RankError);
break;
case "ipv6.opt.rpl.flag.f":
optionSubfield.AssertShowDecimal(optionRoutingProtocolLowPowerAndLossyNetworks.ForwardingError);
break;
case "ipv6.opt.rpl.flag.rsv":
optionSubfield.AssertShowDecimal(0);
break;
case "ipv6.opt.rpl.instance_id":
optionSubfield.AssertShowDecimal(
optionRoutingProtocolLowPowerAndLossyNetworks.RoutingProtocolLowPowerAndLossyNetworksInstanceId);
break;
case "ipv6.opt.rpl.sender_rank":
optionSubfield.AssertShowDecimal(optionRoutingProtocolLowPowerAndLossyNetworks.SenderRank);
break;
default:
throw new InvalidOperationException("Invalid ipv6 option subfield " + optionSubfield.Name());
}
}
++optionsIndex;
// TODO: change to break; after https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10559 is fixed.
return;
case "ipv6.opt.calipso.doi":
headerSubfield.AssertNoFields();
headerSubfield.AssertShowDecimal((uint)optionCalipso.DomainOfInterpretation);
break;
case "ipv6.opt.calipso.cmpt.length":
headerSubfield.AssertNoFields();
headerSubfield.AssertShowDecimal(optionCalipso.CompartmentLength);
break;
case "ipv6.opt.calipso.sens_level":
headerSubfield.AssertNoFields();
headerSubfield.AssertShowDecimal(optionCalipso.SensitivityLevel);
break;
case "ipv6.opt.calipso.checksum":
headerSubfield.AssertNoFields();
headerSubfield.AssertShowDecimal(optionCalipso.Checksum);
break;
case "ipv6.opt.calipso.cmpt_bitmap":
headerSubfield.AssertNoFields();
// TODO: Uncomment and avoid returning when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10561 is fixed.
// headerSubfield.AssertValue(optionCalipso.CompartmentBitmap);
return;
case "ipv6.opt.router_alert":
headerSubfield.AssertNoFields();
var optionRouterAlert = (IpV6OptionRouterAlert)option;
headerSubfield.AssertShowDecimal((ushort)optionRouterAlert.RouterAlertType);
++optionsIndex;
break;
case "ipv6.opt.padn":
Assert.AreEqual(IpV6OptionType.PadN, header.Options[optionsIndex].OptionType);
if (header.Options.IsValid)
headerField.AssertShowDecimal(header.Options[optionsIndex++].Length);
headerSubfield.AssertNoFields();
var optionPadN = (IpV6OptionPadN)option;
headerSubfield.AssertValue(new byte[optionPadN.PaddingDataLength]);
++optionsIndex;
break;
case "ipv6.opt.qs_func":
headerSubfield.AssertNoFields();
headerSubfield.AssertShowDecimal((byte)optionQuickStart.QuickStartFunction);
break;
case "ipv6.opt.qs_rate":
headerSubfield.AssertNoFields();
headerSubfield.AssertShowDecimal(optionQuickStart.Rate);
break;
case "ipv6.opt.qs_ttl":
headerSubfield.AssertNoFields();
headerSubfield.AssertShowDecimal(optionQuickStart.Ttl);
break;
case "ipv6.mipv6_type":
Assert.AreEqual(IpV6OptionType.HomeAddress, header.Options[optionsIndex].OptionType);
case "ipv6.opt.qs_ttl_diff":
headerSubfield.AssertNoFields();
headerSubfield.AssertShowDecimal((256 + ipV6Datagram.HopLimit - optionQuickStart.Ttl) % 256);
break;
case "ipv6.mipv6_length":
headerField.AssertShowDecimal(header.Options[optionsIndex].Length - 2);
case "ipv6.opt.qs_unused":
headerSubfield.AssertNoFields();
headerSubfield.AssertShowDecimal(optionQuickStart.Ttl);
break;
case "ipv6.opt.qs_nonce":
headerSubfield.AssertNoFields();
// TODO: Stop returning and uncomment the code when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10575 is fixed.
return;
case "ipv6.opt.pad1":
headerSubfield.AssertNoFields();
headerSubfield.AssertShow("");
Assert.IsTrue(option is IpV6OptionPad1);
++optionsIndex;
break;
case "ipv6.opt.jumbo":
headerSubfield.AssertNoFields();
headerSubfield.AssertShowDecimal(((IpV6OptionJumboPayload)option).JumboPayloadLength);
++optionsIndex;
break;
case "ipv6.mipv6_home_address":
IpV6OptionHomeAddress homeAddress = (IpV6OptionHomeAddress)header.Options[optionsIndex++];
headerField.AssertShow(homeAddress.HomeAddress.ToString("x"));
headerSubfield.AssertNoFields();
headerSubfield.AssertShow(((IpV6OptionHomeAddress)option).HomeAddress.GetWiresharkString());
++optionsIndex;
break;
case "ipv6.opt.unknown":
headerSubfield.AssertNoFields();
Assert.IsTrue(new[]
{
IpV6OptionType.LineIdentification,
IpV6OptionType.IdentifierLocatorNetworkProtocolNonce,
IpV6OptionType.SimplifiedMulticastForwardingDuplicatePacketDetection,
IpV6OptionType.EndpointIdentification,
}.Contains(option.OptionType),
option.OptionType.ToString());
++optionsIndex;
break;
default:
throw new InvalidOperationException("Invalid ipv6 header subfield " + headerSubfield.Name());
}
}
break;
default:
......
......@@ -61,7 +61,7 @@ namespace PcapDotNet.Core.Test
break;
case "ah.spi":
field.AssertShowHex(authenticationHeader.SecurityParametersIndex);
field.AssertShowDecimal(authenticationHeader.SecurityParametersIndex);
break;
case "ah.sequence":
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -66,7 +66,18 @@ namespace PcapDotNet.Core.Test
case "tcp.ack":
field.AssertShowDecimal(tcpDatagram.AcknowledgmentNumber);
field.AssertNoFields();
foreach (XElement subfield in field.Fields())
{
switch (subfield.Name())
{
case "_ws.expert":
break;
default:
subfield.AssertNoFields();
throw new InvalidOperationException("Invalid TCP subfield name " + subfield.Name());
}
}
break;
case "tcp.hdr_len":
......@@ -79,44 +90,93 @@ namespace PcapDotNet.Core.Test
(ushort)((tcpDatagram.Reserved << 9) |
(((tcpDatagram.ControlBits & TcpControlBits.NonceSum) == TcpControlBits.NonceSum ? 1 : 0) << 8) |
(byte)tcpDatagram.ControlBits);
field.AssertShow("0x" + flags.ToString("x" + 4 * sizeof(byte)));
field.AssertShowDecimal(flags);
foreach (var flagField in field.Fields())
{
switch (flagField.Name())
{
case "tcp.flags.res":
flagField.AssertNoFields();
break;
case "tcp.flags.ns":
flagField.AssertNoFields();
flagField.AssertShowDecimal(tcpDatagram.IsNonceSum);
break;
case "tcp.flags.cwr":
flagField.AssertNoFields();
flagField.AssertShowDecimal(tcpDatagram.IsCongestionWindowReduced);
break;
case "tcp.flags.ecn":
flagField.AssertNoFields();
flagField.AssertShowDecimal(tcpDatagram.IsExplicitCongestionNotificationEcho);
break;
case "tcp.flags.urg":
flagField.AssertNoFields();
flagField.AssertShowDecimal(tcpDatagram.IsUrgent);
break;
case "tcp.flags.ack":
flagField.AssertNoFields();
flagField.AssertShowDecimal(tcpDatagram.IsAcknowledgment);
break;
case "tcp.flags.push":
flagField.AssertNoFields();
flagField.AssertShowDecimal(tcpDatagram.IsPush);
break;
case "tcp.flags.reset":
flagField.AssertShowDecimal(tcpDatagram.IsReset);
foreach (XElement subfield in flagField.Fields())
{
switch (subfield.Name())
{
case "_ws.expert":
break;
default:
throw new InvalidOperationException("Invalid TCP subfield name " + subfield.Name());
}
}
break;
case "tcp.flags.syn":
flagField.AssertShowDecimal(tcpDatagram.IsSynchronize);
foreach (XElement subfield in flagField.Fields())
{
switch (subfield.Name())
{
case "_ws.expert":
break;
default:
throw new InvalidOperationException("Invalid TCP subfield name " + subfield.Name());
}
}
break;
case "tcp.flags.fin":
flagField.AssertShowDecimal(tcpDatagram.IsFin);
foreach (XElement subfield in flagField.Fields())
{
switch (subfield.Name())
{
case "_ws.expert":
break;
default:
throw new InvalidOperationException("Invalid TCP subfield name " + subfield.Name());
}
}
break;
default:
throw new InvalidOperationException("Invalid TCP flag field name " + flagField.Name());
}
flagField.AssertNoFields();
}
break;
......@@ -126,7 +186,7 @@ namespace PcapDotNet.Core.Test
break;
case "tcp.checksum":
field.AssertShowHex(tcpDatagram.Checksum);
field.AssertShowDecimal(tcpDatagram.Checksum);
IpV4Datagram ipV4Datagram = ipDatagram as IpV4Datagram;
if (ipV4Datagram != null && !ipV4Datagram.Options.IsBadForWireshark())
{
......@@ -143,6 +203,11 @@ namespace PcapDotNet.Core.Test
checksumField.AssertShowDecimal(tcpDatagram.Checksum != 0 && !ipDatagram.IsTransportChecksumCorrect);
break;
case "tcp.checksum_calculated":
if (ipDatagram.IsTransportChecksumCorrect)
checksumField.AssertShowDecimal(tcpDatagram.Checksum);
break;
default:
throw new InvalidOperationException("Invalid checksum field name " + checksumField.Name());
}
......@@ -153,7 +218,6 @@ namespace PcapDotNet.Core.Test
case "tcp.urgent_pointer":
field.AssertShowDecimal(tcpDatagram.UrgentPointer);
field.AssertNoFields();
break;
case "tcp.options":
......@@ -164,8 +228,19 @@ namespace PcapDotNet.Core.Test
case "tcp.pdu.size":
case "tcp.window_size":
case "tcp.window_size_scalefactor":
field.AssertNoFields();
break;
case "":
if (field.Show() == "Short segment. Segment/fragment does not contain a full TCP header (might be NMAP or someone else deliberately sending unusual packets)")
{
field.AssertNumFields(1);
field.Fields().First().AssertName("_ws.expert");
}
else
{
field.AssertNoFields();
}
break;
default:
......@@ -220,16 +295,10 @@ namespace PcapDotNet.Core.Test
TcpOptionWindowScale windowScale = (TcpOptionWindowScale)option;
foreach (var subField in field.Fields())
{
if (HandleOptionCommonFields(subField, option))
continue;
switch (subField.Name())
{
case "tcp.option_kind":
subField.AssertShowDecimal((byte)windowScale.OptionType);
break;
case "tcp.option_len":
subField.AssertShowDecimal(windowScale.Length);
break;
case "tcp.options.wscale.shift":
subField.AssertShowDecimal(windowScale.ScaleFactorLog);
break;
......@@ -239,7 +308,7 @@ namespace PcapDotNet.Core.Test
break;
default:
throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name());
throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
}
}
break;
......@@ -249,6 +318,9 @@ namespace PcapDotNet.Core.Test
int blockIndex = 0;
foreach (var subField in field.Fields())
{
if (HandleOptionCommonFields(subField, option))
continue;
subField.AssertNoFields();
switch (subField.Name())
{
case "tcp.options.sack":
......@@ -264,8 +336,12 @@ namespace PcapDotNet.Core.Test
++blockIndex;
break;
case "tcp.options.sack.count":
subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks.Count);
break;
default:
throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name());
throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
}
}
break;
......@@ -274,16 +350,11 @@ namespace PcapDotNet.Core.Test
var timestampOption = (TcpOptionTimestamp)option;
foreach (var subField in field.Fields())
{
if (HandleOptionCommonFields(subField, option))
continue;
subField.AssertNoFields();
switch (subField.Name())
{
case "tcp.option_kind":
subField.AssertShowDecimal((byte)option.OptionType);
break;
case "tcp.option_len":
subField.AssertShowDecimal(option.Length);
break;
case "tcp.options.timestamp.tsval":
subField.AssertShowDecimal(timestampOption.TimestampValue);
break;
......@@ -293,11 +364,130 @@ namespace PcapDotNet.Core.Test
break;
default:
throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name());
throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
}
}
break;
case TcpOptionType.ConnectionCount:
field.AssertShow("CC: " + ((TcpOptionConnectionCount)option).ConnectionCount);
foreach (var subField in field.Fields())
{
if (HandleOptionCommonFields(subField, option))
continue;
subField.AssertNoFields();
switch (subField.Name())
{
default:
throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
}
}
break;
case TcpOptionType.Echo:
field.AssertShow("Echo: " + ((TcpOptionEcho)option).Info);
foreach (var subField in field.Fields())
{
if (HandleOptionCommonFields(subField, option))
continue;
subField.AssertNoFields();
switch (subField.Name())
{
default:
throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
}
}
break;
case TcpOptionType.ConnectionCountNew:
field.AssertShow("CC.NEW: " + ((TcpOptionConnectionCountNew)option).ConnectionCount);
foreach (var subField in field.Fields())
{
if (HandleOptionCommonFields(subField, option))
continue;
subField.AssertNoFields();
switch (subField.Name())
{
default:
throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
}
}
break;
case TcpOptionType.EndOfOptionList:
field.AssertShow("End of Option List (EOL)");
foreach (var subField in field.Fields())
{
if (HandleOptionCommonFields(subField, option))
continue;
switch (subField.Name())
{
default:
subField.AssertNoFields();
throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
}
}
break;
case TcpOptionType.ConnectionCountEcho:
field.AssertShow("CC.ECHO: " + ((TcpOptionConnectionCountEcho)option).ConnectionCount);
foreach (var subField in field.Fields())
{
if (HandleOptionCommonFields(subField, option))
continue;
subField.AssertNoFields();
switch (subField.Name())
{
default:
throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
}
}
break;
case TcpOptionType.Md5Signature:
field.AssertShow("TCP MD5 signature");
foreach (var subField in field.Fields())
{
if (HandleOptionCommonFields(subField, option))
continue;
switch (subField.Name())
{
case "tcp.options.type":
subField.AssertShowDecimal((byte)TcpOptionType.Md5Signature);
break;
default:
subField.AssertNoFields();
throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
}
}
break;
case TcpOptionType.NoOperation:
field.AssertShow("No-Operation (NOP)");
foreach (var subField in field.Fields())
{
if (HandleOptionCommonFields(subField, option))
continue;
throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
}
break;
case TcpOptionType.EchoReply:
field.AssertShow("Echo reply: " + ((TcpOptionEchoReply)option).Info);
foreach (var subField in field.Fields())
{
if (HandleOptionCommonFields(subField, option))
continue;
throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
}
break;
case (TcpOptionType)23:
field.AssertShow("SCPS corruption experienced (with option length = " + option.Length + " bytes; should be 2)");
// TODO: Support 23.
break;
default:
field.AssertNoFields();
break;
......@@ -307,8 +497,24 @@ namespace PcapDotNet.Core.Test
case "tcp.options.mss":
Assert.AreEqual(TcpOptionType.MaximumSegmentSize, option.OptionType);
field.AssertShowDecimal(true);
field.AssertNoFields();
var maximumSegmentSize = (TcpOptionMaximumSegmentSize)option;
field.AssertShowname("Maximum segment size: " + maximumSegmentSize.MaximumSegmentSize + " bytes");
foreach (var subField in field.Fields())
{
if (HandleOptionCommonFields(subField, option))
continue;
subField.AssertNoFields();
switch (subField.Name())
{
case "tcp.options.mss_val":
subField.AssertShowDecimal(maximumSegmentSize.MaximumSegmentSize);
break;
default:
throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name());
}
}
++currentOptionIndex;
break;
case "tcp.options.mss_val":
......@@ -330,13 +536,15 @@ namespace PcapDotNet.Core.Test
break;
case "tcp.options.scps.vector":
// TODO: Support 20.
Assert.AreEqual((TcpOptionType)20, option.OptionType);
if (field.Show() == "0")
++currentOptionIndex;
// if (field.Show() == "0")
// ++currentOptionIndex;
++currentOptionIndex;
break;
case "tcp.options.scps":
// TODO: Support 20.
Assert.AreEqual((TcpOptionType)20, option.OptionType);
Assert.IsFalse(field.Fields().Any());
break;
......@@ -350,7 +558,13 @@ namespace PcapDotNet.Core.Test
case "tcp.options.sack_perm":
Assert.AreEqual(TcpOptionType.SelectiveAcknowledgmentPermitted, option.OptionType);
field.AssertNoFields();
foreach (var subField in field.Fields())
{
if (HandleOptionCommonFields(subField, option))
continue;
subField.AssertNoFields();
throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name());
}
++currentOptionIndex;
break;
......@@ -366,10 +580,39 @@ namespace PcapDotNet.Core.Test
++currentOptionIndex;
break;
case "tcp.options.experimental":
Assert.IsTrue(new []{(TcpOptionType)253, (TcpOptionType)254}.Contains(option.OptionType));
// TODO: Support Experimental.
++currentOptionIndex;
break;
default:
throw new InvalidOperationException("Invalid tcp options field " + field.Name());
}
}
}
private static bool HandleOptionCommonFields(XElement subfield, TcpOption option)
{
switch (subfield.Name())
{
case "tcp.option_kind":
subfield.AssertNoFields();
subfield.AssertShowDecimal((byte)option.OptionType);
return true;
case "tcp.options.type":
subfield.AssertShowDecimal((byte)option.OptionType);
return true;
case "tcp.option_len":
subfield.AssertNoFields();
subfield.AssertShowDecimal(option.Length);
return true;
default:
return false;
}
}
}
}
\ No newline at end of file
......@@ -40,7 +40,7 @@ namespace PcapDotNet.Core.Test
break;
case "udp.checksum":
field.AssertShowHex(udpDatagram.Checksum);
field.AssertShowDecimal(udpDatagram.Checksum);
if (udpDatagram.Checksum != 0)
{
foreach (var checksumField in field.Fields())
......@@ -66,6 +66,9 @@ namespace PcapDotNet.Core.Test
field.AssertShowDecimal(udpDatagram.TotalLength);
break;
case "udp.stream":
break;
default:
throw new InvalidOperationException("Invalid udp field " + field.Name());
}
......
......@@ -19,26 +19,33 @@ namespace PcapDotNet.Core.Test
switch (field.Name())
{
case "vlan.priority":
field.AssertNoFields();
field.AssertShowDecimal((byte)vLanTaggedFrameDatagram.PriorityCodePoint);
break;
case "vlan.cfi":
field.AssertNoFields();
field.AssertShowDecimal(vLanTaggedFrameDatagram.CanonicalFormatIndicator);
break;
case "vlan.id":
field.AssertNoFields();
field.AssertShowDecimal(vLanTaggedFrameDatagram.VLanIdentifier);
break;
case "vlan.etype":
field.AssertShowHex((ushort)vLanTaggedFrameDatagram.EtherType);
field.AssertNoFields();
field.AssertShowDecimal((ushort)vLanTaggedFrameDatagram.EtherType);
break;
case "vlan.len":
field.AssertShowDecimal((ushort)vLanTaggedFrameDatagram.EtherType);
field.AssertNumFields(1);
field.Fields().First().AssertName("_ws.expert");
break;
case "vlan.trailer":
field.AssertNoFields();
if (!new[]
{
(EthernetType)1, (EthernetType)5, (EthernetType)17, (EthernetType)29, (EthernetType)30, (EthernetType)43, (EthernetType)50, EthernetType.ReverseArp,
......@@ -50,7 +57,6 @@ namespace PcapDotNet.Core.Test
default:
throw new InvalidOperationException("Invalid VLanTaggedFrame field " + field.Name());
}
field.AssertNoFields();
return true;
}
......
......@@ -18,7 +18,6 @@ namespace PcapDotNet.Core.Test
switch (currentChar)
{
case '\\':
case '"':
result.Append('\\');
result.Append(currentChar);
continue;
......
......@@ -67,6 +67,11 @@ namespace PcapDotNet.Core.Test
Assert.AreEqual(expectedNumFields, element.Fields().Count());
}
public static void AssertShowname(this XElement element, string expectedValue, bool ignoreCase = false, string message = null)
{
Assert.AreEqual(expectedValue, element.Showname(), ignoreCase, message ?? element.Name());
}
public static void AssertNoShow(this XElement element)
{
Assert.IsNull(element.Attribute("show"));
......@@ -164,7 +169,7 @@ namespace PcapDotNet.Core.Test
public static void AssertValue(this XElement element, string expectedValue, string message = null)
{
Assert.AreEqual(expectedValue.Length, element.Value().Length, message ?? element.Name());
Assert.AreEqual(expectedValue.Length, element.Value().Length, (message ?? element.Name()) + " Length");
Assert.AreEqual(expectedValue, element.Value(), message ?? element.Name());
}
......@@ -208,6 +213,11 @@ namespace PcapDotNet.Core.Test
element.AssertValue(expectedValue.ToString("x16"));
}
public static void AssertValue(this XElement element, UInt128 expectedValue)
{
element.AssertValue(expectedValue.ToString("x32"));
}
public static void AssertValue(this XElement element, SerialNumber32 expectedValue)
{
element.AssertValue(expectedValue.Value);
......
......@@ -92,7 +92,9 @@ namespace PcapDotNet.Packets.Test
EtherType = EthernetType
};
Random random = new Random();
int seed = new Random().Next();
Console.WriteLine(seed);
Random random = new Random(seed);
for (int i = 0; i != 1000; ++i)
{
......
......@@ -180,7 +180,7 @@ namespace PcapDotNet.Packets.TestUtils
return new IpV4OptionQuickStart(random.NextEnum<IpV4OptionQuickStartFunction>(),
random.NextByte(IpV4OptionQuickStart.RateMaximumValue + 1),
random.NextByte(),
random.NextUInt() & 0xFFFFFFFC);
random.NextUInt() & 0x3FFFFFFF);
default:
throw new InvalidOperationException("optionType = " + optionType);
......
......@@ -263,7 +263,7 @@ namespace PcapDotNet.Packets.TestUtils
case IpV6OptionType.QuickStart:
return new IpV6OptionQuickStart(random.NextEnum<IpV4OptionQuickStartFunction>(),
random.NextByte(IpOptionQuickStartCommon.RateMaximumValue + 1), random.NextByte(),
random.NextUInt() & 0xFFFFFFFC);
random.NextUInt() & 0x3FFFFFFF);
case IpV6OptionType.Calipso:
return new IpV6OptionCalipso(random.NextEnum<IpV6CalipsoDomainOfInterpretation>(), random.NextByte(), random.NextUShort(),
......
......@@ -13,6 +13,8 @@ namespace PcapDotNet.Packets.Ip
/// </summary>
public const byte RateMaximumValue = 0x0F;
public const uint NonceMaximumValue = 0x3FFFFFFF;
internal const int DataLength = 6;
private static class Offset
......@@ -29,19 +31,25 @@ namespace PcapDotNet.Packets.Ip
public const byte Rate = 0x0F;
}
private static class Shift
{
public const int Function = 4;
public const int Nonce = 2;
}
internal static void AssertValidParameters(IpV4OptionQuickStartFunction function, byte rate, uint nonce)
{
if (function != IpV4OptionQuickStartFunction.RateRequest &&
function != IpV4OptionQuickStartFunction.RateReport)
{
throw new ArgumentException("Illegal function " + function, "function");
throw new ArgumentException(string.Format("Illegal function {0}", function), "function");
}
if (rate > RateMaximumValue)
throw new ArgumentOutOfRangeException("rate", rate, "Rate maximum value is " + RateMaximumValue);
throw new ArgumentOutOfRangeException("rate", rate, string.Format("Rate maximum value is {0}", RateMaximumValue));
if ((nonce & 0x00000003) != 0)
throw new ArgumentException("nonce last two bits are reserved and must be zero", "nonce");
if (nonce > NonceMaximumValue)
throw new ArgumentException(string.Format("nonce cannot be bigger than {0}", NonceMaximumValue), "nonce");
}
internal static int CalcRateKbps(byte rate)
......@@ -54,17 +62,17 @@ namespace PcapDotNet.Packets.Ip
internal static void ReadData(DataSegment data, out IpV4OptionQuickStartFunction function, out byte rate, out byte ttl, out uint nonce)
{
function = (IpV4OptionQuickStartFunction)(data[Offset.Function] & Mask.Function);
function = (IpV4OptionQuickStartFunction)((data[Offset.Function] & Mask.Function) >> Shift.Function);
rate = (byte)(data[Offset.Rate] & Mask.Rate);
ttl = data[Offset.Ttl];
nonce = data.ReadUInt(Offset.Nonce, Endianity.Big);
nonce = data.ReadUInt(Offset.Nonce, Endianity.Big) >> Shift.Nonce;
}
internal static void WriteData(byte[] buffer, ref int offset, IpV4OptionQuickStartFunction function, byte rate, byte ttl, uint nonce)
{
buffer[offset + Offset.Function] = (byte)(((byte)function & Mask.Function) | (rate & Mask.Rate));
buffer[offset + Offset.Function] = (byte)((((byte)function << Shift.Function) & Mask.Function) | (rate & Mask.Rate));
buffer[offset + Offset.Ttl] = ttl;
buffer.Write(offset + Offset.Nonce, nonce, Endianity.Big);
buffer.Write(offset + Offset.Nonce, nonce << Shift.Nonce, Endianity.Big);
offset += DataLength;
}
}
......
......@@ -9,11 +9,11 @@ namespace PcapDotNet.Packets.IpV4
/// <summary>
/// Request for a specific rate.
/// </summary>
RateRequest = 0x00,
RateRequest = 0x0,
/// <summary>
/// Reports on a specific rate that was agreed (or disagreed).
/// </summary>
RateReport = 0x80
RateReport = 0x8
}
}
\ No newline at end of file
......@@ -229,8 +229,8 @@ namespace PcapDotNet.Packets.IpV6
lastAddressSegment.Write(addressBytes, commonPrefixLengthForLastAddress);
addresses[numAddresses - 1] = addressBytes.ReadIpV6Address(0, Endianity.Big);
}
return new IpV6ExtensionHeaderRoutingProtocolLowPowerAndLossyNetworks(nextHeader, segmentsLeft, commonPrefixLengthForNonLastAddresses, commonPrefixLengthForLastAddress,
addresses);
return new IpV6ExtensionHeaderRoutingProtocolLowPowerAndLossyNetworks(nextHeader, segmentsLeft, commonPrefixLengthForNonLastAddresses,
commonPrefixLengthForLastAddress, addresses);
}
internal override bool EqualsRoutingData(IpV6ExtensionHeaderRouting other)
......
......@@ -15,7 +15,9 @@ namespace PcapDotNet.Packets.IpV6
/// +-----+-------------+--------------+
/// | 0 | Option Type | Opt Data Len |
/// +-----+-------------+--------------+
/// | 16 | Request 1 |
/// | 16 | Reserved |
/// +-----+----------------------------+
/// | 32 | Request 1 |
/// | ... | Request 2 |
/// | | ... |
/// | | Request n |
......@@ -25,6 +27,16 @@ namespace PcapDotNet.Packets.IpV6
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.ContextRequest)]
public sealed class IpV6MobilityOptionContextRequest : IpV6MobilityOptionComplex
{
private static class Offset
{
public const int Requests = sizeof(ushort);
}
/// <summary>
/// The minimum number of bytes this option data takes.
/// </summary>
public const int OptionDataMinimumLength = Offset.Requests;
/// <summary>
/// Creates an instance from an array of requests.
/// </summary>
......@@ -51,7 +63,7 @@ namespace PcapDotNet.Packets.IpV6
: base(IpV6MobilityOptionType.ContextRequest)
{
Requests = requests;
_dataLength = Requests.Sum(request => request.Length);
_dataLength = OptionDataMinimumLength + Requests.Sum(request => request.Length);
if (_dataLength > byte.MaxValue)
throw new ArgumentOutOfRangeException("requests", requests,
string.Format(CultureInfo.InvariantCulture, "requests length is too large. Takes over {0}>{1} bytes.",
......@@ -66,7 +78,7 @@ namespace PcapDotNet.Packets.IpV6
internal override IpV6MobilityOption CreateInstance(DataSegment data)
{
List<IpV6MobilityOptionContextRequestEntry> requests = new List<IpV6MobilityOptionContextRequestEntry>();
int offset = 0;
int offset = Offset.Requests;
while (data.Length > offset)
{
byte requestType = data[offset++];
......@@ -104,6 +116,7 @@ namespace PcapDotNet.Packets.IpV6
internal override void WriteData(byte[] buffer, ref int offset)
{
offset += Offset.Requests;
foreach (var request in Requests)
request.Write(buffer, ref offset);
}
......
......@@ -5,7 +5,7 @@ using PcapDotNet.Base;
namespace PcapDotNet.Packets.IpV6
{
/// <summary>
/// RFC 5845.
/// RFC 5568.
/// <pre>
/// +-----+-------------+---------------+
/// | Bit | 0-7 | 8-15 |
......
......@@ -199,6 +199,14 @@ namespace PcapDotNet.Packets.Transport
get { return Length - HeaderLength; }
}
/// <summary>
/// True iff the NonceSum control bit is turned on.
/// </summary>
public bool IsNonceSum
{
get { return (ControlBits & TcpControlBits.NonceSum) == TcpControlBits.NonceSum; }
}
/// <summary>
/// True iff the CongestionWindowReduced control bit is turned on.
/// </summary>
......
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