80

I want to have tcpdump write raw packet data into a file and also display packet analysis into standard output as the packets are captured (by analysis I mean the lines it displays normally when -w is missing). Can anybody please tell me how to do that?

Guy Avraham
  • 3,482
  • 3
  • 38
  • 50
user2565010
  • 1,876
  • 4
  • 23
  • 37

5 Answers5

153

Here's a neat way to do what you want:

tcpdump -w - -U | tee somefile | tcpdump -r -

What it does:

  • -w - tells tcpdump to write binary data to stdout
  • -U tells tcpdump to write each packet to stdout as it is received, rather than buffering them and outputting in chunks
  • tee writes that binary data to a file AND to its own stdout
  • -r - tells the second tcpdump to get its data from its stdin
tbodt
  • 16,609
  • 6
  • 58
  • 83
cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • 3
    Using this technic, WireShark has complained of some of the files claiming that the last packet is incomplete. I guess tcpdump would unbuffer and write all data before ending, but, in case it doesn't, -U option may be useful here. From the man page: ` Use the -U flag to cause packets to be written as soon as they are received.`. (trying not to lose any buffered/still-not-written-to-file packet when tcpdump is killed). I haven't had a change to confirm that, though. – maganap Jul 29 '15 at 15:32
  • Why can't it be `tcpdump host | tee /tmp/output`. This avoids a second tcpdump that you are using at the end. Right ? – deppfx Aug 05 '15 at 23:05
  • 4
    @deppfx That would work, at the cost of only saving the text. `-w` causes `tcpdump` to write the data in the standard binary format. – cnicutar Aug 06 '15 at 09:46
  • stdout has buffer, how to flush stdout? – http8086 Mar 25 '16 at 10:26
  • 15
    @cnicutar This is genius. I like it. I'm using with options `-U` for packet buffered for printing per packet, `-n` for not converting IP addresses and ports to names. After modifications my command is `tcpdump -w - | tee filename.$(date +%Y-%m-%d.%Z.%H.%M.%S).pcap | tcpdump -r -` part with `$()` provides timestamp which we can't get otherwise since we are writing to `STDOUT` with `-w` . I know the part other than `-U` is not relevant to question, but putting it here in case anyone would like to use. –  Aug 09 '16 at 12:41
  • 6
    Without using `-U` the generated pcap file could be corrupted. – adrianlzt May 26 '17 at 10:17
  • @cnicutar Thanks, still useful in 2017! – kenfire Sep 08 '17 at 07:39
  • 1
    @sdkks that was brilliant! tcpdump -i eth0 port 22 and not host 172.30.247.4 -U -w - | tee capture.pcap |tcpdump -r - God Bless stackoverflow! – Jeff Patton Jan 31 '18 at 20:24
23

Since tcpdump 4.9.3 4.99.0, the --print option can be used:

tcpdump -w somefile --print
Wednesday, December 30, 2020, by mcr@sandelman.ca, denis and fxl.
  Summary for 4.99.0 tcpdump release
    [...]
    User interface:
      [...]
      Add --print, to cause packet printing even with -w.
ysdx
  • 8,889
  • 1
  • 38
  • 51
0

tcpdump > output.txt if you are looking to save the output into a file in text format.

Use sudo if permission issues are there.

My exp, the data gets written continuously.

-1
tcpdump ${ARGS} &
PID=$!
tcpdump ${ARGS} -w ${filename}
kill $PID
Trevor Boyd Smith
  • 18,164
  • 32
  • 127
  • 177
-2

If you want a way to do it without running tcpdump twice, consider:

sudo tcpdump port 80 -w $(tty) | tee /tmp/output.txt

From the interactive command prompt you could use $TTY instead of $(tty) but in a script the former wouldn't be set (though I'm not sure how common it is to run tcpdump in a script).

Side-note: it's not very Unix-y the way tcpdump by default makes you write to a file. Programs should by default write to stdout. Redirection to a file is already provided by the shell constructs. Maybe there's a good reason tcpdump is designed this way but I don't know what that is.

Sridhar Sarnobat
  • 25,183
  • 12
  • 93
  • 106