Esempio n. 1
0
 internal void RemoveData(uint firstSequenceNumber, int bytesToRemove)
 {
     if (this.dataList.Keys[0] != firstSequenceNumber)
     {
         throw new Exception("The data (first data sequence number: " + this.dataList.Keys[0] + ") is not equal to " + firstSequenceNumber);
     }
     else
     {
         while (this.dataList.Count > 0 && this.dataList.Keys[0] + this.dataList.Values[0].Length <= firstSequenceNumber + bytesToRemove)
         {
             this.dataList.RemoveAt(0);
         }
         //see if we need to do a partial removal of a tcp packet
         if (this.dataList.Count > 0 && this.dataList.Keys[0] < firstSequenceNumber + bytesToRemove)
         {
             uint   newFirstSequenceNumber = firstSequenceNumber + (uint)bytesToRemove;
             byte[] oldData       = this.dataList.Values[0];
             byte[] truncatedData = new byte[this.dataList.Keys[0] + oldData.Length - newFirstSequenceNumber];
             Array.Copy(oldData, oldData.Length - truncatedData.Length, truncatedData, 0, truncatedData.Length);
             this.dataList.RemoveAt(0);
             this.dataList.Add(newFirstSequenceNumber, truncatedData);
         }
         this.virtualTcpData = null;
     }
 }
Esempio n. 2
0
 internal VirtualTcpData GetNextVirtualTcpData()
 {
     if (this.virtualTcpData == null)
     {
         if (this.dataList.Count > 0 && this.CountBytesToRead() > 0 && this.CountPacketsToRead() > 0)
         {
             if (this.streamIsClientToServer)
             {
                 this.virtualTcpData = new VirtualTcpData(this, this.networkFlow.FiveTuple.ClientPort, this.networkFlow.FiveTuple.ServerPort);
             }
             else
             {
                 this.virtualTcpData = new VirtualTcpData(this, this.networkFlow.FiveTuple.ServerPort, this.networkFlow.FiveTuple.ClientPort);
             }
             return(virtualTcpData);
         }
         else
         {
             return(null);
         }
     }
     else if (virtualTcpData.TryAppendNextPacket())
     {
         return(virtualTcpData);
     }
     else
     {
         return(null);
     }
 }
 internal TcpDataStream(uint initialTcpSequenceNumber, ushort sourcePort, ushort destinationPort, NetworkTcpSession session)
 {
     this.initialTcpSequenceNumber  = initialTcpSequenceNumber;
     this.expectedTcpSequenceNumber = initialTcpSequenceNumber;
     this.sourcePort      = sourcePort;
     this.destinationPort = destinationPort;
     this.dataList        = new SortedList <uint, byte[]>();
     this.dataListMaxSize = 64;//i hope I shouldn't need more than 64 packets in the list. It depends on how late a misordered packet might get received. Smaller number gives better performance, larger number gives better tolerance to reordered packets
     this.totalByteCount  = 0;
     this.virtualTcpData  = null;
     this.session         = session;
 }
Esempio n. 4
0
            public TcpDataStream(uint initialTcpSequenceNumber, bool streamIsClientToServer, NetworkTcpSession session)
            {
                this.initialTcpSequenceNumber  = initialTcpSequenceNumber;
                this.expectedTcpSequenceNumber = initialTcpSequenceNumber;
                //this.sourcePort=sourcePort;
                //this.destinationPort=destinationPort;
                this.dataList = new SortedList <uint, byte[]>();
                //this.dataListMaxSize=64;//i hope I shouldn't need more than 64 packets in the list. It depends on how late a misordered packet might get received. Smaller number gives better performance, larger number gives better tolerance to reordered packets
                this.dataListMaxSize = 256;//allows data packets to be out-of-order up to 256 packets apart from each other in the same unidirectional stream

                //this.totalByteCount=0;
                this.virtualTcpData = null;
                this.session        = session;
                this.networkFlow    = session.Flow;
                //this.protocolFinder = session.protocolFinder;
                this.streamIsClientToServer = streamIsClientToServer;
            }
 internal VirtualTcpData GetNextVirtualTcpData()
 {
     if (this.virtualTcpData == null)
     {
         if (this.dataList.Count > 0 && this.CountBytesToRead() > 0 && this.CountPacketsToRead() > 0)
         {
             this.virtualTcpData = new VirtualTcpData(this, this.sourcePort, this.destinationPort);
             return(virtualTcpData);
         }
         else
         {
             return(null);
         }
     }
     else if (virtualTcpData.TryAppendNextPacket())
     {
         return(virtualTcpData);
     }
     else
     {
         return(null);
     }
 }
Esempio n. 6
0
 internal void RemoveData(VirtualTcpData data)
 {
     this.RemoveData(data.FirstPacketSequenceNumber, data.ByteCount);
 }
Esempio n. 7
0
            public void AddTcpData(uint tcpSequenceNumber, byte[] tcpSegmentData)
            {
                if (tcpSegmentData.Length > 0)//It is VERY important that no 0 length data arrays are added! There is otherwise a big risk for getting stuck in forever-loops etc.

                //ensure that only new data is written to the dataList
                //partially overlapping resent frames are handled here
                {
                    if ((int)(expectedTcpSequenceNumber - tcpSequenceNumber) > 0 && expectedTcpSequenceNumber - tcpSequenceNumber < tcpSegmentData.Length)
                    {
                        //remove the stuff that has already been parsed
                        uint   bytesToSkip    = expectedTcpSequenceNumber - tcpSequenceNumber;
                        byte[] newSegmentData = new byte[tcpSegmentData.Length - bytesToSkip];
                        Array.Copy(tcpSegmentData, bytesToSkip, newSegmentData, 0, newSegmentData.Length);
                        tcpSegmentData     = newSegmentData;
                        tcpSequenceNumber += bytesToSkip;
                    }
                    //see if we've missed part of the handshake and are now seeing the first data with lower sequence number
                    if (this.TotalByteCount == 0 && initialTcpSequenceNumber == expectedTcpSequenceNumber && (int)(expectedTcpSequenceNumber - tcpSequenceNumber) > 0 && (int)(tcpSequenceNumber - expectedTcpSequenceNumber) < 12345)
                    {
                        this.initialTcpSequenceNumber  = tcpSequenceNumber;
                        this.expectedTcpSequenceNumber = tcpSequenceNumber;
                    }
                    //A check that the tcpSequenceNumber is a reasonable one, i.e. not smaller than expected and not too large
                    if ((int)(expectedTcpSequenceNumber - tcpSequenceNumber) <= 0 && tcpSequenceNumber - expectedTcpSequenceNumber < 1234567)
                    {
                        if (!dataList.ContainsKey(tcpSequenceNumber))
                        {
                            //handle partially overlapping TCP segments that have arrived previously
                            IList <uint> tcpSequenceNumbers = dataList.Keys;
                            //we wanna know if we already have an already stored sequence nr. where: new tcpSeqNr < stored tcpSeqNr < new tcpSeqNr + new tcpSeqData.Length

                            /*
                             * //METHOD #1
                             * for (int i = 0; i < tcpSequenceNumbers.Count; i++) { //this part should be replaced by a binary search function to reduce complexity
                             *  if (tcpSequenceNumbers[i] > tcpSequenceNumber) {
                             *      if (tcpSequenceNumbers[i] < tcpSequenceNumber + tcpSegmentData.Length) {
                             *          //we need to truncate the data since parts of it has already been received
                             *          uint bytesToKeep = tcpSequenceNumbers[i] - tcpSequenceNumber;
                             *          byte[] newSegmentData = new byte[bytesToKeep];
                             *          Array.Copy(tcpSegmentData, 0, newSegmentData, 0, bytesToKeep);
                             *          tcpSegmentData = newSegmentData;
                             *      }
                             *      break;
                             *  }
                             * }
                             * */


                            //METHOD #2
                            for (int i = tcpSequenceNumbers.Count - 1; i >= 0; i--)
                            {
                                if (tcpSequenceNumbers[i] < tcpSequenceNumber)
                                {
                                    break;
                                }
                                else if (tcpSequenceNumbers[i] < tcpSequenceNumber + tcpSegmentData.Length)
                                {
                                    //we need to truncate the data since parts of it has already been received
                                    uint   bytesToKeep    = tcpSequenceNumbers[i] - tcpSequenceNumber;
                                    byte[] newSegmentData = new byte[bytesToKeep];
                                    Array.Copy(tcpSegmentData, 0, newSegmentData, 0, bytesToKeep);
                                    tcpSegmentData = newSegmentData;
                                }
                            }
                            //avoid addint TCP keep-alive null-data (one byte)
                            // a keepalive contains 0 or 1 bytes of data and has a sequence nr that is next_expected-1, never SYN/FIN/RST
                            //if (tcpSegmentData.Length == 1 && tcpSegmentData[0] == 0)
                            //    System.Diagnostics.Debugger.Break();

                            //Avoid adding TCP data for TCP-keepalives with "fake" one-byte L7 data (null value)
                            if (tcpSegmentData.Length > 1 || tcpSegmentData[0] != 0 || this.TotalByteCount > 0)
                            {
                                dataList.Add(tcpSequenceNumber, tcpSegmentData);
                                this.TotalByteCount += tcpSegmentData.Length;
                            }

                            if (expectedTcpSequenceNumber == tcpSequenceNumber)
                            {
                                expectedTcpSequenceNumber += (uint)tcpSegmentData.Length;
                                //check if there are other packets that arrived too early that follows this packet
                                while (dataList.ContainsKey(expectedTcpSequenceNumber))
                                {
                                    expectedTcpSequenceNumber += (uint)dataList[expectedTcpSequenceNumber].Length;
                                }
                            }

                            while (dataList.Count > this.dataListMaxSize)
                            {
                                if (!this.dataListIsTruncated)
                                {
                                    Utils.Logger.Log("Too many unparsed queued packets, queue will be truncated for : " + this.networkFlow.FiveTuple.ToString(), System.Diagnostics.EventLogEntryType.Warning);
#if DEBUG
                                    if (!debugHasBreaked)
                                    {
                                        System.Diagnostics.Debugger.Break();
                                        debugHasBreaked = true;
                                    }
#endif
                                }
                                dataList.RemoveAt(0);            //remove the oldest TCP data
                                this.dataListIsTruncated = true;
                                this.virtualTcpData      = null; //this one has to be reset so that the virtualPacket still will work
                            }
                        }
                        else  //let's replace the old TCP packet with the new one
                              //Or maybe just skip it!
                        {
                        }
                    }
                }
            }
            internal void AddTcpData(uint tcpSequenceNumber, byte[] tcpSegmentData)
            {
                if (tcpSegmentData.Length > 0)//It is VERY important that no 0 length data arrays are added! There is otherwise a big risk for getting stuck in forever-loops etc.

                //ensure that only new data is written to the dataList
                //partially overlapping resent frames are handled here
                {
                    if ((int)(expectedTcpSequenceNumber - tcpSequenceNumber) > 0 && expectedTcpSequenceNumber - tcpSequenceNumber < tcpSegmentData.Length)
                    {
                        //remove the stuff that has already been parsed
                        uint   bytesToSkip    = expectedTcpSequenceNumber - tcpSequenceNumber;
                        byte[] newSegmentData = new byte[tcpSegmentData.Length - bytesToSkip];
                        Array.Copy(tcpSegmentData, bytesToSkip, newSegmentData, 0, newSegmentData.Length);
                        tcpSegmentData     = newSegmentData;
                        tcpSequenceNumber += bytesToSkip;
                    }
                    //A check that the tcpSequenceNumber is a reasonable one, i.e. not smaller that expected and not too large
                    if ((int)(expectedTcpSequenceNumber - tcpSequenceNumber) <= 0 && tcpSequenceNumber - expectedTcpSequenceNumber < 1000000)
                    {
                        if (!dataList.ContainsKey(tcpSequenceNumber))
                        {
                            //handle partially overlapping TCP segments that have arrived previously
                            IList <uint> tcpSequenceNumbers = dataList.Keys;
                            //we wanna know if we already have an already stored sequence nr. where: new tcpSeqNr < stored tcpSeqNr < new tcpSeqNr + new tcpSeqData.Length

                            /*
                             * //METHOD #1
                             * for (int i = 0; i < tcpSequenceNumbers.Count; i++) { //this part should be replaced by a binary search function to reduce complexity
                             *  if (tcpSequenceNumbers[i] > tcpSequenceNumber) {
                             *      if (tcpSequenceNumbers[i] < tcpSequenceNumber + tcpSegmentData.Length) {
                             *          //we need to truncate the data since parts of it has already been received
                             *          uint bytesToKeep = tcpSequenceNumbers[i] - tcpSequenceNumber;
                             *          byte[] newSegmentData = new byte[bytesToKeep];
                             *          Array.Copy(tcpSegmentData, 0, newSegmentData, 0, bytesToKeep);
                             *          tcpSegmentData = newSegmentData;
                             *      }
                             *      break;
                             *  }
                             * }
                             * */


                            //METHOD #2
                            for (int i = tcpSequenceNumbers.Count - 1; i >= 0; i--)
                            {
                                if (tcpSequenceNumbers[i] < tcpSequenceNumber)
                                {
                                    break;
                                }
                                else if (tcpSequenceNumbers[i] < tcpSequenceNumber + tcpSegmentData.Length)
                                {
                                    //we need to truncate the data since parts of it has already been received
                                    uint   bytesToKeep    = tcpSequenceNumbers[i] - tcpSequenceNumber;
                                    byte[] newSegmentData = new byte[bytesToKeep];
                                    Array.Copy(tcpSegmentData, 0, newSegmentData, 0, bytesToKeep);
                                    tcpSegmentData = newSegmentData;
                                }
                            }

                            dataList.Add(tcpSequenceNumber, tcpSegmentData);
                            this.totalByteCount += tcpSegmentData.Length;
                            if (expectedTcpSequenceNumber == tcpSequenceNumber)
                            {
                                expectedTcpSequenceNumber += (uint)tcpSegmentData.Length;
                                //check if there are other packets that arrived too early that follows this packet
                                while (dataList.ContainsKey(expectedTcpSequenceNumber))
                                {
                                    expectedTcpSequenceNumber += (uint)dataList[expectedTcpSequenceNumber].Length;
                                }
                            }

                            while (dataList.Count > this.dataListMaxSize)
                            {
                                dataList.RemoveAt(0);       //remove the oldest TCP data
                                this.virtualTcpData = null; //this one has to be reset so that the virtualPacket still will work
                            }
                        }
                        else  //let's replace the old TCP packet with the new one
                              //Or maybe just skip it!
                        {
                        }
                    }
                }
            }