How to capture network traffic with tcpdump

With tcpdump you can intercept, read, and save TCP/IP packets flowing through a particular network interface. These packets, which are the fundamental unit of data being transmitted over a TCP/IP network such as the internet, consist of two kinds of data. One is control data and the other is user data. Control data is the information about where the user data is to be delivered, where it's coming from, what is its length, and other information about the actual user data. The user data is the actual data being transmitted, which could include just about anything. It could even include passwords and usernames if this data is sent in clear text and not encrypted.

Simply running tcpdump on the command line will capture and display packets flowing through the eth0 network interface, which is the typical default interface used. However, it will only be indiscriminately listing packets with their control data, and you wont actually see any user data. To display that you'll need to run tcpdump with the -X option:

tcpdump -X

To make what you're getting more useful though we can use a few options. For example, we could save this stuff in a file instead of having it just be dumped on our screen, which makes it pretty hard to read anyway:

tcpdump -X -w packets.txt

Once you run this your packets.txt file will start getting filled up with lots of information really quickly so long as there's any traffic flowing through eth0. Let's say that you're running a web server and someone visits your web site. You would see the HTML contents of the web page being requested in the packets.txt file as user data of that packet. You see everything that's being transmitted. If what is being transmitted is by any chance encrypted though you might only see incomprehensible gibberish, but not making it easy to discern what's being transmitted by intercepting these packets is the whole point of encryption.

What if you wanted to read another network interface, like eth1? Simple, just tell it to capture eth1 packets with the -i option:

tcpdump -X -w packets.txt -i eth1

To listen for any and all traffic, just use -i any instead, and it will listen to all network interfaces.

Here are a few more useful options that help you specify what you want to capture and have dumped by tcpdump. To see all of the options you can check the manpage by running man tcpdump.

To disable resolving hostnames and domains, which can save a bit of time, and display only IP addresses use the -n option. To disable port names, use -nn. With these options the first example would look like this:

tcpdump -Xnn

To show only a certain number of packets and then stop instead of running indefinitely you can specify the -c 20 option, where -c stands for "count", and "20" would represent 20 packets.

tcpdump -Xnnc 20

Finally, if you want to make absolutely sure you see the maximum possible information that is being captured use the verbosity options. You can increase verbosity up to three times. With just -v, -vv, or -vvv for maximum verbosity. Also, we can use the -S option to show absolute rather than relative sequence numbers just to make sure we see the actual numbers. So let's construct a command that would show the maximum possible information on a sample of 100 packets, and store it into packets.txt.

tcpdump -XSvvvc 100 -w packets.txt

And that should get you on the right track to playing with and learning network traffic capture with tcpdump.