Exemplo n.º 1
0
        /// <summary>
        ///		This method will calculate the length field and the checksum then pack the fields
        ///		into a byte array in the format of a udp header. This can then be given data,
        ///		attached to a network layer protocol and then transmitted over the internet.
        /// </summary>
        /// <param name="sourceAddress">
        ///		Destination address required for the checksum calculation.
        ///	</param>
        /// <param name="destAddress">
        ///		Destination address required for the checksum calculation.
        ///	</param>
        /// <returns>
        ///		The return value is a byte array with the udp header at the beginning which can be
        ///		appended to a network layer protocol such as IP.
        /// </returns>
        /// <remarks>
        ///		Note that this method WILL CALCULATE A CHECKSUM.
        ///	</remarks>
        public byte[] Serialize(IPAddress sourceAddress, IPAddress destAddress)
        {
            // allocate enough space for the packet
            byte[] packet = Serialize();

            // the checksum is calculated by constructing a pseudo header consisting of the
            // source/destination addresses, the protocol and the length of the udp packet
            // (length of header + data). This pseudo header is then prefixed on to the
            // udp header and the data and the checksum calculation performed on this.
            #region Calculate Checksum

            // now build the pseudo header used for calculating the checksum. The pseudo header
            // looks like this:
            //
            //  +--------+--------+--------+--------+
            //  |          source address           |
            //  +--------+--------+--------+--------+
            //  |        destination address        |
            //  +--------+--------+--------+--------+
            //  |  zero  |protocol|   UDP length    |
            //  +--------+--------+--------+--------+

            byte[] pseudoHeader = new byte[12];

            // first copy in the source and dest addresses
            Array.Copy(sourceAddress.GetAddressBytes(), 0, pseudoHeader, 0, 4);
            Array.Copy(destAddress.GetAddressBytes(), 0, pseudoHeader, 4, 4);

            // then a 0 byte followed by the protocol id (udp)
            pseudoHeader[8] = 0;
            pseudoHeader[9] = (byte)ProtocolType.Udp;

            // now convert the length to network byte order and copy that in
            Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)m_length)), 0, pseudoHeader, 10, 2);

            // at this point we have build the pseudo header. Now we prefix it onto the udp header
            // and the data (which we already have stored in the variable "packet" as a byte array)
            //
            //  +-----------------------------------+
            //  |          Pseudo Header            |
            //  +-----------------------------------+
            //  |            Udp Header             |
            //  +-----------------------------------+
            //  |                                   |
            //  |          data octets ...
            //  +---------------- ...

            byte[] tempBuffer = new byte[pseudoHeader.Length + packet.Length];
            Array.Copy(pseudoHeader, 0, tempBuffer, 0, pseudoHeader.Length);
            Array.Copy(packet, 0, tempBuffer, pseudoHeader.Length, packet.Length);

            // now finally calculate the checksum from the temp buffer and copy it into
            // the packet
            m_checksum = PacketUtils.CalculateChecksum(tempBuffer);
            Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)m_checksum)), 0, packet, 6, 2);

            #endregion

            return(packet);
        }
Exemplo n.º 2
0
        /// <summary>
        ///		This method will calculate the checksum then pack the fields into a byte array
        ///		in the format of an icmp header. This can then be attached to a network
        ///		layer protocol and then transmitted over the internet.
        /// </summary>
        /// <returns>
        ///		The return value is a byte array with the Icmp header at the beginning which can be
        ///		appended to a network layer protocol such as IP.
        /// </returns>
        public byte[] Serialize()
        {
            // allocate enough space
            byte[] packet = new byte[4 + (m_data != null ? m_data.Length : 0)];

            // copy in the message type
            packet[0] = (byte)m_type;

            // copy in the code
            packet[1] = m_code;

            // and the rest of the data
            if (m_data != null)
            {
                Array.Copy(m_data, 0, packet, 4, m_data.Length);
            }

            // calculate in the checksum
            m_checksum = PacketUtils.CalculateChecksum(packet);
            Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)m_checksum)), 0, packet, 2, 2);


            return(packet);
        }
Exemplo n.º 3
0
        /// <summary>
        ///		This method will calculate several fields such as the checksum then pack the fields
        ///		into a byte array in the format of a tcp header. This can then be attached to a
        ///		network layer protocol and then transmitted over the internet.
        /// </summary>
        /// <returns>
        ///		The return value is a byte array with the tcp header at the beginning which can be
        ///		appended to a network layer protocol such as IP.
        /// </returns>
        public byte[] Serialize(IPAddress sourceAddress, IPAddress destAddress)
        {
            #region Initial Calculations

            m_offset = 0x14;

            if (m_options != null)
            {
                int optionsLength = 0;

                for (int i = 0; i < m_options.Length; i++)
                {
                    optionsLength += m_options[i].Length;
                }

                // if the options field isn't a multiple of 4 it needs padding
                if (optionsLength % 4 != 0)
                {
                    m_padding = new byte[4 - (optionsLength % 4)];
                }

                int paddingLength = (m_padding != null ? m_padding.Length : 0);

                // add on the length of the options field + the new padding onto the header length
                m_offset += (ushort)(optionsLength + paddingLength);
            }

            #endregion

            // allocate a large enough buffer to hold the header + the data
            byte[] buffer   = new byte[m_offset + (m_data != null ? m_data.Length : 0)];
            int    position = 0;

            #region Copy TCP Header Fields

            // copy in the source port
            Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)m_sourcePort)), 0, buffer, position, 2);
            position += 2;

            // copy in the destination port
            Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)m_destPort)), 0, buffer, position, 2);
            position += 2;

            // copy in the sequence number
            Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((int)m_sequenceNumber)), 0, buffer, position, 4);
            position += 4;

            // copy in the acknowledgment number
            Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((int)m_acknowledgmentNumber)), 0, buffer, position, 4);
            position += 4;

            // copy in the offset field
            buffer[position] = (byte)((m_offset / 4) << 4);
            position++;

            // copy in the flags field
            buffer[position] = m_flags;
            position++;

            // copy in the window field
            Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)m_window)), 0, buffer, position, 2);
            position += 2;

            // skip over the checksum field right now. We leave it 0 until we have finished
            // filling in everything else, then we calculate the checksum
            position += 2;

            // copy in the urgent pointer
            Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)m_urgentPointer)), 0, buffer, position, 2);
            position += 2;

            #endregion

            #region Copy In Options

            // now copy in any options
            if (m_options != null)
            {
                // go through each options
                for (int i = 0; i < m_options.Length; i++)
                {
                    buffer[position] = (byte)m_options[i].OptionType;
                    position++;

                    if (m_options[i].OptionType == TcpOptionNumber.EndOfOptions)
                    {
                        break;
                    }
                    else if (m_options[i].OptionType != TcpOptionNumber.NoOperation)
                    {
                        buffer[position] = (byte)m_options[i].Length;
                        position++;
                        Array.Copy(m_options[i].Data, 0, buffer, position, m_options[i].Length - 2);
                        position += m_options[i].Length - 2;
                    }
                }
            }

            // now copy in any padding
            if (m_padding != null)
            {
                Array.Copy(m_padding, 0, buffer, position, m_padding.Length);
                position += m_padding.Length;
            }

            #endregion

            // copy in any data after that
            if (m_data != null)
            {
                Array.Copy(m_data, 0, buffer, position, m_data.Length);
            }

            // the checksum is calculated by constructing a pseudo header consisting of the
            // source/destination addresses, the protocol and the length of the tcp packet
            // (length of header + data). This pseudo header is then prefixed on to the
            // udp header and the data and the checksum calculation performed on this.
            #region Calculate Checksum

            // now build the pseudo header used for calculating the checksum. The pseudo header
            // looks like this:
            //
            //  +--------+--------+--------+--------+
            //  |          source address           |
            //  +--------+--------+--------+--------+
            //  |        destination address        |
            //  +--------+--------+--------+--------+
            //  |  zero  |protocol|   TCP length    |
            //  +--------+--------+--------+--------+

            byte[] pseudoHeader = new byte[12];

            // first copy in the source and dest addresses
            Array.Copy(sourceAddress.GetAddressBytes(), 0, pseudoHeader, 0, 4);
            Array.Copy(destAddress.GetAddressBytes(), 0, pseudoHeader, 4, 4);

            // then a 0 byte followed by the protocol id (tcp)
            pseudoHeader[8] = 0;
            pseudoHeader[9] = (byte)ProtocolType.Tcp;

            // now convert the length to network byte order and copy that in
            Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)(m_offset + (m_data != null ? m_data.Length : 0)))), 0, pseudoHeader, 10, 2);

            // at this point we have build the pseudo header. Now we prefix it onto the tcp header
            // and the data (which we already have stored in the variable "packet" as a byte array)
            //
            //  +-----------------------------------+
            //  |          Pseudo Header            |
            //  +-----------------------------------+
            //  |            Tcp Header             |
            //  +-----------------------------------+
            //  |                                   |
            //  |          data octets ...
            //  +---------------- ...

            byte[] tempBuffer = new byte[pseudoHeader.Length + buffer.Length];
            Array.Copy(pseudoHeader, 0, tempBuffer, 0, pseudoHeader.Length);
            Array.Copy(buffer, 0, tempBuffer, pseudoHeader.Length, buffer.Length);

            // now finally calculate the checksum from the temp buffer and copy it into
            // the packet
            m_checksum = PacketUtils.CalculateChecksum(tempBuffer);
            Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)m_checksum)), 0, buffer, 16, 2);

            #endregion

            return(buffer);
        }