Example #1
0
        /* here we search through all the frag we have collected to see if
         * one fits */
        bool check_fragments(int index, PacketDotNet.TcpPacket tcpPacket)
        {
            TcpFrag prev = null;
            TcpFrag current;

            current = frags[index];
            while (current != null)
            {
                if (current.seq == seq[index])
                {
                    /* this fragment fits the stream */
                    if (current.data != null)
                    {
                        write_packet_data(index, current.data, tcpPacket);
                    }
                    seq[index] += current.len;
                    if (prev != null)
                    {
                        prev.next = current.next;
                    }
                    else
                    {
                        frags[index] = current.next;
                    }
                    current.data = null;
                    current      = null;
                    return(true);
                }
                prev    = current;
                current = current.next;
            }
            return(false);
        }
Example #2
0
        /// <summary>
        /// Reconstructs the tcp session
        /// </summary>
        /// <param name="sequence">Sequence number of the tcp packet</param>
        /// <param name="length">The size of the original packet data</param>
        /// <param name="data">The captured data</param>
        /// <param name="data_length">The length of the captured data</param>
        /// <param name="synflag"></param>
        /// <param name="net_src">The source ip address</param>
        /// <param name="net_dst">The destination ip address</param>
        /// <param name="srcport">The source port</param>
        /// <param name="dstport">The destination port</param>
        private void reassemble_tcp(ulong sequence, ulong length, byte[] data,
                                    ulong data_length, bool synflag, long net_src,
                                    long net_dst, uint srcport, uint dstport, PacketDotNet.TcpPacket tcpPacket)
        {
            long    srcx, dstx;
            int     src_index, j;
            bool    first = false;
            ulong   newseq;
            TcpFrag tmp_frag;

            src_index = -1;

            /* Now check if the packet is for this connection. */
            srcx = net_src;
            dstx = net_dst;

            // Check to see if we have seen this source IP and port before.
            // Note: We have to check both source IP and port, the connection
            // might be between two different ports on the same machine.
            for (j = 0; j < 2; j++)
            {
                if (src_addr[j] == srcx && src_port[j] == srcport)
                {
                    src_index = j;
                }
            }

            // We didn't find it if src_index == -1.
            if (src_index < 0)
            {
                // Assign it to a src_index and get going.
                for (j = 0; j < 2; j++)
                {
                    if (src_port[j] == 0)
                    {
                        src_addr[j] = srcx;
                        src_port[j] = srcport;
                        src_index   = j;
                        first       = true;
                        break;
                    }
                }
            }

            if (src_index < 0)
            {
                throw new Exception("ERROR in reassemble_tcp: Too many addresses!");
            }

            if (data_length < length)
            {
                incomplete_tcp_stream = true;
            }

            /* now that we have filed away the srcs, lets get the sequence number stuff
             * figured out */
            if (first)
            {
                /* this is the first time we have seen this src's sequence number */
                seq[src_index] = sequence + length;
                if (synflag)
                {
                    seq[src_index]++;
                }
                /* write out the packet data */
                write_packet_data(src_index, data, tcpPacket);
                return;
            }

            /* if we are here, we have already seen this src, let's
             * try and figure out if this packet is in the right place */
            if (sequence < seq[src_index])
            {
                /* this sequence number seems dated, but
                 * check the end to make sure it has no more
                 * info than we have already seen */
                newseq = sequence + length;
                if (newseq > seq[src_index])
                {
                    ulong new_len;

                    /* this one has more than we have seen. let's get the
                     * payload that we have not seen. */

                    new_len = seq[src_index] - sequence;

                    if (data_length <= new_len)
                    {
                        data                  = null;
                        data_length           = 0;
                        incomplete_tcp_stream = true;
                    }
                    else
                    {
                        data_length -= new_len;
                        byte[] tmpData = new byte[data_length];
                        for (ulong i = 0; i < data_length; i++)
                        {
                            tmpData[i] = data[i + new_len];
                        }

                        data = tmpData;
                    }
                    sequence = seq[src_index];
                    length   = newseq - seq[src_index];

                    /* this will now appear to be right on time :) */
                }
            }
            if (sequence == seq[src_index])
            {
                /* right on time */
                seq[src_index] += length;
                if (synflag)
                {
                    seq[src_index]++;
                }
                if (data != null)
                {
                    write_packet_data(src_index, data, tcpPacket);
                }
                /* done with the packet, see if it caused a fragment to fit */
                while (check_fragments(src_index, tcpPacket))
                {
                    ;
                }
            }
            else
            {
                /* out of order packet */
                if (data_length > 0 && sequence > seq[src_index])
                {
                    tmp_frag          = new TcpFrag();
                    tmp_frag.data     = data;
                    tmp_frag.seq      = sequence;
                    tmp_frag.len      = length;
                    tmp_frag.data_len = data_length;

                    if (frags[src_index] != null)
                    {
                        tmp_frag.next = frags[src_index];
                    }
                    else
                    {
                        tmp_frag.next = null;
                    }
                    frags[src_index] = tmp_frag;
                }
            }
        }