Commit 1328e773 authored by Brickner_cp's avatar Brickner_cp

GRE

Overload UInt48.Parse()
Code Coverage 97.68%
parent 6f0f18cd
...@@ -56,12 +56,72 @@ namespace PcapDotNet.Base.Test ...@@ -56,12 +56,72 @@ namespace PcapDotNet.Base.Test
for (int i = 0; i != 100; ++i) for (int i = 0; i != 100; ++i)
{ {
UInt48 expected = (UInt48)random.NextLong(UInt48.MaxValue + 1); UInt48 expected = (UInt48)random.NextLong(UInt48.MaxValue + 1);
UInt48 actual = UInt48.Parse(expected.ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture); UInt48 actual = UInt48.Parse(expected.ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture);
Assert.AreEqual(expected, actual);
actual = UInt48.Parse(expected.ToString(), NumberStyles.Integer);
Assert.AreEqual(expected, actual);
actual = UInt48.Parse(expected.ToString(), CultureInfo.InvariantCulture);
Assert.AreEqual(expected, actual);
actual = UInt48.Parse(expected.ToString());
Assert.AreEqual(expected, actual); Assert.AreEqual(expected, actual);
} }
} }
[TestMethod]
[ExpectedException(typeof(OverflowException))]
public void ParseTooBigTest()
{
UInt48 value = UInt48.Parse(ulong.MaxValue.ToString());
Assert.IsNotNull(value);
}
[TestMethod]
[ExpectedException(typeof(OverflowException))]
public void ParseTooBigTestEvenForUInt64()
{
UInt48 value = UInt48.Parse(ulong.MaxValue + "0");
Assert.IsNotNull(value);
}
// [TestMethod]
// public void UInt48Test()
// {
// UInt48 value = (UInt48)0x010203040506;
// byte[] buffer = new byte[UInt48.SizeOf];
//
// buffer.Write(0, value, Endianity.Big);
// Assert.AreEqual(value, buffer.ReadUInt48(0, Endianity.Big));
// Assert.AreEqual(0x01, buffer[0]);
// Assert.AreEqual(0x02, buffer[1]);
// Assert.AreEqual(0x03, buffer[2]);
// Assert.AreEqual(0x04, buffer[3]);
// Assert.AreEqual(0x05, buffer[4]);
// Assert.AreEqual(0x06, buffer[5]);
//
// int offset = 0;
// buffer.Write(ref offset, value, Endianity.Big);
// Assert.AreEqual(value, buffer.ReadUInt48(0, Endianity.Big));
// Assert.AreEqual(6, offset);
//
// buffer.Write(0, value, Endianity.Small);
// Assert.AreEqual(value, buffer.ReadUInt48(0, Endianity.Small));
// Assert.AreEqual(0x06, buffer[0]);
// Assert.AreEqual(0x05, buffer[1]);
// Assert.AreEqual(0x04, buffer[2]);
// Assert.AreEqual(0x03, buffer[3]);
// Assert.AreEqual(0x02, buffer[4]);
// Assert.AreEqual(0x01, buffer[5]);
//
// offset = 0;
// buffer.Write(ref offset, value, Endianity.Small);
// Assert.AreEqual(value, buffer.ReadUInt48(0, Endianity.Small));
// Assert.AreEqual(6, offset);
// }
[TestMethod] [TestMethod]
public void UInt48Test() public void UInt48Test()
{ {
...@@ -71,6 +131,7 @@ namespace PcapDotNet.Base.Test ...@@ -71,6 +131,7 @@ namespace PcapDotNet.Base.Test
UInt48 value = random.NextUInt48(); UInt48 value = random.NextUInt48();
Assert.AreEqual(value, value); Assert.AreEqual(value, value);
Assert.AreNotEqual(value, "1");
Assert.IsTrue(value == value); Assert.IsTrue(value == value);
Assert.IsFalse(value != value); Assert.IsFalse(value != value);
Assert.IsNotNull(value.GetHashCode()); Assert.IsNotNull(value.GetHashCode());
......
...@@ -15,26 +15,389 @@ namespace PcapDotNet.Base ...@@ -15,26 +15,389 @@ namespace PcapDotNet.Base
/// </summary> /// </summary>
public const int SizeOf = 6; public const int SizeOf = 6;
/// <summary>
/// The minimum value of this type.
/// </summary>
public static readonly UInt48 MinValue = 0;
/// <summary> /// <summary>
/// The maximum value of this type. /// The maximum value of this type.
/// </summary> /// </summary>
public static readonly UInt48 MaxValue = (UInt48)0x0000FFFFFFFFFFFF; public static readonly UInt48 MaxValue = (UInt48)0x0000FFFFFFFFFFFF;
/// <summary> /// <summary>
/// Converts the string representation of a number in a specified style to its 48-bit unsigned integer equivalent. /// Converts the string representation of a number to its 48-bit unsigned integer equivalent.
/// </summary>
/// <param name="value">A string that represents the number to convert.</param>
/// <returns>A 48-bit unsigned integer equivalent to the number contained in <paramref name="value"/>.</returns>
/// <exception cref="ArgumentNullException">The <paramref name="value"/> parameter is <see langword="null"/>.</exception>
/// <exception cref="FormatException">The <paramref name="value"/> parameter is not in the correct format.</exception>
/// <exception cref="OverflowException">The <paramref name="value"/> parameter represents a number less than <see cref="UInt48.MinValue"/> or greater than <see cref="UInt48.MaxValue"/>.</exception>
/// <remarks>
/// The <paramref name="value"/> parameter should be the string representation of a number in the following form.
/// <para>[ws][sign]digits[ws]</para>
/// <para> Elements in square brackets ([ and ]) are optional. The following table describes each element.</para>
/// <list type="table">
/// <listheader>
/// <term>Element</term>
/// <description>Description</description>
/// </listheader>
/// <item><term>ws</term><description>Optional white space.</description></item>
/// <item>
/// <term>sign</term>
/// <description>
/// An optional sign.
/// Valid sign characters are determined by the <see cref="NumberFormatInfo.NegativeSign"/> and <see cref="NumberFormatInfo.PositiveSign"/> properties of the current culture.
/// However, the negative sign symbol can be used only with zero; otherwise, the method throws an <see cref="OverflowException"/>.
/// </description>
/// </item>
/// <item><term>digits</term><description>A sequence of digits ranging from 0 to 9. Any leading zeros are ignored.</description></item>
/// </list>
/// <note>
/// The string specified by the <paramref name="value"/> parameter is interpreted by using the <see cref="NumberStyles.Integer"/> style.
/// It cannot contain any group separators or decimal separator, and it cannot have a decimal portion.
/// </note>
/// The <paramref name="value"/> parameter is parsed by using the formatting information in a <see cref="NumberFormatInfo"/> object that is initialized for the current system culture.
/// For more information, see <see cref="NumberFormatInfo.CurrentInfo"/>.
/// To parse a string by using the formatting information of a specific culture, use the <see cref="Parse(String, IFormatProvider)"/> method.
/// </remarks>
public static UInt48 Parse(string value)
{
return Parse(value, NumberStyles.Integer, CultureInfo.CurrentCulture);
}
/// <summary>
/// Converts the string representation of a number in a specified culture-specific format to its 64-bit unsigned integer equivalent.
/// </summary>
/// <param name="value">A string that represents the number to convert.</param>
/// <param name="provider">An object that supplies culture-specific formatting information about <paramref name="value"/>.</param>
/// <returns>A 48-bit unsigned integer equivalent to the number specified in <paramref name="value"/>.</returns>
/// <exception cref="ArgumentNullException">The <paramref name="value"/> parameter is <see langword="null"/>.</exception>
/// <exception cref="FormatException">The <paramref name="value"/> parameter is not in the correct style.</exception>
/// <exception cref="OverflowException">
/// The <paramref name="value"/> parameter represents a number less than <see cref="UInt48.MinValue"/> or greater than <see cref="UInt48.MaxValue"/>.
/// </exception>
/// <remarks>
/// This overload of the Parse(String, IFormatProvider) method is typically used to convert text that can be formatted in a variety of ways to a <see cref="UInt48"/> value.
/// For example, it can be used to convert the text entered by a user into an HTML text box to a numeric value.
/// <para>The <paramref name="value"/> parameter contains a number of the form:</para>
/// <para>[ws][sign]digits[ws]</para>
/// <para>
/// Items in square brackets ([ and ]) are optional.
/// The following table describes each element.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Element</term>
/// <description>Description</description>
/// </listheader>
/// <item><term>ws</term><description>Optional white space.</description></item>
/// <item>
/// <term>sign</term>
/// <description>An optional positive sign, or a negative sign if <paramref name="value"/> represents the value zero.</description>
/// </item>
/// <item><term>digits</term><description>A sequence of digits from 0 through 9.</description></item>
/// </list>
/// The <paramref name="value"/> parameter is interpreted using the <see cref="NumberStyles.Integer"/> style.
/// In addition to the unsigned integer value's decimal digits, only leading and trailing spaces along with a leading sign is allowed.
/// (If the negative sign is present, <paramref name="value"/> must represent a value of zero, or the method throws an <see cref="OverflowException"/>.)
/// To explicitly define the style elements together with the culture-specific formatting information that can be present in <paramref name="value"/>, use the <see cref="Parse(String, NumberStyles, IFormatProvider)"/> method.
/// <para>
/// The <paramref name="provider"/> parameter is an <see cref="IFormatProvider"/> implementation whose <see cref="IFormatProvider.GetFormat"/> method returns a <see cref="NumberFormatInfo"/> object that provides culture-specific information about the format of <paramref name="value"/>.
/// There are three ways to use the <paramref name="provider"/> parameter to supply custom formatting information to the parse operation:
/// </para>
/// <list type="bullet">
/// <item>You can pass the actual <see cref="NumberFormatInfo"/> object that provides formatting information. (Its implementation of <see cref="IFormatProvider.GetFormat"/> simply returns itself.)</item>
/// <item>You can pass a <see cref="CultureInfo"/> object that specifies the culture whose formatting is to be used. Its <see cref="CultureInfo.NumberFormat"/> property provides formatting information.</item>
/// <item>You can pass a custom <see cref="IFormatProvider"/> implementation. Its <see cref="IFormatProvider.GetFormat"/> method must instantiate and return the <see cref="NumberFormatInfo"/> object that provides formatting information.</item>
/// </list>
/// If provider is <see langword="null"/>, the <see cref="NumberFormatInfo"/> object for the current culture is used.
/// </remarks>
public static UInt48 Parse(string value, IFormatProvider provider)
{
return Parse(value, NumberStyles.Integer, provider);
}
/// <summary>
/// Converts the string representation of a number in a specified style to its 64-bit unsigned integer equivalent.
/// </summary> /// </summary>
/// <param name="value">A string representing the number to convert.</param> /// <param name="value">
/// A string that represents the number to convert.
/// The string is interpreted by using the style specified by the <paramref name="style"/> parameter.
/// </param>
/// <param name="style">
/// A bitwise combination of the enumeration values that specifies the permitted format of <paramref name="value"/>.
/// A typical value to specify is <see cref="NumberStyles.Integer"/>.
/// </param>
/// <returns>A 48-bit unsigned integer equivalent to the number specified in <paramref name="value"/>.</returns>
/// <exception cref="ArgumentNullException">The <paramref name="value"/> parameter is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException">
/// <paramref name="style"/> is not a <see cref="NumberStyles"/> value.
/// <para>-or-</para>
/// <para><paramref name="style"/> is not a combination of <see cref="NumberStyles.AllowHexSpecifier"/> and <see cref="NumberStyles.HexNumber"/> values.</para>
/// </exception>
/// <exception cref="FormatException">The <paramref name="value"/> parameter is not in a format compliant with <paramref name="style"/>.</exception>
/// <exception cref="OverflowException">
/// The <paramref name="value"/> parameter represents a number less than <see cref="UInt48.MinValue"/> or greater than <see cref="UInt48.MaxValue"/>.
/// <para>-or-</para>
/// <para><paramref name="value"/> includes non-zero, fractional digits.</para>
/// </exception>
/// <remarks>
/// The <paramref name="style"/> parameter defines the style elements (such as white space, the positive or negative sign symbol, the group separator symbol, or the decimal point symbol) that are allowed in the s parameter for the parse operation to succeed.
/// It must be a combination of bit flags from the <see cref="NumberStyles"/> enumeration.
/// <para>Depending on the value of style, the <paramref name="value"/> parameter may include the following elements:</para>
/// <para>[ws][$][sign][digits,]digits[.fractional_digits][E[sign]exponential_digits][ws]</para>
/// <para>
/// Elements in square brackets ([ and ]) are optional.
/// If <paramref name="style"/> includes <see cref="NumberStyles.AllowHexSpecifier"/>, the <paramref name="value"/> parameter may contain the following elements:
/// </para>
/// <para>[ws]hexdigits[ws]</para>
/// <para>The following table describes each element.</para>
/// <list type="table">
/// <listheader>
/// <term>Element</term>
/// <description>Description</description>
/// </listheader>
/// <item>
/// <term>ws</term>
/// <description>
/// Optional white space.
/// White space can appear at the start of <paramref name="value"/> if <paramref name="style"/> includes the <see cref="NumberStyles.AllowLeadingWhite"/> flag,
/// and it can appear at the end of <paramref name="style"/> if <paramref name="style"/> includes the <see cref="NumberStyles.AllowTrailingWhite"/> flag.
/// </description>
/// </item>
/// <item>
/// <term>$</term>
/// <description>
/// A culture-specific currency symbol.
/// Its position in the string is defined by the <see cref="NumberFormatInfo.CurrencyNegativePattern"/> and <see cref="NumberFormatInfo.CurrencyPositivePattern"/> properties of the current culture.
/// The current culture's currency symbol can appear in <paramref name="value"/> if <paramref name="style"/> includes the <see cref="NumberStyles.AllowCurrencySymbol"/> flag.
/// </description>
/// </item>
/// <item>
/// <term>sign</term>
/// <description>
/// An optional sign.
/// The sign can appear at the start of <paramref name="value"/> if <paramref name="style"/> includes the <see cref="NumberStyles.AllowLeadingSign"/> flag, and it can appear at the end of <paramref name="value"/> if <paramref name="style"/> includes the <see cref="NumberStyles.AllowTrailingSign"/> flag.
/// Parentheses can be used in <paramref name="value"/> to indicate a negative value if <paramref name="style"/> includes the <see cref="NumberStyles.AllowParentheses"/> flag.
/// However, the negative sign symbol can be used only with zero; otherwise, the method throws an <see cref="OverflowException"/>.
/// </description>
/// </item>
/// <item>
/// <term>digits<para>fractional_digits</para><para>exponential_digits</para></term>
/// <description>A sequence of digits from 0 through 9. For fractional_digits, only the digit 0 is valid.</description>
/// </item>
/// <item>
/// <term>.</term>
/// <description>
/// A culture-specific decimal point symbol.
/// The current culture's decimal point symbol can appear in <paramref name="value"/> if <paramref name="style"/> includes the <see cref="NumberStyles.AllowDecimalPoint"/> flag.
/// </description>
/// </item>
/// <item>
/// <term>,</term>
/// <description>
/// A culture-specific group separator symbol.
/// The current culture's group separator can appear in <paramref name="value"/> if <paramref name="style"/> includes the <see cref="NumberStyles.AllowThousands"/> flag.</description>
/// </item>
/// <item>
/// <term>E</term>
/// <description>
/// The "e" or "E" character, which indicates that the value is represented in exponential (scientific) notation.
/// The <paramref name="value"/> parameter can represent a number in exponential notation if <paramref name="style"/> includes the <see cref="NumberStyles.AllowExponent"/> flag.
/// </description>
/// </item>
/// <item>
/// <term>hexdigits</term>
/// <description>A sequence of hexadecimal digits from 0 through f, or 0 through F.</description>
/// </item>
/// <item><term>hexdigits</term><description>A sequence of hexadecimal digits from 0 through f, or 0 through F.</description></item>
/// </list>
/// A string with decimal digits only (which corresponds to the <see cref="NumberStyles.None"/> style) always parses successfully.
/// Most of the remaining <see cref="NumberStyles"/> members control elements that may be present, but are not required to be present, in this input string.
/// The following table indicates how individual <see cref="NumberStyles"/> members affect the elements that may be present in <paramref name="value"/>.
/// <list type="table">
/// <listheader>
/// <term><see cref="NumberStyles"/> value</term>
/// <description>Elements permitted in <paramref name="value"/> in addition to digits</description>
/// </listheader>
/// <item><term><see cref="NumberStyles.None"/></term><description>The digits element only.</description></item>
/// <item><term><see cref="NumberStyles.AllowDecimalPoint"/></term><description>The decimal point (.) and fractional-digits elements.</description></item>
/// <item><term><see cref="NumberStyles.AllowExponent"/></term><description>The "e" or "E" character, which indicates exponential notation, along with exponential_digits.</description></item>
/// <item><term><see cref="NumberStyles.AllowLeadingWhite"/></term><description>The ws element at the start of <paramref name="value"/>.</description></item>
/// <item><term><see cref="NumberStyles.AllowTrailingWhite"/></term><description>The ws element at the end of <paramref name="value"/>.</description></item>
/// <item><term><see cref="NumberStyles.AllowLeadingSign"/></term><description>The sign element at the start of <paramref name="value"/>.</description></item>
/// <item><term><see cref="NumberStyles.AllowTrailingSign"/></term><description>The sign element at the end of <paramref name="value"/>.</description></item>
/// <item><term><see cref="NumberStyles.AllowParentheses"/></term><description>The sign element in the form of parentheses enclosing the numeric value.</description></item>
/// <item><term><see cref="NumberStyles.AllowThousands"/></term><description>The group separator (,) element. </description></item>
/// <item><term><see cref="NumberStyles.AllowCurrencySymbol"/></term><description>The currency ($) element.</description></item>
/// <item><term><see cref="NumberStyles.Currency"/></term><description>All elements. However, <paramref name="value"/> cannot represent a hexadecimal number or a number in exponential notation.</description></item>
/// <item><term><see cref="NumberStyles.Float"/></term><description>The ws element at the start or end of <paramref name="value"/>, sign at the start of <paramref name="value"/>, and the decimal point (.) symbol. The <paramref name="value"/> parameter can also use exponential notation.</description></item>
/// <item><term><see cref="NumberStyles.Number"/></term><description>The ws, sign, group separator (,), and decimal point (.) elements.</description></item>
/// <item><term><see cref="NumberStyles.Any"/></term><description>All elements. However, <paramref name="value"/> cannot represent a hexadecimal number.</description></item>
/// </list>
/// Unlike the other <see cref="NumberStyles"/> values, which allow for, but do not require, the presence of particular style elements in <paramref name="value"/>, the <see cref="NumberStyles.AllowHexSpecifier"/> style value means that the individual numeric characters in <paramref name="value"/> are always interpreted as hexadecimal characters.
/// Valid hexadecimal characters are 0-9, A-F, and a-f.
/// The only other flags that can be combined with the <paramref name="style"/> parameter are <see cref="NumberStyles.AllowLeadingWhite"/> and <see cref="NumberStyles.AllowTrailingWhite"/>.
/// (The <see cref="NumberStyles"/> enumeration includes a composite number style, <see cref="NumberStyles.HexNumber"/>, that includes both white-space flags.)
/// <note>
/// If <paramref name="value"/> is the string representation of a hexadecimal number, it cannot be preceded by any decoration (such as 0x or &amp;h) that differentiates it as a hexadecimal number.
/// This causes the conversion to fail.
/// </note>
/// The <paramref name="value"/> parameter is parsed by using the formatting information in a <see cref="NumberFormatInfo"/> object that is initialized for the current system culture.
/// To specify the culture whose formatting information is used for the parse operation, call the <see cref="Parse(String, NumberStyles, IFormatProvider)"/> overload.
/// </remarks>
public static UInt48 Parse(string value, NumberStyles style)
{
return Parse(value, style, CultureInfo.CurrentCulture.NumberFormat);
}
/// <summary>
/// Converts the string representation of a number in a specified style and culture-specific format to its 48-bit unsigned integer equivalent.
/// </summary>
/// <param name="value">
/// A string that represents the number to convert.
/// The string is interpreted by using the style specified by the <paramref name="style"/> parameter.
/// </param>
/// <param name="style"> /// <param name="style">
/// A bitwise combination of NumberStyles values that indicates the permitted format of value. /// A bitwise combination of enumeration values that indicates the style elements that can be present in <paramref name="value"/>.
/// A typical value to specify is NumberStyles.Integer. /// A typical value to specify is <see cref="NumberStyles.Integer"/>.
/// </param> /// </param>
/// <param name="provider">An System.IFormatProvider that supplies culture-specific formatting information about value.</param> /// <param name="provider">An object that supplies culture-specific formatting information about <paramref name="value"/>.</param>
/// <returns>A 48-bit unsigned integer equivalent to the number specified in s.</returns> /// <returns>A 48-bit unsigned integer equivalent to the number specified in <paramref name="value"/>.</returns>
/// <exception cref="ArgumentNullException">The <paramref name="value"/> parameter is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException">
/// <paramref name="style"/> is not a <see cref="NumberStyles"/> value.
/// <para>-or-</para>
/// <para><paramref name="style"/> is not a combination of <see cref="NumberStyles.AllowHexSpecifier"/> and <see cref="NumberStyles.HexNumber"/> values.</para>
/// </exception>
/// <exception cref="FormatException">The <paramref name="value"/> parameter is not in a format compliant with <paramref name="style"/>.</exception>
/// <exception cref="OverflowException">
/// The <paramref name="value"/> parameter represents a number less than <see cref="UInt48.MinValue"/> or greater than <see cref="UInt48.MaxValue"/>.
/// <para>-or-</para>
/// <para><paramref name="value"/> includes non-zero, fractional digits.</para>
/// </exception>
/// <remarks>
/// The <paramref name="style"/> parameter defines the style elements (such as white space or the positive or negative sign symbol) that are allowed in the s parameter for the parse operation to succeed.
/// It must be a combination of bit flags from the <see cref="NumberStyles"/> enumeration.
/// <para>Depending on the value of style, the <paramref name="value"/> parameter may include the following elements:</para>
/// <para>[ws][$][sign]digits[.fractional_digits][E[sign]exponential_digits][ws]</para>
/// <para>
/// Elements in square brackets ([ and ]) are optional.
/// If <paramref name="style"/> includes <see cref="NumberStyles.AllowHexSpecifier"/>, the <paramref name="value"/> parameter may include the following elements:
/// </para>
/// <para>[ws]hexdigits[ws]</para>
/// <para>The following table describes each element.</para>
/// <list type="table">
/// <listheader>
/// <term>Element</term>
/// <description>Description</description>
/// </listheader>
/// <item>
/// <term>ws</term>
/// <description>
/// Optional white space.
/// White space can appear at the beginning of <paramref name="value"/> if <paramref name="style"/> includes the <see cref="NumberStyles.AllowLeadingWhite"/> flag,
/// and it can appear at the end of <paramref name="style"/> if <paramref name="style"/> includes the <see cref="NumberStyles.AllowTrailingWhite"/> flag.
/// </description>
/// </item>
/// <item>
/// <term>$</term>
/// <description>
/// A culture-specific currency symbol.
/// Its position in the string is defined by the <see cref="NumberFormatInfo.CurrencyPositivePattern"/> property of the <see cref="NumberFormatInfo"/> object that is returned by the <see cref="IFormatProvider.GetFormat"/> method of the provider parameter.
/// The currency symbol can appear in <paramref name="value"/> if <paramref name="style"/> includes the <see cref="NumberStyles.AllowCurrencySymbol"/> flag.
/// </description>
/// </item>
/// <item>
/// <term>sign</term>
/// <description>
/// An optional sign.
/// (The method throws an <see cref="OverflowException"/> if <paramref name="value"/> includes a negative sign and represents a non-zero number.)
/// The sign can appear at the beginning of <paramref name="value"/> if <paramref name="style"/> includes the <see cref="NumberStyles.AllowLeadingSign"/> flag, and it can appear the end of <paramref name="value"/> if <paramref name="style"/> includes the <see cref="NumberStyles.AllowTrailingSign"/> flag.
/// Parentheses can be used in <paramref name="value"/> to indicate a negative value if <paramref name="style"/> includes the <see cref="NumberStyles.AllowParentheses"/> flag.
/// </description>
/// </item>
/// <item><term>digits</term><description>A sequence of digits from 0 through 9.</description></item>
/// <item>
/// <term>.</term>
/// <description>
/// A culture-specific decimal point symbol.
/// The current culture's decimal point symbol can appear in <paramref name="value"/> if <paramref name="style"/> includes the <see cref="NumberStyles.AllowDecimalPoint"/> flag.
/// </description>
/// </item>
/// <item>
/// <term>fractional_digits</term>
/// <description>
/// One or more occurrences of the digit 0-9 if <paramref name="style"/> includes the <see cref="NumberStyles.AllowExponent"/> flag,
/// or one or more occurrences of the digit 0 if it does not.
/// Fractional digits can appear in <paramref name="value"/> only if <paramref name="style"/> includes the <see cref="NumberStyles.AllowDecimalPoint"/> flag.
/// </description>
/// </item>
/// <item>
/// <term>E</term>
/// <description>
/// The "e" or "E" character, which indicates that the value is represented in exponential (scientific) notation.
/// The <paramref name="value"/> parameter can represent a number in exponential notation if <paramref name="style"/> includes the <see cref="NumberStyles.AllowExponent"/> flag.
/// </description>
/// </item>
/// <item>
/// <term>exponential_digits</term>
/// <description>
/// A sequence of digits from 0 through 9.
/// The <paramref name="value"/> parameter can represent a number in exponential notation if <paramref name="style"/> includes the <see cref="NumberStyles.AllowExponent"/> flag.
/// </description>
/// </item>
/// <item><term>hexdigits</term><description>A sequence of hexadecimal digits from 0 through f, or 0 through F.</description></item>
/// </list>
/// A string with decimal digits only (which corresponds to the <see cref="NumberStyles.None"/> style) always parses successfully.
/// Most of the remaining <see cref="NumberStyles"/> members control elements that may be present, but are not required to be present, in this input string.
/// The following table indicates how individual <see cref="NumberStyles"/> members affect the elements that may be present in <paramref name="value"/>.
/// <list type="table">
/// <listheader>
/// <term>Non-composite <see cref="NumberStyles"/> values</term>
/// <description>Elements permitted in <paramref name="value"/> in addition to digits</description>
/// </listheader>
/// <item><term><see cref="NumberStyles.None"/></term><description>Decimal digits only.</description></item>
/// <item><term><see cref="NumberStyles.AllowDecimalPoint"/></term><description>The decimal point (.) and fractional_digits elements. However, if <paramref name="style"/> does not include the <see cref="NumberStyles.AllowExponent"/> flag, fractional_digits must consist of only one or more 0 digits; otherwise, an <see cref="OverflowException"/> is thrown.</description></item>
/// <item><term><see cref="NumberStyles.AllowExponent"/></term><description>The "e" or "E" character, which indicates exponential notation, along with exponential_digits.</description></item>
/// <item><term><see cref="NumberStyles.AllowLeadingWhite"/></term><description>The ws element at the beginning of <paramref name="value"/>.</description></item>
/// <item><term><see cref="NumberStyles.AllowTrailingWhite"/></term><description>The ws element at the end of <paramref name="value"/>.</description></item>
/// <item><term><see cref="NumberStyles.AllowLeadingSign"/></term><description>A sign before digits.</description></item>
/// <item><term><see cref="NumberStyles.AllowTrailingSign"/></term><description>A sign after digits.</description></item>
/// <item><term><see cref="NumberStyles.AllowParentheses"/></term><description>Parentheses before and after digits to indicate a negative value.</description></item>
/// <item><term><see cref="NumberStyles.AllowThousands"/></term><description>The group separator (,) element. </description></item>
/// <item><term><see cref="NumberStyles.AllowCurrencySymbol"/></term><description>The currency ($) element.</description></item>
/// </list>
/// If the <see cref="NumberStyles.AllowHexSpecifier"/> flag is used, <paramref name="value"/> must be a hexadecimal value.
/// The only other flags that can be combined with it are <see cref="NumberStyles.AllowLeadingWhite"/> and <see cref="NumberStyles.AllowTrailingWhite"/>.
/// (The <see cref="NumberStyles"/> enumeration includes a composite number style, <see cref="NumberStyles.HexNumber"/>, that includes both white-space flags.)
/// <note>
/// If the <paramref name="value"/> parameter is the string representation of a hexadecimal number, it cannot be preceded by any decoration (such as 0x or &amp;h) that differentiates it as a hexadecimal number.
/// This causes the parse operation to throw an exception.
/// </note>
/// The <paramref name="provider"/> parameter is an <see cref="IFormatProvider"/> implementation whose <see cref="IFormatProvider.GetFormat"/> method returns a <see cref="NumberFormatInfo"/> object that provides culture-specific information about the format of <paramref name="value"/>.
/// There are three ways to use the <paramref name="provider"/> parameter to supply custom formatting information to the parse operation:
/// <list type="bullet">
/// <item>You can pass the actual <see cref="NumberFormatInfo"/> object that provides formatting information. (Its implementation of <see cref="IFormatProvider.GetFormat"/> simply returns itself.)</item>
/// <item>You can pass a <see cref="CultureInfo"/> object that specifies the culture whose formatting is to be used. Its <see cref="CultureInfo.NumberFormat"/> property provides formatting information.</item>
/// <item>You can pass a custom <see cref="IFormatProvider"/> implementation. Its <see cref="IFormatProvider.GetFormat"/> method must instantiate and return the <see cref="NumberFormatInfo"/> object that provides formatting information.</item>
/// </list>
/// If provider is <see langword="null"/>, the <see cref="NumberFormatInfo"/> object for the current culture is used.
/// </remarks>
public static UInt48 Parse(string value, NumberStyles style, IFormatProvider provider) public static UInt48 Parse(string value, NumberStyles style, IFormatProvider provider)
{ {
ulong parsedValue = ulong.Parse(value, style, provider); ulong parsedValue;
try
{
parsedValue = ulong.Parse(value, style, provider);
}
catch (OverflowException)
{
throw new OverflowException("Value was either too large or too small for a UInt48");
}
if (parsedValue > MaxValue) if (parsedValue > MaxValue)
throw new FormatException("parsed value " + parsedValue + " is larger than max value " + MaxValue); throw new OverflowException("Value was too large for a UInt48");
return (UInt48)parsedValue; return (UInt48)parsedValue;
} }
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Net; using System.Net;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
...@@ -73,7 +74,7 @@ namespace PcapDotNet.Core.Test ...@@ -73,7 +74,7 @@ namespace PcapDotNet.Core.Test
Assert.AreEqual(PacketCommunicatorReceiveResult.Timeout, result); Assert.AreEqual(PacketCommunicatorReceiveResult.Timeout, result);
Assert.AreEqual<uint>(0, communicator.TotalStatistics.PacketsCaptured); Assert.AreEqual<uint>(0, communicator.TotalStatistics.PacketsCaptured);
MoreAssert.IsInRange(TimeSpan.FromSeconds(0.99), TimeSpan.FromSeconds(1.04), finishedWaiting - startWaiting); MoreAssert.IsInRange(TimeSpan.FromSeconds(0.99), TimeSpan.FromSeconds(1.075), finishedWaiting - startWaiting);
Packet sentPacket = _random.NextEthernetPacket(24, SourceMac, DestinationMac); Packet sentPacket = _random.NextEthernetPacket(24, SourceMac, DestinationMac);
...@@ -134,7 +135,7 @@ namespace PcapDotNet.Core.Test ...@@ -134,7 +135,7 @@ namespace PcapDotNet.Core.Test
TestReceivePackets(NumPacketsToSend, NumPacketsToSend + 1, int.MaxValue, 2, PacketSize, PacketCommunicatorReceiveResult.None, NumPacketsToSend, 2, 2.035); TestReceivePackets(NumPacketsToSend, NumPacketsToSend + 1, int.MaxValue, 2, PacketSize, PacketCommunicatorReceiveResult.None, NumPacketsToSend, 2, 2.035);
// Break loop // Break loop
TestReceivePackets(NumPacketsToSend, NumPacketsToSend, 0, 2, PacketSize, PacketCommunicatorReceiveResult.BreakLoop, 0, 0, 0.02); TestReceivePackets(NumPacketsToSend, NumPacketsToSend, 0, 2, PacketSize, PacketCommunicatorReceiveResult.BreakLoop, 0, 0, 0.027);
TestReceivePackets(NumPacketsToSend, NumPacketsToSend, NumPacketsToSend / 2, 2, PacketSize, PacketCommunicatorReceiveResult.BreakLoop, NumPacketsToSend / 2, 0, 0.02); TestReceivePackets(NumPacketsToSend, NumPacketsToSend, NumPacketsToSend / 2, 2, PacketSize, PacketCommunicatorReceiveResult.BreakLoop, NumPacketsToSend / 2, 0, 0.02);
} }
...@@ -148,11 +149,11 @@ namespace PcapDotNet.Core.Test ...@@ -148,11 +149,11 @@ namespace PcapDotNet.Core.Test
TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend, int.MaxValue, 2, PacketSize, NumPacketsToSend, 0, 0.3); TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend, int.MaxValue, 2, PacketSize, NumPacketsToSend, 0, 0.3);
// Wait for less packets // Wait for less packets
TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend / 2, int.MaxValue, 2, PacketSize, NumPacketsToSend / 2, 0, 0.02); TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend / 2, int.MaxValue, 2, PacketSize, NumPacketsToSend / 2, 0, 0.027);
// Wait for more packets // Wait for more packets
TestReceivePacketsEnumerable(NumPacketsToSend, -1, int.MaxValue, 2, PacketSize, NumPacketsToSend, 2, 2.02); TestReceivePacketsEnumerable(NumPacketsToSend, -1, int.MaxValue, 2, PacketSize, NumPacketsToSend, 2, 2.02);
TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend + 1, int.MaxValue, 2, PacketSize, NumPacketsToSend, 2, 2.03); TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend + 1, int.MaxValue, 2, PacketSize, NumPacketsToSend, 2, 2.13);
// Break loop // Break loop
TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend, 0, 2, PacketSize, 0, 0, 0.02); TestReceivePacketsEnumerable(NumPacketsToSend, NumPacketsToSend, 0, 2, PacketSize, 0, 0, 0.02);
...@@ -538,6 +539,9 @@ namespace PcapDotNet.Core.Test ...@@ -538,6 +539,9 @@ namespace PcapDotNet.Core.Test
communicator.SetFilter("ether src " + sourceMac + " and ether dst " + destinationMac); communicator.SetFilter("ether src " + sourceMac + " and ether dst " + destinationMac);
communicator.SetSamplingMethod(new SamplingMethodFirstAfterInterval(TimeSpan.FromSeconds(1))); communicator.SetSamplingMethod(new SamplingMethodFirstAfterInterval(TimeSpan.FromSeconds(1)));
Packet expectedPacket = _random.NextEthernetPacket(60, sourceMac, destinationMac); Packet expectedPacket = _random.NextEthernetPacket(60, sourceMac, destinationMac);
List<Packet> packets = new List<Packet>(6);
Thread thread = new Thread(() => packets.AddRange(communicator.ReceivePackets(6)));
thread.Start();
communicator.SendPacket(expectedPacket); communicator.SendPacket(expectedPacket);
Thread.Sleep(TimeSpan.FromSeconds(0.75)); Thread.Sleep(TimeSpan.FromSeconds(0.75));
for (int i = 0; i != 10; ++i) for (int i = 0; i != 10; ++i)
...@@ -547,15 +551,18 @@ namespace PcapDotNet.Core.Test ...@@ -547,15 +551,18 @@ namespace PcapDotNet.Core.Test
Thread.Sleep(TimeSpan.FromSeconds(0.5)); Thread.Sleep(TimeSpan.FromSeconds(0.5));
} }
if (!thread.Join(TimeSpan.FromSeconds(10)))
thread.Abort();
Assert.AreEqual(6, packets.Count);
Packet packet; Packet packet;
PacketCommunicatorReceiveResult result;
for (int i = 0; i != 6; ++i) for (int i = 0; i != 6; ++i)
{ {
result = communicator.ReceivePacket(out packet); // result = communicator.ReceivePacket(out packet);
Assert.AreEqual(PacketCommunicatorReceiveResult.Ok, result); // Assert.AreEqual(PacketCommunicatorReceiveResult.Ok, result);
Assert.AreEqual(60 * (i * 2 + 1), packet.Length); // Assert.AreEqual(60 * (i * 2 + 1), packet.Length, i.ToString());
Assert.AreEqual(60 * (i * 2 + 1), packets[i].Length, i.ToString());
} }
result = communicator.ReceivePacket(out packet); PacketCommunicatorReceiveResult result = communicator.ReceivePacket(out packet);
Assert.AreEqual(PacketCommunicatorReceiveResult.Timeout, result); Assert.AreEqual(PacketCommunicatorReceiveResult.Timeout, result);
Assert.IsNull(packet); Assert.IsNull(packet);
} }
...@@ -601,6 +608,26 @@ namespace PcapDotNet.Core.Test ...@@ -601,6 +608,26 @@ namespace PcapDotNet.Core.Test
} }
} }
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void SetInvalidDataLink()
{
using (PacketCommunicator communicator = OpenLiveDevice())
{
communicator.DataLink = new PcapDataLink(0);
Assert.AreEqual(new PcapDataLink(0), communicator.DataLink);
}
}
[TestMethod]
public void SendZeroPacket()
{
using (PacketCommunicator communicator = OpenLiveDevice())
{
communicator.SendPacket(new Packet(new byte[0], DateTime.Now, DataLinkKind.Ethernet));
}
}
private static void TestGetStatistics(string sourceMac, string destinationMac, int numPacketsToSend, int numStatisticsToGather, int numStatisticsToBreakLoop, double secondsToWait, int packetSize, private static void TestGetStatistics(string sourceMac, string destinationMac, int numPacketsToSend, int numStatisticsToGather, int numStatisticsToBreakLoop, double secondsToWait, int packetSize,
PacketCommunicatorReceiveResult expectedResult, int expectedNumStatistics, int expectedNumPackets, double expectedMinSeconds, double expectedMaxSeconds) PacketCommunicatorReceiveResult expectedResult, int expectedNumStatistics, int expectedNumPackets, double expectedMinSeconds, double expectedMaxSeconds)
{ {
...@@ -817,7 +844,9 @@ namespace PcapDotNet.Core.Test ...@@ -817,7 +844,9 @@ namespace PcapDotNet.Core.Test
Assert.AreNotEqual(null, totalStatistics); Assert.AreNotEqual(null, totalStatistics);
Assert.AreEqual(totalStatistics.GetHashCode(), totalStatistics.GetHashCode()); Assert.AreEqual(totalStatistics.GetHashCode(), totalStatistics.GetHashCode());
Assert.IsTrue(totalStatistics.Equals(totalStatistics)); Assert.IsTrue(totalStatistics.Equals(totalStatistics));
Assert.IsFalse(totalStatistics.Equals(null));
Assert.AreNotEqual(null, totalStatistics); Assert.AreNotEqual(null, totalStatistics);
Assert.AreNotEqual(totalStatistics, 2);
MoreAssert.IsSmallerOrEqual<uint>(1, totalStatistics.PacketsCaptured, "PacketsCaptured"); MoreAssert.IsSmallerOrEqual<uint>(1, totalStatistics.PacketsCaptured, "PacketsCaptured");
Assert.AreEqual<uint>(0, totalStatistics.PacketsDroppedByDriver, "PacketsDroppedByDriver"); Assert.AreEqual<uint>(0, totalStatistics.PacketsDroppedByDriver, "PacketsDroppedByDriver");
Assert.AreEqual<uint>(0, totalStatistics.PacketsDroppedByInterface, "PacketsDroppedByInterface"); Assert.AreEqual<uint>(0, totalStatistics.PacketsDroppedByInterface, "PacketsDroppedByInterface");
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Threading; using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using PcapDotNet.Packets; using PcapDotNet.Packets;
......
...@@ -115,10 +115,14 @@ namespace PcapDotNet.Core.Test ...@@ -115,10 +115,14 @@ namespace PcapDotNet.Core.Test
dataLinkName = dataLink.Name; dataLinkName = dataLink.Name;
Assert.IsNotNull(dataLinkName); Assert.IsNotNull(dataLinkName);
} }
catch (ArgumentException) catch (InvalidOperationException)
{ {
return dataLink; return dataLink;
} }
catch (Exception)
{
Assert.Fail();
}
} }
Assert.Fail(); Assert.Fail();
return new PcapDataLink(); return new PcapDataLink();
......
...@@ -182,10 +182,20 @@ namespace PcapDotNet.Core.Test ...@@ -182,10 +182,20 @@ namespace PcapDotNet.Core.Test
private static void ComparePacketsToWireshark(IEnumerable<Packet> packets) private static void ComparePacketsToWireshark(IEnumerable<Packet> packets)
{ {
string pcapFilename = Path.GetTempPath() + "temp." + new Random().NextByte() + ".pcap"; string pcapFilename = Path.GetTempPath() + "temp." + new Random().NextByte() + ".pcap";
PacketDumpFile.Dump(pcapFilename, new PcapDataLink(DataLinkKind.Ethernet), PacketDevice.DefaultSnapshotLength, packets); // const bool isRetry = true;
// List<Packet> packetsList = new List<Packet>(); const bool isRetry = false;
// new OfflinePacketDevice(pcapFilename).Open().ReceivePackets(1000, packetsList.Add); if (!isRetry)
// packets = packetsList; {
PacketDumpFile.Dump(pcapFilename, new PcapDataLink(DataLinkKind.Ethernet), PacketDevice.DefaultSnapshotLength, packets);
}
else
{
const byte retryNumber = 24;
pcapFilename = Path.GetTempPath() + "temp." + retryNumber + ".pcap";
List<Packet> packetsList = new List<Packet>();
new OfflinePacketDevice(pcapFilename).Open().ReceivePackets(1000, packetsList.Add);
packets = packetsList;
}
// Create pdml file // Create pdml file
string documentFilename = pcapFilename + ".pdml"; string documentFilename = pcapFilename + ".pdml";
......
...@@ -101,40 +101,5 @@ namespace PcapDotNet.Packets.Test ...@@ -101,40 +101,5 @@ namespace PcapDotNet.Packets.Test
Assert.AreEqual(0x02, buffer[2]); Assert.AreEqual(0x02, buffer[2]);
Assert.AreEqual(0x01, buffer[3]); Assert.AreEqual(0x01, buffer[3]);
} }
[TestMethod]
public void UInt48Test()
{
UInt48 value = (UInt48)0x010203040506;
byte[] buffer = new byte[UInt48.SizeOf];
buffer.Write(0, value, Endianity.Big);
Assert.AreEqual(value, buffer.ReadUInt48(0, Endianity.Big));
Assert.AreEqual(0x01, buffer[0]);
Assert.AreEqual(0x02, buffer[1]);
Assert.AreEqual(0x03, buffer[2]);
Assert.AreEqual(0x04, buffer[3]);
Assert.AreEqual(0x05, buffer[4]);
Assert.AreEqual(0x06, buffer[5]);
int offset = 0;
buffer.Write(ref offset, value, Endianity.Big);
Assert.AreEqual(value, buffer.ReadUInt48(0, Endianity.Big));
Assert.AreEqual(6, offset);
buffer.Write(0, value, Endianity.Small);
Assert.AreEqual(value, buffer.ReadUInt48(0, Endianity.Small));
Assert.AreEqual(0x06, buffer[0]);
Assert.AreEqual(0x05, buffer[1]);
Assert.AreEqual(0x04, buffer[2]);
Assert.AreEqual(0x03, buffer[3]);
Assert.AreEqual(0x02, buffer[4]);
Assert.AreEqual(0x01, buffer[5]);
offset = 0;
buffer.Write(ref offset, value, Endianity.Small);
Assert.AreEqual(value, buffer.ReadUInt48(0, Endianity.Small));
Assert.AreEqual(6, offset);
}
} }
} }
\ No newline at end of file
...@@ -3,7 +3,7 @@ using System.Linq; ...@@ -3,7 +3,7 @@ using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using PcapDotNet.Packets.Ethernet; using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.TestUtils; using PcapDotNet.Packets.TestUtils;
using PcapDotNet.TestUtils; using PcapDotNet.Packets.Transport;
namespace PcapDotNet.Packets.Test namespace PcapDotNet.Packets.Test
{ {
...@@ -77,5 +77,21 @@ namespace PcapDotNet.Packets.Test ...@@ -77,5 +77,21 @@ namespace PcapDotNet.Packets.Test
Assert.AreEqual(payloadLayer.Data, packet.Ethernet.Payload); Assert.AreEqual(payloadLayer.Data, packet.Ethernet.Payload);
} }
} }
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void AutomaticEthernetTypeNoNextLayer()
{
Packet packet = PacketBuilder.Build(DateTime.Now, new EthernetLayer());
Assert.IsTrue(packet.IsValid);
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void AutomaticEthernetTypeBadNextLayer()
{
Packet packet = PacketBuilder.Build(DateTime.Now, new EthernetLayer(), new TcpLayer());
Assert.IsTrue(packet.IsValid);
}
} }
} }
\ No newline at end of file
...@@ -136,6 +136,7 @@ namespace PcapDotNet.Packets.Test ...@@ -136,6 +136,7 @@ namespace PcapDotNet.Packets.Test
foreach (GreSourceRouteEntry entry in actualGre.Routing) foreach (GreSourceRouteEntry entry in actualGre.Routing)
{ {
Assert.AreNotEqual(entry, 2); Assert.AreNotEqual(entry, 2);
Assert.AreEqual(entry.GetHashCode(), entry.GetHashCode());
switch (entry.AddressFamily) switch (entry.AddressFamily)
{ {
case GreSourceRouteEntryAddressFamily.AsSourceRoute: case GreSourceRouteEntryAddressFamily.AsSourceRoute:
...@@ -179,6 +180,29 @@ namespace PcapDotNet.Packets.Test ...@@ -179,6 +180,29 @@ namespace PcapDotNet.Packets.Test
} }
} }
[TestMethod]
public void GreAutomaticProtocolType()
{
Packet packet = PacketBuilder.Build(DateTime.Now, new EthernetLayer(), new IpV4Layer(), new GreLayer(), new IpV4Layer(), new IcmpEchoLayer());
Assert.IsTrue(packet.IsValid);
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void GreAutomaticProtocolTypeNoNextLayer()
{
Packet packet = PacketBuilder.Build(DateTime.Now, new EthernetLayer(), new IpV4Layer(), new GreLayer());
Assert.IsTrue(packet.IsValid);
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void GreAutomaticProtocolTypeBadNextLayer()
{
Packet packet = PacketBuilder.Build(DateTime.Now, new EthernetLayer(), new IpV4Layer(), new GreLayer(), new PayloadLayer());
Assert.IsTrue(packet.IsValid);
}
[TestMethod] [TestMethod]
public void InvalidGreTest() public void InvalidGreTest()
{ {
...@@ -204,7 +228,7 @@ namespace PcapDotNet.Packets.Test ...@@ -204,7 +228,7 @@ namespace PcapDotNet.Packets.Test
PacketBuilder packetBuilder = new PacketBuilder(ethernetLayer, ipV4Layer, greLayer); PacketBuilder packetBuilder = new PacketBuilder(ethernetLayer, ipV4Layer, greLayer);
Packet packet = packetBuilder.Build(DateTime.Now); Packet packet = packetBuilder.Build(DateTime.Now);
Assert.IsTrue(packet.IsValid); Assert.IsTrue(packet.IsValid, "IsValid");
GreDatagram gre = packet.Ethernet.IpV4.Gre; GreDatagram gre = packet.Ethernet.IpV4.Gre;
......
...@@ -138,7 +138,18 @@ namespace PcapDotNet.Packets.Gre ...@@ -138,7 +138,18 @@ namespace PcapDotNet.Packets.Gre
/// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param> /// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param>
public override void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer) public override void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer)
{ {
GreDatagram.WriteHeader(buffer, offset, RecursionControl, FutureUseBits, Version, ProtocolType, ChecksumPresent, Key, SequenceNumber, AcknowledgmentSequenceNumber, Routing, RoutingOffset, StrictSourceRoute); EthernetType protocolType = ProtocolType;
if (protocolType == EthernetType.None)
{
if (nextLayer == null)
throw new ArgumentException("Can't determine protocol type automatically from next layer because there is not next layer");
IEthernetNextLayer ethernetNextLayer = nextLayer as IEthernetNextLayer;
if (ethernetNextLayer == null)
throw new ArgumentException("Can't determine protocol type automatically from next layer (" + nextLayer.GetType() + ")");
protocolType = ethernetNextLayer.PreviousLayerEtherType;
}
GreDatagram.WriteHeader(buffer, offset, RecursionControl, FutureUseBits, Version, protocolType, ChecksumPresent, Key, SequenceNumber, AcknowledgmentSequenceNumber, Routing, RoutingOffset, StrictSourceRoute);
} }
/// <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