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>
......
...@@ -84,7 +84,8 @@ namespace PcapDotNet.Packets.Test ...@@ -84,7 +84,8 @@ namespace PcapDotNet.Packets.Test
IcmpLayer icmpLayer = random.NextIcmpLayer(); IcmpLayer icmpLayer = random.NextIcmpLayer();
icmpLayer.Checksum = null; icmpLayer.Checksum = null;
bool isIpV4Payload; IpV4Layer icmpIpV4Layer = null;
IEnumerable<ILayer> icmpIpV4PayloadLayers = null;
switch (icmpLayer.MessageType) switch (icmpLayer.MessageType)
{ {
case IcmpMessageType.DestinationUnreachable: case IcmpMessageType.DestinationUnreachable:
...@@ -92,8 +93,47 @@ namespace PcapDotNet.Packets.Test ...@@ -92,8 +93,47 @@ namespace PcapDotNet.Packets.Test
case IcmpMessageType.ParameterProblem: case IcmpMessageType.ParameterProblem:
case IcmpMessageType.SourceQuench: case IcmpMessageType.SourceQuench:
case IcmpMessageType.Redirect: case IcmpMessageType.Redirect:
case IcmpMessageType.SecurityFailures:
icmpIpV4Layer = random.NextIpV4Layer();
icmpIpV4PayloadLayers = new[] {random.NextPayloadLayer(IcmpIpV4HeaderPlus64BitsPayloadDatagram.OriginalDatagramPayloadLength)};
break;
case IcmpMessageType.ConversionFailed: case IcmpMessageType.ConversionFailed:
isIpV4Payload = true; icmpIpV4Layer = random.NextIpV4Layer();
if (icmpLayer.MessageTypeAndCode == IcmpMessageTypeAndCode.ConversionFailedUnsupportedTransportProtocol)
icmpIpV4PayloadLayers = new[]
{
random.NextPayloadLayer(
IcmpConversionFailedDatagram.OriginalDatagramLengthForUnsupportedTransportProtocol - icmpIpV4Layer.Length)
};
else
{
switch (icmpIpV4Layer.Protocol)
{
case IpV4Protocol.Udp:
icmpIpV4PayloadLayers = new ILayer[]
{
random.NextUdpLayer(),
random.NextPayloadLayer(random.Next(100))
};
break;
case IpV4Protocol.Tcp:
icmpIpV4PayloadLayers = new ILayer[]
{
random.NextTcpLayer(),
random.NextPayloadLayer(random.Next(100))
};
break;
default:
icmpIpV4PayloadLayers = new[]
{
random.NextPayloadLayer(random.Next(200))
};
break;
}
}
break; break;
case IcmpMessageType.Echo: case IcmpMessageType.Echo:
...@@ -108,25 +148,35 @@ namespace PcapDotNet.Packets.Test ...@@ -108,25 +148,35 @@ namespace PcapDotNet.Packets.Test
case IcmpMessageType.AddressMaskReply: case IcmpMessageType.AddressMaskReply:
case IcmpMessageType.Traceroute: case IcmpMessageType.Traceroute:
case IcmpMessageType.DomainNameRequest: case IcmpMessageType.DomainNameRequest:
case IcmpMessageType.SecurityFailures:
isIpV4Payload = false;
break; break;
case IcmpMessageType.DomainNameReply: case IcmpMessageType.DomainNameReply:
default: default:
throw new InvalidOperationException("Invalid icmpMessageType " + icmpLayer.MessageType); throw new InvalidOperationException("Invalid icmpMessageType " + icmpLayer.MessageType);
} }
PacketBuilder packetBuilder;
IpV4Layer icmpIpV4Layer = null;
PayloadLayer icmpIpV4PayloadLayer = null;
if (isIpV4Payload)
{
icmpIpV4Layer = random.NextIpV4Layer();
icmpIpV4PayloadLayer = random.NextPayloadLayer(random.Next(200)); int icmpPayloadLength = (icmpIpV4Layer != null ? icmpIpV4Layer.Length + icmpIpV4PayloadLayers.Select(layer => layer.Length).Sum() : 0);
packetBuilder = new PacketBuilder(ethernetLayer, ipV4Layer, icmpLayer, icmpIpV4Layer, icmpIpV4PayloadLayer); switch (icmpLayer.MessageType)
{
// case IcmpMessageType.DestinationUnreachable:
// case IcmpMessageType.TimeExceeded:
case IcmpMessageType.ParameterProblem:
((IcmpParameterProblemLayer)icmpLayer).Pointer %= (byte)icmpPayloadLength;
break;
// case IcmpMessageType.SourceQuench:
// case IcmpMessageType.Redirect:
case IcmpMessageType.SecurityFailures:
((IcmpSecurityFailuresLayer)icmpLayer).Pointer %= (ushort)icmpPayloadLength;
// icmpIpV4Layer = random.NextIpV4Layer();
// icmpIpV4PayloadLayers = new[] {random.NextPayloadLayer(IcmpIpV4HeaderPlus64BitsPayloadDatagram.OriginalDatagramPayloadLength)};
break;
// case IcmpMessageType.ConversionFailed:
} }
PacketBuilder packetBuilder;
if (icmpIpV4Layer != null)
packetBuilder = new PacketBuilder(new ILayer[] {ethernetLayer, ipV4Layer, icmpLayer, icmpIpV4Layer}.Concat(icmpIpV4PayloadLayers));
else else
packetBuilder = new PacketBuilder(ethernetLayer, ipV4Layer, icmpLayer); packetBuilder = new PacketBuilder(ethernetLayer, ipV4Layer, icmpLayer);
...@@ -145,7 +195,7 @@ namespace PcapDotNet.Packets.Test ...@@ -145,7 +195,7 @@ namespace PcapDotNet.Packets.Test
ipV4Layer.HeaderChecksum = null; ipV4Layer.HeaderChecksum = null;
Assert.AreEqual(ipV4Layer.Length, packet.Ethernet.IpV4.HeaderLength); Assert.AreEqual(ipV4Layer.Length, packet.Ethernet.IpV4.HeaderLength);
Assert.IsTrue(packet.Ethernet.IpV4.IsHeaderChecksumCorrect); Assert.IsTrue(packet.Ethernet.IpV4.IsHeaderChecksumCorrect);
Assert.AreEqual(ipV4Layer.Length + icmpLayer.Length + (isIpV4Payload ? icmpIpV4Layer.Length + icmpIpV4PayloadLayer.Length : 0), Assert.AreEqual(ipV4Layer.Length + icmpLayer.Length + icmpPayloadLength,
packet.Ethernet.IpV4.TotalLength); packet.Ethernet.IpV4.TotalLength);
Assert.AreEqual(IpV4Datagram.DefaultVersion, packet.Ethernet.IpV4.Version); Assert.AreEqual(IpV4Datagram.DefaultVersion, packet.Ethernet.IpV4.Version);
...@@ -154,43 +204,45 @@ namespace PcapDotNet.Packets.Test ...@@ -154,43 +204,45 @@ namespace PcapDotNet.Packets.Test
icmpLayer.Checksum = actualIcmpLayer.Checksum; icmpLayer.Checksum = actualIcmpLayer.Checksum;
Assert.AreEqual(icmpLayer, actualIcmpLayer); Assert.AreEqual(icmpLayer, actualIcmpLayer);
Assert.IsTrue(packet.Ethernet.IpV4.Icmp.IsChecksumCorrect); Assert.IsTrue(packet.Ethernet.IpV4.Icmp.IsChecksumCorrect);
Assert.AreEqual(icmpLayer.MessageType, packet.Ethernet.IpV4.Icmp.MessageType);
switch (packet.Ethernet.IpV4.Icmp.MessageType) Assert.AreEqual(icmpLayer.CodeValue, packet.Ethernet.IpV4.Icmp.Code);
{
case IcmpMessageType.DestinationUnreachable: // switch (packet.Ethernet.IpV4.Icmp.MessageType)
// Assert.AreEqual(icmpIpV4Layer, packet.Ethernet.IpV4.Icmp.DestinationUncreachable.IpV4.ExtractLayer()); // {
// case IcmpMessageType.DestinationUnreachable:
case IcmpMessageType.TimeExceeded: //// Assert.AreEqual(icmpIpV4Layer, packet.Ethernet.IpV4.Icmp.DestinationUncreachable.IpV4.ExtractLayer());
case IcmpMessageType.ParameterProblem: //
case IcmpMessageType.SourceQuench: // case IcmpMessageType.TimeExceeded:
case IcmpMessageType.Redirect: // case IcmpMessageType.ParameterProblem:
case IcmpMessageType.ConversionFailed: // case IcmpMessageType.SourceQuench:
isIpV4Payload = true; // case IcmpMessageType.Redirect:
break; // case IcmpMessageType.ConversionFailed:
// isIpV4Payload = true;
case IcmpMessageType.Echo: // break;
case IcmpMessageType.EchoReply: //
case IcmpMessageType.Timestamp: // case IcmpMessageType.Echo:
case IcmpMessageType.TimestampReply: // case IcmpMessageType.EchoReply:
case IcmpMessageType.InformationRequest: // case IcmpMessageType.Timestamp:
case IcmpMessageType.InformationReply: // case IcmpMessageType.TimestampReply:
case IcmpMessageType.RouterAdvertisement: // case IcmpMessageType.InformationRequest:
case IcmpMessageType.RouterSolicitation: // case IcmpMessageType.InformationReply:
// packet.Ethernet.IpV4.Icmp.RouterSolicitation // case IcmpMessageType.RouterAdvertisement:
case IcmpMessageType.AddressMaskRequest: // case IcmpMessageType.RouterSolicitation:
case IcmpMessageType.AddressMaskReply: //// packet.Ethernet.IpV4.Icmp.RouterSolicitation
case IcmpMessageType.Traceroute: // case IcmpMessageType.AddressMaskRequest:
case IcmpMessageType.DomainNameRequest: // case IcmpMessageType.AddressMaskReply:
case IcmpMessageType.SecurityFailures: // case IcmpMessageType.Traceroute:
isIpV4Payload = false; // case IcmpMessageType.DomainNameRequest:
break; // case IcmpMessageType.SecurityFailures:
// isIpV4Payload = false;
case IcmpMessageType.DomainNameReply: // break;
//
default: // case IcmpMessageType.DomainNameReply:
throw new InvalidOperationException("Invalid icmpMessageType " + packet.Ethernet.IpV4.Icmp.MessageType); //
// default:
} // throw new InvalidOperationException("Invalid icmpMessageType " + packet.Ethernet.IpV4.Icmp.MessageType);
//
// }
} }
} }
} }
......
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