Next, add the ICMP for Ipv4 header definition class.
class IcmpHeader : ProtocolHeader { private byte icmpType; // ICMP message type private byte icmpCode; // ICMP message code private ushort icmpChecksum; // Checksum of ICMP header and payload private ushort icmpId; // Message ID private ushort icmpSequence; // ICMP sequence number
static public byte EchoRequestType = 8; // ICMP echo request static public byte EchoRequestCode = 0; // ICMP echo request code static public byte EchoReplyType = 0; // ICMP echo reply static public byte EchoReplyCode = 0; // ICMP echo reply code
static public int IcmpHeaderLength = 8; // Length of ICMP header
/// <summary> /// Default constructor for ICMP packet /// </summary> public IcmpHeader() : base() { icmpType = 0; icmpCode = 0; icmpChecksum = 0; icmpId = 0; icmpSequence = 0; }
/// <summary> /// ICMP message type. /// </summary> public byte Type { get { return icmpType; } set { icmpType = value; } }
/// <summary> /// ICMP message code. /// </summary> public byte Code { get { return icmpCode; } set { icmpCode = value; } }
/// <summary> /// Checksum of ICMP packet and payload. Performs the necessary byte order conversion. /// </summary> public ushort Checksum { get { return (ushort)IPAddress.NetworkToHostOrder((short)icmpChecksum); } set { icmpChecksum = (ushort)IPAddress.HostToNetworkOrder((short)value); } }
/// <summary> /// ICMP message ID. Used to uniquely identify the source of the ICMP packet. /// Performs the necessary byte order conversion. /// </summary> public ushort Id { get { return (ushort)IPAddress.NetworkToHostOrder((short)icmpId); } set { icmpId = (ushort)IPAddress.HostToNetworkOrder((short)value); } }
/// <summary> /// ICMP sequence number. As each ICMP message is sent the sequence should be incremented. /// Performs the necessary byte order conversion. /// </summary> public ushort Sequence { get { return (ushort)IPAddress.NetworkToHostOrder((short)icmpSequence); } set { icmpSequence = (ushort)IPAddress.HostToNetworkOrder((short)value); } }
/// <summary> /// This routine creates an instance of the IcmpHeader class from a byte /// array that is a received IGMP packet. This is useful when a packet /// is received from the network and the header object needs to be /// constructed from those values. /// </summary> /// <param name="icmpPacket">Byte array containing the binary ICMP header</param> /// <param name="bytesCopied">Number of bytes used in header</param> /// <returns>Returns the IcmpHeader object created from the byte array</returns> static public IcmpHeader Create(byte[] icmpPacket, ref int bytesCopied) { IcmpHeader icmpHeader = new IcmpHeader(); int offset = 0;
// Make sure byte array is large enough to contain an ICMP header if (icmpPacket.Length < IcmpHeader.IcmpHeaderLength) return null;
icmpHeader.icmpType = icmpPacket[offset++]; icmpHeader.icmpCode = icmpPacket[offset++]; icmpHeader.icmpChecksum = BitConverter.ToUInt16(icmpPacket, offset); offset += 2; icmpHeader.icmpId = BitConverter.ToUInt16(icmpPacket, offset); offset += 2; icmpHeader.icmpSequence = BitConverter.ToUInt16(icmpPacket, offset); bytesCopied = IcmpHeader.IcmpHeaderLength; return icmpHeader; }
/// <summary> /// This routine builds the ICMP packet suitable for sending on a raw socket. /// It builds the ICMP packet and payload into a byte array and computes /// the checksum. /// </summary> /// <param name="payLoad">Data payload of the ICMP packet</param> /// <returns>Byte array representing the ICMP packet and payload</returns> public override byte[] GetProtocolPacketBytes(byte[] payLoad) { byte[ ] icmpPacket, byteValue; int offset = 0;
icmpPacket = new byte[IcmpHeaderLength + payLoad.Length]; icmpPacket[offset++] = icmpType; icmpPacket[offset++] = icmpCode; icmpPacket[offset++] = 0; // Zero out the checksum until the packet is assembled icmpPacket[offset++] = 0;
byteValue = BitConverter.GetBytes(icmpId); Array.Copy(byteValue, 0, icmpPacket, offset, byteValue.Length); offset += byteValue.Length;
byteValue = BitConverter.GetBytes(icmpSequence); Array.Copy(byteValue, 0, icmpPacket, offset, byteValue.Length); offset += byteValue.Length;
if (payLoad.Length > 0) { Array.Copy(payLoad, 0, icmpPacket, offset, payLoad.Length); offset += payLoad.Length; }
// Compute the checksum over the entire packet Checksum = ComputeChecksum(icmpPacket);
// Put the checksum back into the packet byteValue = BitConverter.GetBytes(icmpChecksum); Array.Copy(byteValue, 0, icmpPacket, 2, byteValue.Length); return icmpPacket; } } |
Then, add the IGMP for Ipv4 header definition class.
class IgmpHeader : ProtocolHeader { private byte igmpVersionType; private byte igmpMaxResponseTime; private ushort igmpChecksum; private IPAddress igmpGroupAddress;
static public int IgmpHeaderLength = 8;
// IGMP message types v1 static public byte IgmpMembershipQuery = 0x11; static public byte IgmpMembershipReport = 0x12; // IGMP message types v2 static public byte IgmpMembershipReportV2 = 0x16; static public byte IgmpLeaveGroup = 0x17;
// IGMP queries and responses are send to the all systems address static public IPAddress AllSystemsAddress = IPAddress.Parse("224.0.0.1");
/// <summary> /// Simple constructor for the IGMP header that initializes the member fields. /// </summary> public IgmpHeader() : base() { igmpVersionType = IgmpMembershipQuery; igmpMaxResponseTime = 0; igmpChecksum = 0; igmpGroupAddress = IPAddress.Any; }
/// <summary> /// Sets both the version and type codes. Since the version and type codes /// are tied together there is only one property which sets both values. /// </summary> public byte VersionType { get { return igmpVersionType; } set { igmpVersionType = value; } }
/// <summary> /// The maximum response time for the IGMP query. /// </summary> public byte MaximumResponseTime { get { return igmpMaxResponseTime; } set { igmpMaxResponseTime = value; } }
/// <summary> /// The multicast group address for the IGMP message. /// </summary> public IPAddress GroupAddress { get { return igmpGroupAddress; } set { igmpGroupAddress = value; } }
/// <summary> /// Checksum value for the IGMP packet and payload. /// </summary> public ushort Checksum { get { return (ushort)IPAddress.NetworkToHostOrder((short)igmpChecksum); } set { igmpChecksum = (ushort)IPAddress.HostToNetworkOrder((short)value); } }
/// <summary> /// This routine creates an instance of the IgmpHeader class from a byte /// array that is a received IGMP packet. This is useful when a packet /// is received from the network and the header object needs to be /// constructed from those values. /// </summary> /// <param name="igmpPacket">Byte array containing the binary IGMP header</param> /// <param name="bytesCopied">Number of bytes used in header</param> /// <returns>Returns the IgmpHeader object created from the byte array</returns> static public IgmpHeader Create(byte[] igmpPacket, ref int bytesCopied) { IgmpHeader igmpHeader = new IgmpHeader(); int offset = 0;
// Verify byte array is large enough to contain IGMP header if (igmpPacket.Length < IgmpHeader.IgmpHeaderLength) return null;
igmpHeader.igmpVersionType = igmpPacket[offset++]; igmpHeader.igmpMaxResponseTime = igmpPacket[offset++]; igmpHeader.igmpChecksum = BitConverter.ToUInt16(igmpPacket, offset);
bytesCopied = IgmpHeader.IgmpHeaderLength; return igmpHeader; }
/// <summary> /// This routine creates the byte array representation of the IGMP packet as it /// would look on the wire. /// </summary> /// <param name="payLoad">Payload to copy after the IGMP header</param> /// <returns>Byte array representing the IGMP header and payload</returns> public override byte[] GetProtocolPacketBytes(byte[] payLoad) { byte[ ] igmpPacket, addressBytes, byteValue; int offset = 0;
igmpPacket = new byte[IgmpHeaderLength + payLoad.Length];
// Build the IGMP packet igmpPacket[offset++] = igmpVersionType; igmpPacket[offset++] = igmpMaxResponseTime; igmpPacket[offset++] = 0; // Zero the checksum for now igmpPacket[offset++] = 0;
// Copy the group address bytes addressBytes = igmpGroupAddress.GetAddressBytes(); Array.Copy(addressBytes, 0, igmpPacket, offset, addressBytes.Length); offset += addressBytes.Length;
// Copy the payload if specified. Normally, there is no payload to the IGMP // packet -- only the IGMP header. if (payLoad.Length > 0) { Array.Copy(payLoad, 0, igmpPacket, offset, payLoad.Length); offset += payLoad.Length; }
// Compute the checksum on the IGMP packet and payload Checksum = ComputeChecksum(igmpPacket);
// Put the checksum value into the packet byteValue = BitConverter.GetBytes(igmpChecksum); Array.Copy(byteValue, 0, igmpPacket, 2, byteValue.Length);
return igmpPacket; } } |
< Adding C# Ipv6 & Ipv6 Fragment Header Definition Classes 3 | Main | Adding C# ICMP & Ipv6 Echo Request & UDP Header Classes 5 >