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)
return new WiresharkDatagramComparerIpV6AuthenticationHeader(count); {
// TODO: Remove this condition when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10705 is fixed.
if (parentName == "ipv6")
return new WiresharkDatagramComparerIpV6AuthenticationHeader(count);
}
return null; 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:
......
...@@ -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.request.line":
case "http.response.line":
if (_data.ToString().EndsWith(field.Value()))
break;
{
_data.Append(field.Value());
}
break;
case "http.transfer_encoding": case "http.transfer_encoding":
_data.Append(field.Value());
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":
......
...@@ -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.
...@@ -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