public PcapStreamReader(System.IO.Stream pcapStream, int packetQueueSize, StreamReadCompletedCallback streamReadCompletedCallback, bool startBackgroundWorkers, long streamMaxLength, int readTimeoutMilliseconds)
        {
            this.pcapStream              = pcapStream;
            this.streamLength            = streamMaxLength;
            this.readBytesEstimate       = 0;
            this.readTimeoutMilliseconds = readTimeoutMilliseconds;

            this.packetQueueSize             = packetQueueSize;
            this.streamReadCompletedCallback = streamReadCompletedCallback;


            //TODO: Figure out if it is a libpcap or pcapNG stream...
            this.pcapParser = PcapParserFactory.CreatePcapParser(this);// new PcapParser(pcapStream, this.AbortReadingPcapStream);

            /*
             * byte[] buffer4=new byte[4];//32 bits is suitable
             * byte[] buffer2=new byte[2];//16 bits is sometimes needed
             * uint wiresharkMagicNumber=0xa1b2c3d4;
             *
             * //Section Header Block (mandatory)
             *
             * this.pcapStream.Read(buffer4, 0, 4);
             *
             * if(wiresharkMagicNumber==this.ToUInt32(buffer4, false))
             *  this.littleEndian=false;
             * else if(wiresharkMagicNumber==this.ToUInt32(buffer4, true))
             *  this.littleEndian=true;
             * else
             *  throw new System.IO.InvalidDataException("The stream is not a PCAP file. Magic number is "+this.ToUInt32(buffer4, false).ToString("X2")+" or "+this.ToUInt32(buffer4, true).ToString("X2")+" but should be "+wiresharkMagicNumber.ToString("X2")+".");
             *
             *
             * this.pcapStream.Read(buffer2, 0, 2);
             * this.majorVersionNumber=ToUInt16(buffer2, this.littleEndian);
             *
             * this.pcapStream.Read(buffer2, 0, 2);
             * this.minorVersionNumber=ToUInt16(buffer2, this.littleEndian);
             *
             * this.pcapStream.Read(buffer4, 0, 4);
             * this.timezoneOffsetSeconds=(int)ToUInt32(buffer4, this.littleEndian);
             *
             * this.pcapStream.Read(buffer4, 0, 4);
             *
             * this.pcapStream.Read(buffer4, 0, 4);
             * this.maximumPacketSize=ToUInt32(buffer4, this.littleEndian);
             *
             * this.pcapStream.Read(buffer4, 0, 4); //offset = 20 = 0x14
             * this.dataLinkType=(DataLinkType)ToUInt32(buffer4, this.littleEndian);
             */
            //this.pcapHeaderSize = this.pcapStream.Position;

            this.backgroundStreamReader = new System.ComponentModel.BackgroundWorker();
            this.backgroundStreamReader.WorkerSupportsCancellation = true;
            this.packetQueue       = new Queue <PcapFrame>(this.packetQueueSize);
            this.enqueuedByteCount = 0;
            this.dequeuedByteCount = 0;
            if (startBackgroundWorkers)
            {
                this.StartBackgroundWorkers();
            }
        }
Beispiel #2
0
        public void Dispose()
        {
            //throw new Exception("The method or operation is not implemented.");
            if (this.backgroundStreamReaderCanceller != null)
            {
                try {
                    this.backgroundStreamReaderCanceller.Cancel();
                    this.backgroundStreamReaderCanceller.Dispose();
                }
                catch (ObjectDisposedException) { }
            }
            if (this.pcapStream != null)
            {
                try {
                    this.pcapStream.Close();
                }
                catch {
                    this.pcapStream.Dispose();
                }
                finally {
                    this.pcapStream = null;
                }

                /*
                 * if(this.pcapStream.CanWrite)
                 *  this.pcapStream.Flush();
                 */
            }

            this.streamReadCompletedCallback = null;
        }
        public IEnumerable <PcapFrame> PacketEnumerator(EmptyDelegate waitFunction, StreamReadCompletedCallback captureCompleteCallback)
        {
            const int MIN_TAKE_TIMEOUT = 100;
            int       timeoutMilliSecs = MIN_TAKE_TIMEOUT;

            var cancellationToken = this.backgroundStreamReaderCanceller.Token;
            //int maxSleepMS = (int)Math.Sqrt(2.0 * this.readTimeoutMilliseconds);//200*200/2 = 20.000 = 20 seconds
            //maxSleepMS += timeoutMilliSecs;//to make sure BlockingRead timeouts before
            int maxSleepMS = (int)Math.Sqrt(2.0 * this.readTimeoutMilliseconds + timeoutMilliSecs * timeoutMilliSecs);

            while (!cancellationToken.IsCancellationRequested && (/*this.backgroundStreamReader.IsBusy ||*/ !this.EndOfStream() || this.packetQueue.Count > 0))
            {
                /*
                 * if(this.packetQueue.Count>0) {
                 *  sleepMilliSecs = 20;
                 *  PcapFrame packet;
                 *  lock(this.packetQueue) {
                 *      packet=this.packetQueue.Dequeue();
                 *  }
                 *  this.dequeuedByteCount+=packet.Data.Length;
                 *  if (this.packetQueue.Count < this.packetQueueMaxSize / 2)
                 *      this.packetQueueHasRoomEvent.Set();
                 *  yield return packet;
                 * }
                 * else {
                 *  if (sleepMilliSecs++ > maxSleepMS) {//200*200/2 = 20.000 = 20 seconds
                 *      //abort the reading, something has gone wrong...
                 *      yield break;
                 *  }
                 *  if (waitFunction != null)
                 *      waitFunction();
                 *  else {
                 *      //This works in .NET 4.5 and .NET Standard:
                 *      System.Threading.Tasks.Task.Delay(sleepMilliSecs).Wait();
                 *
                 *      //This works in .NET 4.0
                 *      //System.Threading.Thread.Sleep(sleepMilliSecs);
                 *
                 *  }
                 * }
                 */
                if (this.packetQueue.TryTake(out PcapFrame packet, timeoutMilliSecs, cancellationToken))
                {
                    timeoutMilliSecs        = MIN_TAKE_TIMEOUT;
                    this.dequeuedByteCount += packet.Data.Length;
                    yield return(packet);
                }
                else
                {
                    if (timeoutMilliSecs++ > maxSleepMS)  //20 seconds of total waiting time since last Take/Dequeue
                    //abort the reading, something has gone wrong...
                    {
                        yield break;
                    }
                    waitFunction?.Invoke();
                }
            }

            //yield break;
        }
Beispiel #4
0
        public IEnumerable <PcapFrame> PacketEnumerator(EmptyDelegate waitFunction, StreamReadCompletedCallback captureCompleteCallback)
        {
            int sleepMilliSecs = 20;

            var cancellationToken = this.backgroundStreamReaderCanceller.Token;
            int maxSleepMS        = (int)Math.Sqrt(2.0 * this.readTimeoutMilliseconds); //200*200/2 = 20.000 = 20 seconds

            maxSleepMS += sleepMilliSecs;                                               //to make sure BlockingRead timeouts before
            while (!cancellationToken.IsCancellationRequested && (/*this.backgroundStreamReader.IsBusy ||*/ !this.EndOfStream() || this.packetQueue.Count > 0))
            {
                if (this.packetQueue.Count > 0)
                {
                    sleepMilliSecs = 20;
                    PcapFrame packet;
                    lock (this.packetQueue) {
                        packet = this.packetQueue.Dequeue();
                    }
                    this.dequeuedByteCount += packet.Data.Length;
                    if (this.packetQueue.Count < this.packetQueueMaxSize / 2)
                    {
                        this.packetQueueHasRoomEvent.Set();
                    }
                    yield return(packet);
                }
                else
                {
                    if (sleepMilliSecs++ > maxSleepMS)  //200*200/2 = 20.000 = 20 seconds
                    //abort the reading, something has gone wrong...
                    {
                        yield break;
                    }
                    if (waitFunction != null)
                    {
                        waitFunction();
                    }
                    else
                    {
                        //This works in .NET 4.5 and .NET Standard:
                        System.Threading.Tasks.Task.Delay(sleepMilliSecs).Wait();

                        //This works in .NET 4.0
                        //System.Threading.Thread.Sleep(sleepMilliSecs);
                    }
                }
            }

            //yield break;
        }
        public IEnumerable <PcapFrame> PacketEnumerator(EmptyDelegate waitFunction, StreamReadCompletedCallback captureCompleteCallback)
        {
            int sleepMilliSecs = 20;
            int maxSleepMS     = (int)Math.Sqrt(2.0 * this.readTimeoutMilliseconds); //200*200/2 = 20.000 = 20 seconds

            maxSleepMS += sleepMilliSecs;                                            //to make sure BlockingRead timeouts before
            while (!this.backgroundStreamReader.CancellationPending && (this.backgroundStreamReader.IsBusy || !this.EndOfStream() || this.packetQueue.Count > 0))
            {
                if (this.packetQueue.Count > 0)
                {
                    sleepMilliSecs = 20;
                    PcapFrame packet;
                    lock (this.packetQueue) {
                        packet = this.packetQueue.Dequeue();
                    }
                    this.dequeuedByteCount += packet.Data.Length;
                    yield return(packet);
                }
                else
                {
                    if (sleepMilliSecs++ > maxSleepMS)  //200*200/2 = 20.000 = 20 seconds
                    //abort the reading, something has gone wrong...
                    {
                        yield break;
                    }
                    if (waitFunction != null)
                    {
                        waitFunction();
                    }
                    else
                    {
                        System.Threading.Thread.Sleep(sleepMilliSecs);
                    }
                }
            }

            //yield break;
        }
 public PcapStreamReader(System.IO.Stream pcapStream, int packetQueueSize, StreamReadCompletedCallback streamReadCompletedCallback, bool startBackgroundWorkers, long streamMaxLength)
     : this(pcapStream, packetQueueSize, streamReadCompletedCallback, startBackgroundWorkers, streamMaxLength, /*20000*/ pcapStream.ReadTimeout)
 {
 }
 public PcapStreamReader(System.Net.Sockets.NetworkStream pcapStream, int packetQueueSize, StreamReadCompletedCallback streamReadCompletedCallback, bool startBackgroundWorkers, long streamMaxLength)
     : this(pcapStream, packetQueueSize, streamReadCompletedCallback, startBackgroundWorkers, long.MaxValue, pcapStream.ReadTimeout)
 {
 }
 public PcapStreamReader(System.IO.FileStream pcapStream, int packetQueueSize, StreamReadCompletedCallback streamReadCompletedCallback, bool startBackgroundWorkers, long streamMaxLength)
     : this(pcapStream, packetQueueSize, streamReadCompletedCallback, startBackgroundWorkers, long.MaxValue, 20000)
 {
 }
 public PcapStreamReader(System.IO.Stream pcapStream, int packetQueueSize, StreamReadCompletedCallback streamReadCompletedCallback)
     : this(pcapStream, packetQueueSize, streamReadCompletedCallback, true)
 {
 }
Beispiel #10
0
        public PcapStreamReader(System.IO.Stream pcapStream, int packetQueueSize, StreamReadCompletedCallback streamReadCompletedCallback, bool startBackgroundWorkers, long streamMaxLength, int readTimeoutMilliseconds)
        {
            this.pcapStream              = pcapStream;
            this.streamLength            = streamMaxLength;
            this.readBytesEstimate       = 0;
            this.readTimeoutMilliseconds = readTimeoutMilliseconds;

            this.packetQueueMaxSize          = packetQueueSize;
            this.streamReadCompletedCallback = streamReadCompletedCallback;


            //TODO: Figure out if it is a libpcap or pcapNG stream...
            this.pcapParser = PcapParserFactory.CreatePcapParser(this);// new PcapParser(pcapStream, this.AbortReadingPcapStream);

            /*
             * byte[] buffer4=new byte[4];//32 bits is suitable
             * byte[] buffer2=new byte[2];//16 bits is sometimes needed
             * uint wiresharkMagicNumber=0xa1b2c3d4;
             *
             * //Section Header Block (mandatory)
             *
             * this.pcapStream.Read(buffer4, 0, 4);
             *
             * if(wiresharkMagicNumber==this.ToUInt32(buffer4, false))
             *  this.littleEndian=false;
             * else if(wiresharkMagicNumber==this.ToUInt32(buffer4, true))
             *  this.littleEndian=true;
             * else
             *  throw new System.IO.InvalidDataException("The stream is not a PCAP file. Magic number is "+this.ToUInt32(buffer4, false).ToString("X2")+" or "+this.ToUInt32(buffer4, true).ToString("X2")+" but should be "+wiresharkMagicNumber.ToString("X2")+".");
             *
             *
             * this.pcapStream.Read(buffer2, 0, 2);
             * this.majorVersionNumber=ToUInt16(buffer2, this.littleEndian);
             *
             * this.pcapStream.Read(buffer2, 0, 2);
             * this.minorVersionNumber=ToUInt16(buffer2, this.littleEndian);
             *
             * this.pcapStream.Read(buffer4, 0, 4);
             * this.timezoneOffsetSeconds=(int)ToUInt32(buffer4, this.littleEndian);
             *
             * this.pcapStream.Read(buffer4, 0, 4);
             *
             * this.pcapStream.Read(buffer4, 0, 4);
             * this.maximumPacketSize=ToUInt32(buffer4, this.littleEndian);
             *
             * this.pcapStream.Read(buffer4, 0, 4); //offset = 20 = 0x14
             * this.dataLinkType=(DataLinkType)ToUInt32(buffer4, this.littleEndian);
             */
            //this.pcapHeaderSize = this.pcapStream.Position;

            //this.backgroundStreamReader = new System.Threading.Tasks.Task()
            //this.backgroundStreamReader=new System.ComponentModel.BackgroundWorker();
            //this.backgroundStreamReader.WorkerSupportsCancellation = true;
            this.packetQueue             = new Queue <PcapFrame>(this.packetQueueMaxSize);
            this.packetQueueHasRoomEvent = new System.Threading.AutoResetEvent(true);
            this.enqueuedByteCount       = 0;
            this.dequeuedByteCount       = 0;

            this.backgroundStreamReaderCanceller = new System.Threading.CancellationTokenSource();
            System.Threading.CancellationToken cancellationToken = backgroundStreamReaderCanceller.Token;
            this.readAction = new Action(() => {
                DateTime firstFrameTimestamp = DateTime.MinValue;
                DateTime lastFrameTimestamp  = DateTime.MinValue;
                int framesCount = 0;
                try {
                    //int sleepMilliSecs = 20;


                    while (!cancellationToken.IsCancellationRequested && !this.EndOfStream())
                    {
                        if (this.packetQueue.Count < this.packetQueueMaxSize)
                        {
                            PcapFrame packet = this.pcapParser.ReadPcapPacketBlocking();
                            if (firstFrameTimestamp == DateTime.MinValue)
                            {
                                firstFrameTimestamp = packet.Timestamp;
                            }
                            lastFrameTimestamp = packet.Timestamp;
                            framesCount++;
                            lock (this.packetQueue) {
                                this.packetQueue.Enqueue(packet);
                            }
                            this.enqueuedByteCount += packet.Data.Length;
                            //sleepMilliSecs = 20;
                        }
                        else
                        {
                            //this.packetQueueHasRoomEvent.WaitOne();
                            bool signalReceived = this.packetQueueHasRoomEvent.WaitOne(1000);
#if DEBUG
                            if (!signalReceived)
                            {
                                System.Diagnostics.Debugger.Break();
                            }
#endif

                            /*System.Threading.Thread.Sleep(sleepMilliSecs);
                             * if (sleepMilliSecs < 1000)
                             *  sleepMilliSecs+=10;*/
                        }
                    }
                }
                catch (System.IO.EndOfStreamException) {
                    //Do nothing, just stop reading
                    this.pcapStream = null;
                }
                catch (System.IO.IOException) {
                    //probably a socket timout
                    if (!(this.pcapStream is System.IO.FileStream) && this.pcapStream != null)
                    {
                        if (this.pcapStream.CanWrite)
                        {
                            this.pcapStream.Flush();
                        }
                        this.pcapStream.Dispose();
                    }
                    //this.pcapStream = null;
                }
                catch (OperationCanceledException) {
                    if (!(this.pcapStream is System.IO.FileStream) && this.pcapStream != null)
                    {
                        if (this.pcapStream.CanWrite)
                        {
                            this.pcapStream.Flush();
                        }
                        this.pcapStream.Dispose();
                    }
                }

#if !DEBUG
                catch (Exception ex) {
                    this.pcapStream = null;
                    //this.backgroundStreamReaderCanceller.Cancel();
                    //e.Cancel = true;
                    //e.Result = ex.Message;
                    this.AbortFileRead();
                }
#endif
                //do a callback with this.filename as well as first and last timestamp
                if (this.streamReadCompletedCallback != null && firstFrameTimestamp != DateTime.MinValue && lastFrameTimestamp != DateTime.MinValue)
                {
                    this.streamReadCompletedCallback(framesCount, firstFrameTimestamp, lastFrameTimestamp);
                }
            });

            if (startBackgroundWorkers)
            {
                this.StartBackgroundWorkers();
            }
        }
Beispiel #11
0
        public PcapStreamReader(System.IO.Stream pcapStream, int packetQueueSize, StreamReadCompletedCallback streamReadCompletedCallback, bool startBackgroundWorkers, long streamMaxLength, int readTimeoutMilliseconds)
        {
            this.pcapStream              = pcapStream;
            this.streamLength            = streamMaxLength;
            this.readBytesEstimate       = 0;
            this.readTimeoutMilliseconds = readTimeoutMilliseconds;

            this.packetQueueMaxSize          = packetQueueSize;
            this.streamReadCompletedCallback = streamReadCompletedCallback;


            //TODO: Figure out if it is a libpcap or pcapNG stream...
            this.pcapParser = PcapParserFactory.CreatePcapParser(this);// new PcapParser(pcapStream, this.AbortReadingPcapStream);

            this.packetQueueBC = new System.Collections.Concurrent.BlockingCollection <PcapFrame>(this.packetQueueMaxSize);
            //this.packetQueue = new System.Collections.Concurrent.ConcurrentQueue<PcapFrame>();
            //this.packetQueueHasRoomEvent = new System.Threading.AutoResetEvent(true);
            this.enqueuedByteCount = 0;
            this.dequeuedByteCount = 0;

            this.backgroundStreamReaderCanceller = new System.Threading.CancellationTokenSource();
            System.Threading.CancellationToken cancellationToken = backgroundStreamReaderCanceller.Token;
            this.readAction = new Action(() => {
                DateTime firstFrameTimestamp = DateTime.MinValue;
                DateTime lastFrameTimestamp  = DateTime.MinValue;
                int framesCount = 0;
                try {
                    //int sleepMilliSecs = 20;

                    while (!cancellationToken.IsCancellationRequested && !this.EndOfStream())
                    {
                        PcapFrame packet = this.pcapParser.ReadPcapPacketBlocking();
                        //PcapFrame packet = await this.pcapParser.ReadPcapPacketAsync(cancellationToken);
                        if (firstFrameTimestamp == DateTime.MinValue)
                        {
                            firstFrameTimestamp = packet.Timestamp;
                        }
                        lastFrameTimestamp = packet.Timestamp;
                        framesCount++;
                        this.enqueuedByteCount += packet.Data.Length;

                        while (!this.packetQueueBC.TryAdd(packet, 1000, cancellationToken))
                        {
                            if (cancellationToken.IsCancellationRequested || this.EndOfStream())
                            {
                                break;
                            }
                        }
                        //this.packetQueue.Enqueue(packet);
                    }
                }
                catch (System.IO.EndOfStreamException) {
                    //Do nothing, just stop reading
                    this.pcapStream = null;
                }
                catch (System.IO.IOException) {
                    //probably a socket timout
                    if (!(this.pcapStream is System.IO.FileStream) && this.pcapStream != null)
                    {
                        if (this.pcapStream.CanWrite)
                        {
                            this.pcapStream.Flush();
                        }
                        this.pcapStream.Dispose();
                    }
                    //this.pcapStream = null;
                }
                catch (OperationCanceledException) {
                    if (!(this.pcapStream is System.IO.FileStream) && this.pcapStream != null)
                    {
                        if (this.pcapStream.CanWrite)
                        {
                            this.pcapStream.Flush();
                        }
                        this.pcapStream.Dispose();
                    }
                }

#if !DEBUG
                catch (Exception ex) {
                    this.pcapStream = null;
                    //this.backgroundStreamReaderCanceller.Cancel();
                    //e.Cancel = true;
                    //e.Result = ex.Message;
                    this.AbortFileRead();
                }
#endif
                //do a callback with this.filename as well as first and last timestamp
                if (this.streamReadCompletedCallback != null && firstFrameTimestamp != DateTime.MinValue && lastFrameTimestamp != DateTime.MinValue)
                {
                    this.streamReadCompletedCallback(framesCount, firstFrameTimestamp, lastFrameTimestamp);
                }
            });

            if (startBackgroundWorkers)
            {
                this.StartBackgroundWorkers();
            }
        }