how to control the period or end of packet capture?

Aug 26, 2010 at 8:49 PM

Hi,

What's a good way to control the period of capture or ending a capture.  That is, in the examples you basically setup a capture which (I assume) then blocks whilst capturing is occurring, with the results coming back to a callback.  So what would be a good way then to:

a) say you only want to capture for 5 minutes?  

b) capture ongoing, but if the user clicks "stop" button, then want to be able to immediately stop the capture (i.e. irrespective of whether there is traffic flowing at that time - i.e. not relying on packets coming back into the callback)

 

thanks

Aug 27, 2010 at 8:55 AM

The solution that I use is to just run the capture in a second thread.

I give a rough demo of this below

 

public class Capture
{
        private PacketCommunicator communicator = null;
        private PacketDevice selectedDevice = null;
        private Thread captureThread = null;
        private string filePath = null;
        private bool captureStarted = false;

         public Capture()
        {
            // Retrieve the device list from the local machine
            IList<LivePacketDevice> allDevices = LivePacketDevice.AllLocalMachine;

            if (allDevices.Count == 0)
            {
                Console.WriteLine("No interfaces found! Make sure WinPcap is installed.");
                return;
            }

	    //Just choose first device for the demo
            PacketDevice selectedDevice = allDevices[0];
            communicator = selectedDevice.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 1000);

            //Create new thread to run the capture in.
            captureThread = new Thread(new ThreadStart(StartThread));
        }

        /// <summary>
        ///     Starts the capture thread using the given file name to store the results.
        /// </summary>
        /// <param name="filePath">filepath for capture file</param>
        public void Start(string filePath)
        {
            this.filePath = filePath;
            captureThread.Start();
	    //Make sure thread has started before returning.
            while (!captureStarted) ;
        }

        /// <summary>
        ///     Start delegate, runs inside a separate thread to store packets as they are captured.
	///
	///	We use captureStarted here to make sure that we don't miss anything at the start, otherwise 
	///	we can miss packets that are sent during the initialisation of the thread.
        /// </summary>
        private void StartThread()
        {
            using (PacketDumpFile dump = communicator.OpenDump(filePath))
            {
                captureStarted = true;
                communicator.ReceivePackets(0, dump.Dump);
                captureStarted = false;
            }
        }

        /// <summary>
        ///     Stops the capture.
        /// </summary>
        public void Stop()
        {
            communicator.Break();
            captureThread.Join();
        }
    }

 

 

Aug 27, 2010 at 9:33 AM

thanks Stephen - looks good - I assume I could also still use this technique with the capture approach I have current which uses a callback?  (e.g. _communicator.ReceivePackets(0, PacketCapturerCallback)).   So the difference then for me would be just wrapping what I'm currently doing in another thread, so that I can kill this thread easily right?

Aug 27, 2010 at 3:20 PM

Sounds about right to me, but I don't use the callback so I can't guarantee it would work, worth checking it out.