Commit b12c6b77 authored by Brickner_cp's avatar Brickner_cp

IPv6.

Rafactored Options so it can be used for IPv6 options.
Moved general options classes to a new PcapDotNet.Packets.Ip namespace.
Upgrade to Resharper 7.
parent a399a230
<Configuration>
<CodeStyleSettings>
<ExternalPath IsNull="False">
</ExternalPath>
<Sharing>SOLUTION</Sharing>
<CSharp>
<FormatSettings>
<ANONYMOUS_METHOD_DECLARATION_BRACES>NEXT_LINE</ANONYMOUS_METHOD_DECLARATION_BRACES>
<CASE_BLOCK_BRACES>NEXT_LINE</CASE_BLOCK_BRACES>
<INITIALIZER_BRACES>NEXT_LINE</INITIALIZER_BRACES>
<MODIFIERS_ORDER IsNull="False">
<Item>public</Item>
<Item>protected</Item>
<Item>internal</Item>
<Item>private</Item>
<Item>new</Item>
<Item>abstract</Item>
<Item>virtual</Item>
<Item>override</Item>
<Item>sealed</Item>
<Item>static</Item>
<Item>readonly</Item>
<Item>extern</Item>
<Item>unsafe</Item>
<Item>volatile</Item>
</MODIFIERS_ORDER>
<SPACE_AFTER_TYPECAST_PARENTHESES>False</SPACE_AFTER_TYPECAST_PARENTHESES>
<SPACE_AROUND_MULTIPLICATIVE_OP>True</SPACE_AROUND_MULTIPLICATIVE_OP>
<SPACE_BEFORE_SIZEOF_PARENTHESES>False</SPACE_BEFORE_SIZEOF_PARENTHESES>
<SPACE_BEFORE_TYPEOF_PARENTHESES>False</SPACE_BEFORE_TYPEOF_PARENTHESES>
<WRAP_LIMIT>160</WRAP_LIMIT>
</FormatSettings>
<UsingsSettings />
<Naming2>
<EventHandlerPatternLong>$object$_On$event$</EventHandlerPatternLong>
<EventHandlerPatternShort>$event$Handler</EventHandlerPatternShort>
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="TypesAndNamespaces" />
<PredefinedRule Inspect="True" Prefix="I" Suffix="" Style="AaBb" ElementKind="Interfaces" />
<PredefinedRule Inspect="True" Prefix="T" Suffix="" Style="AaBb" ElementKind="TypeParameters" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="MethodPropertyEvent" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="aaBb" ElementKind="Locals" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="aaBb" ElementKind="LocalConstants" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="aaBb" ElementKind="Parameters" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="PublicFields" />
<PredefinedRule Inspect="True" Prefix="_" Suffix="" Style="aaBb" ElementKind="PrivateInstanceFields" />
<PredefinedRule Inspect="True" Prefix="_" Suffix="" Style="aaBb" ElementKind="PrivateStaticFields" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="Constants" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="PrivateConstants" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="StaticReadonly" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="PrivateStaticReadonly" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="EnumMember" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="Other" />
</Naming2>
</CSharp>
<VB>
<FormatSettings />
<ImportsSettings />
<Naming2>
<EventHandlerPatternLong>$object$_On$event$</EventHandlerPatternLong>
<EventHandlerPatternShort>$event$Handler</EventHandlerPatternShort>
</Naming2>
</VB>
<Web>
<Naming2 />
</Web>
<Xaml>
<Naming2 />
</Xaml>
<XML>
<FormatSettings />
</XML>
<GenerateMemberBody />
<Naming2>
<EventHandlerPatternLong>$object$_On$event$</EventHandlerPatternLong>
<EventHandlerPatternShort>$event$Handler</EventHandlerPatternShort>
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="aaBb" ElementKind="Parameters" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="TypesAndNamespaces" />
<PredefinedRule Inspect="True" Prefix="I" Suffix="" Style="AaBb" ElementKind="Interfaces" />
<PredefinedRule Inspect="True" Prefix="T" Suffix="" Style="AaBb" ElementKind="TypeParameters" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="MethodPropertyEvent" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="aaBb" ElementKind="Locals" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="LocalConstants" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="PublicFields" />
<PredefinedRule Inspect="True" Prefix="_" Suffix="" Style="aaBb" ElementKind="PrivateInstanceFields" />
<PredefinedRule Inspect="True" Prefix="_" Suffix="" Style="aaBb" ElementKind="PrivateStaticFields" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="Constants" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="PrivateConstants" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="StaticReadonly" />
<PredefinedRule Inspect="True" Prefix="_" Suffix="" Style="aaBb" ElementKind="PrivateStaticReadonly" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="EnumMember" />
<PredefinedRule Inspect="True" Prefix="" Suffix="" Style="AaBb" ElementKind="Other" />
</Naming2>
</CodeStyleSettings>
</Configuration>
\ No newline at end of file
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Ip
{
public interface IIpOptionQuickStart
{
/// <summary>
/// The function of this quick start option.
/// </summary>
IpV4OptionQuickStartFunction Function { get; }
/// <summary>
/// If function is request then this field is the rate request.
/// If function is report then this field is the rate report.
/// </summary>
byte Rate { get; }
/// <summary>
/// The rate translated to KBPS.
/// </summary>
int RateKbps { get; }
/// <summary>
/// The Quick-Start TTL (QS TTL) field.
/// The sender MUST set the QS TTL field to a random value.
/// Routers that approve the Quick-Start Request decrement the QS TTL (mod 256) by the same amount that they decrement the IP TTL.
/// The QS TTL is used by the sender to detect if all the routers along the path understood and approved the Quick-Start option.
///
/// <para>
/// For a Rate Request, the transport sender MUST calculate and store the TTL Diff,
/// the difference between the IP TTL value, and the QS TTL value in the Quick-Start Request packet, as follows:
/// TTL Diff = ( IP TTL - QS TTL ) mod 256
/// </para>
/// </summary>
byte Ttl { get; }
/// <summary>
/// The QS Nonce gives the Quick-Start sender some protection against receivers lying about the value of the received Rate Request.
/// This is particularly important if the receiver knows the original value of the Rate Request
/// (e.g., when the sender always requests the same value, and the receiver has a long history of communication with that sender).
/// Without the QS Nonce, there is nothing to prevent the receiver from reporting back to the sender a Rate Request of K,
/// when the received Rate Request was, in fact, less than K.
///
/// <para>
/// The format for the 30-bit QS Nonce.
/// <list type="table">
/// <listheader>
/// <term>Bits</term>
/// <description>Purpose</description>
/// </listheader>
/// <item><term>Bits 0-1</term><description>Rate 15 -> Rate 14</description></item>
/// <item><term>Bits 2-3</term><description>Rate 14 -> Rate 13</description></item>
/// <item><term>Bits 4-5</term><description>Rate 13 -> Rate 12</description></item>
/// <item><term>Bits 6-7</term><description>Rate 12 -> Rate 11</description></item>
/// <item><term>Bits 8-9</term><description>Rate 11 -> Rate 10</description></item>
/// <item><term>Bits 10-11</term><description>Rate 10 -> Rate 9</description></item>
/// <item><term>Bits 12-13</term><description>Rate 9 -> Rate 8</description></item>
/// <item><term>Bits 14-15</term><description>Rate 8 -> Rate 7</description></item>
/// <item><term>Bits 16-17</term><description>Rate 7 -> Rate 6</description></item>
/// <item><term>Bits 18-19</term><description>Rate 6 -> Rate 5</description></item>
/// <item><term>Bits 20-21</term><description>Rate 5 -> Rate 4</description></item>
/// <item><term>Bits 22-23</term><description>Rate 4 -> Rate 3</description></item>
/// <item><term>Bits 24-25</term><description>Rate 3 -> Rate 2</description></item>
/// <item><term>Bits 26-27</term><description>Rate 2 -> Rate 1</description></item>
/// <item><term>Bits 28-29</term><description>Rate 1 -> Rate 0</description></item>
/// </list>
/// </para>
///
/// <para>
/// The transport sender MUST initialize the QS Nonce to a random value.
/// If the router reduces the Rate Request from rate K to rate K-1,
/// then the router MUST set the field in the QS Nonce for "Rate K -> Rate K-1" to a new random value.
/// Similarly, if the router reduces the Rate Request by N steps,
/// the router MUST set the 2N bits in the relevant fields in the QS Nonce to a new random value.
/// The receiver MUST report the QS Nonce back to the sender.
/// </para>
///
/// <para>
/// If the Rate Request was not decremented in the network, then the QS Nonce should have its original value.
/// Similarly, if the Rate Request was decremented by N steps in the network,
/// and the receiver reports back a Rate Request of K, then the last 2K bits of the QS Nonce should have their original value.
/// </para>
/// </summary>
uint Nonce { get; }
}
}
\ No newline at end of file
namespace PcapDotNet.Packets namespace PcapDotNet.Packets.Ip
{ {
/// <summary> /// <summary>
/// This interface is used to create all complex options. /// This interface is used to create all complex options.
......
namespace PcapDotNet.Packets namespace PcapDotNet.Packets.Ip
{ {
/// <summary> /// <summary>
/// A factory interface for an unknown option. /// A factory interface for an unknown option.
......
using System;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Ip
{
internal static class IpOptionQuickStartCommon
{
public const int DataLength = 6;
/// <summary>
/// The maximum value for the rate field.
/// </summary>
public const byte RateMaximumValue = 0x0F;
private static class Offset
{
public const int Function = 0;
public const int Rate = Function;
public const int Ttl = Rate + sizeof(byte);
public const int Nonce = Ttl + sizeof(byte);
}
private static class Mask
{
public const byte Function = 0xF0;
public const byte Rate = 0x0F;
}
public static void AssertValidParameters(IpV4OptionQuickStartFunction function, byte rate, byte ttl, uint nonce)
{
if (function != IpV4OptionQuickStartFunction.RateRequest &&
function != IpV4OptionQuickStartFunction.RateReport)
{
throw new ArgumentException("Illegal function " + function, "function");
}
if (rate > RateMaximumValue)
throw new ArgumentOutOfRangeException("rate", rate, "Rate maximum value is " + RateMaximumValue);
if ((nonce & 0x00000003) != 0)
throw new ArgumentException("nonce last two bits are reserved and must be zero", "nonce");
}
public static int CalcRateKbps(byte rate)
{
if (rate == 0)
return 0;
return 40*(1 << rate);
}
public static void ReadData(DataSegment data, out IpV4OptionQuickStartFunction function, out byte rate, out byte ttl, out uint nonce)
{
function = (IpV4OptionQuickStartFunction)(data[Offset.Function] & Mask.Function);
rate = (byte)(data[Offset.Rate] & Mask.Rate);
ttl = data[Offset.Ttl];
nonce = data.ReadUInt(Offset.Nonce, Endianity.Big);
}
public 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.Ttl] = ttl;
buffer.Write(offset + Offset.Nonce, nonce, Endianity.Big);
offset += DataLength;
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets namespace PcapDotNet.Packets.Ip
{ {
/// <summary> /// <summary>
/// A generic option (for IPv4 and TCP). /// A generic option (for IPv4, IPv6 and TCP).
/// The option is read from buffer and can be of different length. /// The option is read from buffer and can be of different length.
/// </summary> /// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Option")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Option")]
...@@ -12,19 +12,6 @@ namespace PcapDotNet.Packets ...@@ -12,19 +12,6 @@ namespace PcapDotNet.Packets
/// </summary> /// </summary>
public abstract int Length { get; } public abstract int Length { get; }
/// <summary>
/// True iff this option may appear at most once in a datagram.
/// </summary>
public abstract bool IsAppearsAtMostOnce { get; }
/// <summary>
/// Checks whether two options have equivalent type.
/// Useful to check if an option that must appear at most once appears in the list.
/// </summary>
public abstract bool Equivalent(Option other);
internal abstract Option Read(byte[] buffer, ref int offset, int length);
internal abstract void Write(byte[] buffer, ref int offset); internal abstract void Write(byte[] buffer, ref int offset);
} }
} }
\ No newline at end of file
...@@ -4,7 +4,7 @@ using System.Linq; ...@@ -4,7 +4,7 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using PcapDotNet.Base; using PcapDotNet.Base;
namespace PcapDotNet.Packets namespace PcapDotNet.Packets.Ip
{ {
internal static class OptionComplexFactory<TOptionType> internal static class OptionComplexFactory<TOptionType>
{ {
......
using System;
namespace PcapDotNet.Packets.Ip
{
internal abstract class OptionTypeRegistrationAttribute : Attribute
{
public abstract object OptionType { get; }
public abstract Type OptionTypeType { get; }
}
}
\ No newline at end of file
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using PcapDotNet.Base; using PcapDotNet.Base;
namespace PcapDotNet.Packets namespace PcapDotNet.Packets.Ip
{ {
/// <summary> /// <summary>
/// A generic Options class. /// A generic Options class.
/// Represents a list of options (either IPv4 options or TCP options). /// Represents a list of options (either IPv4 options, IPv6 options or TCP options).
/// </summary> /// </summary>
/// <typeparam name="T">The Option type this collection contains.</typeparam> /// <typeparam name="T">The Option type this collection contains.</typeparam>
public abstract class Options<T> where T : Option public abstract class Options<T> where T : Option
...@@ -88,12 +87,6 @@ namespace PcapDotNet.Packets ...@@ -88,12 +87,6 @@ namespace PcapDotNet.Packets
return OptionsCollection.SequenceToString(", ", GetType().Name + " {", "}"); return OptionsCollection.SequenceToString(", ", GetType().Name + " {", "}");
} }
internal Options(byte[] buffer, int offset, int length, T end)
: this(Read(buffer, offset, length, end))
{
BytesLength = length;
}
internal void Write(byte[] buffer, int offset) internal void Write(byte[] buffer, int offset)
{ {
int offsetEnd = offset + BytesLength; int offsetEnd = offset + BytesLength;
...@@ -105,66 +98,30 @@ namespace PcapDotNet.Packets ...@@ -105,66 +98,30 @@ namespace PcapDotNet.Packets
buffer[offset++] = 0; buffer[offset++] = 0;
} }
internal Options(IList<T> options, T end, int maximumBytesLength) internal Options(IList<T> options, bool isValid, int? length)
: this(EndOptions(options, end), true)
{
if (BytesLength > maximumBytesLength)
throw new ArgumentException("given options take " + BytesLength + " bytes and maximum number of bytes for options is " + maximumBytesLength, "options");
}
private Options(IList<T> options, bool isValid)
{ {
_options = options.AsReadOnly(); _options = options.AsReadOnly();
IsValid = isValid; IsValid = isValid;
BytesLength = SumBytesLength(OptionsCollection); if (length.HasValue)
{
if (BytesLength % 4 != 0) BytesLength = length.Value;
BytesLength = (BytesLength / 4 + 1) * 4; }
} else
{
private static IList<T> EndOptions(IList<T> options, T end) BytesLength = SumBytesLength(OptionsCollection);
{
if (options.Count == 0 || options.Last().Equivalent(end) || SumBytesLength(options) % 4 == 0)
return options;
return new List<T>(options.Concat(end)); if (BytesLength % 4 != 0)
BytesLength = (BytesLength / 4 + 1) * 4;
}
} }
private static int SumBytesLength(IEnumerable<T> options) internal static int SumBytesLength(IEnumerable<T> options)
{ {
return options.Sum(option => option.Length); return options.Sum(option => option.Length);
} }
private Options(Tuple<IList<T>, bool> optionsAndIsValid)
: this(optionsAndIsValid.Item1, optionsAndIsValid.Item2)
{
}
private static Tuple<IList<T>, bool> Read(byte[] buffer, int offset, int length, T end)
{
int offsetEnd = offset + length;
List<T> options = new List<T>();
while (offset != offsetEnd)
{
T option = (T)end.Read(buffer, ref offset, offsetEnd - offset);
if (option == null ||
option.IsAppearsAtMostOnce && options.Any(option.Equivalent))
{
// Invalid
return new Tuple<IList<T>, bool>(options, false);
}
options.Add(option);
if (option.Equivalent(end))
break; // Valid?
}
return new Tuple<IList<T>, bool>(options, true);
}
private readonly ReadOnlyCollection<T> _options; private readonly ReadOnlyCollection<T> _options;
} }
} }
\ No newline at end of file
namespace PcapDotNet.Packets.Ip
{
public abstract class V4Option : Option
{
/// <summary>
/// True iff this option may appear at most once in a datagram.
/// </summary>
public abstract bool IsAppearsAtMostOnce { get; }
/// <summary>
/// Checks whether two options have equivalent type.
/// Useful to check if an option that must appear at most once appears in the list.
/// </summary>
public abstract bool Equivalent(Option other);
internal abstract V4Option Read(byte[] buffer, ref int offset, int length);
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using PcapDotNet.Base;
namespace PcapDotNet.Packets.Ip
{
public abstract class V4Options<T> : Options<T> where T : V4Option
{
internal V4Options(byte[] buffer, int offset, int length, T end)
: this(Read(buffer, offset, length, end), length)
{
}
internal V4Options(IList<T> options, T end, int maximumBytesLength)
: this(EndOptions(options, end), true, null)
{
if (BytesLength > maximumBytesLength)
throw new ArgumentException("given options take " + BytesLength + " bytes and maximum number of bytes for options is " + maximumBytesLength, "options");
}
private V4Options(Tuple<IList<T>, bool> optionsAndIsValid, int? length)
: this(optionsAndIsValid.Item1, optionsAndIsValid.Item2, length)
{
}
private V4Options(IList<T> options, bool isValid, int? length)
:base(options, isValid, length)
{
}
private static Tuple<IList<T>, bool> Read(byte[] buffer, int offset, int length, T end)
{
int offsetEnd = offset + length;
List<T> options = new List<T>();
while (offset != offsetEnd)
{
T option = (T)end.Read(buffer, ref offset, offsetEnd - offset);
if (option == null ||
option.IsAppearsAtMostOnce && options.Any(option.Equivalent))
{
// Invalid
return new Tuple<IList<T>, bool>(options, false);
}
options.Add(option);
if (option.Equivalent(end))
break; // Valid?
}
return new Tuple<IList<T>, bool>(options, true);
}
private static IList<T> EndOptions(IList<T> options, T end)
{
if (options.Count == 0 || options.Last().Equivalent(end) || SumBytesLength(options) % 4 == 0)
return options;
return new List<T>(options.Concat(end));
}
}
}
\ No newline at end of file
using System; using System;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.IpV4 namespace PcapDotNet.Packets.IpV4
{ {
/// <summary> /// <summary>
/// Represents an ip option according to rfc 791. /// Represents an ip option according to rfc 791.
/// </summary> /// </summary>
public abstract class IpV4Option : Option, IEquatable<IpV4Option> public abstract class IpV4Option : V4Option, IEquatable<IpV4Option>
{ {
///<summary> ///<summary>
/// This option indicates the end of the option list.<br/> /// This option indicates the end of the option list.<br/>
...@@ -28,7 +29,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -28,7 +29,7 @@ namespace PcapDotNet.Packets.IpV4
} }
/// <summary> /// <summary>
/// The type of the ip option. /// The type of the IP option.
/// </summary> /// </summary>
public IpV4OptionType OptionType public IpV4OptionType OptionType
{ {
...@@ -79,7 +80,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -79,7 +80,7 @@ namespace PcapDotNet.Packets.IpV4
return OptionType.ToString(); return OptionType.ToString();
} }
internal sealed override Option Read(byte[] buffer, ref int offset, int length) internal sealed override V4Option Read(byte[] buffer, ref int offset, int length)
{ {
int offsetEnd = offset + length; int offsetEnd = offset + length;
if (offset == offsetEnd) if (offset == offsetEnd)
...@@ -94,7 +95,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -94,7 +95,7 @@ namespace PcapDotNet.Packets.IpV4
return Nop; return Nop;
default: default:
return OptionComplexFactory<IpV4OptionType>.Read(optionType, buffer, ref offset, offsetEnd - offset); return (V4Option)OptionComplexFactory<IpV4OptionType>.Read(optionType, buffer, ref offset, offsetEnd - offset);
} }
} }
......
using System; using System;
using PcapDotNet.Base; using PcapDotNet.Base;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.IpV4 namespace PcapDotNet.Packets.IpV4
{ {
...@@ -40,7 +41,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -40,7 +41,7 @@ namespace PcapDotNet.Packets.IpV4
/// </pre> /// </pre>
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.BasicSecurity)] [IpV4OptionTypeRegistration(IpV4OptionType.BasicSecurity)]
public sealed class IpV4OptionBasicSecurity : IpV4OptionComplex, IOptionComplexFactory, IEquatable<IpV4OptionBasicSecurity> public sealed class IpV4OptionBasicSecurity : IpV4OptionComplex, IOptionComplexFactory, IEquatable<IpV4OptionBasicSecurity>
{ {
/// <summary> /// <summary>
......
using System.Collections.Generic; using System.Collections.Generic;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.IpV4 namespace PcapDotNet.Packets.IpV4
{ {
...@@ -56,7 +57,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -56,7 +57,7 @@ namespace PcapDotNet.Packets.IpV4
/// Appears at most once in a datagram. /// Appears at most once in a datagram.
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.LooseSourceRouting)] [IpV4OptionTypeRegistration(IpV4OptionType.LooseSourceRouting)]
public class IpV4OptionLooseSourceRouting : IpV4OptionRoute, IOptionComplexFactory public class IpV4OptionLooseSourceRouting : IpV4OptionRoute, IOptionComplexFactory
{ {
/// <summary> /// <summary>
......
using System; using System;
using PcapDotNet.Base; using PcapDotNet.Base;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.IpV4 namespace PcapDotNet.Packets.IpV4
{ {
/// <summary> /// <summary>
/// RFC 4782.
/// The Quick-Start Option for IPv4 /// The Quick-Start Option for IPv4
///
/// <para> /// <para>
/// The Quick-Start Request for IPv4 is defined as follows: /// The Quick-Start Request for IPv4 is defined as follows:
/// <pre> /// <pre>
...@@ -20,23 +21,23 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -20,23 +21,23 @@ namespace PcapDotNet.Packets.IpV4
/// </pre> /// </pre>
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.QuickStart)] [IpV4OptionTypeRegistration(IpV4OptionType.QuickStart)]
public sealed class IpV4OptionQuickStart : IpV4OptionComplex, IOptionComplexFactory, IEquatable<IpV4OptionQuickStart> public sealed class IpV4OptionQuickStart : IpV4OptionComplex, IIpOptionQuickStart, IOptionComplexFactory, IEquatable<IpV4OptionQuickStart>
{ {
/// <summary> /// <summary>
/// The number of bytes this option take. /// The number of bytes this option take.
/// </summary> /// </summary>
public const int OptionLength = 8; public const int OptionLength = OptionValueLength + OptionHeaderLength;
/// <summary> /// <summary>
/// The number of bytes this option's value take. /// The number of bytes this option's value take.
/// </summary> /// </summary>
public const int OptionValueLength = OptionLength - OptionHeaderLength; public const int OptionValueLength = IpOptionQuickStartCommon.DataLength;
/// <summary> /// <summary>
/// The maximum value for the rate field. /// The maximum value for the rate field.
/// </summary> /// </summary>
public const byte RateMaximumValue = 0x0F; public const byte RateMaximumValue = IpOptionQuickStartCommon.RateMaximumValue;
/// <summary> /// <summary>
/// Create a quick start option according to the given field values. /// Create a quick start option according to the given field values.
...@@ -55,22 +56,12 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -55,22 +56,12 @@ namespace PcapDotNet.Packets.IpV4
public IpV4OptionQuickStart(IpV4OptionQuickStartFunction function, byte rate, byte ttl, uint nonce) public IpV4OptionQuickStart(IpV4OptionQuickStartFunction function, byte rate, byte ttl, uint nonce)
: base(IpV4OptionType.QuickStart) : base(IpV4OptionType.QuickStart)
{ {
if (function != IpV4OptionQuickStartFunction.RateRequest && IpOptionQuickStartCommon.AssertValidParameters(function, rate, ttl, nonce);
function != IpV4OptionQuickStartFunction.RateReport)
{
throw new ArgumentException("Illegal function " + function, "function");
}
if (rate > RateMaximumValue) Function = function;
throw new ArgumentOutOfRangeException("rate", rate, "Rate maximum value is " + RateMaximumValue); Rate = rate;
Ttl = ttl;
if ((nonce & 0x00000003) != 0) Nonce = nonce;
throw new ArgumentException("nonce last two bits are reserved and must be zero", "nonce");
_function = function;
_rate = rate;
_ttl = ttl;
_nonce = nonce;
} }
/// <summary> /// <summary>
...@@ -84,32 +75,20 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -84,32 +75,20 @@ namespace PcapDotNet.Packets.IpV4
/// <summary> /// <summary>
/// The function of this quick start option. /// The function of this quick start option.
/// </summary> /// </summary>
public IpV4OptionQuickStartFunction Function public IpV4OptionQuickStartFunction Function { get; private set; }
{
get { return _function; }
}
/// <summary> /// <summary>
/// If function is request then this field is the rate request. /// If function is request then this field is the rate request.
/// If function is report then this field is the rate report. /// If function is report then this field is the rate report.
/// </summary> /// </summary>
public byte Rate public byte Rate { get; private set; }
{
get { return _rate; }
}
/// <summary> /// <summary>
/// The rate translated to KBPS. /// The rate translated to KBPS.
/// </summary> /// </summary>
public int RateKbps public int RateKbps
{ {
get get { return IpOptionQuickStartCommon.CalcRateKbps(Rate); }
{
if (Rate == 0)
return 0;
return 40 * (1 << Rate);
}
} }
/// <summary> /// <summary>
...@@ -124,10 +103,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -124,10 +103,7 @@ namespace PcapDotNet.Packets.IpV4
/// TTL Diff = ( IP TTL - QS TTL ) mod 256 /// TTL Diff = ( IP TTL - QS TTL ) mod 256
/// </para> /// </para>
/// </summary> /// </summary>
public byte Ttl public byte Ttl { get; private set; }
{
get { return _ttl; }
}
/// <summary> /// <summary>
/// The QS Nonce gives the Quick-Start sender some protection against receivers lying about the value of the received Rate Request. /// The QS Nonce gives the Quick-Start sender some protection against receivers lying about the value of the received Rate Request.
...@@ -176,10 +152,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -176,10 +152,7 @@ namespace PcapDotNet.Packets.IpV4
/// and the receiver reports back a Rate Request of K, then the last 2K bits of the QS Nonce should have their original value. /// and the receiver reports back a Rate Request of K, then the last 2K bits of the QS Nonce should have their original value.
/// </para> /// </para>
/// </summary> /// </summary>
public uint Nonce public uint Nonce { get; private set; }
{
get { return _nonce; }
}
/// <summary> /// <summary>
/// The number of bytes this option will take. /// The number of bytes this option will take.
...@@ -241,12 +214,12 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -241,12 +214,12 @@ namespace PcapDotNet.Packets.IpV4
if (valueLength != OptionValueLength) if (valueLength != OptionValueLength)
return null; return null;
byte functionAndRate = buffer[offset++]; IpV4OptionQuickStartFunction function;
IpV4OptionQuickStartFunction function = (IpV4OptionQuickStartFunction)(functionAndRate & 0xF0); byte rate;
byte rate = (byte)(functionAndRate & 0x0F); byte ttl;
uint nonce;
byte ttl = buffer[offset++]; IpOptionQuickStartCommon.ReadData(new DataSegment(buffer, offset, valueLength), out function, out rate, out ttl, out nonce);
uint nonce = buffer.ReadUInt(ref offset, Endianity.Big); offset += OptionValueLength;
return new IpV4OptionQuickStart(function, rate, ttl, nonce); return new IpV4OptionQuickStart(function, rate, ttl, nonce);
} }
...@@ -255,14 +228,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -255,14 +228,7 @@ namespace PcapDotNet.Packets.IpV4
{ {
base.Write(buffer, ref offset); base.Write(buffer, ref offset);
buffer[offset++] = (byte)((byte)Function | Rate); IpOptionQuickStartCommon.WriteData(buffer, ref offset, Function, Rate, Ttl, Nonce);
buffer[offset++] = Ttl;
buffer.Write(ref offset, Nonce, Endianity.Big);
} }
private readonly IpV4OptionQuickStartFunction _function;
private readonly byte _rate;
private readonly byte _ttl;
private readonly uint _nonce;
} }
} }
\ No newline at end of file
namespace PcapDotNet.Packets.IpV4 namespace PcapDotNet.Packets.IpV4
{ {
/// <summary> /// <summary>
/// RFC 4782.
/// Defines the possible quick start functions. /// Defines the possible quick start functions.
/// </summary> /// </summary>
public enum IpV4OptionQuickStartFunction : byte public enum IpV4OptionQuickStartFunction : byte
...@@ -14,6 +15,5 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -14,6 +15,5 @@ namespace PcapDotNet.Packets.IpV4
/// 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 = 0x80
} }
} }
\ No newline at end of file
using System.Collections.Generic; using System.Collections.Generic;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.IpV4 namespace PcapDotNet.Packets.IpV4
{ {
...@@ -52,7 +53,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -52,7 +53,7 @@ namespace PcapDotNet.Packets.IpV4
/// Appears at most once in a datagram. /// Appears at most once in a datagram.
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.RecordRoute)] [IpV4OptionTypeRegistration(IpV4OptionType.RecordRoute)]
public class IpV4OptionRecordRoute : IpV4OptionRoute, IOptionComplexFactory public class IpV4OptionRecordRoute : IpV4OptionRoute, IOptionComplexFactory
{ {
/// <summary> /// <summary>
......
using System; using System;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.IpV4 namespace PcapDotNet.Packets.IpV4
{ {
...@@ -31,7 +32,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -31,7 +32,7 @@ namespace PcapDotNet.Packets.IpV4
/// </pre> /// </pre>
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.RouterAlert)] [IpV4OptionTypeRegistration(IpV4OptionType.RouterAlert)]
public sealed class IpV4OptionRouterAlert : IpV4OptionComplex, IOptionComplexFactory, IEquatable<IpV4OptionRouterAlert> public sealed class IpV4OptionRouterAlert : IpV4OptionComplex, IOptionComplexFactory, IEquatable<IpV4OptionRouterAlert>
{ {
/// <summary> /// <summary>
......
using System; using System;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.IpV4 namespace PcapDotNet.Packets.IpV4
{ {
...@@ -16,7 +17,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -16,7 +17,7 @@ namespace PcapDotNet.Packets.IpV4
/// Must be copied on fragmentation. /// Must be copied on fragmentation.
/// Appears at most once in a datagram. /// Appears at most once in a datagram.
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.StreamIdentifier)] [IpV4OptionTypeRegistration(IpV4OptionType.StreamIdentifier)]
public sealed class IpV4OptionStreamIdentifier : IpV4OptionComplex, IOptionComplexFactory, IEquatable<IpV4OptionStreamIdentifier> public sealed class IpV4OptionStreamIdentifier : IpV4OptionComplex, IOptionComplexFactory, IEquatable<IpV4OptionStreamIdentifier>
{ {
/// <summary> /// <summary>
......
using System.Collections.Generic; using System.Collections.Generic;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.IpV4 namespace PcapDotNet.Packets.IpV4
{ {
...@@ -60,7 +61,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -60,7 +61,7 @@ namespace PcapDotNet.Packets.IpV4
/// Appears at most once in a datagram. /// Appears at most once in a datagram.
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.StrictSourceRouting)] [IpV4OptionTypeRegistration(IpV4OptionType.StrictSourceRouting)]
public class IpV4OptionStrictSourceRouting : IpV4OptionRoute, IOptionComplexFactory public class IpV4OptionStrictSourceRouting : IpV4OptionRoute, IOptionComplexFactory
{ {
/// <summary> /// <summary>
......
using System; using System;
using PcapDotNet.Base; using PcapDotNet.Base;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.IpV4 namespace PcapDotNet.Packets.IpV4
{ {
...@@ -73,7 +74,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -73,7 +74,7 @@ namespace PcapDotNet.Packets.IpV4
/// </summary> /// </summary>
public abstract class IpV4OptionTimestamp : IpV4OptionComplex, IEquatable<IpV4OptionTimestamp> public abstract class IpV4OptionTimestamp : IpV4OptionComplex, IEquatable<IpV4OptionTimestamp>
{ {
[OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.InternetTimestamp)] [IpV4OptionTypeRegistration(IpV4OptionType.InternetTimestamp)]
internal class IpV4OptionTimestampFactory : IOptionComplexFactory internal class IpV4OptionTimestampFactory : IOptionComplexFactory
{ {
Option IOptionComplexFactory.CreateInstance(byte[] buffer, ref int offset, byte valueLength) Option IOptionComplexFactory.CreateInstance(byte[] buffer, ref int offset, byte valueLength)
......
using System; using System;
using PcapDotNet.Base; using PcapDotNet.Base;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.IpV4 namespace PcapDotNet.Packets.IpV4
{ {
...@@ -31,7 +32,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -31,7 +32,7 @@ namespace PcapDotNet.Packets.IpV4
/// Number: 18 (F+C+Number = 82) /// Number: 18 (F+C+Number = 82)
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(IpV4OptionType), IpV4OptionType.TraceRoute)] [IpV4OptionTypeRegistration(IpV4OptionType.TraceRoute)]
public sealed class IpV4OptionTraceRoute : IpV4OptionComplex, IOptionComplexFactory, IEquatable<IpV4OptionTraceRoute> public sealed class IpV4OptionTraceRoute : IpV4OptionComplex, IOptionComplexFactory, IEquatable<IpV4OptionTraceRoute>
{ {
/// <summary> /// <summary>
......
using System;
using PcapDotNet.Packets.Ip;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets
{
internal sealed class IpV4OptionTypeRegistrationAttribute : OptionTypeRegistrationAttribute
{
public IpV4OptionTypeRegistrationAttribute(IpV4OptionType optionType)
{
IpV4OptionType = optionType;
}
public IpV4OptionType IpV4OptionType { get; private set; }
public override object OptionType
{
get { return IpV4OptionType; }
}
public override Type OptionTypeType
{
get { return typeof(IpV4OptionType); }
}
}
}
\ No newline at end of file
...@@ -3,6 +3,7 @@ using System.Collections.Generic; ...@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using PcapDotNet.Base; using PcapDotNet.Base;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.IpV4 namespace PcapDotNet.Packets.IpV4
{ {
......
using System.Collections.Generic; using System.Collections.Generic;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.IpV4 namespace PcapDotNet.Packets.IpV4
{ {
...@@ -8,7 +9,7 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -8,7 +9,7 @@ namespace PcapDotNet.Packets.IpV4
/// They must be implemented by all IP modules (host and gateways). /// They must be implemented by all IP modules (host and gateways).
/// What is optional is their transmission in any particular datagram, not their implementation. /// What is optional is their transmission in any particular datagram, not their implementation.
/// </summary> /// </summary>
public class IpV4Options : Options<IpV4Option> public class IpV4Options : V4Options<IpV4Option>
{ {
/// <summary> /// <summary>
/// The maximum number of bytes the options may take. /// The maximum number of bytes the options may take.
......
...@@ -206,9 +206,9 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -206,9 +206,9 @@ namespace PcapDotNet.Packets.IpV4
/// </summary> /// </summary>
Bna = 0x31, Bna = 0x31,
/// <summary> /// <summary>
/// Encapsulating Security Payload RFC 2406 /// ESP. Encapsulating Security Payload RFC 2406.
/// </summary> /// </summary>
Esp = 0x32, EncapsulatingSecurityPayload = 0x32,
/// <summary> /// <summary>
/// Authentication Header RFC 2402 /// Authentication Header RFC 2402
/// </summary> /// </summary>
......
using System;
namespace PcapDotNet.Packets
{
internal sealed class OptionTypeRegistrationAttribute : Attribute
{
public OptionTypeRegistrationAttribute(Type optionTypeType, object optionType)
{
OptionTypeType = optionTypeType;
OptionType = optionType;
}
public object OptionType { get; private set; }
public Type OptionTypeType { get; private set; }
}
}
\ No newline at end of file
...@@ -316,17 +316,22 @@ ...@@ -316,17 +316,22 @@
<Compile Include="Igmp\IgmpRecordType.cs" /> <Compile Include="Igmp\IgmpRecordType.cs" />
<Compile Include="Igmp\IgmpMessageType.cs" /> <Compile Include="Igmp\IgmpMessageType.cs" />
<Compile Include="Igmp\IIgmpLayerWithGroupAddress.cs" /> <Compile Include="Igmp\IIgmpLayerWithGroupAddress.cs" />
<Compile Include="Ip\V4Option.cs" />
<Compile Include="Ip\IIpOptionQuickStart.cs" />
<Compile Include="IpV4\IpV4OptionTypeRegistrationAttribute.cs" />
<Compile Include="IpV4\IIpV4NextLayer.cs" /> <Compile Include="IpV4\IIpV4NextLayer.cs" />
<Compile Include="IpV4\IIpV4NextTransportLayer.cs" /> <Compile Include="IpV4\IIpV4NextTransportLayer.cs" />
<Compile Include="ILayer.cs" /> <Compile Include="ILayer.cs" />
<Compile Include="IOptionUnknownFactory.cs" /> <Compile Include="Ip\IOptionUnknownFactory.cs" />
<Compile Include="IpV4\IpV4Layer.cs" /> <Compile Include="IpV4\IpV4Layer.cs" />
<Compile Include="IpV4\IpV4OptionUnknown.cs" /> <Compile Include="IpV4\IpV4OptionUnknown.cs" />
<Compile Include="Ip\IpOptionQuickStartCommon.cs" />
<Compile Include="Transport\TcpOptionTypeRegistrationAttribute.cs" />
<Compile Include="IpV6\IpV6Address.cs" /> <Compile Include="IpV6\IpV6Address.cs" />
<Compile Include="IpV6\IpV6Datagram.cs" /> <Compile Include="IpV6\IpV6Datagram.cs" />
<Compile Include="Layer.cs" /> <Compile Include="Layer.cs" />
<Compile Include="Option.cs" /> <Compile Include="Ip\Option.cs" />
<Compile Include="IOptionComplexFactory.cs" /> <Compile Include="Ip\IOptionComplexFactory.cs" />
<Compile Include="IpV4\IpV4Address.cs" /> <Compile Include="IpV4\IpV4Address.cs" />
<Compile Include="IpV4\IpV4Datagram.cs" /> <Compile Include="IpV4\IpV4Datagram.cs" />
<Compile Include="IpV4\IpV4Fragmentation.cs" /> <Compile Include="IpV4\IpV4Fragmentation.cs" />
...@@ -356,9 +361,9 @@ ...@@ -356,9 +361,9 @@
<Compile Include="IpV4\IpV4OptionType.cs" /> <Compile Include="IpV4\IpV4OptionType.cs" />
<Compile Include="IpV4\IpV4Protocol.cs" /> <Compile Include="IpV4\IpV4Protocol.cs" />
<Compile Include="ByteArrayExtensions.cs" /> <Compile Include="ByteArrayExtensions.cs" />
<Compile Include="OptionComplexFactory.cs" /> <Compile Include="Ip\OptionComplexFactory.cs" />
<Compile Include="Options.cs" /> <Compile Include="Ip\Options.cs" />
<Compile Include="OptionTypeRegistrationAttribute.cs" /> <Compile Include="Ip\OptionTypeRegistrationAttribute.cs" />
<Compile Include="Packet.cs" /> <Compile Include="Packet.cs" />
<Compile Include="PacketBuilder.cs" /> <Compile Include="PacketBuilder.cs" />
<Compile Include="PayloadLayer.cs" /> <Compile Include="PayloadLayer.cs" />
...@@ -400,6 +405,7 @@ ...@@ -400,6 +405,7 @@
<Compile Include="Ethernet\ClassOfService.cs" /> <Compile Include="Ethernet\ClassOfService.cs" />
<Compile Include="Ethernet\VLanTaggedFrameDatagram.cs" /> <Compile Include="Ethernet\VLanTaggedFrameDatagram.cs" />
<Compile Include="Ethernet\VLanTaggedFrameLayer.cs" /> <Compile Include="Ethernet\VLanTaggedFrameLayer.cs" />
<Compile Include="Ip\V4Options.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\PcapDotNet.snk" /> <None Include="..\PcapDotNet.snk" />
......
using System; using System;
using PcapDotNet.Packets.Ip;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
/// <summary> /// <summary>
/// Represents a TCP option according to rfc 793. /// Represents a TCP option according to rfc 793.
/// </summary> /// </summary>
public abstract class TcpOption : Option, IEquatable<TcpOption> public abstract class TcpOption : V4Option, IEquatable<TcpOption>
{ {
/// <summary> /// <summary>
/// This option code indicates the end of the option list. /// This option code indicates the end of the option list.
...@@ -78,7 +80,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -78,7 +80,7 @@ namespace PcapDotNet.Packets.Transport
return OptionType.ToString(); return OptionType.ToString();
} }
internal sealed override Option Read(byte[] buffer, ref int offset, int length) internal sealed override V4Option Read(byte[] buffer, ref int offset, int length)
{ {
int offsetEnd = offset + length; int offsetEnd = offset + length;
if (offset == offsetEnd) if (offset == offsetEnd)
...@@ -93,7 +95,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -93,7 +95,7 @@ namespace PcapDotNet.Packets.Transport
return Nop; return Nop;
default: default:
return OptionComplexFactory<TcpOptionType>.Read(optionType, buffer, ref offset, offsetEnd - offset); return (V4Option)OptionComplexFactory<TcpOptionType>.Read(optionType, buffer, ref offset, offsetEnd - offset);
} }
} }
......
...@@ -3,6 +3,7 @@ using System.Collections.Generic; ...@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using PcapDotNet.Base; using PcapDotNet.Base;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
...@@ -33,7 +34,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -33,7 +34,7 @@ namespace PcapDotNet.Packets.Transport
/// While computing the alternate checksum, the TCP checksum field and the data portion TCP Alternate Checksum Data Option are replaced with zeros. /// While computing the alternate checksum, the TCP checksum field and the data portion TCP Alternate Checksum Data Option are replaced with zeros.
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.AlternateChecksumData)] [TcpOptionTypeRegistration(TcpOptionType.AlternateChecksumData)]
public sealed class TcpOptionAlternateChecksumData : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionAlternateChecksumData> public sealed class TcpOptionAlternateChecksumData : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionAlternateChecksumData>
{ {
/// <summary> /// <summary>
......
using System; using System;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
...@@ -27,7 +28,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -27,7 +28,7 @@ namespace PcapDotNet.Packets.Transport
/// Note that the 8-bit Fletcher algorithm gives a 16-bit checksum and the 16-bit algorithm gives a 32-bit checksum. /// Note that the 8-bit Fletcher algorithm gives a 16-bit checksum and the 16-bit algorithm gives a 32-bit checksum.
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.AlternateChecksumRequest)] [TcpOptionTypeRegistration(TcpOptionType.AlternateChecksumRequest)]
public sealed class TcpOptionAlternateChecksumRequest : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionAlternateChecksumRequest> public sealed class TcpOptionAlternateChecksumRequest : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionAlternateChecksumRequest>
{ {
/// <summary> /// <summary>
......
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
/// <summary> /// <summary>
...@@ -15,7 +17,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -15,7 +17,7 @@ namespace PcapDotNet.Packets.Transport
/// Its SEG.CC value is the TCB.CCsend value from the sender's TCB. /// Its SEG.CC value is the TCB.CCsend value from the sender's TCB.
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.ConnectionCount)] [TcpOptionTypeRegistration(TcpOptionType.ConnectionCount)]
public class TcpOptionConnectionCount : TcpOptionConnectionCountBase, IOptionComplexFactory public class TcpOptionConnectionCount : TcpOptionConnectionCountBase, IOptionComplexFactory
{ {
/// <summary> /// <summary>
......
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
/// <summary> /// <summary>
...@@ -19,7 +21,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -19,7 +21,7 @@ namespace PcapDotNet.Packets.Transport
/// A CC.ECHO option should be sent only in a &lt;SYN,ACK&gt; segment and should be ignored if it is received in any other segment. /// A CC.ECHO option should be sent only in a &lt;SYN,ACK&gt; segment and should be ignored if it is received in any other segment.
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.ConnectionCountEcho)] [TcpOptionTypeRegistration(TcpOptionType.ConnectionCountEcho)]
public class TcpOptionConnectionCountEcho : TcpOptionConnectionCountBase, IOptionComplexFactory public class TcpOptionConnectionCountEcho : TcpOptionConnectionCountBase, IOptionComplexFactory
{ {
/// <summary> /// <summary>
......
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
/// <summary> /// <summary>
...@@ -16,7 +18,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -16,7 +18,7 @@ namespace PcapDotNet.Packets.Transport
/// </para> /// </para>
/// </summary> /// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")]
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.ConnectionCountNew)] [TcpOptionTypeRegistration(TcpOptionType.ConnectionCountNew)]
public class TcpOptionConnectionCountNew : TcpOptionConnectionCountBase, IOptionComplexFactory public class TcpOptionConnectionCountNew : TcpOptionConnectionCountBase, IOptionComplexFactory
{ {
/// <summary> /// <summary>
......
using System; using System;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
...@@ -20,7 +21,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -20,7 +21,7 @@ namespace PcapDotNet.Packets.Transport
/// and the four information bytes will define the time at which the data segment was transmitted in any format convenient to the sender. /// and the four information bytes will define the time at which the data segment was transmitted in any format convenient to the sender.
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.Echo)] [TcpOptionTypeRegistration(TcpOptionType.Echo)]
public sealed class TcpOptionEcho : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionEcho> public sealed class TcpOptionEcho : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionEcho>
{ {
/// <summary> /// <summary>
......
using System; using System;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
...@@ -27,7 +28,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -27,7 +28,7 @@ namespace PcapDotNet.Packets.Transport
/// However, a TCP should not receive one of these options in a non-SYN segment unless it included a TCP Echo option in its own SYN segment. /// However, a TCP should not receive one of these options in a non-SYN segment unless it included a TCP Echo option in its own SYN segment.
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.EchoReply)] [TcpOptionTypeRegistration(TcpOptionType.EchoReply)]
public sealed class TcpOptionEchoReply : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionEchoReply> public sealed class TcpOptionEchoReply : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionEchoReply>
{ {
/// <summary> /// <summary>
......
using System; using System;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
...@@ -17,7 +18,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -17,7 +18,7 @@ namespace PcapDotNet.Packets.Transport
/// If this option is not used, any segment size is allowed. /// If this option is not used, any segment size is allowed.
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.MaximumSegmentSize)] [TcpOptionTypeRegistration(TcpOptionType.MaximumSegmentSize)]
public sealed class TcpOptionMaximumSegmentSize : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionMaximumSegmentSize> public sealed class TcpOptionMaximumSegmentSize : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionMaximumSegmentSize>
{ {
/// <summary> /// <summary>
......
...@@ -3,6 +3,7 @@ using System.Collections.Generic; ...@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using PcapDotNet.Base; using PcapDotNet.Base;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
...@@ -25,7 +26,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -25,7 +26,7 @@ namespace PcapDotNet.Packets.Transport
/// The MD5 digest is always 16 bytes in length, and the option would appear in every segment of a connection. /// The MD5 digest is always 16 bytes in length, and the option would appear in every segment of a connection.
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.Md5Signature)] [TcpOptionTypeRegistration(TcpOptionType.Md5Signature)]
public sealed class TcpOptionMd5Signature: TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionMd5Signature> public sealed class TcpOptionMd5Signature: TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionMd5Signature>
{ {
/// <summary> /// <summary>
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
...@@ -62,7 +63,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -62,7 +63,7 @@ namespace PcapDotNet.Packets.Transport
/// </pre> /// </pre>
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.Mood)] [TcpOptionTypeRegistration(TcpOptionType.Mood)]
public sealed class TcpOptionMood : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionMood> public sealed class TcpOptionMood : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionMood>
{ {
/// <summary> /// <summary>
......
using System; using System;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
...@@ -10,7 +11,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -10,7 +11,7 @@ namespace PcapDotNet.Packets.Transport
/// +-----------+-------------+ /// +-----------+-------------+
/// </pre> /// </pre>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.PartialOrderConnectionPermitted)] [TcpOptionTypeRegistration(TcpOptionType.PartialOrderConnectionPermitted)]
public sealed class TcpOptionPartialOrderConnectionPermitted : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionPartialOrderConnectionPermitted> public sealed class TcpOptionPartialOrderConnectionPermitted : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionPartialOrderConnectionPermitted>
{ {
/// <summary> /// <summary>
......
using System; using System;
using PcapDotNet.Base; using PcapDotNet.Base;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
...@@ -23,7 +24,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -23,7 +24,7 @@ namespace PcapDotNet.Packets.Transport
/// The "Filler" field serves merely to complete the third byte of the option. /// The "Filler" field serves merely to complete the third byte of the option.
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.PartialOrderServiceProfile)] [TcpOptionTypeRegistration(TcpOptionType.PartialOrderServiceProfile)]
public sealed class TcpOptionPartialOrderServiceProfile : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionPartialOrderServiceProfile> public sealed class TcpOptionPartialOrderServiceProfile : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionPartialOrderServiceProfile>
{ {
private const byte NoFlags = 0x00; private const byte NoFlags = 0x00;
......
...@@ -3,6 +3,7 @@ using System.Collections.Generic; ...@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using PcapDotNet.Base; using PcapDotNet.Base;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
...@@ -53,7 +54,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -53,7 +54,7 @@ namespace PcapDotNet.Packets.Transport
/// The SACK option is advisory, in that, while it notifies the data sender that the data receiver has received the indicated segments, /// The SACK option is advisory, in that, while it notifies the data sender that the data receiver has received the indicated segments,
/// the data receiver is permitted to later discard data which have been reported in a SACK option. /// the data receiver is permitted to later discard data which have been reported in a SACK option.
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.SelectiveAcknowledgment)] [TcpOptionTypeRegistration(TcpOptionType.SelectiveAcknowledgment)]
public sealed class TcpOptionSelectiveAcknowledgment : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionSelectiveAcknowledgment> public sealed class TcpOptionSelectiveAcknowledgment : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionSelectiveAcknowledgment>
{ {
/// <summary> /// <summary>
......
using System; using System;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
...@@ -14,7 +15,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -14,7 +15,7 @@ namespace PcapDotNet.Packets.Transport
/// +---------+---------+ /// +---------+---------+
/// </pre> /// </pre>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.SelectiveAcknowledgmentPermitted)] [TcpOptionTypeRegistration(TcpOptionType.SelectiveAcknowledgmentPermitted)]
public sealed class TcpOptionSelectiveAcknowledgmentPermitted : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionSelectiveAcknowledgmentPermitted> public sealed class TcpOptionSelectiveAcknowledgmentPermitted : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionSelectiveAcknowledgmentPermitted>
{ {
/// <summary> /// <summary>
......
using System; using System;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
...@@ -28,7 +29,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -28,7 +29,7 @@ namespace PcapDotNet.Packets.Transport
/// and may send a TSopt in other segments only if it received a TSopt in the initial &lt;SYN&gt; segment for the connection. /// and may send a TSopt in other segments only if it received a TSopt in the initial &lt;SYN&gt; segment for the connection.
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.Timestamp)] [TcpOptionTypeRegistration(TcpOptionType.Timestamp)]
public sealed class TcpOptionTimestamp : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionTimestamp> public sealed class TcpOptionTimestamp : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionTimestamp>
{ {
/// <summary> /// <summary>
......
using System;
using PcapDotNet.Packets.Ip;
using PcapDotNet.Packets.Transport;
namespace PcapDotNet.Packets
{
internal sealed class TcpOptionTypeRegistrationAttribute : OptionTypeRegistrationAttribute
{
public TcpOptionTypeRegistrationAttribute(TcpOptionType optionType)
{
TcpOptionType = optionType;
}
public TcpOptionType TcpOptionType { get; private set; }
public override object OptionType
{
get { return TcpOptionType; }
}
public override Type OptionTypeType
{
get { return typeof(TcpOptionType); }
}
}
}
\ No newline at end of file
...@@ -3,6 +3,7 @@ using System.Collections.Generic; ...@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using PcapDotNet.Base; using PcapDotNet.Base;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
......
using System; using System;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
...@@ -33,7 +34,7 @@ namespace PcapDotNet.Packets.Transport ...@@ -33,7 +34,7 @@ namespace PcapDotNet.Packets.Transport
/// The Window field in a SYN (i.e., a SYN or SYN,ACK) segment itself is never scaled. /// The Window field in a SYN (i.e., a SYN or SYN,ACK) segment itself is never scaled.
/// </para> /// </para>
/// </summary> /// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.WindowScale)] [TcpOptionTypeRegistration(TcpOptionType.WindowScale)]
public sealed class TcpOptionWindowScale: TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionWindowScale> public sealed class TcpOptionWindowScale: TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionWindowScale>
{ {
/// <summary> /// <summary>
......
using System.Collections.Generic; using System.Collections.Generic;
using PcapDotNet.Packets.Ip;
namespace PcapDotNet.Packets.Transport namespace PcapDotNet.Packets.Transport
{ {
/// <summary> /// <summary>
/// A collection of TCP options. /// A collection of TCP options.
/// </summary> /// </summary>
public class TcpOptions : Options<TcpOption> public class TcpOptions : V4Options<TcpOption>
{ {
/// <summary> /// <summary>
/// The maximum number of bytes the options can take. /// The maximum number of bytes the options can take.
......
...@@ -4,9 +4,9 @@ Microsoft Visual Studio Solution File, Format Version 11.00 ...@@ -4,9 +4,9 @@ Microsoft Visual Studio Solution File, Format Version 11.00
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0D5DCCC5-A509-4B4E-90B0-92390C6EA06F}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0D5DCCC5-A509-4B4E-90B0-92390C6EA06F}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
LocalTestRun.testrunconfig = LocalTestRun.testrunconfig LocalTestRun.testrunconfig = LocalTestRun.testrunconfig
PcapDotNet.5.0.ReSharper = PcapDotNet.5.0.ReSharper
PcapDotNet.CodeAnalysisDictionary.xml = PcapDotNet.CodeAnalysisDictionary.xml PcapDotNet.CodeAnalysisDictionary.xml = PcapDotNet.CodeAnalysisDictionary.xml
PcapDotNet.ruleset = PcapDotNet.ruleset PcapDotNet.ruleset = PcapDotNet.ruleset
PcapDotNet.sln.DotSettings = PcapDotNet.sln.DotSettings
PcapDotNet.vsmdi = PcapDotNet.vsmdi PcapDotNet.vsmdi = PcapDotNet.vsmdi
EndProjectSection EndProjectSection
EndProject EndProject
......
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_ARRAY_AND_OBJECT_INITIALIZER/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_ANONYMOUS_METHOD_BLOCK/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_EMBRACED_INITIALIZER_BLOCK/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_BEFORE_SIZEOF_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">160</s:Int64>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/EventHandlerPatternLong/@EntryValue">$object$_On$event$</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/VBNaming/EventHandlerPatternLong/@EntryValue">$object$_On$event$</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/JavaScriptFormatOther/ALIGN_MULTIPLE_DECLARATION/@EntryValue">True</s:Boolean></wpf:ResourceDictionary>
\ No newline at end of file
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