Commit d7ae4b9c authored by Brickner_cp's avatar Brickner_cp

Code Analysis and Documentation - 4 warnings left (ICMP datagrams construction refactoring).

parent 009eea7d
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace PcapDotNet.Base
{
......@@ -16,4 +18,22 @@ namespace PcapDotNet.Base
return (IEnumerable<T>)Enum.GetValues(type);
}
}
/// <summary>
/// Extension methods for MemberInfo.
/// </summary>
public static class MemberInfoExtensions
{
/// <summary>
/// When overridden in a derived class, returns a sequence of custom attributes identified by System.Type.
/// </summary>
/// <typeparam name="T">TThe type of attribute to search for. Only attributes that are assignable to this type are returned.</typeparam>
/// <param name="memberInfo">The memberInfo to look the attributes on.</param>
/// <param name="inherit">Specifies whether to search this member's inheritance chain to find the attributes.</param>
/// <returns>A sequence of custom attributes applied to this member, or a sequence with zero (0) elements if no attributes have been applied.</returns>
public static IEnumerable<T> GetCustomAttributes<T>(this MemberInfo memberInfo, bool inherit) where T : Attribute
{
return memberInfo.GetCustomAttributes(typeof(T), inherit).Cast<T>();
}
}
}
\ No newline at end of file
......@@ -14,13 +14,9 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+-------------------------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.AddressMaskReply)]
public class IcmpAddressMaskReplyDatagram : IcmpAddressMaskRequestDatagram
{
internal IcmpAddressMaskReplyDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
......@@ -34,5 +30,15 @@ namespace PcapDotNet.Packets.Icmp
AddressMask = AddressMask
};
}
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpAddressMaskReplyDatagram(buffer, offset, length);
}
private IcmpAddressMaskReplyDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
}
}
\ No newline at end of file
......@@ -17,6 +17,7 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+-------------------------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.AddressMaskRequest)]
public class IcmpAddressMaskRequestDatagram : IcmpIdentifiedDatagram
{
/// <summary>
......@@ -42,11 +43,6 @@ namespace PcapDotNet.Packets.Icmp
get { return ReadIpV4Address(Offset.AddressMask, Endianity.Big); }
}
internal IcmpAddressMaskRequestDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
......@@ -69,6 +65,16 @@ namespace PcapDotNet.Packets.Icmp
return base.CalculateIsValid() && Length == DatagramLength;
}
internal IcmpAddressMaskRequestDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpAddressMaskRequestDatagram(buffer, offset, length);
}
internal static void WriteHeaderAdditional(byte[] buffer, int offset, IpV4Address addressMask)
{
buffer.Write(offset, addressMask, Endianity.Big);
......
......@@ -22,6 +22,7 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+-------------------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.ConversionFailed)]
public class IcmpConversionFailedDatagram : IcmpIpV4PayloadDatagram
{
/// <summary>
......@@ -100,7 +101,12 @@ namespace PcapDotNet.Packets.Icmp
get { return _maxCode; }
}
internal IcmpConversionFailedDatagram(byte[] buffer, int offset, int length)
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpConversionFailedDatagram(buffer, offset, length);
}
private IcmpConversionFailedDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
......
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using PcapDotNet.Packets.IpV4;
using PcapDotNet.Base;
namespace PcapDotNet.Packets.Icmp
{
......@@ -180,72 +184,129 @@ namespace PcapDotNet.Packets.Icmp
return new IcmpUnknownDatagram(buffer, offset, length);
IcmpMessageType messageType = (IcmpMessageType)buffer[offset + Offset.Type];
switch (messageType)
{
case IcmpMessageType.DestinationUnreachable:
return new IcmpDestinationUnreachableDatagram(buffer, offset, length);
case IcmpMessageType.TimeExceeded:
return new IcmpTimeExceededDatagram(buffer, offset, length);
case IcmpMessageType.SourceQuench:
return new IcmpSourceQuenchDatagram(buffer, offset, length);
case IcmpMessageType.ParameterProblem:
return new IcmpParameterProblemDatagram(buffer, offset, length);
case IcmpMessageType.Redirect:
return new IcmpRedirectDatagram(buffer, offset, length);
case IcmpMessageType.Echo:
return new IcmpEchoDatagram(buffer, offset, length);
case IcmpMessageType.EchoReply:
return new IcmpEchoReplyDatagram(buffer, offset, length);
case IcmpMessageType.Timestamp:
return new IcmpTimestampDatagram(buffer, offset, length);
case IcmpMessageType.TimestampReply:
return new IcmpTimestampReplyDatagram(buffer, offset, length);
case IcmpMessageType.InformationRequest:
return new IcmpInformationRequestDatagram(buffer, offset, length);
return IcmpDatagramFactory.CreateInstance(messageType, buffer, offset, length);
// switch (messageType)
// {
// case IcmpMessageType.DestinationUnreachable:
// return new IcmpDestinationUnreachableDatagram(buffer, offset, length);
//
// case IcmpMessageType.TimeExceeded:
// return new IcmpTimeExceededDatagram(buffer, offset, length);
//
// case IcmpMessageType.SourceQuench:
// return new IcmpSourceQuenchDatagram(buffer, offset, length);
//
// case IcmpMessageType.ParameterProblem:
// return new IcmpParameterProblemDatagram(buffer, offset, length);
//
// case IcmpMessageType.Redirect:
// return new IcmpRedirectDatagram(buffer, offset, length);
//
// case IcmpMessageType.Echo:
// return new IcmpEchoDatagram(buffer, offset, length);
//
// case IcmpMessageType.EchoReply:
// return new IcmpEchoReplyDatagram(buffer, offset, length);
//
// case IcmpMessageType.Timestamp:
// return new IcmpTimestampDatagram(buffer, offset, length);
//
// case IcmpMessageType.TimestampReply:
// return new IcmpTimestampReplyDatagram(buffer, offset, length);
//
// case IcmpMessageType.InformationRequest:
// return new IcmpInformationRequestDatagram(buffer, offset, length);
//
// case IcmpMessageType.InformationReply:
// return new IcmpInformationReplyDatagram(buffer, offset, length);
//
// case IcmpMessageType.DomainNameRequest:
// return new IcmpDomainNameRequestDatagram(buffer, offset, length);
//
// case IcmpMessageType.RouterAdvertisement:
// return new IcmpRouterAdvertisementDatagram(buffer, offset, length);
//
// case IcmpMessageType.AddressMaskRequest:
// return new IcmpAddressMaskRequestDatagram(buffer, offset, length);
//
// case IcmpMessageType.AddressMaskReply:
// return new IcmpAddressMaskReplyDatagram(buffer, offset, length);
//
// case IcmpMessageType.TraceRoute:
// return new IcmpTraceRouteDatagram(buffer, offset, length);
//
// case IcmpMessageType.ConversionFailed:
// return new IcmpConversionFailedDatagram(buffer, offset, length);
//
// case IcmpMessageType.SecurityFailures:
// return new IcmpSecurityFailuresDatagram(buffer, offset, length);
//
// case IcmpMessageType.RouterSolicitation:
// return new IcmpRouterSolicitationDatagram(buffer, offset, length);
//
// case IcmpMessageType.DomainNameReply: // Domain Name Reply is unsupported
// default:
// return new IcmpUnknownDatagram(buffer, offset, length);
// }
}
case IcmpMessageType.InformationReply:
return new IcmpInformationReplyDatagram(buffer, offset, length);
internal abstract IcmpDatagram CreateInstance(byte[] buffer, int offset, int length);
case IcmpMessageType.DomainNameRequest:
return new IcmpDomainNameRequestDatagram(buffer, offset, length);
private bool? _isChecksumCorrect;
private Datagram _payload;
}
case IcmpMessageType.RouterAdvertisement:
return new IcmpRouterAdvertisementDatagram(buffer, offset, length);
internal static class IcmpDatagramFactory
{
internal static IcmpDatagram CreateInstance(IcmpMessageType messageType, byte[] buffer, int offset, int length)
{
IcmpDatagram prototype;
if (!_prototypes.TryGetValue(messageType, out prototype))
return new IcmpUnknownDatagram(buffer, offset, length);
case IcmpMessageType.AddressMaskRequest:
return new IcmpAddressMaskRequestDatagram(buffer, offset, length);
return prototype.CreateInstance(buffer, offset, length);
}
case IcmpMessageType.AddressMaskReply:
return new IcmpAddressMaskReplyDatagram(buffer, offset, length);
private static Dictionary<IcmpMessageType, IcmpDatagram> InitializeComplexOptions()
{
var prototypes =
from type in Assembly.GetExecutingAssembly().GetTypes()
where typeof(IcmpDatagram).IsAssignableFrom(type) &&
GetRegistrationAttribute(type) != null
let constructor =
type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, new[] {typeof(byte[]), typeof(int), typeof(int)}, null)
select new
{
GetRegistrationAttribute(type).MessageType,
Datagram = (IcmpDatagram)constructor.Invoke(new object[] {null, 0, 0})
};
case IcmpMessageType.TraceRoute:
return new IcmpTraceRouteDatagram(buffer, offset, length);
return prototypes.ToDictionary(prototype => prototype.MessageType, prototype => prototype.Datagram);
}
case IcmpMessageType.ConversionFailed:
return new IcmpConversionFailedDatagram(buffer, offset, length);
private static IcmpDatagramRegistrationAttribute GetRegistrationAttribute(Type type)
{
var registrationAttributes =
from attribute in type.GetCustomAttributes<IcmpDatagramRegistrationAttribute>(false)
select attribute;
case IcmpMessageType.SecurityFailures:
return new IcmpSecurityFailuresDatagram(buffer, offset, length);
if (registrationAttributes.IsEmpty())
return null;
case IcmpMessageType.RouterSolicitation:
return new IcmpRouterSolicitationDatagram(buffer, offset, length);
return registrationAttributes.First();
}
case IcmpMessageType.DomainNameReply: // Domain Name Reply is unsupported
default:
return new IcmpUnknownDatagram(buffer, offset, length);
private static readonly Dictionary<IcmpMessageType, IcmpDatagram> _prototypes = InitializeComplexOptions();
}
internal sealed class IcmpDatagramRegistrationAttribute : Attribute
{
public IcmpDatagramRegistrationAttribute(IcmpMessageType messageType)
{
MessageType = messageType;
}
private bool? _isChecksumCorrect;
private Datagram _payload;
public IcmpMessageType MessageType { get; private set; }
}
}
\ No newline at end of file
using System;
using System.Linq;
using PcapDotNet.Base;
......@@ -19,6 +20,7 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+----------------------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.DestinationUnreachable)]
public class IcmpDestinationUnreachableDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{
/// <summary>
......@@ -31,11 +33,6 @@ namespace PcapDotNet.Packets.Icmp
public const int NextHopMtu = 6;
}
internal IcmpDestinationUnreachableDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// The size in octets of the largest datagram that could be forwarded,
/// along the path of the original datagram, without being fragmented at this router.
......@@ -91,6 +88,16 @@ namespace PcapDotNet.Packets.Icmp
get { return _maxCode; }
}
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpDestinationUnreachableDatagram(buffer, offset, length);
}
private IcmpDestinationUnreachableDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
private static readonly byte _minCode = (byte)typeof(IcmpCodeDestinationUnreachable).GetEnumValues<IcmpCodeDestinationUnreachable>().Min();
private static readonly byte _maxCode = (byte)typeof(IcmpCodeDestinationUnreachable).GetEnumValues<IcmpCodeDestinationUnreachable>().Max();
}
......
......@@ -12,13 +12,9 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+-------------+-----------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.DomainNameRequest)]
public class IcmpDomainNameRequestDatagram : IcmpIdentifiedDatagram
{
internal IcmpDomainNameRequestDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
......@@ -31,5 +27,15 @@ namespace PcapDotNet.Packets.Icmp
SequenceNumber = SequenceNumber
};
}
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpDomainNameRequestDatagram(buffer, offset, length);
}
private IcmpDomainNameRequestDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
......@@ -15,6 +17,7 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+-------------------------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.Echo)]
public class IcmpEchoDatagram : IcmpIdentifiedDatagram
{
/// <summary>
......@@ -30,7 +33,12 @@ namespace PcapDotNet.Packets.Icmp
};
}
internal IcmpEchoDatagram(byte[] buffer, int offset, int length)
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpEchoDatagram(buffer, offset, length);
}
private IcmpEchoDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
......
using System;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
......@@ -15,6 +17,7 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+-------------------------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.EchoReply)]
public class IcmpEchoReplyDatagram : IcmpIdentifiedDatagram
{
/// <summary>
......@@ -30,7 +33,12 @@ namespace PcapDotNet.Packets.Icmp
};
}
internal IcmpEchoReplyDatagram(byte[] buffer, int offset, int length)
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpEchoReplyDatagram(buffer, offset, length);
}
private IcmpEchoReplyDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
......
using System;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
......@@ -12,13 +14,9 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+-------------+-----------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.InformationReply)]
public class IcmpInformationReplyDatagram : IcmpIdentifiedDatagram
{
internal IcmpInformationReplyDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
......@@ -31,5 +29,15 @@ namespace PcapDotNet.Packets.Icmp
SequenceNumber = SequenceNumber
};
}
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpInformationReplyDatagram(buffer, offset, length);
}
private IcmpInformationReplyDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
......@@ -12,13 +14,9 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+-------------+-----------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.InformationRequest)]
public class IcmpInformationRequestDatagram : IcmpIdentifiedDatagram
{
internal IcmpInformationRequestDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
......@@ -31,5 +29,15 @@ namespace PcapDotNet.Packets.Icmp
SequenceNumber = SequenceNumber
};
}
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpInformationRequestDatagram(buffer, offset, length);
}
private IcmpInformationRequestDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
}
}
\ No newline at end of file
......@@ -18,6 +18,7 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+----------------------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.ParameterProblem)]
public class IcmpParameterProblemDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{
private static class Offset
......@@ -34,11 +35,6 @@ namespace PcapDotNet.Packets.Icmp
get { return this[Offset.Pointer]; }
}
internal IcmpParameterProblemDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
......@@ -60,5 +56,15 @@ namespace PcapDotNet.Packets.Icmp
{
return base.CalculateIsValid() && Pointer < IpV4.Length;
}
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpParameterProblemDatagram(buffer, offset, length);
}
private IcmpParameterProblemDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
}
}
\ No newline at end of file
......@@ -21,6 +21,7 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+--------------------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.Redirect)]
public class IcmpRedirectDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{
private static class Offset
......@@ -36,11 +37,6 @@ namespace PcapDotNet.Packets.Icmp
get { return ReadIpV4Address(Offset.GatewayInternetAddress, Endianity.Big); }
}
internal IcmpRedirectDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
......@@ -70,6 +66,16 @@ namespace PcapDotNet.Packets.Icmp
get { return _maxCode; }
}
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpRedirectDatagram(buffer, offset, length);
}
private IcmpRedirectDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
private static readonly byte _minCode = (byte)typeof(IcmpCodeRedirect).GetEnumValues<IcmpCodeRedirect>().Min();
private static readonly byte _maxCode = (byte)typeof(IcmpCodeRedirect).GetEnumValues<IcmpCodeRedirect>().Max();
}
......
......@@ -29,6 +29,7 @@ namespace PcapDotNet.Packets.Icmp
/// | . | . |
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.RouterAdvertisement)]
public class IcmpRouterAdvertisementDatagram : IcmpDatagram
{
/// <summary>
......@@ -125,9 +126,9 @@ namespace PcapDotNet.Packets.Icmp
Length == HeaderLength + NumberOfAddresses * AddressEntrySize * IpV4Address.SizeOf;
}
internal IcmpRouterAdvertisementDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpRouterAdvertisementDatagram(buffer, offset, length);
}
internal static int GetPayloadLength(int numEntries)
......@@ -145,6 +146,11 @@ namespace PcapDotNet.Packets.Icmp
}
}
private IcmpRouterAdvertisementDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
private ReadOnlyCollection<IcmpRouterAdvertisementEntry> _entries;
}
}
\ No newline at end of file
using System;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
......@@ -12,13 +14,9 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+-------------------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.RouterSolicitation)]
public class IcmpRouterSolicitationDatagram : IcmpDatagram
{
internal IcmpRouterSolicitationDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
......@@ -26,5 +24,15 @@ namespace PcapDotNet.Packets.Icmp
{
return new IcmpRouterSolicitationLayer();
}
private IcmpRouterSolicitationDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpRouterSolicitationDatagram(buffer, offset, length);
}
}
}
\ No newline at end of file
......@@ -20,6 +20,7 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+------------------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.SecurityFailures)]
public class IcmpSecurityFailuresDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{
private static class Offset
......@@ -27,11 +28,6 @@ namespace PcapDotNet.Packets.Icmp
public const int Pointer = 6;
}
internal IcmpSecurityFailuresDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// An offset into the Original Internet Headers that locates the most significant octet of the offending SPI.
/// Will be zero when no SPI is present.
......@@ -79,6 +75,16 @@ namespace PcapDotNet.Packets.Icmp
get { return _maxCode; }
}
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpSecurityFailuresDatagram(buffer, offset, length);
}
private IcmpSecurityFailuresDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
private static readonly byte _minCode = (byte)typeof(IcmpCodeSecurityFailure).GetEnumValues<IcmpCodeSecurityFailure>().Min();
private static readonly byte _maxCode = (byte)typeof(IcmpCodeSecurityFailure).GetEnumValues<IcmpCodeSecurityFailure>().Max();
}
......
......@@ -18,13 +18,9 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+-------------------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.SourceQuench)]
public class IcmpSourceQuenchDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{
internal IcmpSourceQuenchDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
......@@ -35,5 +31,15 @@ namespace PcapDotNet.Packets.Icmp
Checksum = Checksum
};
}
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpSourceQuenchDatagram(buffer, offset, length);
}
private IcmpSourceQuenchDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
}
}
\ No newline at end of file
......@@ -19,13 +19,9 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+-------------------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.TimeExceeded)]
public class IcmpTimeExceededDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{
internal IcmpTimeExceededDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
......@@ -54,8 +50,17 @@ namespace PcapDotNet.Packets.Icmp
get { return _maxCode; }
}
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpTimeExceededDatagram(buffer, offset, length);
}
private IcmpTimeExceededDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
private static readonly byte _minCode = (byte)typeof(IcmpCodeTimeExceeded).GetEnumValues<IcmpCodeTimeExceeded>().Min();
private static readonly byte _maxCode = (byte)typeof(IcmpCodeTimeExceeded).GetEnumValues<IcmpCodeTimeExceeded>().Max();
}
}
\ No newline at end of file
......@@ -21,6 +21,7 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+-------------------------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.Timestamp)]
public class IcmpTimestampDatagram : IcmpIdentifiedDatagram
{
/// <summary>
......@@ -40,11 +41,6 @@ namespace PcapDotNet.Packets.Icmp
public const int TransmitTimestamp = 16;
}
internal IcmpTimestampDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// The time the sender last touched the message before sending it.
/// </summary>
......@@ -93,6 +89,16 @@ namespace PcapDotNet.Packets.Icmp
return base.CalculateIsValid() && Length == DatagramLength;
}
internal IcmpTimestampDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpTimestampDatagram(buffer, offset, length);
}
internal static void WriteHeaderAdditional(byte[] buffer, int offset, IpV4TimeOfDay originateTimestamp, IpV4TimeOfDay receiveTimestamp, IpV4TimeOfDay transmitTimestamp)
{
buffer.Write(ref offset, originateTimestamp, Endianity.Big);
......
......@@ -18,13 +18,9 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+-------------------------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.TimestampReply)]
public class IcmpTimestampReplyDatagram : IcmpTimestampDatagram
{
internal IcmpTimestampReplyDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
......@@ -40,5 +36,15 @@ namespace PcapDotNet.Packets.Icmp
TransmitTimestamp = TransmitTimestamp
};
}
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpTimestampReplyDatagram(buffer, offset, length);
}
private IcmpTimestampReplyDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
}
}
\ No newline at end of file
......@@ -22,6 +22,7 @@ namespace PcapDotNet.Packets.Icmp
/// +-----+---------------------------------------+
/// </pre>
/// </summary>
[IcmpDatagramRegistration(IcmpMessageType.TraceRoute)]
public class IcmpTraceRouteDatagram : IcmpDatagram
{
/// <summary>
......@@ -48,11 +49,6 @@ namespace PcapDotNet.Packets.Icmp
public const int OutputLinkMtu = 16;
}
internal IcmpTraceRouteDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// The ID Number as copied from the IP Traceroute option of the packet which caused this Traceroute message to be sent.
/// This is NOT related to the ID number in the IP header.
......@@ -148,6 +144,11 @@ namespace PcapDotNet.Packets.Icmp
get { return _maxCode; }
}
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
return new IcmpTraceRouteDatagram(buffer, offset, length);
}
internal static void WriteHeaderAdditional(byte[] buffer, int offset, ushort outboundHopCount, ushort returnHopCount, uint outputLinkSpeed, uint outputLinkMtu)
{
buffer.Write(ref offset, outboundHopCount, Endianity.Big);
......@@ -156,6 +157,11 @@ namespace PcapDotNet.Packets.Icmp
buffer.Write(offset, outputLinkMtu, Endianity.Big);
}
private IcmpTraceRouteDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
private static readonly byte _minCode = (byte)typeof(IcmpCodeTraceRoute).GetEnumValues<IcmpCodeTraceRoute>().Min();
private static readonly byte _maxCode = (byte)typeof(IcmpCodeTraceRoute).GetEnumValues<IcmpCodeTraceRoute>().Max();
}
......
using System;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
......@@ -5,17 +7,6 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpUnknownDatagram : IcmpDatagram
{
/// <summary>
/// Take only part of the bytes as a datagarm.
/// </summary>
/// <param name="buffer">The bytes to take the datagram from.</param>
/// <param name="offset">The offset in the buffer to start taking the bytes from.</param>
/// <param name="length">The number of bytes to take.</param>
internal IcmpUnknownDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary>
/// Creates a Layer that represents the datagram to be used with PacketBuilder.
/// </summary>
......@@ -38,5 +29,21 @@ namespace PcapDotNet.Packets.Icmp
{
return false;
}
/// <summary>
/// Take only part of the bytes as a datagarm.
/// </summary>
/// <param name="buffer">The bytes to take the datagram from.</param>
/// <param name="offset">The offset in the buffer to start taking the bytes from.</param>
/// <param name="length">The number of bytes to take.</param>
internal IcmpUnknownDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
internal override IcmpDatagram CreateInstance(byte[] buffer, int offset, int length)
{
throw new InvalidOperationException("Unknown Icmp Datagram can't be a prototype");
}
}
}
\ No newline at end of file
......@@ -61,7 +61,7 @@ namespace PcapDotNet.Packets
private static OptionTypeRegistrationAttribute GetRegistrationAttribute(Type type)
{
var registraionAttributes =
from attribute in type.GetCustomAttributes(typeof(OptionTypeRegistrationAttribute), false).Cast<OptionTypeRegistrationAttribute>()
from attribute in type.GetCustomAttributes<OptionTypeRegistrationAttribute>(false)
where attribute.OptionTypeType == typeof(TOptionType)
select attribute;
......@@ -71,12 +71,6 @@ namespace PcapDotNet.Packets
return registraionAttributes.First();
}
// [DebuggerHidden]
// private OptionComplexFactory()
// {
// throw new NotImplementedException();
// }
private static readonly Dictionary<TOptionType, IOptionComplexFactory> _complexOptions = InitializeComplexOptions();
private static readonly IOptionUnknownFactory<TOptionType> UnknownFactoryOptionPrototype = InitializeUnknownOptionPrototype();
}
......
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