94

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.

  • 3
    tcpdump is the magic command you want. Wireshark is a nice GUI on top of the library tcpdump uses – Vinko Vrsalovic Aug 13 '09 at 22:48
  • 3
    I know this is an old question but I'm curious to know why using nc for the "server side" as well wasn't an option?

    "nc -l 1234" creates a server that listens on port 1234 and prints out whatever is sent to it and closes the connection. If you want to keep the connection alive and not disconnect you can add the "-k" option.

    – StFS Aug 13 '14 at 14:20
  • 3
    @StFS because he wants to sniff a running port and nc would complain. – infoclogged Sep 06 '17 at 23:51

7 Answers7

121

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
  • 6
    Wow. tcpflow is awesome, thanks! Saved me a TONNE of pain I was having with wireshark. Wireshark, tcpdump, etc have way too much info and don't actually do what the original question asks. tcpflow is perfect for this. – Russ Apr 19 '12 at 22:24
  • 11
    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 – Michal Kováč May 22 '14 at 09:50
  • 6
    Note that -J has been changed to -g in the latest release(s). – tvon Apr 13 '16 at 22:30
  • 4
    Someone needs to explain to the authors of the tool what the term "backward compatibility" means! – Sridhar Sarnobat Jan 20 '17 at 05:04
  • 1
    It prints "things" twice, for me. Why is that ? https://lpaste.net/3984129577801744384 – user1198559 Sep 04 '18 at 04:46
  • 1
    problem solved : packets went through multiple interfaces, so I set sudo tcpflow -e http -i lo0 -C -g port 8043, to only listen to loopback... – user1198559 Sep 04 '18 at 04:57
  • sudo tcpflow -i any -C -e port 37611 => Invalid scanner name 'port'. sudo tcpflow -i any -C -J port 37611 => tcpflow: invalid option -- 'J'. – user2449761 Nov 28 '19 at 16:57
  • This is great. Saved me a ton of pain in debugging how my headers were getting manipulated by Varnish, and coming into the application with duplicate headers. – Justin Fortier Dec 15 '22 at 19:38
35

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
  • 1
    Suppose I don't have control over the client and server, (or I don't want to stop it), so I can't change which port are involved or intercept the traffic. Then what? –  Aug 14 '09 at 01:22
19

Try Wireshark. It's an excellent protocol analyser targeted for both Linux and Windows.

Kevin Boyd
  • 1,321
14

tcpflow is what you want. Extract from the man page:

DESCRIPTION
tcpflow is a program that captures data transmitted as part of TCP connections (flows), and stores the data in a way that is convenient for protocol analysis or debugging. A program like tcpdump(4) shows a summary of packets seen on the wire, but usually doesn't store the data that's actually being transmitted. In contrast, tcpflow reconstructs the actual data streams and stores each flow in a separate file for later analysis. tcpflow understands TCP sequence numbers and will correctly reconstruct data streams regardless of retransmissions or out-of-order delivery.

tcpflow stores all captured data in files that have names of the form

192.168.101.102.02345-010.011.012.013.45103

where the contents of the above file would be data transmitted from host 192.168.101.102 port 2345, to host 10.11.12.13 port 45103.

Set up a connection from your application app to your server. When the connection is up and running, tcpflow is still able to capturs data from it For exemple:

$ sudo tcpflow -i lo port 5555
tcpflow[3006]: listening on lo

Every data will be stored in a file named 127.000.000.001.48842-127.000.000.001.05555.

You may still redirect this on the standard output with the option -Cs . Read the manual page to play with expression to tune the paquets you want tcpflow to capture.

4

ngrep is very nice for this. It takes a BPF string and an optional string to search for within the packets, and then dumps the packet contents to screen in a pretty useful format. It optionally also dumps to a pcap_dump file that you can examine more closely in Wireshark later.

hobbs
  • 1,388
0

Take a look at Chaosreader. Though it does a bit more than you ask for and slightly differently, probably you could modify the code of it to do what you want.

Andrew Y
  • 101
-1

Maybe you can write a wrapper for tcpdump, for example, which will remove all redundant information

dimba
  • 803
  • 3
  • 9
  • 16