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 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 #3
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();
            }
        }