/// ************************************************************************
/// Copyright (C) 2001, Patrick Charles and Jonas Lehmann *
/// Distributed under the Mozilla Public License *
/// http://www.mozilla.org/NPL/MPL-1.1.txt *
/// *************************************************************************
///
using System;
using AnsiEscapeSequences_Fields = SharpPcap.Packets.Util.AnsiEscapeSequences_Fields;
using ArrayHelper = SharpPcap.Packets.Util.ArrayHelper;
using Timeval = SharpPcap.Packets.Util.Timeval;
namespace SharpPcap.Packets
{
/// An ICMP packet.
///
/// Extends an IP packet, adding an ICMP header and ICMP data payload.
///
///
[Serializable]
public class ICMPPacket : IPPacket, ICMPFields
{
/// Fetch the ICMP header a byte array.
virtual public byte[] ICMPHeader
{
get
{
return PacketEncoding.extractHeader(_ipOffset, ICMPFields_Fields.ICMP_HEADER_LEN, Bytes);
}
}
/// Fetch the ICMP header as a byte array.
override public byte[] Header
{
get
{
return ICMPHeader;
}
}
/// Fetch the ICMP data as a byte array.
virtual public byte[] ICMPData
{
get
{
int dataLen = Bytes.Length - _ipOffset - ICMPFields_Fields.ICMP_HEADER_LEN;
return PacketEncoding.extractData(_ipOffset, ICMPFields_Fields.ICMP_HEADER_LEN, Bytes, dataLen);
}
}
/// Fetch the ICMP message type code. Formerly .getMessageType().
virtual public int MessageMajorCode
{
get
{
return ArrayHelper.extractInteger(Bytes, _ipOffset + ICMPFields_Fields.ICMP_CODE_POS, ICMPFields_Fields.ICMP_CODE_LEN);
}
set
{
ArrayHelper.insertLong(Bytes, value, _ipOffset + ICMPFields_Fields.ICMP_CODE_POS, ICMPFields_Fields.ICMP_CODE_LEN);
}
}
/// use getMessageMajorCode().
///
virtual public int MessageType
{
get
{
return MessageMajorCode;
}
set
{
MessageMajorCode = value;
}
}
/// Fetch the ICMP message type, including subcode. Return value can be
/// used with ICMPMessage.getDescription().
///
/// a 2-byte value containing the message type in the high byte
/// and the message type subcode in the low byte.
///
virtual public int MessageCode
{
get
{
return ArrayHelper.extractInteger(Bytes, _ipOffset + ICMPFields_Fields.ICMP_SUBC_POS, ICMPFields_Fields.ICMP_SUBC_LEN);
}
set
{
ArrayHelper.insertLong(Bytes, value, _ipOffset + ICMPFields_Fields.ICMP_SUBC_POS, ICMPFields_Fields.ICMP_SUBC_LEN);
}
}
/// Fetch the ICMP message subcode.
virtual public int MessageMinorCode
{
get
{
return ArrayHelper.extractInteger(Bytes, _ipOffset + ICMPFields_Fields.ICMP_CODE_POS + 1, ICMPFields_Fields.ICMP_CODE_LEN);
}
set
{
ArrayHelper.insertLong(Bytes, value, _ipOffset + ICMPFields_Fields.ICMP_CODE_POS + 1, ICMPFields_Fields.ICMP_CODE_LEN);
}
}
//UPGRADE_NOTE: Respective javadoc comments were merged. It should be changed in order to comply with .NET documentation conventions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1199'"
/// Fetch the ICMP header checksum.
/// Sets the ICMP header checksum.
virtual public int ICMPChecksum
{
get
{
return ArrayHelper.extractInteger(Bytes, _ipOffset + ICMPFields_Fields.ICMP_CSUM_POS, ICMPFields_Fields.ICMP_CSUM_LEN);
}
set
{
ArrayHelper.insertLong(Bytes, value, _ipOffset + ICMPFields_Fields.ICMP_CSUM_POS, ICMPFields_Fields.ICMP_CSUM_LEN);
}
}
virtual public bool ValidICMPChecksum
{
get
{
throw new System.NotImplementedException();
}
}
/// Fetch ascii escape sequence of the color associated with this packet type.
override public System.String Color
{
get
{
return AnsiEscapeSequences_Fields.LIGHT_BLUE;
}
}
public ICMPPacket(int lLen, byte[] bytes)
: base(lLen, bytes)
{
}
public ICMPPacket(int lLen, byte[] bytes, Timeval tv)
: this(lLen, bytes)
{
this._timeval = tv;
}
/// Fetch the ICMP data as a byte array.
public override byte[] Data
{
get
{
return ICMPData;
}
}
/// Fetch the ICMP header checksum.
public int Checksum
{
get
{
return ICMPChecksum;
}
set
{
ICMPChecksum = value;
}
}
/// Computes the ICMP checksum, optionally updating the ICMP checksum header.
///
///
/// Specifies whether or not to update the ICMP checksum
/// header after computing the checksum. A value of true indicates
/// the header should be updated, a value of false indicates it
/// should not be updated.
///
/// The computed ICMP checksum.
///
public int ComputeICMPChecksum(bool update)
{
//return base.ComputeTransportLayerChecksum(ICMPFields_Fields.ICMP_CSUM_POS, update, false);
throw new System.NotImplementedException();
}
/// Same as computeICMPChecksum(true);
///
///
/// The computed ICMP checksum value.
///
public int ComputeICMPChecksum()
{
return ComputeICMPChecksum(true);
}
/// Convert this ICMP packet to a readable string.
public override System.String ToString()
{
return ToColoredString(false);
}
/// Generate string with contents describing this ICMP packet.
/// whether or not the string should contain ansi
/// color escape sequences.
///
public override System.String ToColoredString(bool colored)
{
System.Text.StringBuilder buffer = new System.Text.StringBuilder();
buffer.Append('[');
if (colored)
buffer.Append(Color);
buffer.Append("ICMPPacket");
if (colored)
buffer.Append(AnsiEscapeSequences_Fields.RESET);
buffer.Append(": ");
buffer.Append(ICMPMessage.getDescription(MessageCode));
buffer.Append(", ");
buffer.Append(SourceAddress + " -> " + DestinationAddress);
buffer.Append(" l=" + ICMPFields_Fields.ICMP_HEADER_LEN + "," + (Bytes.Length - _ipOffset - ICMPFields_Fields.ICMP_HEADER_LEN));
buffer.Append(']');
return buffer.ToString();
}
}
}