ln.types/net/ICMPPacket.cs

92 lines
2.9 KiB
C#

using System;
using System.Security;
namespace ln.types.net
{
public class ICMPHeader
{
public byte Type { get; set; }
public byte Code { get; set; }
public ushort Checksum { get; set; }
public Int32 Rest { get; set; }
public int HeaderLength => 8 + Payload.Length;
public ushort Identifier
{
get => (ushort)(Rest & 0x0000FFFF);
set
{
Rest = (int)(Rest & 0xFFFF0000) | (value & 0x0000FFFF);
}
}
public ushort SequenceNumber
{
get => (ushort)((Rest & 0xFFFF0000) >> 16);
set
{
Rest = (int)(Rest & 0x0000FFFF) | ((value << 16) & 0x0000FFFF);
}
}
public byte[] Payload { get; set; } = new byte[0];
public ICMPHeader()
{
}
public ICMPHeader(byte[] buffer, int offset, int length)
{
if (buffer.Length < 8)
throw new ArgumentOutOfRangeException(nameof(buffer));
if (buffer.Length < (offset + 8))
throw new ArgumentOutOfRangeException(nameof(offset));
if (buffer.Length < (offset + length))
throw new ArgumentOutOfRangeException(nameof(length));
Type = buffer[offset];
Code = buffer[offset + 1];
Checksum = BitConverter.ToUInt16(buffer, offset + 2);
Rest = BitConverter.ToInt32(buffer, offset + 4);
Payload = buffer.Slice(offset + 8);
}
public void Write(byte[] buffer, int offset) => Write(buffer, offset, false);
public void Write(byte[] buffer,int offset,bool performChecksum)
{
if (buffer.Length < HeaderLength)
throw new ArgumentOutOfRangeException(nameof(buffer));
if (buffer.Length < (offset + HeaderLength))
throw new ArgumentOutOfRangeException(nameof(offset));
if (performChecksum)
Checksum = 0;
buffer[offset] = Type;
buffer[offset + 1] = Code;
Array.Copy(BitConverter.GetBytes(Checksum), 0, buffer, offset + 2, 2);
Array.Copy(BitConverter.GetBytes(Rest), 0, buffer, offset + 4, 4);
Array.Copy(Payload, 0, buffer, offset + 8, Payload.Length);
if (performChecksum)
{
Checksum = IPv4Header.PerformChecksum(buffer,offset,HeaderLength);
Array.Copy(BitConverter.GetBytes(Checksum), 0, buffer, offset + 2, 2);
}
}
public byte[] ToBytes(bool performChecksum)
{
byte[] packet = new byte[HeaderLength];
Write(packet, 0, performChecksum);
return packet;
}
public static ICMPHeader Parse(byte[] buffer, int offset, int length)
{
return new ICMPHeader(buffer, offset, length);
}
}
}