pythonpyshark

Sniff Continuously and Save PCAP Files Simultaneously using PyShark's LiveCapture Method with display_filter


I am attempting to continuously sniff packets while concurrently saving them to a PCAP file using PyShark's LiveCapture method with the display_filter param. I am attempting to replicate the feature from Wireshark where you can stop and save a capture at any given moment with any filter specified. This setup in python would involve an indefinite timeout and no restriction on packet counts, allowing a process interruption (such as a keyboard interrupt) to halt the process. Here is an example with try/catch where I can print out packets with no problem:

import pyshark

interf = "Wi-Fi"
capture = pyshark.LiveCapture(interface=interf, display_filter='tcp')

try:
    for packet in capture.sniff_continuously():
        print(packet)
except KeyboardInterrupt:
    print("Capture stopped.")

And now after adding the param for output_file, nothing happens:

import pyshark

interf = "Wi-Fi"
capture = pyshark.LiveCapture(interface=interf, display_filter='tcp', output_file="HERE.pcap")

try:
    for packet in capture.sniff_continuously():
        print(packet)
except KeyboardInterrupt:
    print("Capture stopped.")

Currently using pyshark==0.6


Solution

  • Your latter code will fail, because a display_filter cannot be used when using an output_file

    import pyshark
    
    network_interface = 'en0'
    capture = pyshark.LiveCapture(interface=network_interface, display_filter='tcp', output_file="HERE.pcap")
    
    try:
        for packet in capture.sniff_continuously():
            print(packet)
    except KeyboardInterrupt:
        print("Capture stopped.")
    

    Here is the dubug:

    2024-07-08 11:38:26,984 - LiveCapture - DEBUG - Creating Dumpcap subprocess with parameters: /usr/local/bin/dumpcap -q -i en0 -w -
    2024-07-08 11:38:26,987 - LiveCapture - DEBUG - Dumpcap subprocess (pid 75408) created
    2024-07-08 11:38:27,262 - LiveCapture - DEBUG - Creating TShark subprocess with parameters: /usr/local/bin/tshark -l -n -T pdml -Y tcp -w HERE.pcap -i -
    2024-07-08 11:38:27,262 - LiveCapture - DEBUG - Executable: /usr/local/bin/tshark
    2024-07-08 11:38:27,264 - LiveCapture - DEBUG - Capturing on 'Wi-Fi: en0'
    2024-07-08 11:38:27,264 - LiveCapture - DEBUG - File: -
    2024-07-08 11:38:27,264 - LiveCapture - DEBUG - TShark subprocess (pid 75422) created
    2024-07-08 11:38:27,542 - LiveCapture - DEBUG - tshark: Display filters aren't supported when capturing and saving the captured packets.
    2024-07-08 11:38:27,546 - LiveCapture - DEBUG - EOF reached (sync)
    2024-07-08 11:38:27,546 - LiveCapture - DEBUG - Cleanup Subprocess (pid 75422)
    

    You need to use the bpf_filter

    import pyshark
    
    network_interface = 'en0'
    capture = pyshark.LiveCapture(interface=network_interface, bpf_filter='tcp', output_file="HERE.pcap")
    
    try:
        for packet in capture:
            print(packet)
    except KeyboardInterrupt:
        print("Capture stopped.")
    

    Here is the dubug:

    2024-07-08 11:44:30,023 - LiveCapture - DEBUG - Creating Dumpcap subprocess with parameters: /usr/local/bin/dumpcap -q -f tcp -i en0 -w -
    2024-07-08 11:44:30,026 - LiveCapture - DEBUG - Dumpcap subprocess (pid 75542) created
    2024-07-08 11:44:30,324 - LiveCapture - DEBUG - Creating TShark subprocess with parameters: /usr/local/bin/tshark -l -n -T pdml -w HERE.pcap -i -
    2024-07-08 11:44:30,324 - LiveCapture - DEBUG - Executable: /usr/local/bin/tshark
    2024-07-08 11:44:30,327 - LiveCapture - DEBUG - Capturing on 'Wi-Fi: en0'
    2024-07-08 11:44:30,327 - LiveCapture - DEBUG - File: -
    2024-07-08 11:44:30,327 - LiveCapture - DEBUG - TShark subprocess (pid 75556) created
    2024-07-08 11:44:30,630 - LiveCapture - DEBUG - Capturing on '-'
    

    Stopping PyShark cleanly like Wireshark isn't possible with the current code base, because TShark will crash.

    Capture stopped.
    Task exception was never retrieved
    future: <Task finished name='Task-59' coro=<TsharkXmlParser.get_packets_from_stream() done, defined at /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pyshark/tshark/output_parser/tshark_xml.py:24> exception=EOFError()>
    Traceback (most recent call last):
      File "/Users/username/Python_Projects/packet_analysis/test_keyboard.py", line 7, in <module>
        for packet in capture.sniff_continuously():
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pyshark/capture/capture.py", line 221, in _packets_from_tshark_sync
        packet, data = self.eventloop.run_until_complete(
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/base_events.py", line 636, in run_until_complete
        self.run_forever()
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/base_events.py", line 603, in run_forever
        self._run_once()
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/base_events.py", line 1871, in _run_once
        event_list = self._selector.select(timeout)
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/selectors.py", line 562, in select
        kev_list = self._selector.control(None, max_ev, timeout)
    KeyboardInterrupt
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pyshark/tshark/output_parser/tshark_xml.py", line 27, in get_packets_from_stream
        return await super().get_packets_from_stream(stream, existing_data, got_first_packet=got_first_packet)
      File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pyshark/tshark/output_parser/base_parser.py", line 22, in get_packets_from_stream
        raise EOFError()
    EOFError
    2024-07-08 11:46:30,653 - LiveCapture - DEBUG - Cleanup Subprocess (pid 75701)
    2024-07-08 11:46:30,653 - LiveCapture - DEBUG - Cleanup Subprocess (pid 75687)
    

    There were 2 issues opened at PyShark on this issue:

    https://github.com/KimiNewt/pyshark/issues/367

    https://github.com/KimiNewt/pyshark/issues/390

    It's unclear if the issue was resolved or if the issue is only OS dependent.