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

82

52

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.

Dustin Boswell

Posted 2009-08-13T22:44:50.953

Reputation: 1 941

3I 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 – 2014-08-13T14:20:40.010

2@StFS because he wants to sniff a running port and nc would complain. – infoclogged – 2017-09-06T23:51:07.783

2tcpdump is the magic command you want. Wireshark is a nice GUI on top of the library tcpdump uses – Vinko Vrsalovic – 2009-08-13T22:48:00.057

Answers

109

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

Dustin Boswell

Posted 2009-08-13T22:44:50.953

Reputation: 1 941

6Note that -J has been changed to -g in the latest release(s). – tvon – 2016-04-13T22:30:06.030

2Someone needs to explain to the authors of the tool what the term "backward compatibility" means! – Sridhar Sarnobat – 2017-01-20T05:04:15.337

It prints "things" twice, for me. Why is that ? https://lpaste.net/3984129577801744384

– user1198559 – 2018-09-04T04:46:30.807

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 – 2018-09-04T04:57:48.743

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 – 2019-11-28T16:57:49.583

2Wow. 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 – 2012-04-19T22:24:09.287

10From 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áč – 2014-05-22T09:50:35.877

30

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

yves Baumes

Posted 2009-08-13T22:44:50.953

Reputation: 419

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? – None – 2009-08-14T01:22:52.957

20

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

Kevin Boyd

Posted 2009-08-13T22:44:50.953

Reputation: 1 221

3My experience is that the interface really sucks on linux. – Joe Phillips – 2009-08-13T22:54:44.597

damn, you got there before me, +1 on wireshark – None – 2009-08-13T23:04:20.907

Can you give an example command-line? – None – 2009-08-13T23:26:56.440

Have a look at this link http://wiki.wireshark.org/Tools It gives a list of command line tools for wireshark. Look out for Dumpcap.

– Kevin Boyd – 2009-08-14T07:36:00.350

13

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.

yves Baumes

Posted 2009-08-13T22:44:50.953

Reputation: 419

2

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

Posted 2009-08-13T22:44:50.953

Reputation: 701

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

Posted 2009-08-13T22:44:50.953

Reputation: 101

-1

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

dimba

Posted 2009-08-13T22:44:50.953

Reputation: 713