public TcpConnection(TcpPair pair)
        {
            for (int i = 0; i != 2; i++)
            {
                tcbs[i]    = new TCB();
                streams[i] = new TcpStream();
            }

            ConnectionID = GetID();
            Pair         = pair;
        }
Exemple #2
0
        private TcpConnection GetConnection(TcpPair pair)
        {
            TcpConnection conn = null;

            if (!connPool.ContainsKey(pair))
            {
                connPool[pair] = new TcpConnection(pair);
            }
            conn = connPool[pair];

            return(conn);
        }
        public void Save(TcpConnection conn)
        {
            TcpPair pair = conn.Pair;
            string  aip  = pair.AIP.ToString().Replace(':', ' ');
            string  bip  = pair.BIP.ToString().Replace(':', ' ');

            string[] name = new string[]
            {
                string.Format("S[{0}][{1}]D[{2}][{3}]_{4}", aip, pair.APort, bip, pair.BPort, conn.ConnectionID),
                string.Format("S[{0}][{1}]D[{2}][{3}]_{4}", bip, pair.BPort, aip, pair.APort, conn.ConnectionID)
            };

            for (int i = 0; i != 2; i++)
            {
                FileInfo info = new FileInfo(Path.Combine(new string[] { SavePath, name[i] }));
                using (var fs = info.Create())
                {
                    conn.Stream(i).Data.Seek(0, SeekOrigin.Begin);
                    conn.Stream(i).Data.CopyTo(fs);
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// Add a packet to the Reassembly
        /// </summary>
        /// <param name="packet"></param>
        public void AddPacket(IpV4Datagram packet)
        {
            if (packet.Protocol != IpV4Protocol.Tcp)
            {
                return;
            }

            TcpDatagram tcpp      = packet.Transport as TcpDatagram;
            int         tcpLength = packet.TotalLength
                                    - packet.HeaderLength;

            UInt32 origDataLength = (UInt32)(tcpLength - tcpp.HeaderLength);
            // packet.PayloadData.Length < origDataLength means not fully captured.

            IPAddress sip  = IPAddress.Parse(packet.Source.ToString());
            IPAddress dip  = IPAddress.Parse(packet.Destination.ToString());
            TcpPair   pair = new TcpPair(new IPEndPoint(sip, tcpp.SourcePort),
                                         new IPEndPoint(dip, tcpp.DestinationPort));

            tcp_reassemble(tcpp.SequenceNumber, tcpp.AcknowledgmentNumber,
                           origDataLength, tcpp.Payload.ToArray(),
                           tcpp.ControlBits, pair);
        }
Exemple #5
0
        /// <summary>
        /// Reassembly tcp stream
        /// </summary>
        /// <param name="sequence">Sequence number of the tcp packet</param>
        /// <param name="acknowledgement">Acknowledgement number of the tcp packet</param>
        /// <param name="length">Length of the original payload data</param>
        /// <param name="data">Actual captured data</param>
        /// <param name="flags">All control bits of the tcp packet</param>
        /// <param name="pair">Tcp end point pair, we use its AEP as source and BEP as destination</param>
        private void tcp_reassemble(UInt32 sequence, UInt32 acknowledgement, UInt32 length, Byte[] data,
                                    TcpControlBits flags, TcpPair pair)
        {
            // First to get a TcpConnection object, which can either be seen before
            // or a newly created one.
            TcpConnection conn = GetConnection(pair);

            // Check our direction.
            int dir = conn.Pair.AEP.Equals(pair.AEP) ? 0 : 1;

            // Cache some useful object, this is packet receiver. (Only reference here.)
            TCB       tcb    = conn.ControlBlock(dir);
            TcpStream stream = conn.Stream(dir);

            // Whether we have trunced the packet
            if (data.Length < length)
            {
                stream.IsTrunced = true;
            }

            // Before adding data for this flow to the data_out_file, check whether
            // this frame acks fragments that were already seen. This happens when
            // frames are not in the capture file, but were actually seen by the
            // receiving host.
            if (conn.Stream(1 - dir).FragListHead != null)
            {
                while (checkFragment(conn, 1 - dir, acknowledgement))
                {
                    ;
                }
            }

            // now lets get the sequence number stuff figured out
            if (tcb.State == TcpState.CLOSED)
            {
                // Transmit FSM state.
                tcb.Transit(flags, true);
                conn.ControlBlock(1 - dir).Transit(flags, false); // the other side.

                // This is the first time we see sequence number (in this direction)
                tcb.seq = sequence + length;
                if (flags.HasFlag(TcpControlBits.Synchronize))
                {
                    tcb.seq++; // we hold next seq, and in case of syn, next seq is sequence+1
                }
                else
                {
                    // A new conversation should start with three-way handshake, thus syn should be set
                    // but if not, it may means that we are dealing with a connection
                    // which was captured half way.
                    stream.IsTrunced = true;
                }

                conn.WritePacketData(dir, data);
                return;
            }

            // If we got here, it means we've seen packets in this connection and direction

            // transit fsm state.
            tcb.Transit(flags, true);
            conn.ControlBlock(1 - dir).Transit(flags, false);

            // Warning: I didn't care about sequence number wrap-around in
            // all comparisons of sequence numbers. I'm not sure if this will
            // cause problems.
            // check if this packet is in right place
            if (sequence < tcb.seq)
            {
                // the sequence number seems dated,
                // but check the end to make sure it has no more
                // info than we have seen.
                UInt32 endseq = sequence + length;
                if (endseq > tcb.seq)
                {
                    // here's more than we have seen.
                    // Get the payload that we have not seen.
                    UInt32 new_offset = tcb.seq - sequence;

                    if (data.Length <= new_offset)
                    {
                        // Unfortunately, we didn't captured that.
                        // so only useless data left.
                        data             = null;
                        stream.IsTrunced = true;
                    }
                    else
                    {
                        Byte[] tmp = new Byte[data.Length - new_offset];
                        Array.Copy(data, new_offset, tmp, 0, tmp.Length);
                        data = tmp;
                    }

                    // Make things appear to be right on time.
                    sequence = tcb.seq;
                    length   = endseq - sequence;
                }
            }

            if (sequence == tcb.seq)
            {
                // right on time
                tcb.seq += length;
                if (flags.HasFlag(TcpControlBits.Synchronize))
                {
                    tcb.seq++;
                }

                if (data != null)
                {
                    conn.WritePacketData(dir, data);
                }

                if (flags.HasFlag(TcpControlBits.Fin))
                {
                    if (conn.CloseStream(dir))
                    {
                        CloseConnection(conn);
                    }
                }

                // done with the packet, see if it cause a fragment to fit.
                // pass 0 to ack because we don't need to check ack here.
                // should been checked above, before add data.
                while (checkFragment(conn, dir, 0))
                {
                    ;
                }
            }
            else
            {
                // out of order packet
                if (data.Length > 0 && sequence > tcb.seq)
                {
                    TcpFrag frag = new TcpFrag()
                    {
                        seq   = sequence,
                        len   = length,
                        data  = data,
                        flags = flags
                    };

                    // Add to fragment list
                    if (stream.FragListHead == null)
                    {
                        frag.next           = null;
                        stream.FragListHead = frag;
                    }
                    else
                    {
                        frag.next           = stream.FragListHead;
                        stream.FragListHead = frag;
                    }
                }
            }
        }