7

I am running tcpdump in a subprocess like this:

pcap_process = subprocess.Popen(['tcpdump', '-s 0', '-w -', 'tcp'], 
                                  stdout=subprocess.PIPE, stderr=subprocess.PIPE)

The -w - argument is important: it tells tcpdump to print the resulting .pcap file to stdout.

I then go on to access a website using urllib.open(). After this is done, I would like to kill tcpdump and put whatever it printed into a string. I have tried the following:

pcap_process.terminate()
result = pcap_process.stdout.read()    # or readline(), etc.

But (unless I'm doing something wrong), that doesn't work; I killed the process, now there's nothing left to be read. If I use read() or communicate() before terminating, my script will just sit there and read on and on, waiting for tcpdump to finish (which it won't).

Is there a way to do this (preferably without loops)?

Nakilon
  • 34,866
  • 14
  • 107
  • 142
sk29910
  • 2,326
  • 1
  • 18
  • 23
  • 1
    You need to pass each of the parameters to `tcpdump` separately: `Popen(['tcpdump', '-s', '0', '-w', '-', 'tcp'], ...)`. The single argument `-w -` does not get interpreted the same as the two arguments `-w` and `-`, etc. – Adam Rosenfield Aug 23 '11 at 16:19
  • True, that would've been the right answer :) Thanks anyways! – sk29910 Aug 23 '11 at 16:54

1 Answers1

8

Instead of using tcpdump, it's often advisable to use PCAP directly, or Scapy.

If that isn't an option, simply call communicate after terminate - killing a process does not kill data in the pipes to it. However, don't forget to separate arguments in the creation of the subprocess ([,'-w', '-'] instead of [... , '-w -', ..]):

pcap_process = subprocess.Popen(['tcpdump', '-s', '0', '-w', '-', 'tcp'],
                                  stdout=subprocess.PIPE, stderr=subprocess.PIPE)
phihag
  • 278,196
  • 72
  • 453
  • 469
  • 1
    Unfortunately pypcap is not an option here :( ... if I do that, the output is empty. Maybe the problem is somewhere else ... ಠ_ಠ – sk29910 Aug 23 '11 at 16:05
  • 1
    @sebastian_k `'-w -'` writes into a file named `-`. You want either `'-w-'` or `'-w' '-'`. Updated the answer. – phihag Aug 23 '11 at 16:14
  • You're absolutely right on, what a silly mistake. Thanks a bunch, phihag! :) – sk29910 Aug 23 '11 at 16:53