Handling tcpdump output in python

26,050

Solution 1

You can make tcpdump line-buffered with "-l". Then you can use subprocess to capture the output as it comes out.

import subprocess as sub

p = sub.Popen(('sudo', 'tcpdump', '-l'), stdout=sub.PIPE)
for row in iter(p.stdout.readline, b''):
    print row.rstrip()   # process here

Solution 2

By default, pipes are block buffered and interactive output is line buffered. It sounds like you need a line buffered pipe - coming from tcpdump in a subprocess.

In the old days, we'd recommend Dan Bernstein's "pty" program for this kind of thing. Today, it appears that pty hasn't been updated in a long time, but there's a new program called "emtpy" which is more or less the same idea: http://empty.sourceforge.net/

You might try running tcpdump under empty in your subprocess to make tcpdump line buffered even though it's writing to a pipe.

Share:
26,050

Related videos on Youtube

ashish g
Author by

ashish g

Updated on January 28, 2020

Comments

  • ashish g
    ashish g almost 4 years

    Im trying to handle tcpdump output in python.

    What I need is to run tcpdump (which captures the packets and gives me information) and read the output and process it.

    The problem is that tcpdump keeps running forever and I need to read the packet info as soon as it outputs and continue doing it.

    I tried looking into subprocess of python and tried calling tcpdump using popen and piping the stdout but it doesnt seem to work.

    Any directions on how to proceed with this.

    import subprocess
    
    def redirect():
        tcpdump = subprocess.Popen("sudo tcpdump...", stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
        while True:
            s = tcpdump.stdout.readline()
            # do domething with s
    
    redirect()
    
  • jfs
    jfs over 9 years
    use for line in iter(p.stdout.readline, b''): print line, in Python 2 due to "readahead buffer" bug
  • jfs
    jfs over 9 years
    python has pty module in stdlib. Or pexpect could be used. There are also stdbuf, script, unbuffer utilities that may force line-buffered output
  • jfs
    jfs over 8 years
    for line in p.stdout: introduces unnecessary delay in the output on Python 2 (OP wants: "as soon as it outputs"). Use iter(..) as I've mentioned above. See Python: read streaming input from subprocess.communicate()

Related