< Adding C# Ipv6 & Ipv6 Fragment Header Definition Classes 3 | Main | Adding C# ICMP & Ipv6 Echo Request & UDP Header Classes 5 >

 


 

Chapter 8 Part 16:

Client (and Server) Sockets Communication

 

 

What do we have in this chapter 8 Part 16?

  1. Creating Protocols Header Definition Class (C#) 4

 

Creating Protocols Header Definition Class (C#) 4

 

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 >