3

I'm trying to run the following:

$ tcpdump -l -X -i eth1 -n tcp port <port> | tee capture.txt | \
       scp capture.txt  root@10.3.3.227:/home/checker/
  1. tcpdump -l -X -i eth1 -n tcp port <port>

    In step #1 I'm capturing packets, using "-l" to to make standard out line-buffered, so that it will write each packet as it arrives.

  2. tee capture.txt

    In step #2 man tee: "The tee utility copies standard input to standard output, making a copy in zero or more files." The output is unbuffered.

  3. scp capture.txt root@<remote-IP>:/home/

    In step #3 I'm send the capture.txt file to a remote host.

The problem

If I simply perform steps #1 and #2, ALL packets are captured on the specified port. However, if I also use step #3 the capture.txt does NOT contain all the packets (only a few)... This is killing me because I had this running OK just a few minutes ago!

What is wrong here?

bulkmoustache
  • 679
  • 2
  • 10
  • 22

3 Answers3

4

The tee command writes data to the output file as it receives it, but scp copies the file immediately and only copies it once. Since every command in the pipeline runs simultaneously (or nearly so), you only get a few (or no) packets output to the capture.txt file before the file gets copied by scp.

There are a couple ways to do what you seem to want to do.

If you want to copy a few packets from tcpdump, and then transfer the file to the remote host after it finishes, you can use the -c option to terminate tcpdump after it captures that number of packets. Separate your scp command from the pipeline using a semi colon so it gets executed after the tcpdump and tee commands complete:

tcpdump -l -c 10  | tee  /tmp/capture.txt; scp /tmp/capture.txt root@remotehost:/tmp

Or, if you want to see packets in real-time and also copy them in realtime, you could use tee to output the packets to /dev/tty so you can see them, and them pipe them into an ssh command that writes them to a file on the remote host:

tcpdump -l   | tee /dev/tty | ssh root@remotehost "cat > /tmp/capture.txt"

Note that without the -c option here, tcpdump will run until you kill it.

If you wanted the packets stored in a local capture.txt file as well as the remote, you could use multiple tee commands:

tcpdump -l   | tee /tmp/capture.txt | tee /dev/tty | ssh root@remotehost "cat > /tmp/capture.txt"
Johnny
  • 2,140
  • I've just noticed an issue.

    The capute.txt file that is sent to the remote host, on a second run of the tcpdump, is incremented instead of replaced...

    How do I overcome this?

    – bulkmoustache Oct 24 '13 at 01:06
  • I'm not sure which of the command lines I provided you're using, but none of them should be appending to the file. "tee" will overwrite the output file with each run, and the ">" operator will also overwrite the file. Can you give more details? Are you running on Linux? – Johnny Oct 24 '13 at 01:35
  • Yes, I'm running Debian Linux. I'm using:

    tcpdump -l | tee /dev/tty | ssh root@remotehost "cat > /tmp/capture.txt"

    I've tried to "echo /dev/null > capture" and "rm" the capture.txt but none of these are working =\ The file on the remote host keeps incrementing...

    – bulkmoustache Oct 24 '13 at 02:17
  • Is it possible that you have one of the commands running in the background or in another terminal window? – Johnny Oct 24 '13 at 02:26
  • nope =\ I'm trying to "fix" this with something like this: cat > /home/checker/temp.txt | cp /home/checker/temp.txt /home/checker/capture.txt | echo "" /home/checker/temp.txt

    The last part is to make sure the temp.txt is erased and, on the next tcpdump iteration, it is not incremented but instead written as a brand new file. But so far, this is not working (guess the cp is not working properly). Any ideias to copy a file's content into another?

    – bulkmoustache Oct 24 '13 at 02:43
  • Forget what I wrote before. I think the problem is explained here http://www.pixelbeat.org/programming/stdio_buffering/ (ctrl+F for "tcpdump"). Also, take a look at the last post here: http://unix.stackexchange.com/questions/15989/how-to-process-pipe-tcpdumps-output-in-realtime – bulkmoustache Oct 24 '13 at 21:09
3

It is not guaranteed that tee finished writing capture.txt when scp reads it. What you could do is use the stdout of tee and pipe it through ssh like this:

tcpdump -l -X -i eth1 -n tcp port <port> | tee capture.txt | \
  ssh root@10.3.3.227 'cat > /home/checker/capture.txt'
Michael Suelmann
  • 1,085
  • 6
  • 7
2

I think the problem here is that the file you're copying via scp is copied at a moment in time and not continuously, so you end up with a fragment of the contents of that file on server 10.3.3.227.

Try this instead:

$ sudo tcpdump -l -X -i eth1 -n <tcp port> | tee capture.txt | \
    ssh root@10.3.3.227 'cat > /home/checker/capture.txt
slm
  • 369,824