Commit bab1a144 authored by Brickner_cp's avatar Brickner_cp

ICMP

parent 33f0320c
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
<CSharp> <CSharp>
<FormatSettings> <FormatSettings>
<ANONYMOUS_METHOD_DECLARATION_BRACES>NEXT_LINE</ANONYMOUS_METHOD_DECLARATION_BRACES> <ANONYMOUS_METHOD_DECLARATION_BRACES>NEXT_LINE</ANONYMOUS_METHOD_DECLARATION_BRACES>
<CASE_BLOCK_BRACES>NEXT_LINE</CASE_BLOCK_BRACES>
<INDENT_SIZE>4</INDENT_SIZE> <INDENT_SIZE>4</INDENT_SIZE>
<MODIFIERS_ORDER IsNull="False"> <MODIFIERS_ORDER IsNull="False">
<Item>public</Item> <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 ...@@ -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() public override ILayer ExtractLayer()
{ {
return new IcmpAddressMaskRequestLayer return new IcmpAddressMaskRequestLayer
...@@ -55,24 +50,15 @@ namespace PcapDotNet.Packets.Icmp ...@@ -55,24 +50,15 @@ namespace PcapDotNet.Packets.Icmp
AddressMask = AddressMask, AddressMask = AddressMask,
}; };
} }
}
public class IcmpAddressMaskReplyDatagram : IcmpAddressMaskRequestDatagram protected override bool CalculateIsValid()
{
internal IcmpAddressMaskReplyDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{ {
return base.CalculateIsValid() && Length == DatagramLength;
} }
public override ILayer ExtractLayer() internal static void WriteHeaderAdditional(byte[] buffer, int offset, IpV4Address addressMask)
{ {
return new IcmpAddressMaskReplyLayer buffer.Write(offset, addressMask, Endianity.Big);
{
Checksum = Checksum,
Identifier = Identifier,
SequenceNumber = SequenceNumber,
AddressMask = AddressMask
};
} }
} }
} }
\ 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 ...@@ -46,211 +46,4 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
SourceRouteFailed = 0x05, 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;
using System.Linq;
using PcapDotNet.Base;
using PcapDotNet.Packets.IpV4; using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.Transport;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
{ {
...@@ -21,6 +24,8 @@ namespace PcapDotNet.Packets.Icmp ...@@ -21,6 +24,8 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpConversionFailedDatagram : IcmpIpV4PayloadDatagram public class IcmpConversionFailedDatagram : IcmpIpV4PayloadDatagram
{ {
public const int OriginalDatagramLengthForUnsupportedTransportProtocol = 256;
private class Offset private class Offset
{ {
public const int Pointer = 4; public const int Pointer = 4;
...@@ -44,9 +49,46 @@ namespace PcapDotNet.Packets.Icmp ...@@ -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) internal IcmpConversionFailedDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, 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 ...@@ -116,14 +116,17 @@ namespace PcapDotNet.Packets.Icmp
protected override bool CalculateIsValid() protected override bool CalculateIsValid()
{ {
if (Length < HeaderLength || !IsChecksumCorrect) return Length >= HeaderLength && IsChecksumCorrect && Code >= MinCodeValue && Code <= MaxCodeValue;
return false; }
switch (MessageType) protected virtual byte MinCodeValue
{ {
default: get { return 0; }
return false; }
}
protected virtual byte MaxCodeValue
{
get { return 0; }
} }
private ushort CalculateChecksum() private ushort CalculateChecksum()
......
using System.Linq;
using PcapDotNet.Base;
namespace PcapDotNet.Packets.Icmp 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 class IcmpDestinationUnreachableDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{ {
public IcmpDestinationUnreachableDatagram(byte[] buffer, int offset, int length) public IcmpDestinationUnreachableDatagram(byte[] buffer, int offset, int length)
...@@ -15,5 +34,18 @@ namespace PcapDotNet.Packets.Icmp ...@@ -15,5 +34,18 @@ namespace PcapDotNet.Packets.Icmp
Checksum = Checksum 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 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 public class IcmpDomainNameRequestDatagram : IcmpIdentifiedDatagram
{ {
internal IcmpDomainNameRequestDatagram(byte[] buffer, int offset, int length) internal IcmpDomainNameRequestDatagram(byte[] buffer, int offset, int length)
......
namespace PcapDotNet.Packets.Icmp 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 public class IcmpInformationReplyDatagram : IcmpIdentifiedDatagram
{ {
internal IcmpInformationReplyDatagram(byte[] buffer, int offset, int length) internal IcmpInformationReplyDatagram(byte[] buffer, int offset, int length)
......
namespace PcapDotNet.Packets.Icmp 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 public class IcmpInformationRequestDatagram : IcmpIdentifiedDatagram
{ {
internal IcmpInformationRequestDatagram(byte[] buffer, int offset, int length) internal IcmpInformationRequestDatagram(byte[] buffer, int offset, int length)
......
using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
{ {
/// <summary> /// <summary>
...@@ -18,9 +20,19 @@ namespace PcapDotNet.Packets.Icmp ...@@ -18,9 +20,19 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public abstract class IcmpIpV4HeaderPlus64BitsPayloadDatagram : IcmpIpV4PayloadDatagram public abstract class IcmpIpV4HeaderPlus64BitsPayloadDatagram : IcmpIpV4PayloadDatagram
{ {
public const int OriginalDatagramPayloadLength = 8;
internal IcmpIpV4HeaderPlus64BitsPayloadDatagram(byte[] buffer, int offset, int length) internal IcmpIpV4HeaderPlus64BitsPayloadDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, 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 ...@@ -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; private IpV4Datagram _ipV4;
} }
} }
\ No newline at end of file
...@@ -10,6 +10,14 @@ namespace PcapDotNet.Packets.Icmp ...@@ -10,6 +10,14 @@ namespace PcapDotNet.Packets.Icmp
{ {
get { return 0; } get { return 0; }
} }
public IcmpMessageTypeAndCode MessageTypeAndCode
{
get
{
return (IcmpMessageTypeAndCode)(((ushort)MessageType << 8) | CodeValue);
}
}
public ushort? Checksum { get; set; } public ushort? Checksum { get; set; }
protected virtual uint Value protected virtual uint Value
{ {
......
...@@ -47,5 +47,10 @@ namespace PcapDotNet.Packets.Icmp ...@@ -47,5 +47,10 @@ namespace PcapDotNet.Packets.Icmp
Pointer = Pointer Pointer = Pointer
}; };
} }
protected override bool CalculateIsValid()
{
return base.CalculateIsValid() && Pointer < IpV4.Length;
}
} }
} }
\ No newline at end of file
using System; using System;
using System.Linq;
using PcapDotNet.Base;
using PcapDotNet.Packets.IpV4; using PcapDotNet.Packets.IpV4;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
...@@ -48,5 +50,18 @@ namespace PcapDotNet.Packets.Icmp ...@@ -48,5 +50,18 @@ namespace PcapDotNet.Packets.Icmp
GatewayInternetAddress = GatewayInternetAddress 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 ...@@ -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) internal IcmpRouterAdvertisementDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length) : base(buffer, offset, length)
{ {
...@@ -120,14 +137,5 @@ namespace PcapDotNet.Packets.Icmp ...@@ -120,14 +137,5 @@ namespace PcapDotNet.Packets.Icmp
} }
private ReadOnlyCollection<IcmpRouterAdvertisementEntry> _entries; 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;
using System.Linq;
using PcapDotNet.Base;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
{ {
...@@ -25,6 +27,11 @@ namespace PcapDotNet.Packets.Icmp ...@@ -25,6 +27,11 @@ namespace PcapDotNet.Packets.Icmp
public const int Pointer = 6; public const int Pointer = 6;
} }
internal IcmpSecurityFailuresDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary> /// <summary>
/// An offset into the Original Internet Headers that locates the most significant octet of the offending SPI. /// 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. /// Will be zero when no SPI is present.
...@@ -34,19 +41,32 @@ namespace PcapDotNet.Packets.Icmp ...@@ -34,19 +41,32 @@ namespace PcapDotNet.Packets.Icmp
get { return ReadUShort(Offset.Pointer, Endianity.Big); } get { return ReadUShort(Offset.Pointer, Endianity.Big); }
} }
internal IcmpSecurityFailuresDatagram(byte[] buffer, int offset, int length) public override ILayer ExtractLayer()
: base(buffer, offset, length) {
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 get { return _minCode; }
{
Code = (IcmpCodeSecurityFailures)Code,
Checksum = Checksum,
Pointer = Pointer
};
} }
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 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 class IcmpSourceQuenchDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{ {
public IcmpSourceQuenchDatagram(byte[] buffer, int offset, int length) public IcmpSourceQuenchDatagram(byte[] buffer, int offset, int length)
......
using System.Linq;
using PcapDotNet.Base;
namespace PcapDotNet.Packets.Icmp 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 class IcmpTimeExceededDatagram : IcmpIpV4HeaderPlus64BitsPayloadDatagram
{ {
public IcmpTimeExceededDatagram(byte[] buffer, int offset, int length) public IcmpTimeExceededDatagram(byte[] buffer, int offset, int length)
...@@ -15,5 +34,19 @@ namespace PcapDotNet.Packets.Icmp ...@@ -15,5 +34,19 @@ namespace PcapDotNet.Packets.Icmp
Checksum = Checksum 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 ...@@ -33,6 +33,11 @@ namespace PcapDotNet.Packets.Icmp
public const int TransmitTimestamp = 16; public const int TransmitTimestamp = 16;
} }
internal IcmpTimestampDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary> /// <summary>
/// The time the sender last touched the message before sending it. /// The time the sender last touched the message before sending it.
/// </summary> /// </summary>
...@@ -70,9 +75,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -70,9 +75,9 @@ namespace PcapDotNet.Packets.Icmp
}; };
} }
internal IcmpTimestampDatagram(byte[] buffer, int offset, int length) protected override bool CalculateIsValid()
: base(buffer, offset, length)
{ {
return base.CalculateIsValid() && Length == DatagramLength;
} }
internal static void WriteHeaderAdditional(byte[] buffer, int offset, IpV4TimeOfDay originateTimestamp, IpV4TimeOfDay receiveTimestamp, IpV4TimeOfDay transmitTimestamp) internal static void WriteHeaderAdditional(byte[] buffer, int offset, IpV4TimeOfDay originateTimestamp, IpV4TimeOfDay receiveTimestamp, IpV4TimeOfDay transmitTimestamp)
......
using System; using System;
using System.Linq;
using PcapDotNet.Base;
namespace PcapDotNet.Packets.Icmp namespace PcapDotNet.Packets.Icmp
{ {
...@@ -22,7 +24,9 @@ namespace PcapDotNet.Packets.Icmp ...@@ -22,7 +24,9 @@ namespace PcapDotNet.Packets.Icmp
/// </summary> /// </summary>
public class IcmpTracerouteDatagram : IcmpDatagram public class IcmpTracerouteDatagram : IcmpDatagram
{ {
public const int DatagramLength = HeaderLength + PayloadLength;
public const int PayloadLength = 12; public const int PayloadLength = 12;
public const ushort OutboundReturnHopCountValue = 0xFFFF;
private class Offset private class Offset
{ {
...@@ -33,6 +37,11 @@ namespace PcapDotNet.Packets.Icmp ...@@ -33,6 +37,11 @@ namespace PcapDotNet.Packets.Icmp
public const int OutputLinkMtu = 16; public const int OutputLinkMtu = 16;
} }
internal IcmpTracerouteDatagram(byte[] buffer, int offset, int length)
: base(buffer, offset, length)
{
}
/// <summary> /// <summary>
/// The ID Number as copied from the IP Traceroute option of the packet which caused this Traceroute message to be sent. /// 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. /// This is NOT related to the ID number in the IP header.
...@@ -78,9 +87,38 @@ namespace PcapDotNet.Packets.Icmp ...@@ -78,9 +87,38 @@ namespace PcapDotNet.Packets.Icmp
get { return ReadUInt(Offset.OutputLinkMtu, Endianity.Big); } get { return ReadUInt(Offset.OutputLinkMtu, Endianity.Big); }
} }
internal IcmpTracerouteDatagram(byte[] buffer, int offset, int length) public bool IsOutbound
: base(buffer, offset, length)
{ {
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) internal static void WriteHeaderAdditional(byte[] buffer, int offset, ushort outboundHopCount, ushort returnHopCount, uint outputLinkSpeed, uint outputLinkMtu)
...@@ -91,18 +129,7 @@ namespace PcapDotNet.Packets.Icmp ...@@ -91,18 +129,7 @@ namespace PcapDotNet.Packets.Icmp
buffer.Write(offset, outputLinkMtu, Endianity.Big); buffer.Write(offset, outputLinkMtu, Endianity.Big);
} }
public override ILayer ExtractLayer() private static readonly byte _minCode = (byte)typeof(IcmpCodeTraceroute).GetEnumValues<IcmpCodeTraceroute>().Min();
{ private static readonly byte _maxCode = (byte)typeof(IcmpCodeTraceroute).GetEnumValues<IcmpCodeTraceroute>().Max();
return new IcmpTracerouteLayer
{
Code = (IcmpCodeTraceroute)Code,
Checksum = Checksum,
Identification = Identification,
OutboundHopCount = OutboundHopCount,
ReturnHopCount = ReturnHopCount,
OutputLinkSpeed = OutputLinkSpeed,
OutputLinkMtu = OutputLinkMtu
};
}
} }
} }
\ 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 ...@@ -18,5 +18,15 @@ namespace PcapDotNet.Packets.Icmp
Payload = Payload 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 ...@@ -17,10 +17,7 @@ namespace PcapDotNet.Packets.Icmp
protected override uint Value protected override uint Value
{ {
get get { return LayerValue; }
{
return LayerValue;
}
} }
protected override void WritePayload(byte[] buffer, int offset) protected override void WritePayload(byte[] buffer, int offset)
......
...@@ -387,6 +387,9 @@ namespace PcapDotNet.Packets.IpV4 ...@@ -387,6 +387,9 @@ namespace PcapDotNet.Packets.IpV4
case IpV4Protocol.InternetGroupManagementProtocol: case IpV4Protocol.InternetGroupManagementProtocol:
return Igmp.IsValid; return Igmp.IsValid;
case IpV4Protocol.InternetControlMessageProtocol:
return Icmp.IsValid;
default: default:
// Todo check more protocols // Todo check more protocols
return true; return true;
......
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace PcapDotNet.Packets namespace PcapDotNet.Packets
...@@ -23,6 +24,10 @@ namespace PcapDotNet.Packets ...@@ -23,6 +24,10 @@ namespace PcapDotNet.Packets
_dataLink = new DataLink(dataLinkKind.Value); _dataLink = new DataLink(dataLinkKind.Value);
} }
public PacketBuilder(IEnumerable<ILayer> layers)
:this(layers.ToArray())
{
}
public Packet Build(DateTime timestamp) public Packet Build(DateTime timestamp)
{ {
......
...@@ -73,8 +73,14 @@ ...@@ -73,8 +73,14 @@
<Compile Include="Ethernet\EthernetType.cs" /> <Compile Include="Ethernet\EthernetType.cs" />
<Compile Include="Ethernet\MacAddress.cs" /> <Compile Include="Ethernet\MacAddress.cs" />
<Compile Include="Arp\IArpPreviousLayer.cs" /> <Compile Include="Arp\IArpPreviousLayer.cs" />
<Compile Include="Icmp\IcmpAddressMaskReplyDatagram.cs" />
<Compile Include="Icmp\IcmpAddressMaskReplyLayer.cs" /> <Compile Include="Icmp\IcmpAddressMaskReplyLayer.cs" />
<Compile Include="Icmp\IcmpAddressMaskRequestLayer.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\IcmpConversionFailedLayer.cs" />
<Compile Include="Icmp\IcmpDestinationUnreachableDatagram.cs" /> <Compile Include="Icmp\IcmpDestinationUnreachableDatagram.cs" />
<Compile Include="Icmp\IcmpDestinationUnreachableLayer.cs" /> <Compile Include="Icmp\IcmpDestinationUnreachableLayer.cs" />
...@@ -119,7 +125,6 @@ ...@@ -119,7 +125,6 @@
<Compile Include="Icmp\IcmpTracerouteDatagram.cs" /> <Compile Include="Icmp\IcmpTracerouteDatagram.cs" />
<Compile Include="Icmp\IcmpMessageType.cs" /> <Compile Include="Icmp\IcmpMessageType.cs" />
<Compile Include="Icmp\IcmpMessageTypeAndCode.cs" /> <Compile Include="Icmp\IcmpMessageTypeAndCode.cs" />
<Compile Include="Icmp\IcmpTypedDatagram.cs" />
<Compile Include="Icmp\IcmpUnknownDatagram.cs" /> <Compile Include="Icmp\IcmpUnknownDatagram.cs" />
<Compile Include="Icmp\IcmpUnknownLayer.cs" /> <Compile Include="Icmp\IcmpUnknownLayer.cs" />
<Compile Include="IDataLink.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