What's the easiest way to sniff TCP traffic data on Linux?

I want a simple way to show all the TCP data (not the TCP headers or anything else) going over any interface on my Linux box.

For instance, I want a magical command that if I do:

magic_commmand_I_want port=1234

then if there was a server listening on port 1234 on my machine, and someone did:

echo hello | nc localhost 1234
# Note: "nc" (aka "netcat") is a simple tool that sends data to a host/port

Then the magical command would just print out:

hello

I've tried "tcpdump", "ethereal", "tethereal", "tshark", and others, but it isn't obvious how you get them to:

  • not show IP addresses or other metadata
  • only show the "data" being sent, not individual packets and their headers
  • print the data as-is, not in hex, and not with packet-offset markers
  • sniff all network traffic (whether it's on eth0 or eth1 or lo, etc...)

Yes, you could probably string together a piped set of unix commands to do this, but that isn't very easy to remember for next time :)

If you have a simple example of an exact command-line that does this, that's what I'd like.


Update:

As pointed by Michal in the comments: From tcpflow version 1.3 the -e option is used for specifying the scanner name. So the error "Invalid scanner name '8983'" is printed. The correct command is

sudo tcpflow -i any -C -J port 1234

(also -J has been changed to -g in the latest release)


Thanks to yves for pointing me to "tcpflow". Here's the commmand-line:

tcpflow -i any -C -e port 1234  # as root, or with sudo

This does everything I want

  • displays the data byte-for-byte as it comes in
  • doesn't display any other metadata
  • listens on all interfaces (so it captures data coming from within the machine and outside)

The "-C" tells it to dump to the console instead of a file. The "-e" enables colors so client->server and server->client are visually distinct.

I installed tcpflow by simply doing

sudo apt-get install tcpflow

socat is the tool you are asking for. It can act as a proxy:

$socat -v TCP-LISTEN:4444 TCP:localhost:1234
hello

then your application must connect port 4444 instead of directly connect to 1234

-v option is for socat to print out everything it receives on the standard error (stderr).

Update:

If socat is not available on your machine, you may still emulate it that way with netcat:

$netcat -l -p 4444 | tee output_file | netcat localhost 1234

caveats: this option is unidirectional. the second netcat instance will print any reponse from your server to the standard output. You may still do then:

$mkfifo my_fifo
$netcat -l -p 4444 < my_fifo | tee output_file | netcat localhost 1234 > my_fifo