Unix: Gaining network insights with tcpdump

Think you know what's happening on your network? Pull out tcpdump and you might be surprised how much it can tell you.

In some ways, the tcpdump command may seem like a pretty basic tool for grabbing packets (more accurately "frames") off the network and allowing you to examine them. Even so,

you can gain a lot of insight into what is happening on your network by using this handy sniffer and it has a lot more options than you're likely expecting.

The name "tcpdump" doesn't pull any punches. The tcpdump command, which you will likely find on most Linux systems, is a basic "sniffer". That is, it pulls packets off your local network and lets you examine

them in various ways. What may not be obvious rightoff the bat is that tcpdump automatically puts itself into

promiscuous mode. That is, it changes the settings on your network interface card in such a way that it sends all frames that reach it -- not just those intended for your

system -- on for processing. That's what gives it the chops to be a real "sniffer". It gives you the ability to look at all traffic that crosses the "wire" (physical or not) that your system

is connected to.

If you want to run tcpdump without going into promiscuous mode, you have to deliberately turn off that feature using the -p option. So, while it may seem a little counterintuitive, -p means

"turn off promiscuity", not "turn it on".

If you type tcpdump on the command line and get the response "No suitable driver found", you're likely not root. Sorry, but you can't run tcpdump except as root. You can use sudo, but you

need to be root.

If you type tcpdump and your screen starts filling up with lines that look like these, you'll probably have several thousand of them before you even have time to type control-c. Otherwise,

it will continue to fill up your screen until you do. There's generally a lot going on even on a network segment that is relatively quiet.

17:15:59.507360 IP xyz-boson-1.particles.com.ssh > P 3162503
580:3162503776(196) ack 830458431 win 80
17:15:59.507618 IP > xyz-boson-1.particles.com.ssh: . ack 196
 win 251
17:15:59.507738 IP xyz-boson-1.particles.com.30942 > xyz-dc-1.particles.com.dom
ain:  64469+ PTR? (43)
17:15:59.510405 arp who-has tell
17:15:59.523468 IP xyz-dc-1.particles.com.domain > xyz-boson-1.particles.com.309
42:  64469 NXDomain 0/0/0 (43)

A gentler starting strategy for getting started with tcpdump might be to grab just a handful of packets. To do this, you can use the -c (count) option to specify just how many frames you want to collect:

# tcpdump -c 2
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
13:40:11.368233 IP xyz-boson-1.particles.com.ssh > P 3706680
062:3706680258(196) ack 474521172 win 71
13:40:11.368501 IP > xyz-boson-1.particles.com.ssh: . ack 196
 win 255
2 packets captured
5 packets received by filter
0 packets dropped by kernel

The first portion of every line is the timestamp. Those 13:40:11.507360 strings. The 13:40:11 part should be fairly obvious -- hour, minutes, and seconds. The rest allows you to see small portions

of seconds.

We then see the source (left of >) and destination (right of >) systems and some of the packet contents.

Better yet, you can write the packets off to a file so that you can peruse them at your leisure. In the command below, we're capturing ten packets and stuffing them into the file /tmp/c10. This will grab

the first ten packets that appear. Use the -w (write) option.

# tcpdump -c 10 -w /tmp/c10
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
10 packets captured
12 packets received by filter
0 packets dropped by kernel

Once you have done this, you would use another tcpdump command to examine the packets that you've collected and saved in the file.

# tcpdump -r /tmp/c10

This command, using the -r (read) option will list all of the packets that you collected earlier.

You can switch the interface that you want to work with using the -i (interface) option.

# tcpdump -c 10 -w /tmp/c10 -i bond0
tcpdump: listening on bond0, link-type EN10MB (Ethernet), capture size 96 bytes
10 packets captured
10 packets received by filter
0 packets dropped by kernel

You can use the -D option to list the interfaces that tcpdump can collect packets from.

# tcpdump -D
4.any (Pseudo-device that captures on all interfaces)

Of course, looking at all network traffic or all network traffic that passes by on your connection within some fraction of a second is probably not going to fascinate you for

very long. Soon you're going to want to start looking for particular content either to help with troubleshooting or give you a view of what systems are commmunicating on the

network segment to which you're attached or what they're doing.

The tcpdump allows you to specify sources or destinations (or both) for the packets you will be collecting. Just remember that, if you say the source is and the

destination is, you won't see responding to as the roles will be then be reversed.

You can also use the word "host" to see everything to or from a particular system.

# tcpdump -c 100 src fermion.particles.org
# tcpdump host boson.particles.org -w /tmp/boson$$

You can also specify a source or destination port using similar commands. In the example below, we use tcpdump to collect traffic heading to a local web server.

# tcpdump -i bond0 dst port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on bond0, link-type EN10MB (Ethernet), capture size 96 bytes
14:38:13.301801 IP nagios.particles.com.59344 > www.particles.org.http: S 3558234
391:3558234391(0) win 5840 <mss 1460,sackOK,timestamp 3398452148 0,nop,wscale 7>
14:38:13.301900 IP nagios.particles.com.59344 > www.particles.org.http: . ack 231
4423727 win 46 <nop,nop,timestamp 3398452148 2437740292>

You also have choices on how the packets you collect are displayed. In the examle below, we're showing a collected packet in both hex and ASCII format.

# tcpdump -i bond0 -c 1 -XX
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on bond0, link-type EN10MB (Ethernet), capture size 96 bytes
17:38:31.570524 IP xyz-boson-1.particles.com.ssh > P 3162608
328:3162608524(196) ack 830478067 win 80
        0x0000:  0000 0c07 ac01 782b cb5f a949 0800 4510  ......x+._.I..E.
        0x0010:  00ec 3cc6 4000 4006 0025 0a01 029b 0a02  ..<.@.@..%......
        0x0020:  e673 0016 d58d bc81 92c8 3180 16f3 5018  .s........1...P.
        0x0030:  0050 33c4 0000 8775 514e a605 e7f7 505c  .P3....uQN....P\
        0x0040:  f6e6 559e 3bc7 2317 f28d 9a29 8798 cf04  ..U.;.#....)....
        0x0050:  b4a7 36f0 30e9 89d1 1da0 0860 3bb7 cfed  ..6.0......`;...

Whenever you're troubleshooting an issue involving systems that seem to be having problems connection, you might consider using tcpdump to gain some insights into what kind of

traffic is crossing your network. The man page might just show you a string of options like -AdDeflLnNOpqRStuUvxX, but even a simple translation of each letter in that

string won't tell you all you might want to know.

Join the Network World communities on Facebook and LinkedIn to comment on topics that are top of mind.
Now read: Getting grounded in IoT