Commit d499834d authored by Brickner_cp's avatar Brickner_cp

Code Analysis and Documentation - 2 warnings left.

parent ae70efce
namespace PcapDotNet.Packets.IpV4
{
/// <summary>
/// This interface is used to create all complex options.
/// Every complex option should implement such a factory to create itself from a buffer.
/// </summary>
// internal interface IIpv4OptionComplexFactory
// {
// /// <summary>
// /// Tries to read the option from a buffer starting from the option value (after the type and length).
// /// </summary>
// /// <param name="buffer">The buffer to read the option from.</param>
// /// <param name="offset">The offset to the first byte to read the buffer. Will be incremented by the number of bytes read.</param>
// /// <param name="valueLength">The number of bytes the option value should take according to the length field that was already read.</param>
// /// <returns>On success - the complex option read. On failure - null.</returns>
// IpV4OptionComplex CreateInstance(byte[] buffer, ref int offset, byte valueLength);
// }
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ namespace PcapDotNet.Packets
/// A generic option (for IPv4 and TCP).
/// The option is read from buffer and can be of different length.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Option")]
public abstract class Option
{
/// <summary>
......
......@@ -128,10 +128,17 @@ namespace PcapDotNet.Packets
/// <param name="ipV4SourceAddress">The IPv4 source address.</param>
/// <param name="ipV4DestinationAddress">The IPv4 destination address.</param>
/// <param name="ipV4Options">The IPv4 options.</param>
/// <param name="tcpSourcePort">The source udp port.</param>
/// <param name="tcpDestinationPort">The destination udp port.</param>
/// <param name="tcpSourcePort">The source TCP port.</param>
/// <param name="tcpDestinationPort">The destination TCP port.</param>
/// <param name="tcpSequenceNumber">The TCP sequence number.</param>
/// <param name="tcpAcknowledgmentNumber">The TCP ack number.</param>
/// <param name="tcpControlBits">The TCP flags.</param>
/// <param name="tcpWindow">The TCP window size.</param>
/// <param name="tcpUrgentPointer">The TCP urgent pointer value.</param>
/// <param name="tcpOptions">The TCP options.</param>
/// <param name="tcpPayload">The payload of UDP datagram.</param>
/// <returns>A packet with a UDP over IPv4 over Ethernet datagram.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "pointer")]
public static Packet EthernetIpV4Tcp(DateTime timestamp,
MacAddress ethernetSource, MacAddress ethernetDestination,
byte ipV4TypeOfService, ushort ipV4Identification, IpV4Fragmentation ipV4Fragmentation,
......
......@@ -72,7 +72,6 @@
<Compile Include="IpV4\IpV4OptionUnknown.cs" />
<Compile Include="Option.cs" />
<Compile Include="IOptionComplexFactory.cs" />
<Compile Include="IpV4\IIpv4OptionComplexFactory.cs" />
<Compile Include="IpV4\IpV4Address.cs" />
<Compile Include="IpV4\IpV4Datagram.cs" />
<Compile Include="IpV4\IpV4Fragmentation.cs" />
......
......@@ -11,7 +11,7 @@ namespace PcapDotNet.Packets.Transport
/// if the initial SYN segment contained a CC or CC.NEW option.
/// Its SEG.CC value is the SEG.CC value from the initial SYN.
///
/// A CC.ECHO option should be sent only in a <SYN,ACK> 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.
/// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.ConnectionCountEcho)]
public class TcpOptionConnectionCountEcho : TcpOptionConnectionCountBase, IOptionComplexFactory
......
......@@ -7,7 +7,7 @@ namespace PcapDotNet.Packets.Transport
/// +--------+--------+--------+--------+--------+--------+
/// Kind=12 Length=6
///
/// This option may be sent instead of a CC option in an initial <SYN> segment (i.e., SYN but not ACK bit),
/// This option may be sent instead of a CC option in an initial &lt;SYN&gt; segment (i.e., SYN but not ACK bit),
/// to indicate that the SEG.CC value may not be larger than the previous value.
/// Its SEG.CC value is the TCB.CCsend value from the sender's TCB.
/// </summary>
......
......@@ -28,8 +28,14 @@ namespace PcapDotNet.Packets.Transport
/// </summary>
public const int OptionLength = OptionHeaderLength + 16;
/// <summary>
/// The number of bytes this option value take.
/// </summary>
public const int OptionValueLength = OptionLength - OptionHeaderLength;
/// <summary>
/// Creates the option using the given signature data.
/// </summary>
public TcpOptionMd5Signature(IList<byte> data)
: base(TcpOptionType.Md5Signature)
{
......@@ -39,11 +45,17 @@ namespace PcapDotNet.Packets.Transport
Data = new ReadOnlyCollection<byte>(data);
}
/// <summary>
/// The default signature is all zeroes.
/// </summary>
public TcpOptionMd5Signature()
: this(new byte[OptionValueLength])
{
}
/// <summary>
/// The signature value.
/// </summary>
public ReadOnlyCollection<byte> Data { get; private set; }
/// <summary>
......@@ -62,6 +74,9 @@ namespace PcapDotNet.Packets.Transport
get { return true; }
}
/// <summary>
/// Two MD5 signature options are equal if they have the same signature value.
/// </summary>
public bool Equals(TcpOptionMd5Signature other)
{
if (other == null)
......@@ -70,6 +85,9 @@ namespace PcapDotNet.Packets.Transport
return Data.SequenceEqual(other.Data);
}
/// <summary>
/// Two MD5 signature options are equal if they have the same signature value.
/// </summary>
public override bool Equals(TcpOption other)
{
return Equals(other as TcpOptionMd5Signature);
......
......@@ -16,8 +16,14 @@ namespace PcapDotNet.Packets.Transport
/// </summary>
public const int OptionLength = 2;
/// <summary>
/// The number of bytes this option value take.
/// </summary>
public const int OptionValueLength = OptionLength - OptionHeaderLength;
/// <summary>
/// Creates a partial order connection permitted option.
/// </summary>
public TcpOptionPartialOrderConnectionPermitted()
: base(TcpOptionType.PartialOrderConnectionPermitted)
{
......@@ -39,11 +45,17 @@ namespace PcapDotNet.Packets.Transport
get { return true; }
}
/// <summary>
/// Two partial order connection permitted options are always equal.
/// </summary>
public bool Equals(TcpOptionPartialOrderConnectionPermitted other)
{
return other != null;
}
/// <summary>
/// Two partial order connection permitted options are always equal.
/// </summary>
public override bool Equals(TcpOption other)
{
return Equals(other as TcpOptionPartialOrderConnectionPermitted);
......
......@@ -30,8 +30,14 @@ namespace PcapDotNet.Packets.Transport
/// </summary>
public const int OptionLength = 3;
/// <summary>
/// The number of bytes this option value take.
/// </summary>
public const int OptionValueLength = OptionLength - OptionHeaderLength;
/// <summary>
/// Creates the option using the given isStart and isEnd values.
/// </summary>
public TcpOptionPartialOrderServiceProfile(bool isStart, bool isEnd)
: base(TcpOptionType.PartialOrderServiceProfile)
{
......@@ -39,12 +45,22 @@ namespace PcapDotNet.Packets.Transport
IsEnd = isEnd;
}
/// <summary>
/// The default is for service profiles which fit completely in a single segment.
/// </summary>
public TcpOptionPartialOrderServiceProfile()
: this(true, true)
{
}
/// <summary>
/// Indicates that the information in the data section represents the beginning of the service profile.
/// </summary>
public bool IsStart { get; private set; }
/// <summary>
/// Indicates that the information in the data section represents the end of the service profile.
/// </summary>
public bool IsEnd { get; private set; }
/// <summary>
......@@ -63,6 +79,9 @@ namespace PcapDotNet.Packets.Transport
get { return true; }
}
/// <summary>
/// Two partial order service profile options are equal if they agree on both IsStart and IsEnd.
/// </summary>
public bool Equals(TcpOptionPartialOrderServiceProfile other)
{
if (other == null)
......@@ -72,6 +91,9 @@ namespace PcapDotNet.Packets.Transport
(IsEnd == other.IsEnd);
}
/// <summary>
/// Two partial order service profile options are equal if they agree on both IsStart and IsEnd.
/// </summary>
public override bool Equals(TcpOption other)
{
return Equals(other as TcpOptionPartialOrderServiceProfile);
......
......@@ -58,17 +58,26 @@ namespace PcapDotNet.Packets.Transport
/// </summary>
public const int OptionValueMinimumLength = OptionMinimumLength - OptionHeaderLength;
/// <summary>
/// Creates the option from the given list of selective ack blocks.
/// </summary>
public TcpOptionSelectiveAcknowledgment(IList<TcpOptionSelectiveAcknowledgmentBlock> blocks)
: base(TcpOptionType.SelectiveAcknowledgment)
{
_blocks = new ReadOnlyCollection<TcpOptionSelectiveAcknowledgmentBlock>(blocks);
}
/// <summary>
/// The default is no blocks.
/// </summary>
public TcpOptionSelectiveAcknowledgment()
: this(new TcpOptionSelectiveAcknowledgmentBlock[]{})
{
}
/// <summary>
/// The collection of selective ack blocks.
/// </summary>
public ReadOnlyCollection<TcpOptionSelectiveAcknowledgmentBlock> Blocks
{
get { return _blocks; }
......@@ -90,6 +99,9 @@ namespace PcapDotNet.Packets.Transport
get { return true; }
}
/// <summary>
/// Two selective ack options are equal if they have the same selective ack blocks.
/// </summary>
public bool Equals(TcpOptionSelectiveAcknowledgment other)
{
if (other == null)
......@@ -98,6 +110,9 @@ namespace PcapDotNet.Packets.Transport
return Blocks.SequenceEqual(other.Blocks);
}
/// <summary>
/// Two selective ack options are equal if they have the same selective ack blocks.
/// </summary>
public override bool Equals(TcpOption other)
{
return Equals(other as TcpOptionSelectiveAcknowledgment);
......
namespace PcapDotNet.Packets.Transport
{
/// <summary>
/// Represents a block to ack when using the selective ack option.
/// </summary>
public struct TcpOptionSelectiveAcknowledgmentBlock
{
/// <summary>
/// The number of bytes this struct take.
/// </summary>
public const int SizeOf = 8;
/// <summary>
/// Creates a selective ack block.
/// </summary>
/// <param name="leftEdge">The sequence number of the first byte to ack.</param>
/// <param name="rightEdge">The sequence number of the byte after the last byte to ack.</param>
public TcpOptionSelectiveAcknowledgmentBlock(uint leftEdge, uint rightEdge)
: this()
{
......@@ -11,18 +22,27 @@ namespace PcapDotNet.Packets.Transport
RightEdge = rightEdge;
}
/// <summary>
/// The sequence number of the first byte to ack.
/// </summary>
public uint LeftEdge
{
get;
private set;
}
/// <summary>
/// The sequence number of the byte after the last byte to ack.
/// </summary>
public uint RightEdge
{
get;
private set;
}
/// <summary>
/// Creates a string that represents the selective block.
/// </summary>
public override string ToString()
{
return LeftEdge + "-" + RightEdge;
......
......@@ -20,8 +20,14 @@ namespace PcapDotNet.Packets.Transport
/// </summary>
public const int OptionLength = 2;
/// <summary>
/// The number of bytes this option value take.
/// </summary>
public const int OptionValueLength = OptionLength - OptionHeaderLength;
/// <summary>
/// Creates a selective ack permitted option.
/// </summary>
public TcpOptionSelectiveAcknowledgmentPermitted()
: base(TcpOptionType.SelectiveAcknowledgmentPermitted)
{
......@@ -43,11 +49,17 @@ namespace PcapDotNet.Packets.Transport
get { return true; }
}
/// <summary>
/// Two selective ack permitted options are always equal.
/// </summary>
public bool Equals(TcpOptionSelectiveAcknowledgmentPermitted other)
{
return other != null;
}
/// <summary>
/// Two selective ack permitted options are always equal.
/// </summary>
public override bool Equals(TcpOption other)
{
return Equals(other as TcpOptionSelectiveAcknowledgmentPermitted);
......
......@@ -17,8 +17,8 @@ namespace PcapDotNet.Packets.Transport
/// When TSecr is not valid, its value must be zero.
/// The TSecr value will generally be from the most recent Timestamp option that was received; however, there are exceptions that are explained below.
///
/// A TCP may send the Timestamps option (TSopt) in an initial <SYN> segment (i.e., segment containing a SYN bit and no ACK bit),
/// and may send a TSopt in other segments only if it received a TSopt in the initial <SYN> segment for the connection.
/// A TCP may send the Timestamps option (TSopt) in an initial &lt;SYN&gt; segment (i.e., segment containing a SYN bit and no ACK bit),
/// and may send a TSopt in other segments only if it received a TSopt in the initial &lt;SYN&gt; segment for the connection.
/// </summary>
[OptionTypeRegistration(typeof(TcpOptionType), TcpOptionType.Timestamp)]
public class TcpOptionTimestamp : TcpOptionComplex, IOptionComplexFactory, IEquatable<TcpOptionTimestamp>
......@@ -28,8 +28,14 @@ namespace PcapDotNet.Packets.Transport
/// </summary>
public const int OptionLength = 10;
/// <summary>
/// The number of bytes this option value take.
/// </summary>
public const int OptionValueLength = OptionLength - OptionHeaderLength;
/// <summary>
/// Creates the option from the given timestamp value and echo reply.
/// </summary>
public TcpOptionTimestamp(uint timestampValue, uint timestampEchoReply)
: base(TcpOptionType.Timestamp)
{
......@@ -37,12 +43,22 @@ namespace PcapDotNet.Packets.Transport
TimestampEchoReply = timestampEchoReply;
}
/// <summary>
/// The default values for the timestamp value and echo reply are 0.
/// </summary>
public TcpOptionTimestamp()
: this(0, 0)
{
}
/// <summary>
/// The timestamp value.
/// </summary>
public uint TimestampValue { get; private set; }
/// <summary>
/// The echo reply value.
/// </summary>
public uint TimestampEchoReply { get; private set; }
/// <summary>
......@@ -61,6 +77,9 @@ namespace PcapDotNet.Packets.Transport
get { return true; }
}
/// <summary>
/// Two timestamp options are equal if they have the same timestamp value and echo reply.
/// </summary>
public bool Equals(TcpOptionTimestamp other)
{
if (other == null)
......@@ -70,6 +89,9 @@ namespace PcapDotNet.Packets.Transport
TimestampEchoReply == other.TimestampEchoReply;
}
/// <summary>
/// Two timestamp options are equal if they have the same timestamp value and echo reply.
/// </summary>
public override bool Equals(TcpOption other)
{
return Equals(other as TcpOptionTimestamp);
......
namespace PcapDotNet.Packets.Transport
{
/// <summary>
/// An enum for all the different tcp option types.
/// </summary>
public enum TcpOptionType : byte
{
/// <summary>
/// End of Option List (RFC793)
/// </summary>
EndOfOptionList = 0,
/// <summary>
/// No-Operation (RFC793)
/// </summary>
NoOperation = 1,
/// <summary>
/// Maximum Segment Size (RFC793)
/// </summary>
MaximumSegmentSize = 2,
/// <summary>
/// WSOPT - Window Scale (RFC1323)
/// </summary>
WindowScale = 3,
/// <summary>
/// SACK Permitted (RFC2018)
/// </summary>
SelectiveAcknowledgmentPermitted = 4,
/// <summary>
/// SACK (RFC2018)
/// </summary>
SelectiveAcknowledgment = 5,
/// <summary>
/// Echo (obsoleted by option 8) (RFC1072)
/// </summary>
Echo = 6,
/// <summary>
/// Echo Reply (obsoleted by option 8) (RFC1072)
/// </summary>
EchoReply = 7,
/// <summary>
/// TSOPT - Time Stamp Option (RFC1323)
/// </summary>
Timestamp = 8,
/// <summary>
/// Partial Order Connection Permitted (RFC1693)
/// </summary>
PartialOrderConnectionPermitted = 9,
/// <summary>
/// Partial Order Service Profile (RFC1693)
/// </summary>
PartialOrderServiceProfile = 10,
/// <summary>
/// CC (RFC1644)
/// </summary>
ConnectionCount = 11,
/// <summary>
/// CC.NEW (RFC1644)
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")]
ConnectionCountNew = 12,
/// <summary>
/// CC.ECHO (RFC1644)
/// </summary>
ConnectionCountEcho = 13,
/// <summary>
/// TCP Alternate Checksum Request (RFC1146)
/// </summary>
AlternateChecksumRequest = 14,
/// <summary>
/// TCP Alternate Checksum Data (RFC1146)
/// </summary>
AlternateChecksumData = 15,
/// <summary>
/// MD5 Signature Option (RFC2385)
/// </summary>
Md5Signature = 19,
/// <summary>
/// Quick-Start Response (RFC4782)
/// </summary>
QuickStartResponse = 27,
/// <summary>
/// User Timeout Option (RFC5482)
/// </summary>
UserTimeout = 28,
}
}
\ No newline at end of file
......@@ -33,19 +33,31 @@ namespace PcapDotNet.Packets.Transport
/// </summary>
public const int OptionLength = 3;
/// <summary>
/// The number of bytes this option value take.
/// </summary>
public const int OptionValueLength = OptionLength - OptionHeaderLength;
/// <summary>
/// Create a scale factor option using the given scale factor log.
/// </summary>
public TcpOptionWindowScale(byte scaleFactorLog)
: base(TcpOptionType.WindowScale)
{
ScaleFactorLog = scaleFactorLog;
}
/// <summary>
/// The default scale factor log is 0 (scale factor is 1).
/// </summary>
public TcpOptionWindowScale()
: this(0)
{
}
/// <summary>
/// The log of the window scale factor.
/// </summary>
public byte ScaleFactorLog { get; private set; }
/// <summary>
......@@ -64,6 +76,9 @@ namespace PcapDotNet.Packets.Transport
get { return true; }
}
/// <summary>
/// Two window scale options are equal if they have the same scale factor.
/// </summary>
public bool Equals(TcpOptionWindowScale other)
{
if (other == null)
......@@ -71,11 +86,18 @@ namespace PcapDotNet.Packets.Transport
return ScaleFactorLog == other.ScaleFactorLog;
}
/// <summary>
/// Two window scale options are equal if they have the same scale factor.
/// </summary>
public override bool Equals(TcpOption other)
{
return Equals(other as TcpOptionWindowScale);
}
/// <summary>
/// The hash code of the window scale option is the hash code of the option type xored with the hash code of the scale factor log.
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
return base.GetHashCode() ^
......
......@@ -3,15 +3,27 @@ using System.Collections.Generic;
namespace PcapDotNet.Packets.Transport
{
/// <summary>
/// A collection of TCP options.
/// </summary>
public class TcpOptions : Options<TcpOption>
{
/// <summary>
/// The maximum number of bytes the options can take.
/// </summary>
public const int MaximumBytesLength = TcpDatagram.HeaderMaximumLength - TcpDatagram.HeaderMinimumLength;
/// <summary>
/// An empty options collection.
/// </summary>
public static TcpOptions None
{
get { return _none; }
}
/// <summary>
/// Creates the options collection from the given list of options.
/// </summary>
public TcpOptions(IList<TcpOption> options)
: base(options, TcpOption.End, MaximumBytesLength)
{
......
......@@ -52,6 +52,11 @@ namespace PcapDotNet.Packets.Transport
/// </summary>
public abstract bool IsChecksumOptional { get; }
internal TransportDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
internal abstract int ChecksumOffset { get; }
internal static void WriteHeader(byte[] buffer, int offset, ushort sourcePort, ushort destinationPort)
......@@ -59,10 +64,5 @@ namespace PcapDotNet.Packets.Transport
buffer.Write(offset + Offset.SourcePort, sourcePort, Endianity.Big);
buffer.Write(offset + Offset.DestinationPort, destinationPort, Endianity.Big);
}
protected TransportDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
}
}
\ No newline at end of file
......@@ -58,6 +58,9 @@ namespace PcapDotNet.Packets.Transport
get { return ReadUShort(Offset.Checksum, Endianity.Big); }
}
/// <summary>
/// True iff the checksum for the transport type is optional.
/// </summary>
public override bool IsChecksumOptional
{
get { return true; }
......@@ -87,6 +90,9 @@ namespace PcapDotNet.Packets.Transport
buffer.Write(offset + Offset.TotalLength, (ushort)(HeaderLength + payloadLength), Endianity.Big);
}
/// <summary>
/// A udp datagram is valid if it has a full header.
/// </summary>
protected override bool CalculateIsValid()
{
return Length >= HeaderLength;
......
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