19.7. Using tcpdump to Capture and Analyze Traffic

You really need to see what's going over the wires, and you know that tcpdump is just the powerhouse packet sniffer you want. But, you don't know how to filter all those masses of traffic. How do you make it show only what you want to see?

tcpdump can filter your traffic as precisely as you like. Just follow these examples to learn the more commonly used filters.

You should routinely use the -p switch to prevent the interface from going into promiscuous mode because promiscuous mode is pretty much useless on switched networks.

Capture all traffic on a single host:

	# tcpdump -pi eth0 host uberpc

Capture all traffic on more than one host:

	# tcpdump -pi eth0 host uberpc and stinkpad and penguina

Capture all traffic on more than one host, except from a specified host:

	# tcpdump -pi eth0 host uberpc and stinkpad and not penguina

Capture traffic going to a host:

	# tcpdump -pi eth0 dst host uberpc

Capture traffic leaving a host:

	# tcpdump -pi eth0 src host uberpc

Capture a single protocol:

	# tcpdump -pi eth0 tcp

Capture more than one protocol:

	# tcpdump -pi eth0 tcp or udp or icmp

Capture a specific port:

	# tcpdump -pi eth0 port 110

Capture several ports:

	# tcpdump -pi eth0 port 25 or port 80 or port 110

Capture a port range:

	# tcpdump -pi eth0 portrange 3000-4000

Watch traffic leaving a port:

	# tcpdump -pi eth0 src port 110

Watch traffic entering a port:

	# tcpdump -pi eth0 dst port 110

Look for packets smaller than the specified size:

	# tcpdump -pi eth0 less 512

Look for packets larger than the specified size:

	# tcpdump -pi eth0 greater 512

Watch SSH connections from certain hosts:

	# tcpdump -pi eth0 src host uberpc or stinkpad and dst port 22

Watch for traffic leaving one network and entering two other networks:

	# tcpdump -pi eth0 src net 192.168.1.0/16 and dst net 10.0.0.0/8 or 172.16.0.0/16

The -X switch reads the data payload, but the default is to only read 68 bytes, so -s0 displays the whole data payload, as this example from an IRC conversation shows:

	# tcpdump -X -s0 -pi eth0
	10:40:14.683350 IP 192.168.1.10.35386 > 12.222.222.107.6667: P 1:65(64) ack 410 win
	16022 <nop,nop,timestamp 1204830 3703450725>
	        0x0000: 4500 0074 c43b 4000 4006 8157 c0a8 010a   E..t.;@.@..W....
	        0x0010: 8cd3 a66b 8a3a 1a0b 420f ddd1 bb15 eb3b   ...k.:..B......;
	        0x0020: 8018 3e96 4309 0000 0101 080a 0012 625e   ..>.C.........b^
	        0x0030: dcbe 2c65 5052 4956 4d53 4720 236c 696e   ..,ePRIVMSG.#lin
	        0x0040: 7578 6368 6978 203a 746f 2062 6520 6120   uxchix.:to.be.a.
	        0x0050: 7375 7065 722d 7365 6b72 6974 2073 7079   super-sekrit.spy
	        0x0060: 2c20 7573 6520 7468 6520 2d73 2073 7769   ,.use.the.-s.swi
	        0x0070: 7463 680a                                 tch.

This particular incantation:

	# tcpdump -pXi eth0 -w tcpdumpfile -s0 host stinkpad

captures all traffic passing through Stinkpad, including data payload, and stores it in the file tcpdumpfile. You can read this file with:

	# tcpdump -r tcpdumpfile

Directing tcpdump output to a file lets you study it at leisure, or open it with Wireshark to read it in a prettier interface. The -w switch creates a file format that Wireshark can read. Figure 19-1 shows what it looks like in Wireshark.

This command lets you see the live capture and store it in a file. This doesn't create a file that Wireshark can read, but it does create a text file that you can parse with your favorite text-searching utilities:

	# tcpdump -pXi eth0 -s0 host stinkpad -l | tee tcpdumpfile

This is a good way to catch infected hosts that are sending out spam because nobody should be sending anything from port 25 except your official mail servers:

	# tcpdump -pni eth0 dst port 25 and not src host mailserver1

The -n switch turns off name resolution.

Finally, you might want to use the -c switch to limit the number of packets captured:

	# tcpdump -c 1000 -pXi eth0 -w tcpdumpfile -s0

Otherwise, it will run until you hit Ctrl-C.

tcpdump should be your number one network troubleshooting tool because it shows you exactly what is happening over your wires. Don't guess—run tcpdump.

Let's dissect some typical tcpdump output, using an excerpt from checking mail:

	# tcpdump -pi eth0
	14:23:02.983415 IP xena.alrac.net.58154 > host6.foo.com.pop3s: S 3100965180:
	3100965180(0) win 5840 <mss 1460,sackOK,timestamp 4546985 0,nop,wscale 2> (DF)
  • 14:23:02.983415 is the timestamp, in hh:mm:ss:fraction format.

  • xena.alrac.net.58154 is the originating host and port.

  • host6.foo.com.pop3s is the destination host and port.

  • S is the first part of the three-way TCP handshake (SYN, SYN, ACK).

  • 3100965180: 3100965180 is the byte sequence/range. The initial sequence number (ISN) is generated randomly. Then, sequence numbers for the rest of the bytes in the connection are incremented by 1 from the ISN. Because no data are exchanged at this stage, both numbers are the same.

  • win 5840 is the window size, or the number of bytes of buffer space the host has available for receiving data.

  • mss 1460 is the maximum segment size, or maximum IP datagram size that can be handled without using fragmentation. Both sides of the connection must agree on a value; if they are different, the lower value is used. This is called path MTU (Maximum Transmission Unit) discovery. MTU is the size of the total frame, which includes the MSS plus TCP/IP headers, and any other headers that are required by the sending protocol.

  • sackOK means "selective acknowledgments," which allows the receiver to acknowledge packets out of sequence. Back in the olden days, packets could only be acknowledged in sequence. So, if the third packet out of a hundred packets received went missing, the host could only acknowledge the receipt of the first two packets, and the sender would have to resend all packets from number 3 through 1,000. sackOK allows only the missing packets to be resent.

  • timestamp 4546985 0 measures the round-trip time. There are two fields: the Timestamp Value and the Timestamp Echo Reply. On the first exchange, the Echo Reply is set to 0. When the second host receives that packet, it transfers the timestamp from the old packet's Timestamp Value field to the new packet's Timestamp Echo Reply field. Then, it generates a new value for the Timestamp Value field. So, the Timestamp Value field contains the latest timestamp, while the Timestamp Echo Reply field contains the previous timestamp.

  • nop, or "no operation," is just padding. TCP options must be multiples of 4 bytes, so nop is used to pad undersized fields.

  • wscale 0 is a nifty hack to get around the original window size limitation of 65,535 bytes. wscale provides for a full gigabyte of buffer. Both sides of the connection must support this and agree; otherwise, the window size does not change.

  • (DF) means "don't fragment."

Sometimes, you need the correct physical placement to capture the type of information you want. For example, if you want to catch infected hosts sending out spam, or want to watch traffic between networks, you'll need to run tcpdump on a router. Or, plug-in your handy network administrator laptop between the router and the switch, if you have dumb switches. Smart switches have network monitoring ports.

Plug-in your handy network administrator laptop between the Internet and your firewall to get an unfiltered view of what's trying to enter your network.