Packet Capture and threading, capture library waits for "thread stop"

Dark_MadMax

New member
Joined
Apr 5, 2009
Messages
2
Programming Experience
1-3
I seem to have exhausted my own resources as I spent whole weekend reading about threads /delegates and event and it only made me totally confused about the issue altogether.

So I am hacking together an app which listens to traffic using SharpPcap library, it reconstructs the packets from sessions using the code from TpcRcon.

Listening and reconstructing part work on their own . What I want is on each packet arrival main window gets an event so it can display the packet , and when session is reconstructed display a complete packet (I am interested in HTTP ones) . -That is where it breaks with weird symptoms:
for example right now it does not stop on invoking stop listening method - the sharppcap library function hangs there forever waiting on this line of code :
m_pcapThreadEvent.WaitOne();//wait for the 'stopped' signal from thread

I also had it not working and crashing in sharppcap function because I had omitted one parameter in form delegate- which makes no sense, because form delegate does not deal with packet capture at all and only reacts on "New Packet" event from my "Listener" class (which is only there to notify main form)

My app starts as module main instancing class "Listener". MainForm has it
registered as friend with event and handles even "New Packet"

Main Form:
VB.NET:
 Private Sub uiListenStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btListenStart.Click
        aLogger.AddMessage("Started Listening")
        uiStatusBar.Panels(0).Text = "Listening"
        KongListener.StartListening()
    End Sub

 Public Delegate Sub AddNewPacketCallBack(ByVal packet As String, ByVal session As String)

 Private Sub AddNewPacket(ByVal packet As String, ByVal session As String) Handles aKongListener.NewPacket
        If uiLogList.InvokeRequired Then
            Dim d As New AddNewPacketCallBack(AddressOf AddNewPacket)
            Me.Invoke(d, New Object() {packet, session})
        Else
            Me.uiLogList.Items.Add(packet.ToString)
            uiLogList.SelectedIndex = uiLogList.Items.Count - 1
            uiStatusBar.Panels(3).Text = "Packets:" & uiLogList.Items.Count
            If Not session = "" Then
                uiSessionsList.Items.Add(session)
                uiSessionsList.Refresh()
            End If

        End If
    End Sub

Private Sub btListenStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btListenStop.Click
        aLogger.AddMessage("Stopped Listening")
        KongListener.StopListening()
        uiStatusBar.Panels(0).Text = "Not Listening"

    End Sub


Now my listener class -it has an event to notify main form and internal function which is used as a callback for the sharppcap function

VB.NET:
Public Class Listener

    Const CAP_FILTER_STR = "" ' '"ip and tcp" ' only winpcap fitlers can be used (limited)
    Const Device_Index As Integer = 3
    Dim device As PcapDevice
    Dim devices As List(Of PcapDevice)

    ' Holds the file streams for each tcp session in case we use SharpPcap
    Dim sessions As New Dictionary(Of Connection, TcpRecon)()
    Dim prevSessionsCount As Integer = 0
    ' The directory path of the Pcap file
    Dim path As String = ""


    Public Shared Event NewPacket(ByVal packetString As String, ByVal session As String)

    ' A delegate to the reconstruction function the user has chosen
    Private Delegate Sub ReconFuncDelegate(ByVal capFile As String)

    ''' <summary>
    ''' Reconstruct a Pcap file using TcpRecon class
    ''' </summary>
    ''' <param name="capFile"></param>
    Private Sub ReconSingleFileSharpPcap(ByVal capFile As String)
        ' Clean up
        For Each tr As TcpRecon In sessions.Values
            tr.Close()
        Next
        sessions.Clear()
    End Sub

    Public Sub StartListening()
        devices = SharpPcap.Pcap.GetAllDevices

        If devices.Count < 1 Then
            Throw New Exception("No device found on this machine")
            Return
        End If

        device = devices(Device_Index)
        'Register our handler function to the 'packet arrival' event
        AddHandler device.OnPacketArrival, AddressOf device_PcapOnPacketArrival

        'Open the device for capturing
        'true -- means promiscuous mode
        '1000 -- means a read wait of 1000ms
        device.Open(False, 1000)

        'Start the capturing process
        device.SetFilter(CAP_FILTER_STR)
        device.StartCapture()
        
    End Sub

    Public Sub StopListening()
        'Stop the capturing process
        device.StopCapture()

        'Close the pcap device
        device.Close()

    End Sub

    Public Sub ProcessFile(ByVal capfile As String)

        Try
            'Get an offline file pcap device
            device = SharpPcap.Pcap.GetPcapOfflineDevice(capfile)
            'Open the device for capturing
            device.Open()
        Catch ex As Exception
            MsgBox(" Could not open capture file" & ex.Message)
            Return
        End Try

        AddHandler device.OnPacketArrival, AddressOf device_PcapOnPacketArrival
        device.SetFilter(CAP_FILTER_STR)
        'Start capture 'INFINTE' number of packets This method will return when EOF reached.
        device.Capture(SharpPcap.Pcap.INFINITE)
        'Close the pcap device
        device.StopCapture()
        device.Close()
    End Sub

    Private Sub device_PcapOnPacketArrival(ByVal sender As Object, ByVal packet As SharpPcap.Packets.Packet)
        Dim packetString, session As String
        Dim time As DateTime = packet.PcapHeader.[Date]
        Dim len As Integer = packet.PcapHeader.PacketLength
        packetString = String.Format("{0}:{1}:{2},{3} Len={4}", time.Hour, time.Minute, time.Second, time.Millisecond, len)

        If (TypeOf packet Is Packets.TCPPacket) Then
            ReconstructTCPSession(packet)
        End If
        If sessions.Count > prevSessionsCount Then
            session = sessions.Count
            prevSessionsCount = sessions.Count
        End If
        Dim currThread As Thread = Thread.CurrentThread
        RaiseEvent NewPacket(packetString, session)
    End Sub

    ' The packet Reconstruction
    Private Sub ReconstructTCPSession(ByVal tcpPacket As Packets.TCPPacket)

        ' Creates a key for the dictionary
        Dim c As New Connection(tcpPacket)
        ' create a new entry if the key does not exists
        If Not sessions.ContainsKey(c) Then
            Dim fileName As String = c.getFileName(path)
            Dim tcpRecon As New TcpRecon(fileName)
            sessions.Add(c, tcpRecon)
        End If

        ' Use the TcpRecon class to reconstruct the session
        sessions(c).ReassemblePacket(tcpPacket)
    End Sub

    Public Sub New()
        Dim ReconFunc As New ReconFuncDelegate(AddressOf ReconSingleFileSharpPcap)
        sessions = New Dictionary(Of Connection, TcpRecon)()
    End Sub
End Class
 
The issue seem to be the "RaiseEvent NewPacket" From the listener class. That event has a handler in main form - my idea was to use even to notify the form, but I cant figure out why it is causing it and how to fix it
 
Back
Top