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 ...@@ -254,9 +254,17 @@ namespace PcapDotNet.Base.Test
[TestMethod] [TestMethod]
public void ToStringTest() 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); 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 ...@@ -223,6 +223,10 @@ namespace PcapDotNet.Base
/// </remarks> /// </remarks>
public static UInt128 Parse(string value, NumberStyles style, IFormatProvider provider) 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); BigInteger bigIntegerValue = BigInteger.Parse(value, style, provider);
if (bigIntegerValue < 0 || bigIntegerValue > MaxValue) if (bigIntegerValue < 0 || bigIntegerValue > MaxValue)
throw new OverflowException("Value was either too large or too small for an UInt128."); throw new OverflowException("Value was either too large or too small for an UInt128.");
...@@ -523,6 +527,28 @@ namespace PcapDotNet.Base ...@@ -523,6 +527,28 @@ namespace PcapDotNet.Base
return new UInt128(value1._mostSignificant & value2._mostSignificant, value1._leastSignificant & value2._leastSignificant); 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> /// <summary>
/// Sums the given values and returns the sum. /// Sums the given values and returns the sum.
/// </summary> /// </summary>
...@@ -616,7 +642,10 @@ namespace PcapDotNet.Base ...@@ -616,7 +642,10 @@ namespace PcapDotNet.Base
/// </remarks> /// </remarks>
public string ToString(string format, IFormatProvider formatProvider) 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> /// <summary>
......
...@@ -10,150 +10,6 @@ namespace PcapDotNet.Core.Test ...@@ -10,150 +10,6 @@ namespace PcapDotNet.Core.Test
{ {
internal static class IpV4OptionExtensions 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) 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. // 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 ...@@ -76,7 +76,10 @@ namespace PcapDotNet.Core.Test
} }
#pragma warning restore 162 #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) for (int i = 0; i != 10; ++i)
{ {
// Create packets // Create packets
...@@ -436,7 +439,9 @@ namespace PcapDotNet.Core.Test ...@@ -436,7 +439,9 @@ namespace PcapDotNet.Core.Test
{ {
// Wireshark's preferences file is %APPDATA%\Wireshark\preferences // Wireshark's preferences file is %APPDATA%\Wireshark\preferences
FileName = WiresharkTsharkPath, 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.relative_sequence_numbers:FALSE " +
"-o tcp.analyze_sequence_numbers:FALSE " + "-o tcp.analyze_sequence_numbers:FALSE " +
"-o tcp.track_bytes_in_flight:FALSE " + "-o tcp.track_bytes_in_flight:FALSE " +
...@@ -447,13 +452,20 @@ namespace PcapDotNet.Core.Test ...@@ -447,13 +452,20 @@ namespace PcapDotNet.Core.Test
WorkingDirectory = WiresharkDiretory, WorkingDirectory = WiresharkDiretory,
UseShellExecute = false, UseShellExecute = false,
RedirectStandardOutput = true, RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true CreateNoWindow = true
}; };
Console.WriteLine("Starting process " + process.StartInfo.FileName + " " + process.StartInfo.Arguments); Console.WriteLine("Starting process " + process.StartInfo.FileName + " " + process.StartInfo.Arguments);
process.Start(); Assert.IsTrue(process.Start());
string output = process.StandardOutput.ReadToEnd(); string output = process.StandardOutput.ReadToEnd();
string errorOutput = process.StandardError.ReadToEnd();
process.WaitForExit(); process.WaitForExit();
Console.WriteLine(errorOutput);
File.WriteAllText(documentFilename, output); 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 // Fix pdml file
...@@ -533,7 +545,8 @@ namespace PcapDotNet.Core.Test ...@@ -533,7 +545,8 @@ namespace PcapDotNet.Core.Test
break; break;
default: default:
var comparer = WiresharkDatagramComparer.GetComparer(layer.Name(), layerNameToCount[layerName], parentLayerSuccess); var comparer = WiresharkDatagramComparer.GetComparer(layer.Name(), layerNameToCount[layerName], layersContainer.Name(),
parentLayerSuccess);
if (comparer == null) if (comparer == null)
return; return;
currentDatagram = comparer.Compare(layer, currentDatagram); currentDatagram = comparer.Compare(layer, currentDatagram);
......
...@@ -57,7 +57,7 @@ namespace PcapDotNet.Core.Test ...@@ -57,7 +57,7 @@ namespace PcapDotNet.Core.Test
return success; 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) switch (name)
{ {
...@@ -78,7 +78,11 @@ namespace PcapDotNet.Core.Test ...@@ -78,7 +78,11 @@ namespace PcapDotNet.Core.Test
case "ah": case "ah":
if (parentLayerSuccess) 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 new WiresharkDatagramComparerIpV6AuthenticationHeader(count);
}
return null; return null;
case "mipv6": case "mipv6":
......
...@@ -14,6 +14,7 @@ namespace PcapDotNet.Core.Test ...@@ -14,6 +14,7 @@ namespace PcapDotNet.Core.Test
protected override bool CompareField(XElement field, Datagram datagram) protected override bool CompareField(XElement field, Datagram datagram)
{ {
field.AssertNoFields();
ArpDatagram arpDatagram = (ArpDatagram)datagram; ArpDatagram arpDatagram = (ArpDatagram)datagram;
switch (field.Name()) switch (field.Name())
{ {
...@@ -22,7 +23,7 @@ namespace PcapDotNet.Core.Test ...@@ -22,7 +23,7 @@ namespace PcapDotNet.Core.Test
break; break;
case "arp.proto.type": case "arp.proto.type":
field.AssertShowHex((ushort)arpDatagram.ProtocolType); field.AssertShowDecimal((ushort)arpDatagram.ProtocolType);
break; break;
case "arp.hw.size": case "arp.hw.size":
...@@ -65,6 +66,8 @@ namespace PcapDotNet.Core.Test ...@@ -65,6 +66,8 @@ namespace PcapDotNet.Core.Test
break; break;
case "arp.isgratuitous": case "arp.isgratuitous":
case "arp.dst.drarp_error_status":
// TODO: Support DRARP (RFC 1931).
break; break;
default: default:
......
...@@ -28,11 +28,11 @@ namespace PcapDotNet.Core.Test ...@@ -28,11 +28,11 @@ namespace PcapDotNet.Core.Test
switch (field.Name()) switch (field.Name())
{ {
case "dns.id": case "dns.id":
field.AssertShowHex(dnsDatagram.Id); field.AssertShowDecimal(dnsDatagram.Id);
break; break;
case "dns.flags": 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()) foreach (var flagField in field.Fields())
{ {
switch (flagField.Name()) switch (flagField.Name())
...@@ -147,7 +147,7 @@ namespace PcapDotNet.Core.Test ...@@ -147,7 +147,7 @@ namespace PcapDotNet.Core.Test
{ {
XElement[] resourceRecordFieldsArray= resourceRecordFields.ToArray(); XElement[] resourceRecordFieldsArray= resourceRecordFields.ToArray();
DnsResourceRecord[] resourceRecordsArray = resourceRecords.ToArray(); DnsResourceRecord[] resourceRecordsArray = resourceRecords.ToArray();
if (resourceRecordFieldsArray.Length != resourceRecordsArray.Length) if (resourceRecordFieldsArray.Length > resourceRecordsArray.Length)
{ {
var queryNameField = resourceRecordFieldsArray[resourceRecordsArray.Length].Fields().First(); var queryNameField = resourceRecordFieldsArray[resourceRecordsArray.Length].Fields().First();
if (queryNameField.Name() == "dns.qry.name") if (queryNameField.Name() == "dns.qry.name")
...@@ -155,6 +155,13 @@ namespace PcapDotNet.Core.Test ...@@ -155,6 +155,13 @@ namespace PcapDotNet.Core.Test
else else
Assert.AreEqual("dns.resp.name", queryNameField.Name()); 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) for (int i = 0; i != resourceRecordsArray.Length; ++i)
{ {
ResetRecordFields(); ResetRecordFields();
...@@ -170,15 +177,27 @@ namespace PcapDotNet.Core.Test ...@@ -170,15 +177,27 @@ namespace PcapDotNet.Core.Test
resourceRecordAttributeField.AssertNoFields(); resourceRecordAttributeField.AssertNoFields();
break; 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.qry.type":
case "dns.resp.type": case "dns.resp.type":
resourceRecordAttributeField.AssertShowHex((ushort)resourceRecord.DnsType); resourceRecordAttributeField.AssertShowDecimal((ushort)resourceRecord.DnsType);
resourceRecordAttributeField.AssertNoFields(); resourceRecordAttributeField.AssertNoFields();
break; break;
case "dns.qry.class": case "dns.qry.class":
case "dns.resp.class": case "dns.resp.class":
resourceRecordAttributeField.AssertShowHex((ushort)resourceRecord.DnsClass); resourceRecordAttributeField.AssertShowDecimal((ushort)resourceRecord.DnsClass);
resourceRecordAttributeField.AssertNoFields(); resourceRecordAttributeField.AssertNoFields();
break; break;
...@@ -198,13 +217,13 @@ namespace PcapDotNet.Core.Test ...@@ -198,13 +217,13 @@ namespace PcapDotNet.Core.Test
case "dns.srv.service": case "dns.srv.service":
Assert.AreEqual(resourceRecord.DnsType, DnsType.ServerSelection); 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(); resourceRecordAttributeField.AssertNoFields();
break; break;
case "dns.srv.proto": case "dns.srv.proto":
Assert.AreEqual(resourceRecord.DnsType, DnsType.ServerSelection); Assert.AreEqual(resourceRecord.DnsType, DnsType.ServerSelection);
resourceRecordAttributeField.AssertShow(resourceRecord.DomainName.ToString().Split('.')[1].Substring(1)); resourceRecordAttributeField.AssertShow(resourceRecord.DomainName.ToString().Split('.')[1]);
resourceRecordAttributeField.AssertNoFields(); resourceRecordAttributeField.AssertNoFields();
break; break;
...@@ -216,7 +235,8 @@ namespace PcapDotNet.Core.Test ...@@ -216,7 +235,8 @@ namespace PcapDotNet.Core.Test
break; break;
default: default:
CompareResourceRecordData(resourceRecordAttributeField, resourceRecord); if (!CompareResourceRecordData(resourceRecordAttributeField, resourceRecord))
return;
break; break;
} }
} }
...@@ -228,13 +248,16 @@ namespace PcapDotNet.Core.Test ...@@ -228,13 +248,16 @@ namespace PcapDotNet.Core.Test
_hipRendezvousServersIndex = 0; _hipRendezvousServersIndex = 0;
_wksBitmapIndex = 0; _wksBitmapIndex = 0;
_nxtTypeIndex = 0; _nxtTypeIndex = 0;
_spfTypeIndex = 0;
_txtTypeIndex = 0;
_nSecTypeIndex = 0; _nSecTypeIndex = 0;
_nSec3TypeIndex = 0; _nSec3TypeIndex = 0;
_txtIndex = 0; _txtIndex = 0;
_aplItemIndex = 0; _aplItemIndex = 0;
_optOptionIndex = 0;
} }
private void CompareResourceRecordData(XElement dataField, DnsResourceRecord resourceRecord) private bool CompareResourceRecordData(XElement dataField, DnsResourceRecord resourceRecord)
{ {
var data = resourceRecord.Data; var data = resourceRecord.Data;
string dataFieldName = dataField.Name(); string dataFieldName = dataField.Name();
...@@ -243,9 +266,10 @@ namespace PcapDotNet.Core.Test ...@@ -243,9 +266,10 @@ namespace PcapDotNet.Core.Test
switch (resourceRecord.DnsType) switch (resourceRecord.DnsType)
{ {
case DnsType.A: case DnsType.A:
dataField.AssertNoFields();
switch (dataFieldName) switch (dataFieldName)
{ {
case "dns.resp.addr": case "dns.a":
dataField.AssertShow(((DnsResourceDataIpV4)data).Data.ToString()); dataField.AssertShow(((DnsResourceDataIpV4)data).Data.ToString());
break; break;
...@@ -255,243 +279,322 @@ namespace PcapDotNet.Core.Test ...@@ -255,243 +279,322 @@ namespace PcapDotNet.Core.Test
break; break;
case DnsType.Ns: 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)); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
break;
case DnsType.MailForwarder:
dataField.AssertName("dns.mf");
dataField.AssertNoFields(); dataField.AssertNoFields();
dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
break; break;
case DnsType.Md: // 3.
case DnsType.MailForwarder: // 4.
case DnsType.Mailbox: // 7.
case DnsType.MailGroup: // 8. case DnsType.MailGroup: // 8.
dataField.AssertName("dns.mg");
dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
dataField.AssertNoFields();
break;
case DnsType.MailRename: // 9. case DnsType.MailRename: // 9.
dataField.AssertName(""); dataField.AssertName("dns.mr");
dataField.AssertShow("Host: " + GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
dataField.AssertNoFields(); dataField.AssertNoFields();
break; break;
case DnsType.CName: case DnsType.CName:
dataField.AssertName("dns.resp.primaryname"); dataField.AssertName("dns.cname");
dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
dataField.AssertNoFields(); dataField.AssertNoFields();
break; break;
case DnsType.StartOfAuthority: case DnsType.StartOfAuthority:
dataField.AssertName(""); var startOfAuthority = (DnsResourceDataStartOfAuthority)data;
var soaData = (DnsResourceDataStartOfAuthority)data; dataField.AssertNoFields();
switch (dataFieldShowUntilColon) switch (dataField.Name())
{ {
case "Primary name server": case "dns.soa.mname":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(soaData.MainNameServer)); dataField.AssertShow(GetWiresharkDomainName(startOfAuthority.MainNameServer));
break; break;
case "Responsible authority's mailbox": case "dns.soa.rname":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(soaData.ResponsibleMailbox)); dataField.AssertShow(GetWiresharkDomainName(startOfAuthority.ResponsibleMailbox));
break; break;
case "Serial number": case "dns.soa.serial_number":
dataField.AssertShow(dataFieldShowUntilColon + ": " + soaData.Serial); dataField.AssertShowDecimal(startOfAuthority.Serial.Value);
break; break;
case "Refresh interval": case "dns.soa.refresh_interval":
dataField.AssertValue(soaData.Refresh); dataField.AssertShowDecimal(startOfAuthority.Refresh);
break; break;
case "Retry interval": case "dns.soa.retry_interval":
dataField.AssertValue(soaData.Retry); dataField.AssertShowDecimal(startOfAuthority.Retry);
break; break;
case "Expiration limit": case "dns.soa.expire_limit":
dataField.AssertValue(soaData.Expire); dataField.AssertShowDecimal(startOfAuthority.Expire);
break; break;
case "Minimum TTL": case "dns.soa.mininum_ttl":
dataField.AssertValue(soaData.MinimumTtl); dataField.AssertShowDecimal(startOfAuthority.MinimumTtl);
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
} }
dataField.AssertNoFields();
break; break;
case DnsType.Wks: case DnsType.Wks:
dataField.AssertName("");
var wksData = (DnsResourceDataWellKnownService)data; var wksData = (DnsResourceDataWellKnownService)data;
switch (dataFieldShowUntilColon) dataField.AssertNoFields();
switch (dataField.Name())
{ {
case "Addr": case "dns.wks.address":
dataField.AssertShow(dataFieldShowUntilColon + ": " + wksData.Address); dataField.AssertShow(wksData.Address.ToString());
break; break;
case "Protocol": case "dns.wks.protocol":
dataField.AssertValue((byte)wksData.Protocol); // TODO: Uncomment this when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10675 is fixed.
// dataField.AssertShowDecimal((byte)wksData.Protocol);
break; break;
case "Bits": case "dns.wks.bits":
while (wksData.Bitmap[_wksBitmapIndex] == 0x00) while (wksData.Bitmap[_wksBitmapIndex] == 0x00)
++_wksBitmapIndex; ++_wksBitmapIndex;
dataField.AssertValue(wksData.Bitmap[_wksBitmapIndex++]); dataField.AssertShowDecimal(wksData.Bitmap[_wksBitmapIndex++]);
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
} }
dataField.AssertNoFields();
break; break;
case DnsType.Ptr: case DnsType.Ptr:
dataField.AssertName(""); dataField.AssertName("dns.ptr.domain_name");
dataField.AssertShow("Domain name: " + GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
dataField.AssertNoFields(); dataField.AssertNoFields();
break; break;
case DnsType.HInfo: case DnsType.HInfo:
dataField.AssertName(""); dataField.AssertNoFields();
var hInfoData = (DnsResourceDataHostInformation)data; var hInfoData = (DnsResourceDataHostInformation)data;
switch (dataFieldShowUntilColon) switch (dataFieldName)
{ {
case "CPU": case "dns.hinfo.cpu_length":
dataField.AssertValue(new[] {(byte)hInfoData.Cpu.Length}.Concat(hInfoData.Cpu)); dataField.AssertShowDecimal(hInfoData.Cpu.Length);
break;
case "dns.hinfo.cpu":
dataField.AssertValue(hInfoData.Cpu);
break; break;
case "OS": case "dns.hinfo.os_length":
dataField.AssertValue(new[] {(byte)hInfoData.Os.Length}.Concat(hInfoData.Os)); dataField.AssertShowDecimal(hInfoData.Os.Length);
break;
case "dns.hinfo.os":
dataField.AssertValue(hInfoData.Os);
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
} }
dataField.AssertNoFields();
break; break;
case DnsType.MInfo: case DnsType.MInfo:
dataField.AssertName(""); dataField.AssertNoFields();
var mInfoData = (DnsResourceDataMailingListInfo)data; var mInfoData = (DnsResourceDataMailingListInfo)data;
switch (dataFieldShowUntilColon) switch (dataFieldName)
{ {
case "Responsible Mailbox": case "dns.minfo.r":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(mInfoData.MailingList)); dataField.AssertShow(GetWiresharkDomainName(mInfoData.MailingList));
break; break;
case "Error Mailbox": case "dns.minfo.e":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(mInfoData.ErrorMailbox)); dataField.AssertShow(GetWiresharkDomainName(mInfoData.ErrorMailbox));
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
} }
dataField.AssertNoFields();
break; break;
case DnsType.MailExchange: case DnsType.MailExchange:
var mxData = (DnsResourceDataMailExchange)data; var mxData = (DnsResourceDataMailExchange)data;
switch (dataFieldShowUntilColon) dataField.AssertNoFields();
switch (dataFieldName)
{ {
case "Preference": case "dns.mx.preference":
dataField.AssertShow(dataFieldShowUntilColon + ": " + mxData.Preference); dataField.AssertShowDecimal(mxData.Preference);
break; break;
case "Mail exchange": case "dns.mx.mail_exchange":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(mxData.MailExchangeHost)); dataField.AssertShow(GetWiresharkDomainName(mxData.MailExchangeHost));
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
} }
dataField.AssertNoFields();
break; break;
case DnsType.Txt: // 16. case DnsType.Txt: // 16.
case DnsType.Spf: // 99.
var txtData = (DnsResourceDataText)data; var txtData = (DnsResourceDataText)data;
dataField.AssertShow("Text: " + txtData.Text[_txtIndex++].Decode(EncodingExtensions.Iso88591).ToWiresharkLiteral(false, false));
dataField.AssertNoFields(); 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; break;
case DnsType.ResponsiblePerson: case DnsType.ResponsiblePerson:
dataField.AssertName("");
var rpData = (DnsResourceDataResponsiblePerson)data; var rpData = (DnsResourceDataResponsiblePerson)data;
switch (dataFieldShowUntilColon) dataField.AssertNoFields();
switch (dataFieldName)
{ {
case "Mailbox": case "dns.rp.mailbox":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(rpData.Mailbox)); dataField.AssertShow(GetWiresharkDomainName(rpData.Mailbox));
break; break;
case "TXT RR": case "dns.rp.txt_rr":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(rpData.TextDomain)); dataField.AssertShow(GetWiresharkDomainName(rpData.TextDomain));
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
} }
dataField.AssertNoFields();
break; break;
case DnsType.AfsDatabase: case DnsType.AfsDatabase:
dataField.AssertName("");
var afsDbData = (DnsResourceDataAfsDatabase)data; var afsDbData = (DnsResourceDataAfsDatabase)data;
switch (dataFieldShowUntilColon) dataField.AssertNoFields();
switch (dataFieldName)
{ {
case "Subtype": case "dns.afsdb.subtype":
dataField.AssertShow(dataFieldShowUntilColon + ": " + (ushort)afsDbData.Subtype); dataField.AssertShowDecimal((ushort)afsDbData.Subtype);
break; break;
case "Hostname": case "dns.afsdb.hostname":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(afsDbData.HostName)); dataField.AssertShow(GetWiresharkDomainName(afsDbData.HostName));
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
} }
dataField.AssertNoFields();
break; break;
case DnsType.X25: case DnsType.X25:
dataField.AssertName(""); var x25 = (DnsResourceDataString)data;
dataField.AssertShow("PSDN-Address: " + ((DnsResourceDataString)data).String.Decode(EncodingExtensions.Iso88591).ToWiresharkLiteral(false, false));
dataField.AssertNoFields(); 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; break;
case DnsType.Isdn: case DnsType.Isdn:
dataField.AssertName("");
var isdnData = (DnsResourceDataIsdn)data; var isdnData = (DnsResourceDataIsdn)data;
switch (dataFieldShowUntilColon) dataField.AssertNoFields();
switch (dataFieldName)
{ {
case "ISDN Address": case "dns.idsn.length":
dataField.AssertShow(dataFieldShowUntilColon + ": " + dataField.AssertShowDecimal(isdnData.IsdnAddress.Length);
isdnData.IsdnAddress.Decode(EncodingExtensions.Iso88591).ToWiresharkLiteral(false, false));
break; break;
case "Subaddress": case "dns.idsn.address":
dataField.AssertShow(dataFieldShowUntilColon + ": " + dataField.AssertValue(isdnData.IsdnAddress);
isdnData.Subaddress.Decode(EncodingExtensions.Iso88591).ToWiresharkLiteral(false, false)); 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; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
} }
dataField.AssertNoFields(); dataField.AssertNoFields();
break; break;
case DnsType.RouteThrough: case DnsType.RouteThrough:
dataField.AssertName(""); dataField.AssertNoFields();
var rtData = (DnsResourceDataRouteThrough)data; var rtData = (DnsResourceDataRouteThrough)data;
switch (dataFieldShowUntilColon) switch (dataFieldName)
{ {
case "Preference": case "dns.rt.subtype":
dataField.AssertShow(dataFieldShowUntilColon + ": " + rtData.Preference); dataField.AssertShowDecimal(rtData.Preference);
break; break;
case "Intermediate-Host": case "dns.rt.intermediate_host":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(rtData.IntermediateHost)); dataField.AssertShow(GetWiresharkDomainName(rtData.IntermediateHost));
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
} }
dataField.AssertNoFields();
break; break;
case DnsType.NetworkServiceAccessPoint: case DnsType.NetworkServiceAccessPoint:
...@@ -512,66 +615,52 @@ namespace PcapDotNet.Core.Test ...@@ -512,66 +615,52 @@ namespace PcapDotNet.Core.Test
break; break;
case DnsType.NetworkServiceAccessPointPointer: case DnsType.NetworkServiceAccessPointPointer:
dataField.AssertName(""); dataField.AssertName("dns.nsap_ptr.owner");
dataField.AssertShow("Owner: " + GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
dataField.AssertNoFields(); dataField.AssertNoFields();
break; break;
case DnsType.Key: case DnsType.Key:
dataField.AssertName("");
var keyData = (DnsResourceDataKey)data; var keyData = (DnsResourceDataKey)data;
switch (dataFieldShowUntilColon) switch (dataFieldName)
{ {
case "Flags": case "dns.key.flags":
foreach (var flagField in dataField.Fields()) foreach (var flagField in dataField.Fields())
{ {
flagField.AssertNoFields();
int flagCount = GetFlagCount(flagField); int flagCount = GetFlagCount(flagField);
switch (flagCount) switch (flagCount)
{ {
case 0: case 0:
flagField.AssertShow(keyData.AuthenticationProhibited flagField.AssertShowDecimal(keyData.AuthenticationProhibited);
? "1... .... .... .... = Key prohibited for authentication"
: "0... .... .... .... = Key allowed for authentication");
break; break;
case 1: case 1:
flagField.AssertShow(keyData.ConfidentialityProhibited flagField.AssertShowDecimal(keyData.ConfidentialityProhibited);
? ".1.. .... .... .... = Key prohibited for confidentiality"
: ".0.. .... .... .... = Key allowed for confidentiality");
break; break;
case 2: case 2:
flagField.AssertShow(keyData.Experimental flagField.AssertShowDecimal(keyData.Experimental);
? "..1. .... .... .... = Key is experimental or optional"
: "..0. .... .... .... = Key is required");
break; break;
case 5: case 5:
flagField.AssertShow(keyData.UserAssociated flagField.AssertShowDecimal(keyData.UserAssociated);
? ".... .1.. .... .... = Key is associated with a user"
: ".... .0.. .... .... = Key is not associated with a user");
break; break;
case 6: case 6:
flagField.AssertShow(keyData.NameType == DnsKeyNameType.NonZoneEntity flagField.AssertShowDecimal(keyData.NameType == DnsKeyNameType.NonZoneEntity);
? ".... ..1. .... .... = Key is associated with the named entity"
: ".... ..0. .... .... = Key is not associated with the named entity");
break; break;
case 8: case 8:
flagField.AssertShow(keyData.IpSec flagField.AssertShowDecimal(keyData.IpSec);
? ".... .... 1... .... = Key is valid for use with IPSEC"
: ".... .... 0... .... = Key is not valid for use with IPSEC");
break; break;
case 9: case 9:
flagField.AssertShow(keyData.Email flagField.AssertShowDecimal(keyData.Email);
? ".... .... .1.. .... = Key is valid for use with MIME security multiparts"
: ".... .... .0.. .... = Key is not valid for use with MIME security multiparts");
break; break;
case 12: case 12:
Assert.AreEqual(flagField.Show().Substring(19), " = Signatory = " + (byte)keyData.Signatory); flagField.AssertShowDecimal((byte)keyData.Signatory);
break; break;
default: default:
...@@ -580,22 +669,23 @@ namespace PcapDotNet.Core.Test ...@@ -580,22 +669,23 @@ namespace PcapDotNet.Core.Test
} }
break; break;
case "Protocol": case "dns.key.protocol":
dataField.AssertShow(dataFieldShowUntilColon + ": " + (byte)keyData.Protocol);
dataField.AssertNoFields(); dataField.AssertNoFields();
dataField.AssertShowDecimal((byte)keyData.Protocol);
break; break;
case "Algorithm": case "dns.key.algorithm":
dataField.AssertValue((byte)keyData.Algorithm);
dataField.AssertNoFields(); dataField.AssertNoFields();
dataField.AssertShowDecimal((byte)keyData.Algorithm);
break; break;
case "Key id": case "dns.key.key_id":
// TODO: Calculate key tag.
dataField.AssertNoFields(); dataField.AssertNoFields();
// TODO: Calculate key tag.
break; break;
case "Public key": case "dns.key.public_key":
dataField.AssertNoFields();
byte[] flagsExtension; byte[] flagsExtension;
if (keyData.FlagsExtension == null) if (keyData.FlagsExtension == null)
{ {
...@@ -607,329 +697,309 @@ namespace PcapDotNet.Core.Test ...@@ -607,329 +697,309 @@ namespace PcapDotNet.Core.Test
flagsExtension.Write(0, keyData.FlagsExtension.Value, Endianity.Big); flagsExtension.Write(0, keyData.FlagsExtension.Value, Endianity.Big);
} }
dataField.AssertValue(flagsExtension.Concat(keyData.PublicKey)); dataField.AssertValue(flagsExtension.Concat(keyData.PublicKey));
dataField.AssertNoFields();
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
} }
break; break;
case DnsType.Signature: // 24. case DnsType.Signature: // 24.
case DnsType.ResourceRecordSignature: // 46. case DnsType.ResourceRecordSignature: // 46.
dataField.AssertName(""); dataField.AssertNoFields();
var sigData = (DnsResourceDataSignature)data; var sigData = (DnsResourceDataSignature)data;
switch (dataFieldShowUntilColon) switch (dataFieldName)
{ {
case "Type covered": case "dns.rrsig.type_covered":
dataField.AssertValue((ushort)sigData.TypeCovered); dataField.AssertShowDecimal((ushort)sigData.TypeCovered);
break; break;
case "Algorithm": case "dns.rrsig.algorithm":
dataField.AssertValue((byte)sigData.Algorithm); dataField.AssertShowDecimal((byte)sigData.Algorithm);
break; break;
case "Labels": case "dns.rrsig.labels":
dataField.AssertShow(dataFieldShowUntilColon + ": " + sigData.Labels); dataField.AssertShowDecimal(sigData.Labels);
break; break;
case "Original TTL": case "dns.rrsig.original_ttl":
dataField.AssertValue(sigData.OriginalTtl); dataField.AssertShowDecimal(sigData.OriginalTtl);
break; break;
case "Signature expiration": case "dns.rrsig.signature_expiration":
dataField.AssertValue(sigData.SignatureExpiration); dataField.AssertValue(sigData.SignatureExpiration);
break; break;
case "Time signed": case "dns.rrsig.signature_inception":
dataField.AssertValue(sigData.SignatureInception); dataField.AssertValue(sigData.SignatureInception);
break; break;
case "Id of signing key(footprint)": case "dns.rrsig.key_tag":
dataField.AssertShow(dataFieldShowUntilColon + ": " + sigData.KeyTag); dataField.AssertShowDecimal(sigData.KeyTag);
break; break;
case "Signer's name": case "dns.rrsig.signers_name":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(sigData.SignersName)); dataField.AssertShow(GetWiresharkDomainName(sigData.SignersName));
break; break;
case "Signature": case "dns.rrsig.signature":
dataField.AssertValue(sigData.Signature); dataField.AssertValue(sigData.Signature);
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
} }
dataField.AssertNoFields();
break; break;
case DnsType.PointerX400: case DnsType.PointerX400:
dataField.AssertName("");
var pxData = (DnsResourceDataX400Pointer)data; var pxData = (DnsResourceDataX400Pointer)data;
switch (dataFieldShowUntilColon) switch (dataField.Name())
{ {
case "Preference": case "dns.px.preference":
dataField.AssertShow(dataFieldShowUntilColon + ": " + pxData.Preference); dataField.AssertShowDecimal(pxData.Preference);
break; break;
case "MAP822": case "dns.px.map822":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(pxData.Map822)); dataField.AssertShow(GetWiresharkDomainName(pxData.Map822));
break; break;
case "MAPX400": case "dns.px.map400":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(pxData.MapX400)); dataField.AssertShow(GetWiresharkDomainName(pxData.MapX400));
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
} }
dataField.AssertNoFields(); dataField.AssertNoFields();
break; break;
case DnsType.GPos: case DnsType.GPos:
dataField.AssertName(""); dataField.AssertNoFields();
var gposData = (DnsResourceDataGeographicalPosition)data; var gposData = (DnsResourceDataGeographicalPosition)data;
switch (dataFieldShowUntilColon) switch (dataFieldName)
{ {
case "Longitude": case "dns.gpos.longitude_length":
dataField.AssertShow(dataFieldShowUntilColon + ": " + gposData.Longitude); dataField.AssertShowDecimal(gposData.Longitude.Length);
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();
break; break;
case DnsType.Aaaa: case "dns.gpos.longitude":
dataField.AssertName(""); dataField.AssertShow(gposData.Longitude);
dataField.AssertShow("Addr: " + GetWiresharkIpV6(((DnsResourceDataIpV6)data).Data));
break; break;
case DnsType.Loc: case "dns.gpos.latitude_length":
dataField.AssertName(""); dataField.AssertShowDecimal(gposData.Latitude.Length);
var locData = (DnsResourceDataLocationInformation)data;
switch (dataFieldShowUntilColon)
{
case "Version":
dataField.AssertShow(dataFieldShowUntilColon + ": " + locData.Version);
break; break;
case "Data": case "dns.gpos.latitude":
dataField.AssertShow("Data"); dataField.AssertShow(gposData.Latitude);
break; break;
case "Size": case "dns.gpos.altitude_length":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetPrecisionValueString(locData.Size)); dataField.AssertShowDecimal(gposData.Altitude.Length);
break; break;
case "Horizontal precision": case "dns.gpos.altitude":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetPrecisionValueString(locData.HorizontalPrecision)); dataField.AssertShow(gposData.Altitude);
break; break;
case "Vertical precision": default:
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetPrecisionValueString(locData.VerticalPrecision)); throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
}
break; break;
case "Latitude": case DnsType.Aaaa:
dataField.AssertValue(locData.Latitude); dataField.AssertName("dns.aaaa");
dataField.AssertShow(GetWiresharkIpV6(((DnsResourceDataIpV6)data).Data));
dataField.AssertNoFields();
break; break;
case "Longitude": case DnsType.Loc:
dataField.AssertValue(locData.Longitude); var locData = (DnsResourceDataLocationInformation)data;
dataField.AssertNoFields();
switch (dataFieldName)
{
case "dns.loc.version":
dataField.AssertShowDecimal(locData.Version);
break; break;
case "Altitude": case "dns.loc.unknown_data":
dataField.AssertValue(locData.Altitude);
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShowUntilColon); throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
} }
dataField.AssertNoFields();
break; break;
case DnsType.NextDomain: case DnsType.NextDomain:
dataField.AssertName("");
var nxtData = (DnsResourceDataNextDomain)data; var nxtData = (DnsResourceDataNextDomain)data;
switch (dataFieldShowUntilColon) switch (dataField.Name())
{ {
case "Next domain name": case "dns.nxt.next_domain_name":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(nxtData.NextDomainName)); dataField.AssertShow(GetWiresharkDomainName(nxtData.NextDomainName));
break; break;
case "RR type in bit map": case "":
DnsType actualType = nxtData.TypesExist.Skip(_nxtTypeIndex++).First(); // TODO: Uncomment this when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10615 is fixed.
DnsType expectedType; // DnsType actualType = nxtData.TypesExist.Skip(_nxtTypeIndex++).First();
if (!TryGetDnsType(dataFieldShow, out expectedType)) // DnsType expectedType;
throw new InvalidOperationException(string.Format("Can't parse DNS field {0} : {1}", dataFieldShow, actualType)); // if (!TryGetDnsType(dataFieldShow, out expectedType))
Assert.AreEqual(expectedType, actualType); // throw new InvalidOperationException(string.Format("Can't parse DNS field {0} : {1}", dataFieldShow, actualType));
break; // Assert.AreEqual(expectedType, actualType);
return false;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
} }
dataField.AssertNoFields(); dataField.AssertNoFields();
break; break;
case DnsType.ServerSelection: case DnsType.ServerSelection:
dataField.AssertName(""); dataField.AssertNoFields();
var srvData = (DnsResourceDataServerSelection)data; var srvData = (DnsResourceDataServerSelection)data;
switch (dataFieldShowUntilColon) switch (dataFieldName)
{ {
case "Priority": case "dns.srv.priority":
dataField.AssertShow(dataFieldShowUntilColon + ": " + srvData.Priority); dataField.AssertShowDecimal(srvData.Priority);
break; break;
case "Weight": case "dns.srv.weight":
dataField.AssertShow(dataFieldShowUntilColon + ": " + srvData.Weight); dataField.AssertShowDecimal(srvData.Weight);
break; break;
case "Port": case "dns.srv.port":
dataField.AssertShow(dataFieldShowUntilColon + ": " + srvData.Port); dataField.AssertShowDecimal(srvData.Port);
break; break;
case "Target": case "dns.srv.target":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(srvData.Target)); dataField.AssertShow(GetWiresharkDomainName(srvData.Target));
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShowUntilColon); throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
} }
dataField.AssertNoFields();
break; break;
case DnsType.NaPtr: case DnsType.NaPtr:
dataField.AssertName("");
var naPtrData = (DnsResourceDataNamingAuthorityPointer)data; var naPtrData = (DnsResourceDataNamingAuthorityPointer)data;
switch (dataFieldShowUntilColon) dataField.AssertNoFields();
switch (dataFieldName)
{ {
case "Order": case "dns.naptr.order":
dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Order); dataField.AssertShowDecimal(naPtrData.Order);
break; break;
case "Preference": case "dns.naptr.preference":
dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Preference); dataField.AssertShowDecimal(naPtrData.Preference);
break; break;
case "Flags length": case "dns.naptr.flags_length":
dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Flags.Length); dataField.AssertShowDecimal(naPtrData.Flags.Length);
break; break;
case "Flags": case "dns.naptr.flags":
dataField.AssertValue(naPtrData.Flags); dataField.AssertValue(naPtrData.Flags);
break; break;
case "Service length": case "dns.naptr.service_length":
dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Services.Length); dataField.AssertShowDecimal(naPtrData.Services.Length);
break; break;
case "Service": case "dns.naptr.service":
dataField.AssertValue(naPtrData.Services); dataField.AssertValue(naPtrData.Services);
break; break;
case "Regex length": case "dns.naptr.regex_length":
dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.RegularExpression.Length); dataField.AssertShowDecimal(naPtrData.RegularExpression.Length);
break; break;
case "Regex": case "dns.naptr.regex":
dataField.AssertValue(naPtrData.RegularExpression); dataField.AssertValue(naPtrData.RegularExpression);
break; break;
case "Replacement length": case "dns.naptr.replacement_length":
dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Replacement.NonCompressedLength); // TODO: Uncomment when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10700 is fixed.
// dataField.AssertShowDecimal(naPtrData.Replacement.NonCompressedLength);
break; break;
case "Replacement": case "dns.naptr.replacement":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(naPtrData.Replacement)); dataField.AssertShow(GetWiresharkDomainName(naPtrData.Replacement));
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
} }
dataField.AssertNoFields();
break; break;
case DnsType.KeyExchanger: case DnsType.KeyExchanger:
dataField.AssertName(""); dataField.AssertNoFields();
var kxData = (DnsResourceDataKeyExchanger)data; var kxData = (DnsResourceDataKeyExchanger)data;
switch (dataFieldShowUntilColon) switch (dataFieldName)
{ {
case "Preference": case "dns.kx.preference":
dataField.AssertShow(dataFieldShowUntilColon + ": 0"); dataField.AssertShowDecimal(kxData.Preference);
dataField.AssertValue(kxData.Preference);
break; break;
case "Key exchange": case "dns.kx.key_exchange":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(kxData.KeyExchangeHost)); dataField.AssertShow(GetWiresharkDomainName(kxData.KeyExchangeHost));
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
} }
dataField.AssertNoFields();
break; break;
case DnsType.Cert: case DnsType.Cert:
dataField.AssertName(""); dataField.AssertNoFields();
var certData = (DnsResourceDataCertificate)data; var certData = (DnsResourceDataCertificate)data;
switch (dataFieldShowUntilColon) switch (dataFieldName)
{ {
case "Type": case "dns.cert.type":
dataField.AssertValue((ushort)certData.CertificateType); dataField.AssertShowDecimal((ushort)certData.CertificateType);
break; break;
case "Key footprint": case "dns.cert.key_tag":
dataField.AssertValue(certData.KeyTag); dataField.AssertShowDecimal(certData.KeyTag);
break; break;
case "Algorithm": case "dns.cert.algorithm":
dataField.AssertValue((byte)certData.Algorithm); dataField.AssertShowDecimal((byte)certData.Algorithm);
break; break;
case "Public key": case "dns.cert.certificate":
dataField.AssertValue(certData.Certificate); dataField.AssertValue(certData.Certificate);
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
} }
dataField.AssertNoFields();
break; break;
case DnsType.A6: case DnsType.A6:
var a6Data = (DnsResourceDataA6)data; var a6Data = (DnsResourceDataA6)data;
switch (dataFieldShowUntilColon) switch (dataFieldName)
{ {
case "Prefix len": case "dns.a6.prefix_len":
dataField.AssertShow(dataFieldShowUntilColon + ": " + a6Data.PrefixLength); dataField.AssertShowDecimal(a6Data.PrefixLength);
break; break;
case "Address suffix": case "dns.a6.address_suffix":
Assert.AreEqual(new IpV6Address(dataFieldShow.Substring(dataFieldShowUntilColon.Length + 2)), a6Data.AddressSuffix); // TODO: Uncomment when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10652 is fixed.
// Assert.AreEqual(new IpV6Address(dataFieldShow), a6Data.AddressSuffix);
break; break;
case "Prefix name": case "dns.a6.prefix_name":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(a6Data.PrefixName)); dataField.AssertShow(GetWiresharkDomainName(a6Data.PrefixName));
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
} }
dataField.AssertNoFields(); dataField.AssertNoFields();
break; break;
case DnsType.DName: case DnsType.DName:
dataField.AssertName(""); dataField.AssertName("dns.dname");
dataField.AssertShow("Target name: " + GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data)); dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
dataField.AssertNoFields(); dataField.AssertNoFields();
break; break;
...@@ -938,53 +1008,90 @@ namespace PcapDotNet.Core.Test ...@@ -938,53 +1008,90 @@ namespace PcapDotNet.Core.Test
var optData = (DnsResourceDataOptions)data; var optData = (DnsResourceDataOptions)data;
switch (dataFieldName) switch (dataFieldName)
{ {
case "": case "dns.rr.udp_payload_size":
switch (dataFieldShowUntilColon) _optOptionIndex = 0;
{
case "UDP payload size":
dataField.AssertShow(dataFieldShowUntilColon + ": " + optResourceRecord.SendersUdpPayloadSize);
dataField.AssertNoFields(); dataField.AssertNoFields();
dataField.AssertShowDecimal(optResourceRecord.SendersUdpPayloadSize);
break; break;
case "Higher bits in extended RCODE": case "dns.resp.ext_rcode":
dataField.AssertValue(optResourceRecord.ExtendedReturnCode);
dataField.AssertNoFields(); dataField.AssertNoFields();
dataField.AssertShowDecimal(optResourceRecord.ExtendedReturnCode);
break; break;
case "EDNS0 version": case "dns.resp.edns0_version":
dataField.AssertShow(dataFieldShowUntilColon + ": " + (byte)optResourceRecord.Version);
dataField.AssertNoFields(); dataField.AssertNoFields();
dataField.AssertShowDecimal((byte)optResourceRecord.Version);
break; break;
case "Z": case "dns.resp.z":
ushort flags = (ushort)optResourceRecord.Flags; DnsOptFlags flags = optResourceRecord.Flags;
dataField.AssertValue(flags); dataField.AssertShowDecimal((ushort)flags);
if (dataField.Fields().Any()) foreach (XElement subfield in dataField.Fields())
{ {
dataField.AssertNumFields(2); subfield.AssertNoFields();
dataField.Fields().First().AssertShow("Bit 0 (DO bit): 1 (Accepts DNSSEC security RRs)"); switch (subfield.Name())
// 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
{ {
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; break;
case "Data": case "dns.opt":
Assert.AreEqual(dataField.Value().Length, 2 * optData.Options.Options.Sum(option => option.Length)); foreach (XElement subfield in dataField.Fields())
dataField.AssertNoFields(); {
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; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); subfield.AssertValue(((DnsOptionAnything)dnsOption).Data);
break;
} }
++_optOptionIndex;
break; break;
case "dns.resp.len": default:
dataField.AssertShow("Data length: " + optData.Options.Options.Sum(option => option.DataLength)); throw new InvalidOperationException("Invalid DNS data subfield name " + subfield.Name());
dataField.AssertNoFields(); }
}
break; break;
default: default:
...@@ -996,26 +1103,13 @@ namespace PcapDotNet.Core.Test ...@@ -996,26 +1103,13 @@ namespace PcapDotNet.Core.Test
var aplData = (DnsResourceDataAddressPrefixList)data; var aplData = (DnsResourceDataAddressPrefixList)data;
switch (dataFieldName) switch (dataFieldName)
{ {
case "": case "dns.apl.address_family":
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);
}
dataField.AssertNoFields(); dataField.AssertNoFields();
dataField.AssertShowDecimal((ushort)aplData.Items[_aplItemIndex++].AddressFamily);
break; break;
case "dns.apl.coded.prefix": case "dns.apl.coded_prefix":
dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].PrefixLength); dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].PrefixLength);
break; break;
...@@ -1027,6 +1121,11 @@ namespace PcapDotNet.Core.Test ...@@ -1027,6 +1121,11 @@ namespace PcapDotNet.Core.Test
dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].AddressFamilyDependentPart.Length); dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].AddressFamilyDependentPart.Length);
break; break;
case "dns.apl.afdpart.data":
case "dns.apl.afdpart.ipv6":
dataField.AssertValue(aplData.Items[_aplItemIndex - 1].AddressFamilyDependentPart);
break;
default: default:
throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
} }
...@@ -1035,50 +1134,42 @@ namespace PcapDotNet.Core.Test ...@@ -1035,50 +1134,42 @@ namespace PcapDotNet.Core.Test
case DnsType.DelegationSigner: // 43. case DnsType.DelegationSigner: // 43.
case DnsType.DnsSecLookAsideValidation: // 32769. case DnsType.DnsSecLookAsideValidation: // 32769.
dataField.AssertName(""); dataField.AssertNoFields();
var dsData = (DnsResourceDataDelegationSigner)data; var dsData = (DnsResourceDataDelegationSigner)data;
switch (dataFieldShowUntilColon) switch (dataFieldName)
{ {
case "Key id": case "dns.ds.key_id":
dataField.AssertShow(dataFieldShowUntilColon + ": " + dsData.KeyTag.ToString("0000")); dataField.AssertShowDecimal(dsData.KeyTag);
break; break;
case "Algorithm": case "dns.ds.algorithm":
dataField.AssertValue((byte)dsData.Algorithm); dataField.AssertShowDecimal((byte)dsData.Algorithm);
break; break;
case "Digest type": case "dns.ds.digest_type":
dataField.AssertValue((byte)dsData.DigestType); dataField.AssertShowDecimal((byte)dsData.DigestType);
break; break;
case "Public key": case "dns.ds.digest":
dataField.AssertValue(dsData.Digest); dataField.AssertValue(dsData.Digest);
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
} }
dataField.AssertNoFields();
break; break;
case DnsType.SshFingerprint: case DnsType.SshFingerprint:
var sshFpData = (DnsResourceDataSshFingerprint)data; var sshFpData = (DnsResourceDataSshFingerprint)data;
dataField.AssertNoFields();
switch (dataFieldName) switch (dataFieldName)
{ {
case "": case "dns.sshfp.algorithm":
switch (dataFieldShowUntilColon) dataField.AssertShowDecimal((byte)sshFpData.Algorithm);
{
case "Algorithm":
dataField.AssertValue((byte)sshFpData.Algorithm);
break; break;
case "Fingerprint type": case "dns.sshfp.fingerprint.type":
dataField.AssertValue((byte)sshFpData.FingerprintType); dataField.AssertShowDecimal((byte)sshFpData.FingerprintType);
break;
default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
}
break; break;
case "dns.sshfp.fingerprint": case "dns.sshfp.fingerprint":
...@@ -1088,66 +1179,55 @@ namespace PcapDotNet.Core.Test ...@@ -1088,66 +1179,55 @@ namespace PcapDotNet.Core.Test
default: default:
throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
} }
dataField.AssertNoFields();
break; break;
case DnsType.IpSecKey: case DnsType.IpSecKey:
dataField.AssertName(""); dataField.AssertNoFields();
var ipSecKeyData = (DnsResourceDataIpSecKey)data; var ipSecKeyData = (DnsResourceDataIpSecKey)data;
switch (dataFieldShowUntilColon) switch (dataField.Name())
{ {
case "Gateway precedence": case "dns.ipseckey.gateway_precedence":
dataField.AssertValue(ipSecKeyData.Precedence); dataField.AssertShowDecimal(ipSecKeyData.Precedence);
break; break;
case "Algorithm": case "dns.ipseckey.gateway_type":
dataField.AssertValue((byte)ipSecKeyData.Algorithm); dataField.AssertShowDecimal((byte)ipSecKeyData.GatewayType);
break; break;
case "Gateway": case "dns.ipseckey.gateway_algorithm":
switch (ipSecKeyData.GatewayType) dataField.AssertShowDecimal((byte)ipSecKeyData.Algorithm);
{
case DnsGatewayType.None:
dataField.AssertShow(dataFieldShowUntilColon + ": no gateway");
break; break;
case DnsGatewayType.IpV4: case "dns.ipseckey.gateway_ipv4":
dataField.AssertShow(dataFieldShowUntilColon + ": " + ((DnsGatewayIpV4)ipSecKeyData.Gateway).Value); dataField.AssertShow(((DnsGatewayIpV4)ipSecKeyData.Gateway).Value.ToString());
break; break;
case DnsGatewayType.IpV6: case "dns.ipseckey.gateway_ipv6":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkIpV6(((DnsGatewayIpV6)ipSecKeyData.Gateway).Value)); dataField.AssertValue(((DnsGatewayIpV6)ipSecKeyData.Gateway).Value.ToValue());
break; break;
case DnsGatewayType.DomainName: case "dns.ipseckey.gateway_dns":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(((DnsGatewayDomainName)ipSecKeyData.Gateway).Value)); dataField.AssertShow(GetWiresharkDomainName(((DnsGatewayDomainName)ipSecKeyData.Gateway).Value));
break; break;
default: case "dns.ipseckey.public_key":
throw new InvalidOperationException("Invalid Gateway Type " + ipSecKeyData.GatewayType);
}
break;
case "Public key":
dataField.AssertValue(ipSecKeyData.PublicKey); dataField.AssertValue(ipSecKeyData.PublicKey);
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
} }
dataField.AssertNoFields();
break; break;
case DnsType.NSec: case DnsType.NSec:
dataField.AssertName("");
var nSecData = (DnsResourceDataNextDomainSecure)data; var nSecData = (DnsResourceDataNextDomainSecure)data;
switch (dataFieldShowUntilColon) switch (dataField.Name())
{ {
case "Next domain name": case "dns.nsec.next_domain_name":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(nSecData.NextDomainName)); dataField.AssertShow(GetWiresharkDomainName(nSecData.NextDomainName));
break; break;
case "RR type in bit map": case "":
DnsType actualType = nSecData.TypesExist[_nSecTypeIndex++]; DnsType actualType = nSecData.TypesExist[_nSecTypeIndex++];
DnsType expectedType; DnsType expectedType;
if (!TryGetDnsType(dataFieldShow, out expectedType)) if (!TryGetDnsType(dataFieldShow, out expectedType))
...@@ -1157,68 +1237,63 @@ namespace PcapDotNet.Core.Test ...@@ -1157,68 +1237,63 @@ namespace PcapDotNet.Core.Test
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
} }
dataField.AssertNoFields(); dataField.AssertNoFields();
break; break;
case DnsType.DnsKey: case DnsType.DnsKey:
dataField.AssertName("");
var dnsKeyData = (DnsResourceDataDnsKey)data; var dnsKeyData = (DnsResourceDataDnsKey)data;
switch (dataFieldShowUntilColon) switch (dataFieldName)
{ {
case "Flags": case "dns.dnskey.flags":
foreach (var flagField in dataField.Fields()) foreach (XElement subfield in dataField.Fields())
{ {
int flagCount = GetFlagCount(flagField); subfield.AssertNoFields();
switch (flagCount) switch (subfield.Name())
{ {
case 7: case "dns.dnskey.flags.zone_key":
flagField.AssertShow(dnsKeyData.ZoneKey subfield.AssertShowDecimal(dnsKeyData.ZoneKey);
? ".... ...1 .... .... = This is the zone key for the specified zone"
: ".... ...0 .... .... = This is not a zone key");
break; break;
case 8: case "dns.dnskey.flags.key_revoked":
flagField.AssertShow(dnsKeyData.Revoke subfield.AssertShowDecimal(dnsKeyData.Revoke);
? ".... .... 1... .... = Key is revoked"
: ".... .... 0... .... = Key is not revoked");
break; break;
case 15: case "dns.dnskey.flags.secure_entry_point":
flagField.AssertShow(dnsKeyData.SecureEntryPoint subfield.AssertShowDecimal(dnsKeyData.SecureEntryPoint);
? ".... .... .... ...1 = Key is a Key Signing Key"
: ".... .... .... ...0 = Key is a Zone Signing Key");
break; break;
default: case "dns.dnskey.flags.reserved":
throw new InvalidOperationException("Invalid DNS data flag field " + flagField.Show()); subfield.AssertShowDecimal(0);
}
}
break; break;
case "Protocol": case "dns.dnskey.protocol":
dataField.AssertShow(dataFieldShowUntilColon + ": " + dnsKeyData.Protocol); subfield.AssertShowDecimal(dnsKeyData.Protocol);
dataField.AssertNoFields();
break; break;
case "Algorithm": case "dns.dnskey.algorithm":
dataField.AssertValue((byte)dnsKeyData.Algorithm); subfield.AssertShowDecimal((byte)dnsKeyData.Algorithm);
dataField.AssertNoFields(); break;
default:
throw new InvalidOperationException("Invalid DNS flags subfield name " + subfield.Name());
}
}
break; break;
case "Key id": case "dns.dnskey.key_id":
// TODO: Calculate key tag. // TODO: Calculate key tag.
dataField.AssertNoFields(); dataField.AssertNoFields();
break; break;
case "Public key": case "dns.dnskey.public_key":
dataField.AssertValue(dnsKeyData.PublicKey);
dataField.AssertNoFields(); dataField.AssertNoFields();
dataField.AssertValue(dnsKeyData.PublicKey);
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS resource data field name " + dataFieldName);
} }
break; break;
...@@ -1337,37 +1412,28 @@ namespace PcapDotNet.Core.Test ...@@ -1337,37 +1412,28 @@ namespace PcapDotNet.Core.Test
var hipData = (DnsResourceDataHostIdentityProtocol)data; var hipData = (DnsResourceDataHostIdentityProtocol)data;
switch (dataFieldName) switch (dataFieldName)
{ {
case "": case "dns.hip.hit":
switch (dataFieldShowUntilColon) dataField.AssertShow(hipData.HostIdentityTag);
{
case "HIT length":
dataField.AssertShow(dataFieldShowUntilColon + ": " + hipData.HostIdentityTag.Length);
break; break;
case "PK algorithm": case "dns.hip.pk":
dataField.AssertValue((byte)hipData.PublicKeyAlgorithm); dataField.AssertShow(hipData.PublicKey);
break; break;
case "PK length": case "dns.hip.hit.length":
dataField.AssertShow(dataFieldShowUntilColon + ": " + hipData.PublicKey.Length); dataField.AssertShowDecimal(hipData.HostIdentityTag.Length);
break; break;
case "Rendezvous Server": case "dns.hip.hit.pk.algo":
dataField.AssertShow(dataFieldShowUntilColon + ": " + dataField.AssertShowDecimal((byte)hipData.PublicKeyAlgorithm);
GetWiresharkDomainName(hipData.RendezvousServers[_hipRendezvousServersIndex++]));
break; break;
default: case "dns.hip.pk.length":
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); dataField.AssertShowDecimal(hipData.PublicKey.Length);
}
break; break;
case "dns.hip.hit": case "dns.hip.rendezvous_server":
dataField.AssertShow(hipData.HostIdentityTag); dataField.AssertShow(GetWiresharkDomainName(hipData.RendezvousServers[_hipRendezvousServersIndex++]));
break;
case "dns.hip.pk":
dataField.AssertShow(hipData.PublicKey);
break; break;
default: default:
...@@ -1377,50 +1443,49 @@ namespace PcapDotNet.Core.Test ...@@ -1377,50 +1443,49 @@ namespace PcapDotNet.Core.Test
break; break;
case DnsType.TKey: case DnsType.TKey:
dataField.AssertName(""); dataField.AssertNoFields();
var tKeyData = (DnsResourceDataTransactionKey)data; var tKeyData = (DnsResourceDataTransactionKey)data;
switch (dataFieldShowUntilColon) switch (dataFieldName)
{ {
case "Algorithm name": case "dns.tkey.algo_name":
dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(tKeyData.Algorithm)); dataField.AssertShow(GetWiresharkDomainName(tKeyData.Algorithm));
break; break;
case "Signature inception": case "dns.tkey.signature_inception":
dataField.AssertValue(tKeyData.Inception); dataField.AssertValue(tKeyData.Inception);
break; break;
case "Signature expiration": case "dns.tkey.signature_expiration":
dataField.AssertValue(tKeyData.Expiration); dataField.AssertValue(tKeyData.Expiration);
break; break;
case "Mode": case "dns.tkey.mode":
dataField.AssertValue((ushort)tKeyData.Mode); dataField.AssertShowDecimal((ushort)tKeyData.Mode);
break; break;
case "Error": case "dns.tkey.error":
dataField.AssertValue((ushort)tKeyData.Error); dataField.AssertShowDecimal((ushort)tKeyData.Error);
break; break;
case "Key Size": case "dns.tkey.key_size":
dataField.AssertShow(dataFieldShowUntilColon + ": " + tKeyData.Key.Length); dataField.AssertShowDecimal(tKeyData.Key.Length);
break; break;
case "Key Data": case "dns.tkey.key_data":
dataField.AssertValue(tKeyData.Key); dataField.AssertValue(tKeyData.Key);
break; break;
case "Other Size": case "dns.tkey.other_size":
dataField.AssertShow(dataFieldShowUntilColon + ": " + tKeyData.Other.Length); dataField.AssertShowDecimal(tKeyData.Other.Length);
break; break;
case "Other Data": case "dns.tkey.other_data":
dataField.AssertValue(tKeyData.Other); dataField.AssertValue(tKeyData.Other);
break; break;
default: default:
throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow); throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
} }
dataField.AssertNoFields();
break; break;
case DnsType.TransactionSignature: case DnsType.TransactionSignature:
...@@ -1459,8 +1524,7 @@ namespace PcapDotNet.Core.Test ...@@ -1459,8 +1524,7 @@ namespace PcapDotNet.Core.Test
dataField.AssertShow(""); dataField.AssertShow("");
Assert.AreEqual(1, dataField.Fields().Count()); Assert.AreEqual(1, dataField.Fields().Count());
var tsigSubfield = dataField.Fields().First(); var tsigSubfield = dataField.Fields().First();
tsigSubfield.AssertShow("No dissector for algorithm:" + GetWiresharkDomainName(tSigData.Algorithm)); tsigSubfield.AssertName("_ws.expert");
tsigSubfield.AssertValue(tSigData.MessageAuthenticationCode);
break; break;
case "dns.tsig.original_id": case "dns.tsig.original_id":
...@@ -1483,12 +1547,80 @@ namespace PcapDotNet.Core.Test ...@@ -1483,12 +1547,80 @@ namespace PcapDotNet.Core.Test
dataField.AssertNoFields(); dataField.AssertNoFields();
break; break;
case "dns.tsig.time_signed":
dataField.AssertValue(tSigData.TimeSigned);
dataField.AssertNoFields();
break;
case "_ws.expert":
break;
default: default:
throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName); throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
} }
break; 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.EId: // 31.
case DnsType.NimrodLocator: // 32. case DnsType.NimrodLocator: // 32.
case DnsType.AtmA: // 34. case DnsType.AtmA: // 34.
...@@ -1507,14 +1639,20 @@ namespace PcapDotNet.Core.Test ...@@ -1507,14 +1639,20 @@ namespace PcapDotNet.Core.Test
case DnsType.MailA: // 254. case DnsType.MailA: // 254.
case DnsType.Any: // 255. case DnsType.Any: // 255.
case DnsType.Uri: // 256. case DnsType.Uri: // 256.
case DnsType.CertificationAuthorityAuthorization: // 257.
case DnsType.TrustAnchor: // 32768. case DnsType.TrustAnchor: // 32768.
default: default:
dataField.AssertName(""); if (dataField.Name() == "_ws.expert")
dataField.AssertShow("Data"); {
dataField.AssertNoFields(); 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; break;
} }
return true;
} }
private static string GetWiresharkDomainName(DnsDomainName domainName) private static string GetWiresharkDomainName(DnsDomainName domainName)
...@@ -1555,8 +1693,12 @@ namespace PcapDotNet.Core.Test ...@@ -1555,8 +1693,12 @@ namespace PcapDotNet.Core.Test
{"RRSIG", DnsType.ResourceRecordSignature}, // 46 {"RRSIG", DnsType.ResourceRecordSignature}, // 46
{"DHCID", DnsType.DynamicHostConfigurationId}, // 49 {"DHCID", DnsType.DynamicHostConfigurationId}, // 49
{"NSEC3PARAM", DnsType.NSec3Parameters}, // 51 {"NSEC3PARAM", DnsType.NSec3Parameters}, // 51
{"TALINK", DnsType.TrustAnchorLink}, // 58
{"UNSPEC", DnsType.Unspecified}, // 103 {"UNSPEC", DnsType.Unspecified}, // 103
{"TSIG", DnsType.TransactionSignature}, // 250 {"TSIG", DnsType.TransactionSignature}, // 250
{"*", DnsType.Any}, // 255
{"CAA", DnsType.CertificationAuthorityAuthorization}, // 257
{"TA", DnsType.TrustAnchor}, // 32768
{"DLV", DnsType.DnsSecLookAsideValidation}, // 32769 {"DLV", DnsType.DnsSecLookAsideValidation}, // 32769
}; };
...@@ -1585,12 +1727,13 @@ namespace PcapDotNet.Core.Test ...@@ -1585,12 +1727,13 @@ namespace PcapDotNet.Core.Test
return true; 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) 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) private static string GetPrecisionValueString(ulong value)
...@@ -1611,9 +1754,12 @@ namespace PcapDotNet.Core.Test ...@@ -1611,9 +1754,12 @@ namespace PcapDotNet.Core.Test
private int _hipRendezvousServersIndex; private int _hipRendezvousServersIndex;
private int _wksBitmapIndex; private int _wksBitmapIndex;
private int _nxtTypeIndex; private int _nxtTypeIndex;
private int _spfTypeIndex;
private int _txtTypeIndex;
private int _nSecTypeIndex; private int _nSecTypeIndex;
private int _nSec3TypeIndex; private int _nSec3TypeIndex;
private int _txtIndex; private int _txtIndex;
private int _aplItemIndex; private int _aplItemIndex;
private int _optOptionIndex;
} }
} }
...@@ -26,7 +26,7 @@ namespace PcapDotNet.Core.Test ...@@ -26,7 +26,7 @@ namespace PcapDotNet.Core.Test
break; break;
case "eth.type": case "eth.type":
field.AssertShowHex((ushort)ethernetDatagram.EtherType); field.AssertShowDecimal((ushort)ethernetDatagram.EtherType);
break; break;
case "eth.trailer": case "eth.trailer":
...@@ -53,11 +53,20 @@ namespace PcapDotNet.Core.Test ...@@ -53,11 +53,20 @@ namespace PcapDotNet.Core.Test
switch (field.Name()) switch (field.Name())
{ {
case "eth.addr": case "eth.addr":
case "eth.dst_resolved":
case "eth.addr_resolved":
case "eth.src_resolved":
field.AssertShow(address.ToString().ToLower()); field.AssertShow(address.ToString().ToLower());
field.AssertNoFields();
break; break;
case "eth.ig": case "eth.ig":
case "eth.lg": case "eth.lg":
field.AssertNoFields();
break;
case "_ws.expert":
field.AssertNumFields(4);
break; break;
default: default:
......
...@@ -56,7 +56,7 @@ namespace PcapDotNet.Core.Test ...@@ -56,7 +56,7 @@ namespace PcapDotNet.Core.Test
break; break;
case "gre.checksum": case "gre.checksum":
field.AssertShowHex(greDatagram.Checksum); field.AssertShowDecimal(greDatagram.Checksum);
field.AssertNoFields(); field.AssertNoFields();
break; break;
...@@ -138,12 +138,12 @@ namespace PcapDotNet.Core.Test ...@@ -138,12 +138,12 @@ namespace PcapDotNet.Core.Test
break; break;
case "gre.proto": case "gre.proto":
field.AssertShowHex((ushort)greDatagram.ProtocolType); field.AssertShowDecimal((ushort)greDatagram.ProtocolType);
field.AssertNoFields(); field.AssertNoFields();
break; break;
case "gre.key": case "gre.key":
field.AssertShowHex(greDatagram.Key); field.AssertShowDecimal(greDatagram.Key);
field.AssertNoFields(); field.AssertNoFields();
break; break;
......
...@@ -54,13 +54,11 @@ namespace PcapDotNet.Core.Test ...@@ -54,13 +54,11 @@ namespace PcapDotNet.Core.Test
case "": case "":
if (fieldShow == "HTTP chunked response") if (fieldShow == "HTTP chunked response")
{
throw new InvalidOperationException("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()); _data.Append(field.Value());
if (fieldShow == @"\r\n")
break;
if (_isFirstEmptyName) if (_isFirstEmptyName)
{ {
...@@ -168,8 +166,16 @@ namespace PcapDotNet.Core.Test ...@@ -168,8 +166,16 @@ namespace PcapDotNet.Core.Test
} }
break; break;
case "http.transfer_encoding": case "http.request.line":
case "http.response.line":
if (_data.ToString().EndsWith(field.Value()))
break;
{
_data.Append(field.Value()); _data.Append(field.Value());
}
break;
case "http.transfer_encoding":
if (!IsBadHttp(httpDatagram)) if (!IsBadHttp(httpDatagram))
{ {
Assert.AreEqual(fieldShow.ToWiresharkLowerLiteral(), Assert.AreEqual(fieldShow.ToWiresharkLowerLiteral(),
...@@ -192,20 +198,23 @@ namespace PcapDotNet.Core.Test ...@@ -192,20 +198,23 @@ namespace PcapDotNet.Core.Test
{ {
foreach (var field in httpFirstLineElement.Fields()) foreach (var field in httpFirstLineElement.Fields())
{ {
field.AssertNoFields();
switch (field.Name()) switch (field.Name())
{ {
case "http.request.method": case "http.request.method":
field.AssertNoFields();
Assert.IsTrue(httpDatagram.IsRequest, field.Name() + " IsRequest"); Assert.IsTrue(httpDatagram.IsRequest, field.Name() + " IsRequest");
field.AssertShow(((HttpRequestDatagram)httpDatagram).Method.Method); field.AssertShow(((HttpRequestDatagram)httpDatagram).Method.Method);
break; break;
case "http.request.uri": case "http.request.uri":
field.AssertNoFields();
Assert.IsTrue(httpDatagram.IsRequest, field.Name() + " IsRequest"); 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; break;
case "http.request.version": case "http.request.version":
field.AssertNoFields();
if (httpDatagram.Version == null) if (httpDatagram.Version == null)
{ {
if (field.Show() != string.Empty) if (field.Show() != string.Empty)
...@@ -216,11 +225,13 @@ namespace PcapDotNet.Core.Test ...@@ -216,11 +225,13 @@ namespace PcapDotNet.Core.Test
break; break;
case "http.response.code": case "http.response.code":
field.AssertNoFields();
Assert.IsTrue(httpDatagram.IsResponse, field.Name() + " IsResponse"); Assert.IsTrue(httpDatagram.IsResponse, field.Name() + " IsResponse");
field.AssertShowDecimal(IsBadHttp(httpDatagram) ? 0 : ((HttpResponseDatagram)httpDatagram).StatusCode.Value); field.AssertShowDecimal(IsBadHttp(httpDatagram) ? 0 : ((HttpResponseDatagram)httpDatagram).StatusCode.Value);
break; break;
case "http.response.phrase": case "http.response.phrase":
field.AssertNoFields();
Datagram reasonPhrase = ((HttpResponseDatagram)httpDatagram).ReasonPhrase; Datagram reasonPhrase = ((HttpResponseDatagram)httpDatagram).ReasonPhrase;
if (reasonPhrase == null) if (reasonPhrase == null)
Assert.IsTrue(IsBadHttp(httpDatagram)); Assert.IsTrue(IsBadHttp(httpDatagram));
...@@ -228,6 +239,9 @@ namespace PcapDotNet.Core.Test ...@@ -228,6 +239,9 @@ namespace PcapDotNet.Core.Test
field.AssertValue(reasonPhrase); field.AssertValue(reasonPhrase);
break; break;
case "_ws.expert":
break;
default: default:
throw new InvalidOperationException("Invalid HTTP first line field " + field.Name()); throw new InvalidOperationException("Invalid HTTP first line field " + field.Name());
} }
......
...@@ -37,7 +37,7 @@ namespace PcapDotNet.Core.Test ...@@ -37,7 +37,7 @@ namespace PcapDotNet.Core.Test
break; break;
case "icmp.checksum": case "icmp.checksum":
field.AssertShowHex(icmpDatagram.Checksum); field.AssertShowDecimal(icmpDatagram.Checksum);
field.AssertNoFields(); field.AssertNoFields();
break; break;
......
...@@ -37,11 +37,11 @@ namespace PcapDotNet.Core.Test ...@@ -37,11 +37,11 @@ namespace PcapDotNet.Core.Test
break; break;
case "igmp.type": case "igmp.type":
field.AssertShowHex((byte)igmpDatagram.MessageType); field.AssertShowDecimal((byte)igmpDatagram.MessageType);
break; break;
case "igmp.checksum": case "igmp.checksum":
field.AssertShowHex(igmpDatagram.Checksum); field.AssertShowDecimal(igmpDatagram.Checksum);
break; break;
case "igmp.maddr": case "igmp.maddr":
......
using System; using System;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Text;
using System.Xml.Linq; using System.Xml.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using PcapDotNet.Packets; using PcapDotNet.Packets;
...@@ -21,6 +23,9 @@ namespace PcapDotNet.Core.Test ...@@ -21,6 +23,9 @@ namespace PcapDotNet.Core.Test
switch (field.Name()) switch (field.Name())
{ {
case "ip.version": 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.AssertShowDecimal(ipV4Datagram.Version);
field.AssertNoFields(); field.AssertNoFields();
break; break;
...@@ -41,12 +46,12 @@ namespace PcapDotNet.Core.Test ...@@ -41,12 +46,12 @@ namespace PcapDotNet.Core.Test
break; break;
case "ip.id": case "ip.id":
field.AssertShowHex(ipV4Datagram.Identification); field.AssertShowDecimal(ipV4Datagram.Identification);
field.AssertNoFields(); field.AssertNoFields();
break; break;
case "ip.flags": case "ip.flags":
field.AssertShowHex((byte)((ushort)ipV4Datagram.Fragmentation.Options >> 13)); field.AssertShowDecimal(((ushort)ipV4Datagram.Fragmentation.Options >> 13));
foreach (XElement subfield in field.Fields()) foreach (XElement subfield in field.Fields())
{ {
subfield.AssertNoFields(); subfield.AssertNoFields();
...@@ -76,7 +81,18 @@ namespace PcapDotNet.Core.Test ...@@ -76,7 +81,18 @@ namespace PcapDotNet.Core.Test
case "ip.ttl": case "ip.ttl":
field.AssertShowDecimal(ipV4Datagram.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; break;
case "ip.proto": case "ip.proto":
...@@ -85,7 +101,7 @@ namespace PcapDotNet.Core.Test ...@@ -85,7 +101,7 @@ namespace PcapDotNet.Core.Test
break; break;
case "ip.checksum": case "ip.checksum":
field.AssertShowHex(ipV4Datagram.HeaderChecksum); field.AssertShowDecimal(ipV4Datagram.HeaderChecksum);
if (field.Showname().EndsWith(" [not all data available]")) if (field.Showname().EndsWith(" [not all data available]"))
{ {
Assert.IsFalse(ipV4Datagram.IsValid); Assert.IsFalse(ipV4Datagram.IsValid);
...@@ -96,17 +112,21 @@ namespace PcapDotNet.Core.Test ...@@ -96,17 +112,21 @@ namespace PcapDotNet.Core.Test
switch (checksumField.Name()) switch (checksumField.Name())
{ {
case "ip.checksum_good": case "ip.checksum_good":
checksumField.AssertShowDecimal(ipV4Datagram.IsHeaderChecksumCorrect);
checksumField.AssertNoFields(); 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; break;
case "ip.checksum_bad": case "ip.checksum_bad":
if (ipV4Datagram.Length < IpV4Datagram.HeaderMinimumLength || 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; break;
checksumField.AssertShowDecimal(!ipV4Datagram.IsHeaderChecksumCorrect); checksumField.AssertShowDecimal(!ipV4Datagram.IsHeaderChecksumCorrect);
checksumField.AssertNoFields();
break; break;
} }
} }
...@@ -145,8 +165,13 @@ namespace PcapDotNet.Core.Test ...@@ -145,8 +165,13 @@ namespace PcapDotNet.Core.Test
field.AssertNoFields(); field.AssertNoFields();
break; break;
case "ip.cur_rt":
case "ip.cur_rt_host":
field.AssertShow(ipV4Datagram.CurrentDestination.ToString());
break;
case "": case "":
CompareIpV4Options(field, ipV4Datagram.Options); CompareIpV4Options(field, ipV4Datagram, ipV4Datagram.Options);
break; break;
default: default:
...@@ -156,7 +181,7 @@ namespace PcapDotNet.Core.Test ...@@ -156,7 +181,7 @@ namespace PcapDotNet.Core.Test
return true; return true;
} }
private static void CompareIpV4Options(XElement element, IpV4Options options) private static void CompareIpV4Options(XElement element, IpV4Datagram ipV4Datagram, IpV4Options options)
{ {
int currentOptionIndex = 0; int currentOptionIndex = 0;
foreach (var field in element.Fields()) foreach (var field in element.Fields())
...@@ -179,19 +204,447 @@ namespace PcapDotNet.Core.Test ...@@ -179,19 +204,447 @@ namespace PcapDotNet.Core.Test
break; break;
} }
IpV4Option option = options[currentOptionIndex++]; 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())); case "ip.opt.ptr":
continue; // Wireshark doesn't support 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; 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(); case "ip.dst":
MoreAssert.AreSequenceEqual(optionShows, option.GetWiresharkSubfieldStrings()); 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 ...@@ -46,12 +46,11 @@ namespace PcapDotNet.Core.Test
break; break;
case "ipv6.class": case "ipv6.class":
field.AssertShowHex((uint)ipV6Datagram.TrafficClass); field.AssertShowDecimal(ipV6Datagram.TrafficClass);
//field.AssertNoFields();
break; break;
case "ipv6.flow": case "ipv6.flow":
field.AssertShowHex((uint)ipV6Datagram.FlowLabel); field.AssertShowDecimal(ipV6Datagram.FlowLabel);
field.AssertNoFields(); field.AssertNoFields();
break; break;
...@@ -61,7 +60,7 @@ namespace PcapDotNet.Core.Test ...@@ -61,7 +60,7 @@ namespace PcapDotNet.Core.Test
break; break;
case "ipv6.nxt": case "ipv6.nxt":
field.AssertShowHex((byte)ipV6Datagram.NextHeader); field.AssertShowDecimal((byte)ipV6Datagram.NextHeader);
field.AssertNoFields(); field.AssertNoFields();
break; break;
...@@ -111,7 +110,7 @@ namespace PcapDotNet.Core.Test ...@@ -111,7 +110,7 @@ namespace PcapDotNet.Core.Test
IpV6ExtensionHeaderHopByHopOptions hopByHopOptions = IpV6ExtensionHeaderHopByHopOptions hopByHopOptions =
(IpV6ExtensionHeaderHopByHopOptions)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex]; (IpV6ExtensionHeaderHopByHopOptions)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex];
IncrementCurrentExtensionHeaderIndex(ipV6Datagram); IncrementCurrentExtensionHeaderIndex(ipV6Datagram);
CompareOptions(field, ref optionsIndex, hopByHopOptions); CompareOptions(field, ref optionsIndex, ipV6Datagram, hopByHopOptions);
} }
break; break;
...@@ -119,35 +118,83 @@ namespace PcapDotNet.Core.Test ...@@ -119,35 +118,83 @@ namespace PcapDotNet.Core.Test
if (!ipV6Datagram.IsValid) if (!ipV6Datagram.IsValid)
return false; return false;
IpV6ExtensionHeaderRouting routing = (IpV6ExtensionHeaderRouting)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex]; IpV6ExtensionHeaderRouting routing = (IpV6ExtensionHeaderRouting)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex];
IpV6ExtensionHeaderRoutingProtocolLowPowerAndLossyNetworks routingProtocolLowPowerAndLossyNetworks =
routing as IpV6ExtensionHeaderRoutingProtocolLowPowerAndLossyNetworks;
int routingProtocolLowPowerAndLossyNetworksAddressIndex = 0;
IncrementCurrentExtensionHeaderIndex(ipV6Datagram); IncrementCurrentExtensionHeaderIndex(ipV6Datagram);
int sourceRouteAddressIndex = 0; int sourceRouteAddressIndex = 0;
foreach (var headerField in field.Fields()) foreach (var headerField in field.Fields())
{ {
headerField.AssertNoFields();
switch (headerField.Name()) switch (headerField.Name())
{ {
case "": case "":
headerField.AssertNoFields();
ValidateExtensionHeaderUnnamedField(routing, headerField); ValidateExtensionHeaderUnnamedField(routing, headerField);
break; break;
case "ipv6.routing_hdr.type": case "ipv6.routing_hdr.type":
headerField.AssertNoFields();
headerField.AssertShowDecimal((byte)routing.RoutingType); headerField.AssertShowDecimal((byte)routing.RoutingType);
break; break;
case "ipv6.routing_hdr.left": case "ipv6.routing_hdr.left":
headerField.AssertNoFields();
headerField.AssertShowDecimal(routing.SegmentsLeft); headerField.AssertShowDecimal(routing.SegmentsLeft);
break; break;
case "ipv6.mipv6_home_address": case "ipv6.mipv6_home_address":
headerField.AssertNoFields();
IpV6ExtensionHeaderRoutingHomeAddress routingHomeAddress = (IpV6ExtensionHeaderRoutingHomeAddress)routing; IpV6ExtensionHeaderRoutingHomeAddress routingHomeAddress = (IpV6ExtensionHeaderRoutingHomeAddress)routing;
headerField.AssertShow(routingHomeAddress.HomeAddress.ToString("x")); headerField.AssertShow(routingHomeAddress.HomeAddress.ToString("x"));
break; break;
case "ipv6.routing_hdr.addr": case "ipv6.routing_hdr.addr":
headerField.AssertNoFields();
IpV6ExtensionHeaderRoutingSourceRoute routingSourceRoute = (IpV6ExtensionHeaderRoutingSourceRoute)routing; IpV6ExtensionHeaderRoutingSourceRoute routingSourceRoute = (IpV6ExtensionHeaderRoutingSourceRoute)routing;
headerField.AssertShow(routingSourceRoute.Addresses[sourceRouteAddressIndex++].ToString("x")); headerField.AssertShow(routingSourceRoute.Addresses[sourceRouteAddressIndex++].ToString("x"));
break; 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: default:
throw new InvalidOperationException("Invalid IPv6 routing source route field " + headerField.Name()); throw new InvalidOperationException("Invalid IPv6 routing source route field " + headerField.Name());
} }
...@@ -166,7 +213,7 @@ namespace PcapDotNet.Core.Test ...@@ -166,7 +213,7 @@ namespace PcapDotNet.Core.Test
} }
IpV6ExtensionHeaderDestinationOptions destinationOptions = (IpV6ExtensionHeaderDestinationOptions)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex]; IpV6ExtensionHeaderDestinationOptions destinationOptions = (IpV6ExtensionHeaderDestinationOptions)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex];
IncrementCurrentExtensionHeaderIndex(ipV6Datagram); IncrementCurrentExtensionHeaderIndex(ipV6Datagram);
CompareOptions(field, ref optionsIndex, destinationOptions); CompareOptions(field, ref optionsIndex, ipV6Datagram, destinationOptions);
break; break;
case "ipv6.shim6": case "ipv6.shim6":
...@@ -205,7 +252,7 @@ namespace PcapDotNet.Core.Test ...@@ -205,7 +252,7 @@ namespace PcapDotNet.Core.Test
{ {
switch (headerField.Name()) switch (headerField.Name())
{ {
case "": case "ipv6.fragment.nxt":
headerField.AssertValue((byte)fragmentData.NextHeader.Value); headerField.AssertValue((byte)fragmentData.NextHeader.Value);
break; break;
...@@ -217,8 +264,13 @@ namespace PcapDotNet.Core.Test ...@@ -217,8 +264,13 @@ namespace PcapDotNet.Core.Test
headerField.AssertShowDecimal(fragmentData.MoreFragments); headerField.AssertShowDecimal(fragmentData.MoreFragments);
break; break;
case "ipv6.framgent.id": case "ipv6.fragment.id":
headerField.AssertShowHex(fragmentData.Identification); headerField.AssertShowDecimal(fragmentData.Identification);
break;
case "ipv6.fragment.reserved_octet":
case "ipv6.fragment.reserved_bits":
headerField.AssertShowDecimal(0);
break; break;
default: default:
...@@ -239,39 +291,194 @@ namespace PcapDotNet.Core.Test ...@@ -239,39 +291,194 @@ namespace PcapDotNet.Core.Test
return true; 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()) foreach (var headerField in field.Fields())
{ {
headerField.AssertNoFields();
switch (headerField.Name()) switch (headerField.Name())
{ {
case "": case "ipv6.nxt":
ValidateExtensionHeaderUnnamedField(header, headerField, ref optionsIndex); headerField.AssertNoFields();
headerField.AssertShowDecimal((byte)header.NextHeader);
break; break;
case "ipv6.opt.pad1": case "ipv6.opt.length":
if (header.Options.IsValid) headerField.AssertNoFields();
Assert.AreEqual(IpV6OptionType.Pad1, header.Options[optionsIndex++].OptionType); 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; break;
case "ipv6.opt.padn": case "ipv6.opt.padn":
Assert.AreEqual(IpV6OptionType.PadN, header.Options[optionsIndex].OptionType); headerSubfield.AssertNoFields();
if (header.Options.IsValid) var optionPadN = (IpV6OptionPadN)option;
headerField.AssertShowDecimal(header.Options[optionsIndex++].Length); 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; break;
case "ipv6.mipv6_type": case "ipv6.opt.qs_ttl_diff":
Assert.AreEqual(IpV6OptionType.HomeAddress, header.Options[optionsIndex].OptionType); headerSubfield.AssertNoFields();
headerSubfield.AssertShowDecimal((256 + ipV6Datagram.HopLimit - optionQuickStart.Ttl) % 256);
break; break;
case "ipv6.mipv6_length": case "ipv6.opt.qs_unused":
headerField.AssertShowDecimal(header.Options[optionsIndex].Length - 2); 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; break;
case "ipv6.mipv6_home_address": case "ipv6.mipv6_home_address":
IpV6OptionHomeAddress homeAddress = (IpV6OptionHomeAddress)header.Options[optionsIndex++]; headerSubfield.AssertNoFields();
headerField.AssertShow(homeAddress.HomeAddress.ToString("x")); 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; break;
default: default:
......
...@@ -61,7 +61,7 @@ namespace PcapDotNet.Core.Test ...@@ -61,7 +61,7 @@ namespace PcapDotNet.Core.Test
break; break;
case "ah.spi": case "ah.spi":
field.AssertShowHex(authenticationHeader.SecurityParametersIndex); field.AssertShowDecimal(authenticationHeader.SecurityParametersIndex);
break; break;
case "ah.sequence": 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 ...@@ -66,7 +66,18 @@ namespace PcapDotNet.Core.Test
case "tcp.ack": case "tcp.ack":
field.AssertShowDecimal(tcpDatagram.AcknowledgmentNumber); 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; break;
case "tcp.hdr_len": case "tcp.hdr_len":
...@@ -79,44 +90,93 @@ namespace PcapDotNet.Core.Test ...@@ -79,44 +90,93 @@ namespace PcapDotNet.Core.Test
(ushort)((tcpDatagram.Reserved << 9) | (ushort)((tcpDatagram.Reserved << 9) |
(((tcpDatagram.ControlBits & TcpControlBits.NonceSum) == TcpControlBits.NonceSum ? 1 : 0) << 8) | (((tcpDatagram.ControlBits & TcpControlBits.NonceSum) == TcpControlBits.NonceSum ? 1 : 0) << 8) |
(byte)tcpDatagram.ControlBits); (byte)tcpDatagram.ControlBits);
field.AssertShow("0x" + flags.ToString("x" + 4 * sizeof(byte))); field.AssertShowDecimal(flags);
foreach (var flagField in field.Fields()) foreach (var flagField in field.Fields())
{ {
switch (flagField.Name()) 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": case "tcp.flags.cwr":
flagField.AssertNoFields();
flagField.AssertShowDecimal(tcpDatagram.IsCongestionWindowReduced); flagField.AssertShowDecimal(tcpDatagram.IsCongestionWindowReduced);
break; break;
case "tcp.flags.ecn": case "tcp.flags.ecn":
flagField.AssertNoFields();
flagField.AssertShowDecimal(tcpDatagram.IsExplicitCongestionNotificationEcho); flagField.AssertShowDecimal(tcpDatagram.IsExplicitCongestionNotificationEcho);
break; break;
case "tcp.flags.urg": case "tcp.flags.urg":
flagField.AssertNoFields();
flagField.AssertShowDecimal(tcpDatagram.IsUrgent); flagField.AssertShowDecimal(tcpDatagram.IsUrgent);
break; break;
case "tcp.flags.ack": case "tcp.flags.ack":
flagField.AssertNoFields();
flagField.AssertShowDecimal(tcpDatagram.IsAcknowledgment); flagField.AssertShowDecimal(tcpDatagram.IsAcknowledgment);
break; break;
case "tcp.flags.push": case "tcp.flags.push":
flagField.AssertNoFields();
flagField.AssertShowDecimal(tcpDatagram.IsPush); flagField.AssertShowDecimal(tcpDatagram.IsPush);
break; break;
case "tcp.flags.reset": case "tcp.flags.reset":
flagField.AssertShowDecimal(tcpDatagram.IsReset); 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; break;
case "tcp.flags.syn": case "tcp.flags.syn":
flagField.AssertShowDecimal(tcpDatagram.IsSynchronize); 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; break;
case "tcp.flags.fin": case "tcp.flags.fin":
flagField.AssertShowDecimal(tcpDatagram.IsFin); flagField.AssertShowDecimal(tcpDatagram.IsFin);
foreach (XElement subfield in flagField.Fields())
{
switch (subfield.Name())
{
case "_ws.expert":
break; 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; break;
...@@ -126,7 +186,7 @@ namespace PcapDotNet.Core.Test ...@@ -126,7 +186,7 @@ namespace PcapDotNet.Core.Test
break; break;
case "tcp.checksum": case "tcp.checksum":
field.AssertShowHex(tcpDatagram.Checksum); field.AssertShowDecimal(tcpDatagram.Checksum);
IpV4Datagram ipV4Datagram = ipDatagram as IpV4Datagram; IpV4Datagram ipV4Datagram = ipDatagram as IpV4Datagram;
if (ipV4Datagram != null && !ipV4Datagram.Options.IsBadForWireshark()) if (ipV4Datagram != null && !ipV4Datagram.Options.IsBadForWireshark())
{ {
...@@ -143,6 +203,11 @@ namespace PcapDotNet.Core.Test ...@@ -143,6 +203,11 @@ namespace PcapDotNet.Core.Test
checksumField.AssertShowDecimal(tcpDatagram.Checksum != 0 && !ipDatagram.IsTransportChecksumCorrect); checksumField.AssertShowDecimal(tcpDatagram.Checksum != 0 && !ipDatagram.IsTransportChecksumCorrect);
break; break;
case "tcp.checksum_calculated":
if (ipDatagram.IsTransportChecksumCorrect)
checksumField.AssertShowDecimal(tcpDatagram.Checksum);
break;
default: default:
throw new InvalidOperationException("Invalid checksum field name " + checksumField.Name()); throw new InvalidOperationException("Invalid checksum field name " + checksumField.Name());
} }
...@@ -153,7 +218,6 @@ namespace PcapDotNet.Core.Test ...@@ -153,7 +218,6 @@ namespace PcapDotNet.Core.Test
case "tcp.urgent_pointer": case "tcp.urgent_pointer":
field.AssertShowDecimal(tcpDatagram.UrgentPointer); field.AssertShowDecimal(tcpDatagram.UrgentPointer);
field.AssertNoFields();
break; break;
case "tcp.options": case "tcp.options":
...@@ -164,8 +228,19 @@ namespace PcapDotNet.Core.Test ...@@ -164,8 +228,19 @@ namespace PcapDotNet.Core.Test
case "tcp.pdu.size": case "tcp.pdu.size":
case "tcp.window_size": case "tcp.window_size":
case "tcp.window_size_scalefactor": case "tcp.window_size_scalefactor":
field.AssertNoFields();
break;
case "": 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(); field.AssertNoFields();
}
break; break;
default: default:
...@@ -220,16 +295,10 @@ namespace PcapDotNet.Core.Test ...@@ -220,16 +295,10 @@ namespace PcapDotNet.Core.Test
TcpOptionWindowScale windowScale = (TcpOptionWindowScale)option; TcpOptionWindowScale windowScale = (TcpOptionWindowScale)option;
foreach (var subField in field.Fields()) foreach (var subField in field.Fields())
{ {
if (HandleOptionCommonFields(subField, option))
continue;
switch (subField.Name()) 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": case "tcp.options.wscale.shift":
subField.AssertShowDecimal(windowScale.ScaleFactorLog); subField.AssertShowDecimal(windowScale.ScaleFactorLog);
break; break;
...@@ -239,7 +308,7 @@ namespace PcapDotNet.Core.Test ...@@ -239,7 +308,7 @@ namespace PcapDotNet.Core.Test
break; break;
default: default:
throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name()); throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
} }
} }
break; break;
...@@ -249,6 +318,9 @@ namespace PcapDotNet.Core.Test ...@@ -249,6 +318,9 @@ namespace PcapDotNet.Core.Test
int blockIndex = 0; int blockIndex = 0;
foreach (var subField in field.Fields()) foreach (var subField in field.Fields())
{ {
if (HandleOptionCommonFields(subField, option))
continue;
subField.AssertNoFields();
switch (subField.Name()) switch (subField.Name())
{ {
case "tcp.options.sack": case "tcp.options.sack":
...@@ -264,8 +336,12 @@ namespace PcapDotNet.Core.Test ...@@ -264,8 +336,12 @@ namespace PcapDotNet.Core.Test
++blockIndex; ++blockIndex;
break; break;
case "tcp.options.sack.count":
subField.AssertShowDecimal(selectiveAcknowledgmentOption.Blocks.Count);
break;
default: default:
throw new InvalidOperationException("Invalid tcp options subfield " + subField.Name()); throw new InvalidOperationException("Invalid tcp option subfield " + subField.Name());
} }
} }
break; break;
...@@ -274,16 +350,11 @@ namespace PcapDotNet.Core.Test ...@@ -274,16 +350,11 @@ namespace PcapDotNet.Core.Test
var timestampOption = (TcpOptionTimestamp)option; var timestampOption = (TcpOptionTimestamp)option;
foreach (var subField in field.Fields()) foreach (var subField in field.Fields())
{ {
if (HandleOptionCommonFields(subField, option))
continue;
subField.AssertNoFields();
switch (subField.Name()) 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": case "tcp.options.timestamp.tsval":
subField.AssertShowDecimal(timestampOption.TimestampValue); subField.AssertShowDecimal(timestampOption.TimestampValue);
break; break;
...@@ -293,11 +364,130 @@ namespace PcapDotNet.Core.Test ...@@ -293,11 +364,130 @@ namespace PcapDotNet.Core.Test
break; break;
default: 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; 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: default:
field.AssertNoFields(); field.AssertNoFields();
break; break;
...@@ -307,8 +497,24 @@ namespace PcapDotNet.Core.Test ...@@ -307,8 +497,24 @@ namespace PcapDotNet.Core.Test
case "tcp.options.mss": case "tcp.options.mss":
Assert.AreEqual(TcpOptionType.MaximumSegmentSize, option.OptionType); Assert.AreEqual(TcpOptionType.MaximumSegmentSize, option.OptionType);
field.AssertShowDecimal(true); var maximumSegmentSize = (TcpOptionMaximumSegmentSize)option;
field.AssertNoFields(); 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; break;
case "tcp.options.mss_val": case "tcp.options.mss_val":
...@@ -330,13 +536,15 @@ namespace PcapDotNet.Core.Test ...@@ -330,13 +536,15 @@ namespace PcapDotNet.Core.Test
break; break;
case "tcp.options.scps.vector": case "tcp.options.scps.vector":
// TODO: Support 20.
Assert.AreEqual((TcpOptionType)20, option.OptionType); Assert.AreEqual((TcpOptionType)20, option.OptionType);
if (field.Show() == "0") // if (field.Show() == "0")
++currentOptionIndex; // ++currentOptionIndex;
++currentOptionIndex; ++currentOptionIndex;
break; break;
case "tcp.options.scps": case "tcp.options.scps":
// TODO: Support 20.
Assert.AreEqual((TcpOptionType)20, option.OptionType); Assert.AreEqual((TcpOptionType)20, option.OptionType);
Assert.IsFalse(field.Fields().Any()); Assert.IsFalse(field.Fields().Any());
break; break;
...@@ -350,7 +558,13 @@ namespace PcapDotNet.Core.Test ...@@ -350,7 +558,13 @@ namespace PcapDotNet.Core.Test
case "tcp.options.sack_perm": case "tcp.options.sack_perm":
Assert.AreEqual(TcpOptionType.SelectiveAcknowledgmentPermitted, option.OptionType); 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; ++currentOptionIndex;
break; break;
...@@ -366,10 +580,39 @@ namespace PcapDotNet.Core.Test ...@@ -366,10 +580,39 @@ namespace PcapDotNet.Core.Test
++currentOptionIndex; ++currentOptionIndex;
break; break;
case "tcp.options.experimental":
Assert.IsTrue(new []{(TcpOptionType)253, (TcpOptionType)254}.Contains(option.OptionType));
// TODO: Support Experimental.
++currentOptionIndex;
break;
default: default:
throw new InvalidOperationException("Invalid tcp options field " + field.Name()); 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 ...@@ -40,7 +40,7 @@ namespace PcapDotNet.Core.Test
break; break;
case "udp.checksum": case "udp.checksum":
field.AssertShowHex(udpDatagram.Checksum); field.AssertShowDecimal(udpDatagram.Checksum);
if (udpDatagram.Checksum != 0) if (udpDatagram.Checksum != 0)
{ {
foreach (var checksumField in field.Fields()) foreach (var checksumField in field.Fields())
...@@ -66,6 +66,9 @@ namespace PcapDotNet.Core.Test ...@@ -66,6 +66,9 @@ namespace PcapDotNet.Core.Test
field.AssertShowDecimal(udpDatagram.TotalLength); field.AssertShowDecimal(udpDatagram.TotalLength);
break; break;
case "udp.stream":
break;
default: default:
throw new InvalidOperationException("Invalid udp field " + field.Name()); throw new InvalidOperationException("Invalid udp field " + field.Name());
} }
......
...@@ -19,26 +19,33 @@ namespace PcapDotNet.Core.Test ...@@ -19,26 +19,33 @@ namespace PcapDotNet.Core.Test
switch (field.Name()) switch (field.Name())
{ {
case "vlan.priority": case "vlan.priority":
field.AssertNoFields();
field.AssertShowDecimal((byte)vLanTaggedFrameDatagram.PriorityCodePoint); field.AssertShowDecimal((byte)vLanTaggedFrameDatagram.PriorityCodePoint);
break; break;
case "vlan.cfi": case "vlan.cfi":
field.AssertNoFields();
field.AssertShowDecimal(vLanTaggedFrameDatagram.CanonicalFormatIndicator); field.AssertShowDecimal(vLanTaggedFrameDatagram.CanonicalFormatIndicator);
break; break;
case "vlan.id": case "vlan.id":
field.AssertNoFields();
field.AssertShowDecimal(vLanTaggedFrameDatagram.VLanIdentifier); field.AssertShowDecimal(vLanTaggedFrameDatagram.VLanIdentifier);
break; break;
case "vlan.etype": case "vlan.etype":
field.AssertShowHex((ushort)vLanTaggedFrameDatagram.EtherType); field.AssertNoFields();
field.AssertShowDecimal((ushort)vLanTaggedFrameDatagram.EtherType);
break; break;
case "vlan.len": case "vlan.len":
field.AssertShowDecimal((ushort)vLanTaggedFrameDatagram.EtherType); field.AssertShowDecimal((ushort)vLanTaggedFrameDatagram.EtherType);
field.AssertNumFields(1);
field.Fields().First().AssertName("_ws.expert");
break; break;
case "vlan.trailer": case "vlan.trailer":
field.AssertNoFields();
if (!new[] if (!new[]
{ {
(EthernetType)1, (EthernetType)5, (EthernetType)17, (EthernetType)29, (EthernetType)30, (EthernetType)43, (EthernetType)50, EthernetType.ReverseArp, (EthernetType)1, (EthernetType)5, (EthernetType)17, (EthernetType)29, (EthernetType)30, (EthernetType)43, (EthernetType)50, EthernetType.ReverseArp,
...@@ -50,7 +57,6 @@ namespace PcapDotNet.Core.Test ...@@ -50,7 +57,6 @@ namespace PcapDotNet.Core.Test
default: default:
throw new InvalidOperationException("Invalid VLanTaggedFrame field " + field.Name()); throw new InvalidOperationException("Invalid VLanTaggedFrame field " + field.Name());
} }
field.AssertNoFields();
return true; return true;
} }
......
...@@ -18,7 +18,6 @@ namespace PcapDotNet.Core.Test ...@@ -18,7 +18,6 @@ namespace PcapDotNet.Core.Test
switch (currentChar) switch (currentChar)
{ {
case '\\': case '\\':
case '"':
result.Append('\\'); result.Append('\\');
result.Append(currentChar); result.Append(currentChar);
continue; continue;
......
...@@ -67,6 +67,11 @@ namespace PcapDotNet.Core.Test ...@@ -67,6 +67,11 @@ namespace PcapDotNet.Core.Test
Assert.AreEqual(expectedNumFields, element.Fields().Count()); 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) public static void AssertNoShow(this XElement element)
{ {
Assert.IsNull(element.Attribute("show")); Assert.IsNull(element.Attribute("show"));
...@@ -164,7 +169,7 @@ namespace PcapDotNet.Core.Test ...@@ -164,7 +169,7 @@ namespace PcapDotNet.Core.Test
public static void AssertValue(this XElement element, string expectedValue, string message = null) 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()); Assert.AreEqual(expectedValue, element.Value(), message ?? element.Name());
} }
...@@ -208,6 +213,11 @@ namespace PcapDotNet.Core.Test ...@@ -208,6 +213,11 @@ namespace PcapDotNet.Core.Test
element.AssertValue(expectedValue.ToString("x16")); 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) public static void AssertValue(this XElement element, SerialNumber32 expectedValue)
{ {
element.AssertValue(expectedValue.Value); element.AssertValue(expectedValue.Value);
......
...@@ -92,7 +92,9 @@ namespace PcapDotNet.Packets.Test ...@@ -92,7 +92,9 @@ namespace PcapDotNet.Packets.Test
EtherType = EthernetType 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) for (int i = 0; i != 1000; ++i)
{ {
......
...@@ -180,7 +180,7 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -180,7 +180,7 @@ namespace PcapDotNet.Packets.TestUtils
return new IpV4OptionQuickStart(random.NextEnum<IpV4OptionQuickStartFunction>(), return new IpV4OptionQuickStart(random.NextEnum<IpV4OptionQuickStartFunction>(),
random.NextByte(IpV4OptionQuickStart.RateMaximumValue + 1), random.NextByte(IpV4OptionQuickStart.RateMaximumValue + 1),
random.NextByte(), random.NextByte(),
random.NextUInt() & 0xFFFFFFFC); random.NextUInt() & 0x3FFFFFFF);
default: default:
throw new InvalidOperationException("optionType = " + optionType); throw new InvalidOperationException("optionType = " + optionType);
......
...@@ -263,7 +263,7 @@ namespace PcapDotNet.Packets.TestUtils ...@@ -263,7 +263,7 @@ namespace PcapDotNet.Packets.TestUtils
case IpV6OptionType.QuickStart: case IpV6OptionType.QuickStart:
return new IpV6OptionQuickStart(random.NextEnum<IpV4OptionQuickStartFunction>(), return new IpV6OptionQuickStart(random.NextEnum<IpV4OptionQuickStartFunction>(),
random.NextByte(IpOptionQuickStartCommon.RateMaximumValue + 1), random.NextByte(), random.NextByte(IpOptionQuickStartCommon.RateMaximumValue + 1), random.NextByte(),
random.NextUInt() & 0xFFFFFFFC); random.NextUInt() & 0x3FFFFFFF);
case IpV6OptionType.Calipso: case IpV6OptionType.Calipso:
return new IpV6OptionCalipso(random.NextEnum<IpV6CalipsoDomainOfInterpretation>(), random.NextByte(), random.NextUShort(), return new IpV6OptionCalipso(random.NextEnum<IpV6CalipsoDomainOfInterpretation>(), random.NextByte(), random.NextUShort(),
......
...@@ -13,6 +13,8 @@ namespace PcapDotNet.Packets.Ip ...@@ -13,6 +13,8 @@ namespace PcapDotNet.Packets.Ip
/// </summary> /// </summary>
public const byte RateMaximumValue = 0x0F; public const byte RateMaximumValue = 0x0F;
public const uint NonceMaximumValue = 0x3FFFFFFF;
internal const int DataLength = 6; internal const int DataLength = 6;
private static class Offset private static class Offset
...@@ -29,19 +31,25 @@ namespace PcapDotNet.Packets.Ip ...@@ -29,19 +31,25 @@ namespace PcapDotNet.Packets.Ip
public const byte Rate = 0x0F; 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) internal static void AssertValidParameters(IpV4OptionQuickStartFunction function, byte rate, uint nonce)
{ {
if (function != IpV4OptionQuickStartFunction.RateRequest && if (function != IpV4OptionQuickStartFunction.RateRequest &&
function != IpV4OptionQuickStartFunction.RateReport) function != IpV4OptionQuickStartFunction.RateReport)
{ {
throw new ArgumentException("Illegal function " + function, "function"); throw new ArgumentException(string.Format("Illegal function {0}", function), "function");
} }
if (rate > RateMaximumValue) 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) if (nonce > NonceMaximumValue)
throw new ArgumentException("nonce last two bits are reserved and must be zero", "nonce"); throw new ArgumentException(string.Format("nonce cannot be bigger than {0}", NonceMaximumValue), "nonce");
} }
internal static int CalcRateKbps(byte rate) internal static int CalcRateKbps(byte rate)
...@@ -54,17 +62,17 @@ namespace PcapDotNet.Packets.Ip ...@@ -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) 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); rate = (byte)(data[Offset.Rate] & Mask.Rate);
ttl = data[Offset.Ttl]; 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) 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[offset + Offset.Ttl] = ttl;
buffer.Write(offset + Offset.Nonce, nonce, Endianity.Big); buffer.Write(offset + Offset.Nonce, nonce << Shift.Nonce, Endianity.Big);
offset += DataLength; offset += DataLength;
} }
} }
......
...@@ -9,11 +9,11 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -9,11 +9,11 @@ namespace PcapDotNet.Packets.IpV4
/// <summary> /// <summary>
/// Request for a specific rate. /// Request for a specific rate.
/// </summary> /// </summary>
RateRequest = 0x00, RateRequest = 0x0,
/// <summary> /// <summary>
/// Reports on a specific rate that was agreed (or disagreed). /// Reports on a specific rate that was agreed (or disagreed).
/// </summary> /// </summary>
RateReport = 0x80 RateReport = 0x8
} }
} }
\ No newline at end of file
...@@ -229,8 +229,8 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -229,8 +229,8 @@ namespace PcapDotNet.Packets.IpV6
lastAddressSegment.Write(addressBytes, commonPrefixLengthForLastAddress); lastAddressSegment.Write(addressBytes, commonPrefixLengthForLastAddress);
addresses[numAddresses - 1] = addressBytes.ReadIpV6Address(0, Endianity.Big); addresses[numAddresses - 1] = addressBytes.ReadIpV6Address(0, Endianity.Big);
} }
return new IpV6ExtensionHeaderRoutingProtocolLowPowerAndLossyNetworks(nextHeader, segmentsLeft, commonPrefixLengthForNonLastAddresses, commonPrefixLengthForLastAddress, return new IpV6ExtensionHeaderRoutingProtocolLowPowerAndLossyNetworks(nextHeader, segmentsLeft, commonPrefixLengthForNonLastAddresses,
addresses); commonPrefixLengthForLastAddress, addresses);
} }
internal override bool EqualsRoutingData(IpV6ExtensionHeaderRouting other) internal override bool EqualsRoutingData(IpV6ExtensionHeaderRouting other)
......
...@@ -15,7 +15,9 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -15,7 +15,9 @@ namespace PcapDotNet.Packets.IpV6
/// +-----+-------------+--------------+ /// +-----+-------------+--------------+
/// | 0 | Option Type | Opt Data Len | /// | 0 | Option Type | Opt Data Len |
/// +-----+-------------+--------------+ /// +-----+-------------+--------------+
/// | 16 | Request 1 | /// | 16 | Reserved |
/// +-----+----------------------------+
/// | 32 | Request 1 |
/// | ... | Request 2 | /// | ... | Request 2 |
/// | | ... | /// | | ... |
/// | | Request n | /// | | Request n |
...@@ -25,6 +27,16 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -25,6 +27,16 @@ namespace PcapDotNet.Packets.IpV6
[IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.ContextRequest)] [IpV6MobilityOptionTypeRegistration(IpV6MobilityOptionType.ContextRequest)]
public sealed class IpV6MobilityOptionContextRequest : IpV6MobilityOptionComplex 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> /// <summary>
/// Creates an instance from an array of requests. /// Creates an instance from an array of requests.
/// </summary> /// </summary>
...@@ -51,7 +63,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -51,7 +63,7 @@ namespace PcapDotNet.Packets.IpV6
: base(IpV6MobilityOptionType.ContextRequest) : base(IpV6MobilityOptionType.ContextRequest)
{ {
Requests = requests; Requests = requests;
_dataLength = Requests.Sum(request => request.Length); _dataLength = OptionDataMinimumLength + Requests.Sum(request => request.Length);
if (_dataLength > byte.MaxValue) if (_dataLength > byte.MaxValue)
throw new ArgumentOutOfRangeException("requests", requests, throw new ArgumentOutOfRangeException("requests", requests,
string.Format(CultureInfo.InvariantCulture, "requests length is too large. Takes over {0}>{1} bytes.", string.Format(CultureInfo.InvariantCulture, "requests length is too large. Takes over {0}>{1} bytes.",
...@@ -66,7 +78,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -66,7 +78,7 @@ namespace PcapDotNet.Packets.IpV6
internal override IpV6MobilityOption CreateInstance(DataSegment data) internal override IpV6MobilityOption CreateInstance(DataSegment data)
{ {
List<IpV6MobilityOptionContextRequestEntry> requests = new List<IpV6MobilityOptionContextRequestEntry>(); List<IpV6MobilityOptionContextRequestEntry> requests = new List<IpV6MobilityOptionContextRequestEntry>();
int offset = 0; int offset = Offset.Requests;
while (data.Length > offset) while (data.Length > offset)
{ {
byte requestType = data[offset++]; byte requestType = data[offset++];
...@@ -104,6 +116,7 @@ namespace PcapDotNet.Packets.IpV6 ...@@ -104,6 +116,7 @@ namespace PcapDotNet.Packets.IpV6
internal override void WriteData(byte[] buffer, ref int offset) internal override void WriteData(byte[] buffer, ref int offset)
{ {
offset += Offset.Requests;
foreach (var request in Requests) foreach (var request in Requests)
request.Write(buffer, ref offset); request.Write(buffer, ref offset);
} }
......
...@@ -5,7 +5,7 @@ using PcapDotNet.Base; ...@@ -5,7 +5,7 @@ using PcapDotNet.Base;
namespace PcapDotNet.Packets.IpV6 namespace PcapDotNet.Packets.IpV6
{ {
/// <summary> /// <summary>
/// RFC 5845. /// RFC 5568.
/// <pre> /// <pre>
/// +-----+-------------+---------------+ /// +-----+-------------+---------------+
/// | Bit | 0-7 | 8-15 | /// | Bit | 0-7 | 8-15 |
......
...@@ -199,6 +199,14 @@ namespace PcapDotNet.Packets.Transport ...@@ -199,6 +199,14 @@ namespace PcapDotNet.Packets.Transport
get { return Length - HeaderLength; } 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> /// <summary>
/// True iff the CongestionWindowReduced control bit is turned on. /// True iff the CongestionWindowReduced control bit is turned on.
/// </summary> /// </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