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 > 10.20.30.115.54669: P 3162503 580:3162503776(196) ack 830458431 win 80 17:15:59.507618 IP 10.20.30.115.54669 > 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? 22.214.171.124.in-addr.arpa. (43) 17:15:59.510405 arp who-has 10.2.248.27 tell 10.2.248.25 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 > 10.2.230.115.58774: P 3706680 062:3706680258(196) ack 474521172 win 71 13:40:11.368501 IP 10.20.30.115.58774 > 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
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 1.eth0 2.bond0 3.eth1 4.any (Pseudo-device that captures on all interfaces) 5.lo
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 10.20.30.40 and the
destination is 10.20.30.50, you won't see 10.20.30.50 responding to 10.20.30.40 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 > 10.20.30.115.54669: 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.