Search code examples
pythonpython-3.xsubprocesspopentshark

Tshark not executing through subprocess.Popen


I'm trying to execute tshark in python as follows:

class ARPSniffer:
    def testTshark(self, iface):
        print("Testing if tshark works. Using {}".format(iface))

        cmd = "tshark -i " + iface
        args = shlex.split(cmd)
        tshark = subprocess.Popen(args, stdout=PIPE)
        for line in io.TextIOWrapper(tshark.stdout, encoding="utf-8"):
            print(line)

    def run(self, iface):
        try:
            t = Thread(target=self.testTshark, args=(iface, ))
            t.daemon = True
            t.start()
            t.join
        except KeyboardInterrupt:
            print("\nExiting ARP monitor...")
            sys.exit(0)

if __name__ == '__main__':
    iface = 'wlan1'
    arps = ARPSniffer()
    arps.run(iface)

It prints "Testing if tshark works. Using wlan1" but tshark doesn't start. I checked it using top and there is not any process running. What am I doing wrong? I'm running it using sudo.

Thank you all of you.


Solution

  • As @Rawing pointed out in comments, there's a typo on t.join. You should also use the -l option of tshark if you want to see the output packets immediately. Otherwise tshark buffers them.

    import subprocess
    from threading import Thread
    import shlex
    import sys
    import io
    
    class ARPSniffer:
        def testTshark(self, iface):
            print("Testing if tshark works. Using {}".format(iface))
    
            cmd = "tshark -l -i " + iface
            args = shlex.split(cmd)
            tshark = subprocess.Popen(args, stdout=subprocess.PIPE)
            for line in io.TextIOWrapper(tshark.stdout, encoding="utf-8"):
                print("test: %s" % line.rstrip())
    
        def run(self, iface):
            try:
                t = Thread(target=self.testTshark, args=(iface, ))
                t.daemon = True
                t.start()
                t.join()
            except KeyboardInterrupt:
                print("\nExiting ARP monitor...")
                sys.exit(0)
    
    if __name__ == '__main__':
        iface = 'wlan1'
        arps = ARPSniffer()
        arps.run(iface)
    

    The above works for Python 3:

    $ python3 tmp.py 
    Testing if tshark works. Using wlan1
    Capturing on 'wlan1'
    3 test:     1 0.000000000 192.30.253.124 → 192.168.1.14 TLSv1.2 97 Application Data
    test:     2 0.000264000 192.168.1.14 → 192.30.253.124 TLSv1.2 101 Application Data
    test:     3 0.097729614 192.30.253.124 → 192.168.1.14 TCP 66 443 → 37756 [ACK] Seq=32 Ack=36 Win=38 Len=0 TSval=722975562 TSecr=2649326593