Search code examples
packetpacket-snifferspacket-capturepyshark

I want to stop packet capture while sniffing continuously once a condition is met


Problem

I have written a script that sniffs packet from a host, however, I am sniffing the packets in continuous mode and would like to stop sniffing on a timeout. I have written the following code to stop packet sniffing, but it doesn't seem to stop when the time has clearly exceeded the timeout. What could I be doing wrong in here?

import time
import pyshark

prog_start = time.time()
capture = pyshark.LiveCapture(interface='en0')
capture.sniff(timeout=10)
start_time = capture[0].frame_info.time_epoch
end_time = capture[-1].frame_info.time_epoch
print("Capture lasted:", float(end_time) - float(start_time))
pkt_num = 0
for pkt in capture:
    pkt_num += 1
    print("Time", time.time() - prog_start, "Pkt#", pkt_num)

We then get this output, with thousands of additional packets a second, past when the capture should have stopped:

Capture lasted: 9.148329019546509
Time 10.346031188964844 Pkt# 1
Time 10.348641157150269 Pkt# 2
Time 10.351708889007568 Pkt# 3
Time 10.353564977645874 Pkt# 4
Time 10.35555100440979 Pkt# 5
...

Question

Why does PyShark continue to capture packets after the timeout?


Solution

  • Problems with PyShark

    It looks like you're running into a known issue with PyShark that hasn't been fixed in years. Per the thread, the author wrote

    You can subclass LiveCapture and override the get_parameters() function, adding your own parameters.

    You could modify the parameters sent to tshark, but at this point, why not just use a tshark command directly?

    Using Tshark Instead

    PyShark is just a wrapper for tshark on your system. If you want to use subprocess with Python, the equivalent tshark command is tshark -a duration:5. The other advantage of using tshark directly is that subprocess gives you a pid that you can kill on an arbitrary condition.

    See the manpage for more details.