< C# Protocols Header Definition Class 1 | Main | Adding C# Ipv6 & Ipv6 Fragment Header Definition Classes 3 >


 

Chapter 8 Part 14:

Client (and Server) Sockets Communication

 

 

What do we have in this chapter 8 Part 14?

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

 

Creating Protocols Header Definition Class (C#) 2

 

Then add a derived class, Ipv4Header. This is IPv4 definition.

 

 

    /// <summary>

    /// This is the IPv4 protocol header.

    /// </summary>

    class Ipv4Header : ProtocolHeader

    {

        private byte ipVersion;              // actually only 4 bits

        private byte ipLength;                // actually only 4 bits

        private byte ipTypeOfService;

        private ushort ipTotalLength;

        private ushort ipId;

        private ushort ipOffset;

        private byte ipTtl;

        private byte ipProtocol;

        private ushort ipChecksum;

        private IPAddress ipSourceAddress;

        private IPAddress ipDestinationAddress;

 

        static public int Ipv4HeaderLength = 20;

 

        /// <summary>

        /// Simple constructor that initializes the members to zero.

        /// </summary>

        public Ipv4Header(): base()

        {

            ipVersion = 4;

            ipLength = (byte)Ipv4HeaderLength;    // Set the property so it will convert properly

            ipTypeOfService = 0;

            ipId = 0;

            ipOffset = 0;

            ipTtl = 1;

            ipProtocol = 0;

            ipChecksum = 0;

            ipSourceAddress = IPAddress.Any;

            ipDestinationAddress = IPAddress.Any;

        }

 

        /// <summary>

        /// Gets and sets the IP version. This should be 4 to indicate the IPv4 header.

        /// </summary>

        public byte Version

        {

            get

            {

                return ipVersion;

            }

            set

            {

                ipVersion = value;

            }

        }

 

        /// <summary>

        /// Gets and sets the length of the IPv4 header. This property takes and returns

        /// the number of bytes, but the actual field is the number of 32-bit DWORDs

        /// (the IPv4 header is a multiple of 4-bytes).

        /// </summary>

        public byte Length

        {

            get

            {

                return (byte)(ipLength * 4);

            }

            set

            {

                ipLength = (byte)(value / 4);

            }

        }

 

        /// <summary>

        /// Gets and sets the type of service field of the IPv4 header. Since it

        /// is a byte, no byte order conversion is required.

        /// </summary>

        public byte TypeOfService

        {

            get

            {

                return ipTypeOfService;

            }

            set

            {

                ipTypeOfService = value;

            }

        }

 

        /// <summary>

        ///  Gets and sets the total length of the IPv4 header and its encapsulated

        ///  payload. Byte order conversion is required.

        /// </summary>

        public ushort TotalLength

        {

            get

            {

                return (ushort)IPAddress.NetworkToHostOrder((short)ipTotalLength);

            }

            set

            {

                ipTotalLength = (ushort)IPAddress.HostToNetworkOrder((short)value);

            }

        }

 

        /// <summary>

        /// Gets and sets the ID field of the IPv4 header. Byte order conversion is required.

        /// </summary>

        public ushort Id

        {

            get

            {

                return (ushort)IPAddress.NetworkToHostOrder((short)ipId);

            }

            set

            {

                ipId = (ushort)IPAddress.HostToNetworkOrder((short)value);

            }

        }

 

        /// <summary>

        /// Gets and sets the offset field of the IPv4 header which indicates if

        /// IP fragmentation has occurred.

        /// </summary>

        public ushort Offset

        {

            get

            {

                return (ushort)IPAddress.NetworkToHostOrder((short)ipOffset);

            }

            set

            {

                ipOffset = (ushort)IPAddress.HostToNetworkOrder((short)value);

            }

        }

 

        /// <summary>

        /// Gets and sets the time-to-live (TTL) value of the IP header. This field

        /// determines how many router hops the packet is valid for.

        /// </summary>

        public byte Ttl

        {

            get

            {

                return ipTtl;

            }

            set

            {

                ipTtl = value;

            }

        }

 

        /// <summary>

        /// Gets and sets the protocol field of the IPv4 header. This field indicates

        /// what the encapsulated protocol is.

        /// </summary>

        public byte Protocol

        {

            get

            {

                return ipProtocol;

            }

            set

            {

                ipProtocol = value;

            }

        }

 

 

 

 

        /// <summary>

        /// Gets and sets the checksum field of the IPv4 header. For the IPv4 header, the

        /// checksum is calculated over the header and payload. Note that this field isn't

        /// meant to be set by the user as the GetProtocolPacketBytes method computes the

        /// checksum when the packet is built.

        /// </summary>

        public ushort Checksum

        {

            get

            {

                return (ushort)IPAddress.NetworkToHostOrder((short)ipChecksum);

            }

            set

            {

                ipChecksum = (ushort)IPAddress.HostToNetworkOrder((short)value);

            }

        }

 

        /// <summary>

        /// Gets and sets the source IP address of the IPv4 packet. This is stored

        /// as an IPAddress object which will be serialized to the appropriate

        /// byte representation in the GetProtocolPacketBytes method.

        /// </summary>

        public IPAddress SourceAddress

        {

            get

            {

                return ipSourceAddress;

            }

            set

            {

                ipSourceAddress = value;

            }

        }

 

        /// <summary>

        /// Gets and sets the destination IP address of the IPv4 packet. This is stored

        /// as an IPAddress object which will be serialized to the appropriate byte

        /// representation in the GetProtocolPacketBytes method.

        /// </summary>

        public IPAddress DestinationAddress

        {

            get

            {

                return ipDestinationAddress;

            }

            set

            {

                ipDestinationAddress = value;

            }

        }

 

        /// <summary>

        /// This routine creates an instance of the Ipv4Header 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="ipv4Packet">Byte array containing the binary IPv4 header</param>

        /// <param name="bytesCopied">Number of bytes used in header</param>

        /// <returns>Returns the Ipv4Header object created from the byte array</returns>

        static public Ipv4Header Create(byte[ ] ipv4Packet, ref int bytesCopied)

        {

            Ipv4Header ipv4Header = new Ipv4Header();

 

            // Make sure byte array is large enough to contain an IPv4 header

            if (ipv4Packet.Length < Ipv4Header.Ipv4HeaderLength)

                return null;

 

            // Decode the data in the array back into the class properties

            ipv4Header.ipVersion = (byte)((ipv4Packet[0] >> 4) & 0xF);

            ipv4Header.ipLength = (byte)(ipv4Packet[0] & 0xF);

            ipv4Header.ipTypeOfService = ipv4Packet[1];

            ipv4Header.ipTotalLength = BitConverter.ToUInt16(ipv4Packet, 2);

            ipv4Header.ipId = BitConverter.ToUInt16(ipv4Packet, 4);

            ipv4Header.ipOffset = BitConverter.ToUInt16(ipv4Packet, 6);

            ipv4Header.ipTtl = ipv4Packet[8];

            ipv4Header.ipProtocol = ipv4Packet[9];

            ipv4Header.ipChecksum = BitConverter.ToUInt16(ipv4Packet, 10);

 

            ipv4Header.ipSourceAddress = new IPAddress(BitConverter.ToUInt32(ipv4Packet, 12));

            ipv4Header.ipDestinationAddress = new IPAddress(BitConverter.ToUInt32(ipv4Packet, 16));

 

            bytesCopied = ipv4Header.Length;

 

            return ipv4Header;

        }

 

        /// <summary>

        /// This routine takes the properties of the IPv4 header and marhalls them into

        /// a byte array representing the IPv4 header that is to be sent on the wire.

        /// </summary>

        /// <param name="payLoad">The encapsulated headers and data</param>

        /// <returns>A byte array of the IPv4 header and payload</returns>

        public override byte[ ] GetProtocolPacketBytes(byte[ ] payLoad)

        {

            byte[ ] ipv4Packet, byteValue;

            int index = 0;

 

            // Allocate space for the IPv4 header plus payload

            ipv4Packet = new byte[Ipv4HeaderLength + payLoad.Length];

 

            ipv4Packet[index++] = (byte)((ipVersion << 4) | ipLength);

            ipv4Packet[index++] = ipTypeOfService;

 

            byteValue = BitConverter.GetBytes(ipTotalLength);

            Array.Copy(byteValue, 0, ipv4Packet, index, byteValue.Length);

            index += byteValue.Length;

 

            byteValue = BitConverter.GetBytes(ipId);

            Array.Copy(byteValue, 0, ipv4Packet, index, byteValue.Length);

            index += byteValue.Length;

 

            byteValue = BitConverter.GetBytes(ipOffset);

            Array.Copy(byteValue, 0, ipv4Packet, index, byteValue.Length);

            index += byteValue.Length;

 

            ipv4Packet[index++] = ipTtl;

            ipv4Packet[index++] = ipProtocol;

            ipv4Packet[index++] = 0; // Zero the checksum for now since we will

            ipv4Packet[index++] = 0; // calculate it later

 

            // Copy the source address

            byteValue = ipSourceAddress.GetAddressBytes();

            Array.Copy(byteValue, 0, ipv4Packet, index, byteValue.Length);

            index += byteValue.Length;

 

            // Copy the destination address

            byteValue = ipDestinationAddress.GetAddressBytes();

            Array.Copy(byteValue, 0, ipv4Packet, index, byteValue.Length);

            index += byteValue.Length;

 

            // Copy the payload

            Array.Copy(payLoad, 0, ipv4Packet, index, payLoad.Length);

            index += payLoad.Length;

 

            // Compute the checksum over the entire packet (IPv4 header + payload)

            Checksum = ComputeChecksum(ipv4Packet);

 

            // Set the checksum into the built packet

            byteValue = BitConverter.GetBytes(ipChecksum);

            Array.Copy(byteValue, 0, ipv4Packet, 10, byteValue.Length);

 

            return ipv4Packet;

        }

    }

 

 


< C# Protocols Header Definition Class 1 | Main | Adding C# Ipv6 & Ipv6 Fragment Header Definition Classes 3 >