Commit bab1a144 authored by Brickner_cp's avatar Brickner_cp

ICMP

parent 33f0320c
......@@ -6,6 +6,7 @@
<CSharp>
<FormatSettings>
<ANONYMOUS_METHOD_DECLARATION_BRACES>NEXT_LINE</ANONYMOUS_METHOD_DECLARATION_BRACES>
<CASE_BLOCK_BRACES>NEXT_LINE</CASE_BLOCK_BRACES>
<INDENT_SIZE>4</INDENT_SIZE>
<MODIFIERS_ORDER IsNull="False">
<Item>public</Item>
......
namespace PcapDotNet.Packets.Icmp
{
public class IcmpAddressMaskReplyDatagram : IcmpAddressMaskRequestDatagram
{
internal IcmpAddressMaskReplyDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
public override ILayer ExtractLayer()
{
return new IcmpAddressMaskReplyLayer
{
Checksum = Checksum,
Identifier = Identifier,
SequenceNumber = SequenceNumber,
AddressMask = AddressMask
};
}
}
}
\ No newline at end of file
......@@ -40,11 +40,6 @@ namespace PcapDotNet.Packets.Icmp
{
}
internal static void WriteHeaderAdditional(byte[] buffer, int offset, IpV4Address addressMask)
{
buffer.Write(offset, addressMask, Endianity.Big);
}
public override ILayer ExtractLayer()
{
return new IcmpAddressMaskRequestLayer
......@@ -55,24 +50,15 @@ namespace PcapDotNet.Packets.Icmp
AddressMask = AddressMask,
};
}
}
public class IcmpAddressMaskReplyDatagram : IcmpAddressMaskRequestDatagram
{
internal IcmpAddressMaskReplyDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
protected override bool CalculateIsValid()
{
return base.CalculateIsValid() && Length == DatagramLength;
}
public override ILayer ExtractLayer()
internal static void WriteHeaderAdditional(byte[] buffer, int offset, IpV4Address addressMask)
{
return new IcmpAddressMaskReplyLayer
{
Checksum = Checksum,
Identifier = Identifier,
SequenceNumber = SequenceNumber,
AddressMask = AddressMask
};
buffer.Write(offset, addressMask, Endianity.Big);
}
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Icmp
{
public enum IcmpCodeConversionFailed : byte
{
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
UnknownOrUnspecifiedError = 0x00,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
DontConvertOptionPresent = 0x01,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
UnknownMandatoryOptionPresent = 0x02,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
KnownUnsupportedOptionPresent = 0x03,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
UnsupportedTransportProtocol = 0x04,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
OverallLengthExceeded = 0x05,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
IpHeaderLengthExceeded = 0x06,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
TransportProtocolIsBiggerThan255 = 0x07,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
PortConversionOutOfRange = 0x08,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
TransportHeaderLengthExceeded = 0x09,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
Code32BitRolloverMissingAndAckSet = 0x0A,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
UnknownMandatoryTransportOptionPresent = 0x0B,
}
}
\ No newline at end of file
......@@ -46,211 +46,4 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
SourceRouteFailed = 0x05,
}
public enum IcmpCodeTimeExceeded : byte
{
/// <summary>
/// RFC 792.
/// If the gateway processing a datagram finds the time to live field is zero it must discard the datagram.
/// The gateway may also notify the source host via the time exceeded message.
/// </summary>
TimeToLive = 0x00,
/// <summary>
/// RFC 792.
/// If a host reassembling a fragmented datagram cannot complete the reassembly due to missing fragments within its time limit it discards the datagram,
/// and it may send a time exceeded message.
/// If fragment zero is not available then no time exceeded need be sent at all.
/// </summary>
FragmentReassembly = 0x01,
}
public enum IcmpCodeRedirect : byte
{
/// <summary>
/// RFC 792.
/// </summary>
ForTheNetwork = 0x00,
/// <summary>
/// RFC 792.
/// </summary>
ForTheHost = 0x01,
/// <summary>
/// RFC 792.
/// </summary>
ForTheTypeOfServiceAndNetwork = 0x02,
/// <summary>
/// RFC 792.
/// </summary>
ForTheTypeOfServiceAndHost = 0x03,
}
public enum IcmpCodeTraceroute : byte
{
/// <summary>
/// RFC 1393.
/// </summary>
OutboundPacketSuccessfullyForwarded = 0x00,
/// <summary>
/// RFC 1393.
/// </summary>
NoRouteForOutboundPacketDiscarded = 0x01,
}
public enum IcmpCodeConversionFailed : byte
{
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
UnknownOrUnspecifiedError = 0x00,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
DontConvertOptionPresent = 0x01,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
UnknownMandatoryOptionPresent = 0x02,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
KnownUnsupportedOptionPresent = 0x03,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
UnsupportedTransportProtocol = 0x04,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
OverallLengthExceeded = 0x05,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
IpHeaderLengthExceeded = 0x06,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
TransportProtocolIsBiggerThan255 = 0x07,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
PortConversionOutOfRange = 0x08,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
TransportHeaderLengthExceeded = 0x09,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
Code32BitRolloverMissingAndAckSet = 0x0A,
/// <summary>
/// RFC 1475.
/// The introduction of network layer conversion requires a new message type, to report conversion errors.
/// Note that an invalid datagram should result in the sending of some other ICMP message (e.g., parameter problem) or the silent discarding of the datagram.
/// This message is only sent when a valid datagram cannot be converted.
/// </summary>
UnknownMandatoryTransportOptionPresent = 0x0B,
}
public enum IcmpCodeSecurityFailures : byte
{
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram includes a Security Parameters Index (SPI) that is invalid or has expired.
/// </summary>
BadSpi = 0x00,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram failed the authenticity or integrity check for a given SPI.
///
/// <para>
/// Note that the SPI may indicate an outer Encapsulating Security Protocol when a separate Authentication Header SPI is hidden inside.
/// </para>
/// </summary>
AuthenticationFailed = 0x01,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram failed a decompression check for a given SPI.
/// </summary>
DecompressionFailed = 0x02,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram failed a decryption check for a given SPI.
/// </summary>
DecryptionFailed = 0x03,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram will not be accepted without additional authentication.
///
/// <para>
/// In this case, either no SPI is present, or an unsuitable SPI is present.
/// For example, an encryption SPI without integrity arrives from a secure operating system with mutually suspicious users.
/// </para>
/// </summary>
NeedAuthentication = 0x04,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram will not be accepted because it has insufficient authorization.
///
/// <para>
/// In this case, an authentication SPI is present that is inappropriate for the target transport or application.
/// The principle party denoted by the SPI does not have proper authorization for the facilities used by the datagram.
/// For example, the party is authorized for Telnet access, but not for FTP access.
/// </para>
/// </summary>
NeedAuthorization = 0x05,
}
}
namespace PcapDotNet.Packets.Icmp
{
public enum IcmpCodeRedirect : byte
{
/// <summary>
/// RFC 792.
/// </summary>
ForTheNetwork = 0x00,
/// <summary>
/// RFC 792.
/// </summary>
ForTheHost = 0x01,
/// <summary>
/// RFC 792.
/// </summary>
ForTheTypeOfServiceAndNetwork = 0x02,
/// <summary>
/// RFC 792.
/// </summary>
ForTheTypeOfServiceAndHost = 0x03,
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Icmp
{
public enum IcmpCodeSecurityFailures : byte
{
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram includes a Security Parameters Index (SPI) that is invalid or has expired.
/// </summary>
BadSpi = 0x00,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram failed the authenticity or integrity check for a given SPI.
///
/// <para>
/// Note that the SPI may indicate an outer Encapsulating Security Protocol when a separate Authentication Header SPI is hidden inside.
/// </para>
/// </summary>
AuthenticationFailed = 0x01,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram failed a decompression check for a given SPI.
/// </summary>
DecompressionFailed = 0x02,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram failed a decryption check for a given SPI.
/// </summary>
DecryptionFailed = 0x03,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram will not be accepted without additional authentication.
///
/// <para>
/// In this case, either no SPI is present, or an unsuitable SPI is present.
/// For example, an encryption SPI without integrity arrives from a secure operating system with mutually suspicious users.
/// </para>
/// </summary>
NeedAuthentication = 0x04,
/// <summary>
/// RFC 2521.
/// Indicates that a received datagram will not be accepted because it has insufficient authorization.
///
/// <para>
/// In this case, an authentication SPI is present that is inappropriate for the target transport or application.
/// The principle party denoted by the SPI does not have proper authorization for the facilities used by the datagram.
/// For example, the party is authorized for Telnet access, but not for FTP access.
/// </para>
/// </summary>
NeedAuthorization = 0x05,
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Icmp
{
public enum IcmpCodeTimeExceeded : byte
{
/// <summary>
/// RFC 792.
/// If the gateway processing a datagram finds the time to live field is zero it must discard the datagram.
/// The gateway may also notify the source host via the time exceeded message.
/// </summary>
TimeToLive = 0x00,
/// <summary>
/// RFC 792.
/// If a host reassembling a fragmented datagram cannot complete the reassembly due to missing fragments within its time limit it discards the datagram,
/// and it may send a time exceeded message.
/// If fragment zero is not available then no time exceeded need be sent at all.
/// </summary>
FragmentReassembly = 0x01,
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Icmp
{
public enum IcmpCodeTraceroute : byte
{
/// <summary>
/// RFC 1393.
/// </summary>
OutboundPacketSuccessfullyForwarded = 0x00,
/// <summary>
/// RFC 1393.
/// </summary>
NoRouteForOutboundPacketDiscarded = 0x01,
}
}
\ No newline at end of file
using System;
using System.Linq;
using PcapDotNet.Base;
using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.Transport;
namespace PcapDotNet.Packets.Icmp
{
......@@ -21,6 +24,8 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpConversionFailedDatagram : IcmpIpV4PayloadDatagram
{
public const int OriginalDatagramLengthForUnsupportedTransportProtocol = 256;
private class Offset
{
public const int Pointer = 4;
......@@ -44,9 +49,46 @@ namespace PcapDotNet.Packets.Icmp
};
}
protected override bool CalculateIsValid()
{
if (!base.CalculateIsValid())
return false;
IpV4Datagram ip = IpV4;
if ((IcmpCodeConversionFailed)Code == IcmpCodeConversionFailed.UnsupportedTransportProtocol)
return ip.Length == OriginalDatagramLengthForUnsupportedTransportProtocol;
switch (ip.Protocol)
{
case IpV4Protocol.Udp:
return ip.Udp.Length >= UdpDatagram.HeaderLength;
case IpV4Protocol.Tcp:
TcpDatagram tcp = ip.Tcp;
return tcp.Length >= TcpDatagram.HeaderMinimumLength && tcp.Length >= tcp.HeaderLength;
default: // Todo: support more protocols
return true;
}
}
protected override byte MinCodeValue
{
get { return _minCode; }
}
protected override byte MaxCodeValue
{
get { return _maxCode; }
}
internal IcmpConversionFailedDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
private static readonly byte _minCode = (byte)typeof(IcmpCodeConversionFailed).GetEnumValues<IcmpCodeConversionFailed>().Min();
private static readonly byte _maxCode = (byte)typeof(IcmpCodeConversionFailed).GetEnumValues<IcmpCodeConversionFailed>().Max();
}
}
\ No newline at end of file
......@@ -116,14 +116,17 @@ namespace PcapDotNet.Packets.Icmp
protected override bool CalculateIsValid()
{
if (Length < HeaderLength || !IsChecksumCorrect)
return false;
return Length >= HeaderLength && IsChecksumCorrect && Code >= MinCodeValue && Code <= MaxCodeValue;
}
switch (MessageType)
{
default:
return false;
}
protected virtual byte MinCodeValue
{
get { return 0; }
}
protected virtual byte MaxCodeValue
{
get { return 0; }
}
private ushort CalculateChecksum()
......
using System.Linq;
using PcapDotNet.Base;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 792.
/// <pre>
/// +-----+------+------+-----------+
/// | Bit | 0-7 | 8-15 | 16-31 |
/// +-----+------+------+-----------+
/// | 0 | Type | Code | Checksum |
/// +-----+------+------+-----------+
/// | 32 | unused |
/// +-----+-------------------------+
/// | 64 | Internet Header |
/// | | + 64 bits of |
/// | | Original Data Datagram |
/// +-----+-------------------------+
/// </pre>
/// </summary>
public class IcmpDestinationUnreachableDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{
public IcmpDestinationUnreachableDatagram(byte[] buffer, int offset, int length)
......@@ -15,5 +34,18 @@ namespace PcapDotNet.Packets.Icmp
Checksum = Checksum
};
}
protected override byte MinCodeValue
{
get { return _minCode; }
}
protected override byte MaxCodeValue
{
get { return _maxCode; }
}
private static readonly byte _minCode = (byte)typeof(IcmpCodeDestinationUnrechable).GetEnumValues<IcmpCodeDestinationUnrechable>().Min();
private static readonly byte _maxCode = (byte)typeof(IcmpCodeDestinationUnrechable).GetEnumValues<IcmpCodeDestinationUnrechable>().Max();
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 1788.
/// <pre>
/// +-----+------+------+-----------------+
/// | Bit | 0-7 | 8-15 | 16-31 |
/// +-----+------+------+-----------------+
/// | 0 | Type | Code | Checksum |
/// +-----+------+------+-----------------+
/// | 32 | Identifier | Sequence Number |
/// +-----+-------------+-----------------+
/// </pre>
/// </summary>
public class IcmpDomainNameRequestDatagram : IcmpIdentifiedDatagram
{
internal IcmpDomainNameRequestDatagram(byte[] buffer, int offset, int length)
......
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 792.
/// <pre>
/// +-----+------+------+-----------------+
/// | Bit | 0-7 | 8-15 | 16-31 |
/// +-----+------+------+-----------------+
/// | 0 | Type | Code | Checksum |
/// +-----+------+------+-----------------+
/// | 32 | Identifier | Sequence Number |
/// +-----+-------------+-----------------+
/// </pre>
/// </summary>
public class IcmpInformationReplyDatagram : IcmpIdentifiedDatagram
{
internal IcmpInformationReplyDatagram(byte[] buffer, int offset, int length)
......
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 792.
/// <pre>
/// +-----+------+------+-----------------+
/// | Bit | 0-7 | 8-15 | 16-31 |
/// +-----+------+------+-----------------+
/// | 0 | Type | Code | Checksum |
/// +-----+------+------+-----------------+
/// | 32 | Identifier | Sequence Number |
/// +-----+-------------+-----------------+
/// </pre>
/// </summary>
public class IcmpInformationRequestDatagram : IcmpIdentifiedDatagram
{
internal IcmpInformationRequestDatagram(byte[] buffer, int offset, int length)
......
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
......@@ -18,9 +20,19 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public abstract class IcmpIpV4HeaderPlus64BitsPayloadDatagram : IcmpIpV4PayloadDatagram
{
public const int OriginalDatagramPayloadLength = 8;
internal IcmpIpV4HeaderPlus64BitsPayloadDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
protected override bool CalculateIsValid()
{
if (!base.CalculateIsValid())
return false;
return IpV4.Payload.Length == OriginalDatagramPayloadLength;
}
}
}
\ No newline at end of file
......@@ -32,6 +32,15 @@ namespace PcapDotNet.Packets.Icmp
}
}
protected override bool CalculateIsValid()
{
if (!base.CalculateIsValid())
return false;
IpV4Datagram ip = IpV4;
return (ip.Length >= IpV4Datagram.HeaderMinimumLength && ip.Length >= ip.HeaderLength);
}
private IpV4Datagram _ipV4;
}
}
\ No newline at end of file
......@@ -10,6 +10,14 @@ namespace PcapDotNet.Packets.Icmp
{
get { return 0; }
}
public IcmpMessageTypeAndCode MessageTypeAndCode
{
get
{
return (IcmpMessageTypeAndCode)(((ushort)MessageType << 8) | CodeValue);
}
}
public ushort? Checksum { get; set; }
protected virtual uint Value
{
......
......@@ -47,5 +47,10 @@ namespace PcapDotNet.Packets.Icmp
Pointer = Pointer
};
}
protected override bool CalculateIsValid()
{
return base.CalculateIsValid() && Pointer < IpV4.Length;
}
}
}
\ No newline at end of file
using System;
using System.Linq;
using PcapDotNet.Base;
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp
......@@ -48,5 +50,18 @@ namespace PcapDotNet.Packets.Icmp
GatewayInternetAddress = GatewayInternetAddress
};
}
protected override byte MinCodeValue
{
get { return _minCode; }
}
protected override byte MaxCodeValue
{
get { return _maxCode; }
}
private static readonly byte _minCode = (byte)typeof(IcmpCodeRedirect).GetEnumValues<IcmpCodeRedirect>().Min();
private static readonly byte _maxCode = (byte)typeof(IcmpCodeRedirect).GetEnumValues<IcmpCodeRedirect>().Max();
}
}
\ No newline at end of file
......@@ -99,6 +99,23 @@ namespace PcapDotNet.Packets.Icmp
}
}
public override ILayer ExtractLayer()
{
return new IcmpRouterAdvertisementLayer
{
Checksum = Checksum,
Lifetime = Lifetime,
Entries = Entries.ToList()
};
}
protected override bool CalculateIsValid()
{
return base.CalculateIsValid() &&
AddressEntrySize == DefaultAddressEntrySize &&
Length == HeaderLength + NumAddresses * AddressEntrySize * IpV4Address.SizeOf;
}
internal IcmpRouterAdvertisementDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
......@@ -120,14 +137,5 @@ namespace PcapDotNet.Packets.Icmp
}
private ReadOnlyCollection<IcmpRouterAdvertisementEntry> _entries;
public override ILayer ExtractLayer()
{
return new IcmpRouterAdvertisementLayer
{
Checksum = Checksum,
Lifetime = Lifetime,
Entries = Entries.ToList()
};
}
}
}
\ No newline at end of file
using System;
using System.Linq;
using PcapDotNet.Base;
namespace PcapDotNet.Packets.Icmp
{
......@@ -25,6 +27,11 @@ 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.
......@@ -34,19 +41,32 @@ namespace PcapDotNet.Packets.Icmp
get { return ReadUShort(Offset.Pointer, Endianity.Big); }
}
internal IcmpSecurityFailuresDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
public override ILayer ExtractLayer()
{
return new IcmpSecurityFailuresLayer
{
Code = (IcmpCodeSecurityFailures)Code,
Checksum = Checksum,
Pointer = Pointer
};
}
protected override bool CalculateIsValid()
{
return base.CalculateIsValid() && Pointer < IpV4.Length;
}
public override ILayer ExtractLayer()
protected override byte MinCodeValue
{
return new IcmpSecurityFailuresLayer
{
Code = (IcmpCodeSecurityFailures)Code,
Checksum = Checksum,
Pointer = Pointer
};
get { return _minCode; }
}
protected override byte MaxCodeValue
{
get { return _maxCode; }
}
private static readonly byte _minCode = (byte)typeof(IcmpCodeSecurityFailures).GetEnumValues<IcmpCodeSecurityFailures>().Min();
private static readonly byte _maxCode = (byte)typeof(IcmpCodeSecurityFailures).GetEnumValues<IcmpCodeSecurityFailures>().Max();
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 792.
/// <pre>
/// +-----+------+------+-----------+
/// | Bit | 0-7 | 8-15 | 16-31 |
/// +-----+------+------+-----------+
/// | 0 | Type | Code | Checksum |
/// +-----+------+------+-----------+
/// | 32 | unused |
/// +-----+-------------------------+
/// | 64 | Internet Header |
/// | | + 64 bits of |
/// | | Original Data Datagram |
/// +-----+-------------------------+
/// </pre>
/// </summary>
public class IcmpSourceQuenchDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{
public IcmpSourceQuenchDatagram(byte[] buffer, int offset, int length)
......
using System.Linq;
using PcapDotNet.Base;
namespace PcapDotNet.Packets.Icmp
{
/// <summary>
/// RFC 792.
/// <pre>
/// +-----+------+------+-----------+
/// | Bit | 0-7 | 8-15 | 16-31 |
/// +-----+------+------+-----------+
/// | 0 | Type | Code | Checksum |
/// +-----+------+------+-----------+
/// | 32 | unused |
/// +-----+-------------------------+
/// | 64 | Internet Header |
/// | | + 64 bits of |
/// | | Original Data Datagram |
/// +-----+-------------------------+
/// </pre>
/// </summary>
public class IcmpTimeExceededDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{
public IcmpTimeExceededDatagram(byte[] buffer, int offset, int length)
......@@ -15,5 +34,19 @@ namespace PcapDotNet.Packets.Icmp
Checksum = Checksum
};
}
protected override byte MinCodeValue
{
get { return _minCode; }
}
protected override byte MaxCodeValue
{
get { return _maxCode; }
}
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
......@@ -33,6 +33,11 @@ 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>
......@@ -70,9 +75,9 @@ namespace PcapDotNet.Packets.Icmp
};
}
internal IcmpTimestampDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
protected override bool CalculateIsValid()
{
return base.CalculateIsValid() && Length == DatagramLength;
}
internal static void WriteHeaderAdditional(byte[] buffer, int offset, IpV4TimeOfDay originateTimestamp, IpV4TimeOfDay receiveTimestamp, IpV4TimeOfDay transmitTimestamp)
......
using System;
using System.Linq;
using PcapDotNet.Base;
namespace PcapDotNet.Packets.Icmp
{
......@@ -22,7 +24,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary>
public class IcmpTracerouteDatagram : IcmpDatagram
{
public const int DatagramLength = HeaderLength + PayloadLength;
public const int PayloadLength = 12;
public const ushort OutboundReturnHopCountValue = 0xFFFF;
private class Offset
{
......@@ -33,6 +37,11 @@ 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.
......@@ -78,9 +87,38 @@ namespace PcapDotNet.Packets.Icmp
get { return ReadUInt(Offset.OutputLinkMtu, Endianity.Big); }
}
internal IcmpTracerouteDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
public bool IsOutbound
{
get { return ReturnHopCount == OutboundReturnHopCountValue; }
}
public override ILayer ExtractLayer()
{
return new IcmpTracerouteLayer
{
Code = (IcmpCodeTraceroute)Code,
Checksum = Checksum,
Identification = Identification,
OutboundHopCount = OutboundHopCount,
ReturnHopCount = ReturnHopCount,
OutputLinkSpeed = OutputLinkSpeed,
OutputLinkMtu = OutputLinkMtu
};
}
protected override bool CalculateIsValid()
{
return base.CalculateIsValid() && Length == DatagramLength;
}
protected override byte MinCodeValue
{
get { return _minCode; }
}
protected override byte MaxCodeValue
{
get { return _maxCode; }
}
internal static void WriteHeaderAdditional(byte[] buffer, int offset, ushort outboundHopCount, ushort returnHopCount, uint outputLinkSpeed, uint outputLinkMtu)
......@@ -91,18 +129,7 @@ namespace PcapDotNet.Packets.Icmp
buffer.Write(offset, outputLinkMtu, Endianity.Big);
}
public override ILayer ExtractLayer()
{
return new IcmpTracerouteLayer
{
Code = (IcmpCodeTraceroute)Code,
Checksum = Checksum,
Identification = Identification,
OutboundHopCount = OutboundHopCount,
ReturnHopCount = ReturnHopCount,
OutputLinkSpeed = OutputLinkSpeed,
OutputLinkMtu = OutputLinkMtu
};
}
private static readonly byte _minCode = (byte)typeof(IcmpCodeTraceroute).GetEnumValues<IcmpCodeTraceroute>().Min();
private static readonly byte _maxCode = (byte)typeof(IcmpCodeTraceroute).GetEnumValues<IcmpCodeTraceroute>().Max();
}
}
\ No newline at end of file
namespace PcapDotNet.Packets.Icmp
{
// public class IcmpTypedDatagram : Datagram
// {
// public const int HeaderMinimumLength = 4;
//
// internal IcmpTypedDatagram(byte[] buffer, int offset, int length)
// : base(buffer, offset, length)
// {
// }
// }
}
\ No newline at end of file
......@@ -18,5 +18,15 @@ namespace PcapDotNet.Packets.Icmp
Payload = Payload
};
}
protected override byte MinCodeValue
{
get { return byte.MinValue; }
}
protected override byte MaxCodeValue
{
get { return byte.MaxValue; }
}
}
}
\ No newline at end of file
......@@ -17,10 +17,7 @@ namespace PcapDotNet.Packets.Icmp
protected override uint Value
{
get
{
return LayerValue;
}
get { return LayerValue; }
}
protected override void WritePayload(byte[] buffer, int offset)
......
......@@ -387,6 +387,9 @@ namespace PcapDotNet.Packets.IpV4
case IpV4Protocol.InternetGroupManagementProtocol:
return Igmp.IsValid;
case IpV4Protocol.InternetControlMessageProtocol:
return Icmp.IsValid;
default:
// Todo check more protocols
return true;
......
using System;
using System.Collections.Generic;
using System.Linq;
namespace PcapDotNet.Packets
......@@ -23,6 +24,10 @@ namespace PcapDotNet.Packets
_dataLink = new DataLink(dataLinkKind.Value);
}
public PacketBuilder(IEnumerable<ILayer> layers)
:this(layers.ToArray())
{
}
public Packet Build(DateTime timestamp)
{
......
......@@ -73,8 +73,14 @@
<Compile Include="Ethernet\EthernetType.cs" />
<Compile Include="Ethernet\MacAddress.cs" />
<Compile Include="Arp\IArpPreviousLayer.cs" />
<Compile Include="Icmp\IcmpAddressMaskReplyDatagram.cs" />
<Compile Include="Icmp\IcmpAddressMaskReplyLayer.cs" />
<Compile Include="Icmp\IcmpAddressMaskRequestLayer.cs" />
<Compile Include="Icmp\IcmpCodeConversionFailed.cs" />
<Compile Include="Icmp\IcmpCodeRedirect.cs" />
<Compile Include="Icmp\IcmpCodeSecurityFailures.cs" />
<Compile Include="Icmp\IcmpCodeTimeExceeded.cs" />
<Compile Include="Icmp\IcmpCodeTraceroute.cs" />
<Compile Include="Icmp\IcmpConversionFailedLayer.cs" />
<Compile Include="Icmp\IcmpDestinationUnreachableDatagram.cs" />
<Compile Include="Icmp\IcmpDestinationUnreachableLayer.cs" />
......@@ -119,7 +125,6 @@
<Compile Include="Icmp\IcmpTracerouteDatagram.cs" />
<Compile Include="Icmp\IcmpMessageType.cs" />
<Compile Include="Icmp\IcmpMessageTypeAndCode.cs" />
<Compile Include="Icmp\IcmpTypedDatagram.cs" />
<Compile Include="Icmp\IcmpUnknownDatagram.cs" />
<Compile Include="Icmp\IcmpUnknownLayer.cs" />
<Compile Include="IDataLink.cs" />
......
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