using System; namespace Cosmos.System.Network.IPv4 { /// /// ICMPPacket class. See also: . /// internal class ICMPPacket : IPPacket { /// /// Packet type. /// protected byte icmpType; /// /// Packet code. /// protected byte icmpCode; /// /// Packet CRC. /// protected ushort icmpCRC; /// /// Received reply. /// public static ICMPEchoReply recvd_reply; /// /// Create new inctanse of the class. /// /// Packet data. /// Thrown if packetData is invalid. internal static void ICMPHandler(byte[] packetData) { NetworkStack.debugger.Send("ICMP Handler called"); ICMPPacket icmp_packet = new ICMPPacket(packetData); switch (icmp_packet.ICMP_Type) { case 0: recvd_reply = new ICMPEchoReply(packetData); NetworkStack.debugger.Send("Received ICMP Echo reply from " + recvd_reply.SourceIP.ToString()); break; case 8: ICMPEchoRequest request = new ICMPEchoRequest(packetData); NetworkStack.debugger.Send("Received " + request.ToString()); ICMPEchoReply reply = new ICMPEchoReply(request); NetworkStack.debugger.Send("Sending ICMP Echo reply to " + reply.DestinationIP.ToString()); OutgoingBuffer.AddPacket(reply); NetworkStack.Update(); break; } } /// /// Work around to make VMT scanner include the initFields method /// public static void VMTInclude() { new ICMPPacket(); } /// /// Create new inctanse of the class. /// internal ICMPPacket() : base() { } /// /// Create new inctanse of the class. /// /// Raw data. internal ICMPPacket(byte[] rawData) : base(rawData) { } /// /// Init ICMPPacket fields.1 /// /// Thrown if RawData is invalid or null. protected override void initFields() { //Sys.Console.WriteLine("ICMPPacket.initFields() called;"); base.initFields(); icmpType = RawData[DataOffset]; icmpCode = RawData[DataOffset + 1]; icmpCRC = (ushort)((RawData[DataOffset + 2] << 8) | RawData[DataOffset + 3]); } /// /// Create new inctanse of the class. /// /// Source address. /// Destination address. /// Type. /// Code. /// ID. /// SEQ. /// Data size. /// Thrown if RawData is invalid or null. internal ICMPPacket(Address source, Address dest, byte type, byte code, ushort id, ushort seq, ushort icmpDataSize) : base(icmpDataSize, 1, source, dest, 0x00) { RawData[DataOffset] = type; RawData[DataOffset + 1] = code; RawData[DataOffset + 2] = 0x00; RawData[DataOffset + 3] = 0x00; RawData[DataOffset + 4] = (byte)((id >> 8) & 0xFF); RawData[DataOffset + 5] = (byte)((id >> 0) & 0xFF); RawData[DataOffset + 6] = (byte)((seq >> 8) & 0xFF); RawData[DataOffset + 7] = (byte)((seq >> 0) & 0xFF); icmpCRC = CalcICMPCRC((ushort)(icmpDataSize + 8)); RawData[DataOffset + 2] = (byte)((icmpCRC >> 8) & 0xFF); RawData[DataOffset + 3] = (byte)((icmpCRC >> 0) & 0xFF); initFields(); } /// /// Calculate ICMP CRC3. /// /// Lenght. /// protected ushort CalcICMPCRC(ushort length) { return CalcOcCRC(DataOffset, length); } /// /// Get ICMP type. /// internal byte ICMP_Type => icmpType; /// /// Get ICMP code. /// internal byte ICMP_Code => icmpCode; /// /// Get ICMP CRC. /// internal ushort ICMP_CRC => icmpCRC; /// /// Get ICMP data length. /// internal ushort ICMP_DataLength => (ushort)(DataLength - 8); /// /// Get ICMP data. /// /// byte array value. internal byte[] GetICMPData() { byte[] data = new byte[ICMP_DataLength]; for (int b = 0; b < ICMP_DataLength; b++) { data[b] = RawData[DataOffset + 8 + b]; } return data; } /// /// To string. /// /// string value. public override string ToString() { return "ICMP Packet Src=" + SourceIP + ", Dest=" + DestinationIP + ", Type=" + icmpType + ", Code=" + icmpCode; } } /// /// ICMPEchoRequest class. See also: . /// internal class ICMPEchoRequest : ICMPPacket { protected ushort icmpID; protected ushort icmpSequence; /// /// Create new inctanse of the class. /// internal ICMPEchoRequest() { } /// /// Create new inctanse of the class. /// /// Raw data. internal ICMPEchoRequest(byte[] rawData) : base(rawData) { } internal ICMPEchoRequest(Address source, Address dest, ushort id, ushort sequence) : base(source, dest, 8, 0, id, sequence, 40) { for (int b = 8; b < ICMP_DataLength; b++) { RawData[DataOffset + b] = (byte)b; } RawData[DataOffset + 2] = 0x00; RawData[DataOffset + 3] = 0x00; icmpCRC = CalcICMPCRC((ushort)(ICMP_DataLength + 8)); RawData[DataOffset + 2] = (byte)((icmpCRC >> 8) & 0xFF); RawData[DataOffset + 3] = (byte)((icmpCRC >> 0) & 0xFF); } /// /// Work around to make VMT scanner include the initFields method /// public new static void VMTInclude() { new ICMPEchoRequest(); } protected override void initFields() { //Sys.Console.WriteLine("ICMPEchoRequest.initFields() called;"); base.initFields(); icmpID = (ushort)((RawData[DataOffset + 4] << 8) | RawData[DataOffset + 5]); icmpSequence = (ushort)((RawData[DataOffset + 6] << 8) | RawData[DataOffset + 7]); } internal ushort ICMP_ID => icmpID; internal ushort ICMP_Sequence => icmpSequence; /// /// To string. /// /// string value. public override string ToString() { return "ICMP Echo Request Src=" + SourceIP + ", Dest=" + DestinationIP + ", ID=" + icmpID + ", Sequence=" + icmpSequence; } } /// /// ICMPEchoReply class. See also: . /// internal class ICMPEchoReply : ICMPPacket { protected ushort icmpID; protected ushort icmpSequence; /// /// Create new inctanse of the class. /// internal ICMPEchoReply() { } /// /// Create new inctanse of the class. /// /// Raw data. internal ICMPEchoReply(byte[] rawData) : base(rawData) { } /// /// Work around to make VMT scanner include the initFields method /// public new static void VMTInclude() { new ICMPEchoReply(); } /// /// Init ICMPEchoReply fields. /// /// Thrown if RawData is invalid or null. protected override void initFields() { //Sys.Console.WriteLine("ICMPEchoReply.initFields() called;"); base.initFields(); icmpID = (ushort)((RawData[DataOffset + 4] << 8) | RawData[DataOffset + 5]); icmpSequence = (ushort)((RawData[DataOffset + 6] << 8) | RawData[DataOffset + 7]); } /// /// Create new inctanse of the class. /// /// ICMP echo request. /// Thrown if RawData is invalid or null. internal ICMPEchoReply(ICMPEchoRequest request) : base(request.DestinationIP, request.SourceIP, 0, 0, request.ICMP_ID, request.ICMP_Sequence, (ushort)(request.ICMP_DataLength + 8)) { for (int b = 0; b < ICMP_DataLength; b++) { RawData[DataOffset + 8 + b] = request.RawData[DataOffset + 8 + b]; } RawData[DataOffset + 2] = 0x00; RawData[DataOffset + 3] = 0x00; icmpCRC = CalcICMPCRC((ushort)(ICMP_DataLength + 8)); RawData[DataOffset + 2] = (byte)((icmpCRC >> 8) & 0xFF); RawData[DataOffset + 3] = (byte)((icmpCRC >> 0) & 0xFF); } /// /// Get ICMP ID. /// internal UInt16 ICMP_ID => icmpID; /// /// Get ICMP sequence. /// internal UInt16 ICMP_Sequence => icmpSequence; /// /// To string. /// /// string value. public override string ToString() { return "ICMP Echo Reply Src=" + SourceIP + ", Dest=" + DestinationIP + ", ID=" + icmpID + ", Sequence=" + icmpSequence; } } }