Network Troubleshooting Tools

by Joseph D. Sloan - O'Reilly Press

Packet Capture -- Part 2

1.4. tcpdump

The tcpdump program was developed at the Lawrence Berkeley Laboratory at the University of California, Berkeley, by Van Jacobson, Craig Leres, and Steven McCanne. It was originally developed to analyze TCP/IP performance problems. A number of features have been added over time although some options may not be available with every implementation. The program has been ported to a wide variety of systems and comes preinstalled on many systems.

For a variety of reasons, tcpdump is an ideal tool to begin with. It is freely available, runs on many Unix platforms, and has even been ported to Microsoft Windows. Features of its syntax and its file format have been used or supported by a large number of subsequent programs. In particular, its capture software, libpcap, is frequently used by other capture programs. Even when proprietary programs with additional features exist, the universality of tcpdump makes it a compelling choice. If you work with a wide variety of platforms, being able to use the same program on all or most of the platforms can easily outweigh small advantages proprietary programs might have. This is particularly true if you use the programs on an irregular basis or don't otherwise have time to fully master them. It is better to know a single program well than several programs superficially. In such situations, special features of other programs will likely go unused.

Since tcpdump is text based, it is easy to run remotely using a Telnet connection. Its biggest disadvantage is a lack of analysis, but you can easily capture traffic, move it to your local machine, and analyze it with a tool like ethereal. Typically, I use tcpdump in text-only environments or on remote computers. I use ethereal in a Microsoft Windows or X Window environment and to analyze tcpdump files.

1.4.1. Using tcpdump

The simplest way to run tcpdump is interactively by simply typing the program's name. The output will appear on your screen. You can terminate the program by typing Ctrl-C. But unless you have an idle network, you are likely to be overwhelmed by the amount of traffic you capture. What you are interested in will likely scroll off your screen before you have a chance to read it.

Fortunately, there are better ways to run tcpdump. The first question is how you plan to use tcpdump. Issues include whether you also plan to use the host on which tcpdump is running to generate traffic in addition to capturing traffic, how much traffic you expect to capture, and how you will determine that the traffic you need has been captured.

There are several very simple, standard ways around the problem of being overwhelmed by data. The Unix commands tee and script are commonly used to allow a user to both view and record output from a Unix session. (Both tee and script are described in .) For example, script could be started, tcpdump run, and script stopped to leave a file that could be examined later.

The tee command is slightly more complicated since tcpdump must be placed in line mode to display output with tee. This is done with the -l option. The syntax for capturing a file with tee is:

bsd1# tcpdump -l  | tee outfile

Of course, additional arguments would probably be used.

Using multiple Telnet connections to a host or multiple windows in an X Window session allows you to record in one window while taking actions to generate traffic in another window. This approach can be very helpful in some circumstances.

An alternative is to use telnet to connect to the probe computer. The session could be logged with many of the versions of telnet that are available. Be aware, however, that the Telnet connection will generate considerable traffic that may become part of your log file unless you are using filtering. (Filtering, which is discussed later in this chapter, allows you to specify the type of traffic you want to examine.) The additional traffic may also overload the connection, resulting in lost packets.

Another alternative is to run tcpdump as a detached process by including an & at the end of the command line. Here is an example:

bsd1# tcpdump -w outfile &
[1] 70260
bsd1# tcpdump: listening on xl0

The command starts tcpdump, prints a process number, and returns the user prompt along with a message that tcpdump has started. You can now enter commands to generate the traffic you are interested in. (You really have a prompt at this point; the message from tcpdump just obscures it.) Once you have generated the traffic of interest, you can terminate tcpdump by issuing a kill command using the process number reported when tcpdump was started. (You can use the ps command if you have forgotten the process number.)

bsd1# kill 70260
153 packets received by filter
0 packets dropped by kernel
[1]    Done                   tcpdump -w outfile

You can now analyze the capture file. (Running tcpdump as a detached process can also be useful when you are trying to capture traffic that might not show up for a while, e.g., RADIUS or DNS exchanges. You might want to use the nohup command to run it in the background.)

Yet another approach is to use the -w option to write the captured data directly to a file. This option has the advantage of collecting raw data in binary format. The data can then be replayed with tcpdump using the -r option. The binary format decreases the amount of storage needed, and different filters can be applied to the file without having to recapture the traffic. Using previously captured traffic is an excellent way of fine-tuning filters to be sure they work as you expect. Of course, you can selectively analyze data captured as text files in Unix by using the many tools Unix provides, but you can't use tcpdump filtering on text files. And you can always generate a text file from a tcpdump file for subsequent analysis with Unix tools by simply redirecting the output. To capture data you might type:

bsd1# tcpdump -w rawfile

The data could be converted to a text file with:

bsd1# tcpdump -r rawfile   > textfile

This approach has several limitations. Because the data is being written directly to a file, you must know when to terminate recording without actually seeing the traffic. Also, if you limit what is captured with the original run, the data you exclude is lost. For these reasons, you will probably want to be very liberal in what you capture, offsetting some of the storage gains of the binary format. Clearly, each approach has its combination of advantages and disadvantages. If you use tcpdump very much, you will probably need each from time to time.

1.4.2. tcpdump Options

A number of command-line options are available with tcpdump. Roughly speaking, options can be separated into four broad categories -- commands that control the program operations (excluding filtering), commands that control how data is displayed, commands that control what data is displayed, and filtering commands. We will consider each category in turn.

1.4.2.1. Controlling program behavior

This class of command-line options affects program behavior, including the way data is collected. We have already seen two examples of control commands, -r and -w. The -w option allows us to redirect output to a file for later analysis, which can be extremely helpful if you are not sure exactly how you want to analyze your data. You can subsequently play back capture data using the -r option. You can repeatedly apply different display options or filters to the data until you have found exactly the information you want. These options are extremely helpful in learning to use tcpdump and are essential for documentation and sharing.

If you know how many packets you want to capture or if you just have an upper limit on the number of packets, the -c option allows you to specify that number. The program will terminate automatically when that number is reached, eliminating the need to use a kill command or Ctrl-C. In the next example, tcpdump will terminate after 100 packets are collected:

bsd1# tcpdump -c100

While limiting packet capture can be useful in some circumstances, it is generally difficult to predict accurately how many packets need to be collected.

If you are running tcpdump on a host with more than one network interface, you can specify which interface you want to use with the -i option. Use the command ifconfig -a to discover what interfaces are available and what networks they correspond to if you aren't sure. For example, suppose you are using a computer with two class C interfaces, xl0 with an IP address of 205.153.63.238 and xl1 with an IP address of 205.153.61.178. Then, to capture traffic on the 205.153.61.0 network, you would use the command:

bsd1# tcpdump -i xl1

Without an explicitly identified interface, tcpdump defaults to the lowest numbered interface.

The -p option says that the interface should not be put into promiscuous mode. This option would, in theory, limit capture to the normal traffic on the interface -- traffic to or from the host, multicast traffic, and broadcast traffic. In practice, the interface might be in promiscuous mode for some other reason. In this event, -p will not turn promiscuous mode off.

Finally, -s controls the amount of data captured. Normally, tcpdump defaults to some maximum byte count and will only capture up to that number of bytes from individual packets. The actual number of bytes depends on the pseudodevice driver used by the operating system. The default is selected to capture appropriate headers, but not to collect packet data unnecessarily. By limiting the number of bytes collected, privacy can be improved. Limiting the number of bytes collected also decreases processing and buffering requirements.

If you need to collect more data, the -s option can be used to specify the number of bytes to collect. If you are dropping packets and can get by with fewer bytes, -s can be used to decrease the number of bytes collected. The following command will collect the entire packet if its length is less than or equal to 200 bytes:

bsd1# tcpdump -s200

Longer packets will be truncated to 200 bytes.

If you are capturing files using the -w option, you should be aware that the number of bytes collected will be what is specified by the -s option at the time of capture. The -s option does not apply to files read back with the -r option. Whatever you captured is what you have. If it was too few bytes, then you will have to recapture the data.

1.4.2.2. Controlling how information is displayed

The -a, -n, -N, and -f options determine how address information is displayed. The -a option attempts to force network addresses into names, the -n option prevents the conversion of addresses into names, the -N option prevents domain name qualification, and the -f option prevents remote name resolution. In the following, the remote site www.cisco.com (192.31.7.130) is pinged from sloan.lander.edu (205.153.63.30) without an option, with -a, with -n, with -N, and with -f, respectively. (The options -c1 host 192.31.7.130 restricts capture to one packet to or from the host 192.31.7.130.)

bsd1# tcpdump -c1 host 192.31.7.130
tcpdump: listening on xl0
14:16:35.897342 sloan.lander.edu > cio-sys.cisco.com: icmp: echo request
bsd1# tcpdump -c1 -a host 192.31.7.130
tcpdump: listening on xl0
14:16:14.567917 sloan.lander.edu > cio-sys.cisco.com: icmp: echo request
bsd1# tcpdump -c1 -n host 192.31.7.130
tcpdump: listening on xl0
14:17:09.737597 205.153.63.30 > 192.31.7.130: icmp: echo request
bsd1# tcpdump -c1 -N host 192.31.7.130
tcpdump: listening on xl0
14:17:28.891045 sloan > cio-sys: icmp: echo request
bsd1# tcpdump -c1 -f host 192.31.7.130
tcpdump: listening on xl0
14:17:49.274907 sloan.lander.edu > 192.31.7.130: icmp: echo request

Clearly, the -a option is the default.

Not using name resolution can eliminate the overhead and produce terser output. If the network is broken, you may not be able to reach your name server and will find yourself with long delays, while name resolution times out. Finally, if you are running tcpdump interactively, name resolution will create more traffic that will have to be filtered out.

The -t and -tt options control the printing of timestamps. The -t option suppresses the display of the timestamp while -tt produces unformatted timestamps. The following shows the output for the same packet using tcpdump without an option, with the -t option, and with the -tt option, respectively:

12:36:54.772066 sloan.lander.edu.1174 > 205.153.63.238.telnet: . ack 3259091394
win 8647 (DF)
   
sloan.lander.edu.1174 > 205.153.63.238.telnet: . ack 3259091394 win 8647 (DF)
                                                                          
934303014.772066 sloan.lander.edu.1174 > 205.153.63.238.telnet: . ack 3259091394 
win 8647 (DF)

The -t option produces a more terse output while the -tt output can simplify subsequent processing, particularly if you are writing scripts to process the data.

1.4.2.3. Controlling what's displayed

The verbose modes provided by -v and -vv options can be used to print some additional information. For example, the -v option will print TTL fields. For less information, use the -q, or quiet, option. Here is the output for the same packet presented with the -q option, without options, with the -v option, and with the -vv option, respectively:

12:36:54.772066 sloan.lander.edu.1174 > 205.153.63.238.telnet: tcp 0 (DF)
     
12:36:54.772066 sloan.lander.edu.1174 > 205.153.63.238.telnet: . ack 3259091394
win 8647 (DF)
     
12:36:54.772066 sloan.lander.edu.1174 > 205.153.63.238.telnet: . ack 3259091394
win 8647 (DF) (ttl 128, id 45836)
       
12:36:54.772066 sloan.lander.edu.1174 > 205.153.63.238.telnet: . ack 3259091394
win 8647 (DF) (ttl 128, id 45836

This additional information might be useful in a few limited contexts, while the quiet mode provides shorter output lines. In this instance, there was no difference between the results with -v and -vv, but this isn't always the case.

The -e option is used to display link-level header information. For the packet from the previous example, with the -e option, the output is:

12:36:54.772066 0:10:5a:a1:e9:8 0:10:5a:e3:37:c ip 60:
sloan.lander.edu.1174 > 205.153.63.238.telnet: . ack 3259091394 win 8647 (DF)

0:10:5a:a1:e9:8 is the Ethernet address of the 3Com card in sloan.lander.edu, while 0:10:5a:e3:37:c is the Ethernet address of the 3Com card in 205.153.63.238. (We can discover the types of adapters used by looking up the OUI portion of these addresses, as described in .)

For the masochist who wants to decode packets manually, the -x option provides a hexadecimal dump of packets, excluding link-level headers. A packet displayed with the -x and -vv options looks like this:

13:57:12.719718 bsd1.lander.edu.1657 > 205.153.60.5.domain: 11587+ A? www.
microsoft.com. (35) (ttl 64, id 41353)
                         4500 003f a189 0000 4011 c43a cd99 3db2
                         cd99 3c05 0679 0035 002b 06d9 2d43 0100
                         0001 0000 0000 0000 0377 7777 096d 6963
                         726f 736f 6674 0363 6f6d 0000 0100 01

Please note that the amount of information displayed will depend on how many bytes are collected, as determined by the -s option. Such hex listings are typical of what might be seen with many capture programs.

Describing how to do such an analysis in detail is beyond the scope of this book, as it requires a detailed understanding of the structure of packets for a variety of protocols. Interpreting this data is a matter of taking packets apart byte by byte or even bit by bit, realizing that the interpretation of the results at one step may determine how the next steps will be done. For header formats, you can look to the appropriate RFC or in any number of books. Table 1-1 (next page) summarizes the analysis for this particular packet, but every packet is different. This particular packet was a DNS lookup for www.microsoft.com. (For more information on decoding packets, see Eric A. Hall's Internet Core Protocols: The Definitive Guide.)

Table 1-1. Packet analysis summary

Raw data in hex

Interpretation

IP header

First 4 bits of 45

IP version -- 4

Last 4 bits of 45

Length of header multiplier -- 5 (times 4 or 20 bytes)

00

Type of service

00 3f

Packet length in hex -- 63 bytes

a1 89

ID

First 3 bits of 00

000 -- flags, none set

Last 13 bits of 00 00

Fragmentation offset

40

TTL -- 64 hops

11

Protocol number in hex -- UDP

c4 3a

Header checksum

cd 99 3d b2

Source IP -- 205.153.61.178

cd 99 3c 05

Destination IP -- 205.153.60.5

UDP header

06 79

Source port

00 35

Destination port -- DNS

00 2b

UDP packet length -- 43 bytes

06 d9

Header checksum

DNS message

2d 43

ID

01 00

Flags -- query with recursion desired

00 01

Number of queries

00 00

Number of answers

00 00

Number of authority RRs

00 00

Number of additional RRs

Query

03

Length -- 3

77 77 77

String -- "www"

09

Length -- 9

6d 69 63 72 6f 73 6f 66 74

String -- "microsoft"

03

Length -- 3

63 6f 6d

String -- "com"

00

Length -- 0

00 01

Query type -- IP address

00 01

Query class -- Internet

This analysis was included here primarily to give a better idea of how packet analysis works. Several programs that analyze packet data from a tcpdump trace file are described later in this chapter. Unix utilities like strings, od, and hexdump can also make the process easier. For example, in the following example, this makes it easier to pick out www.microsoft.com in the data:

bsd1# hexdump -C tracefile
00000000  d4 c3 b2 a1 02 00 04 00  00 00 00 00 00 00 00 00  |................|
00000010  c8 00 00 00 01 00 00 00  78 19 06 38 66 fb 0a 00  |........x..8f...|
00000020  4d 00 00 00 4d 00 00 00  00 00 a2 c6 0e 43 00 60  |M...M........C.`|
00000030  97 92 4a 7b 08 00 45 00  00 3f a1 89 00 00 40 11  |..J{..E..?....@.|
00000040  c4 3a cd 99 3d b2 cd 99  3c 05 06 79 00 35 00 2b  |.:..=...<..y.5.+|
00000050  06 d9 2d 43 01 00 00 01  00 00 00 00 00 00 03 77  |..-C...........w|
00000060  77 77 09 6d 69 63 72 6f  73 6f 66 74 03 63 6f 6d  |ww.microsoft.com|
00000070  00 00 01 00 01                                    |.....|
00000075

The -vv option could also be used to get as much information as possible.

Hopefully, you will have little need for the -x option. But occasionally you may encounter a packet that is unknown to tcpdump, and you have no choice. For example, some of the switches on my local network use a proprietary implementation of a spanning tree protocol to implement virtual local area networks (VLANs). Most packet analyzers, including tcpdump, won't recognize these. Fortunately, once you have decoded one unusual packet, you can usually easily identify similar packets.

1.4.2.4. Filtering

To effectively use tcpdump, it is necessary to master the use of filters. Filters permit you to specify what traffic you want to capture, allowing you to focus on just what is of interest. This can be absolutely essential if you need to extract a small amount of traffic from a massive trace file. Moreover, tools like ethereal use the tcpdump filter syntax for capturing traffic, so you'll want to learn the syntax if you plan to use these tools.

If you are absolutely certain that you are not interested in some kinds of traffic, you can exclude traffic as you capture. If you are unclear of what traffic you want, you can collect the raw data to a file and apply the filters as you read back the file. In practice, you will often alternate between these two approaches.

Filters at their simplest are keywords added to the end of the command line. However, extremely complex commands can be constructed using logical and relational operators. In the latter case, it is usually better to save the filter to a file and use the -F option. For example, if testfilter is a text file containing the filter host 205.153.63.30, then typing tcpdump -Ftestfilter is equivalent to typing the command tcpdump host 205.153.63.30. Generally, you will want to use this feature with complex filters only. However, you can't combine filters on the command line with a filters file in the same command

1.4.2.4.1. Address filtering.

It should come as no surprise that filters can select traffic based on addresses. For example, consider the command:

bsd1# tcpdump host 205.153.63.30

This command captures all traffic to and from the host with the IP address 205.153.63.30. The host may be specified by IP number or name. Since an IP address has been specified, you might incorrectly guess that the captured traffic will be limited to IP traffic. In fact, other traffic, such as ARP traffic, will also be collected by this filter. Restricting capture to a particular protocol requires a more complex filter. Nonintuitive behavior like this necessitates a thorough testing of all filters.

Addresses can be specified and restricted in several ways. Here is an example that uses the Ethernet address of a computer to select traffic:

bsd1# tcpdump ether host 0:10:5a:e3:37:c

Capture can be further restricted to traffic flows for a single direction, either to a host or from a host, using src to specify the source of the traffic or dst to specify the destination. The next example shows a filter that collects traffic sent to the host at 205.153.63.30 but not from it:

bsd1# tcpdump dst 205.153.63.30

Note that the keyword host was omitted in this example. Such omissions are OK in several instances, but it is always safer to include these keywords.

Multicast or broadcast traffic can be selected by using the keyword multicast or broadcast, respectively. Since multicast and broadcast traffic are specified differently at the link level and the network level, there are two forms for each of these filters. The filter ether multicast captures traffic with an Ethernet multicast address, while ip multicast captures traffic with an IP multicast address. Similar qualifiers are used with broadcast traffic. Be aware that multicast filters may capture broadcast traffic. As always, test your filters.

Traffic capture can be restricted to networks as well as hosts. For example, the following command restricts capture to packets coming from or going to the 205.153.60.0 network:

bsd1# tcpdump net 205.153.60

The following command does the same thing:

bsd1# tcpdump net 205.153.60.0 mask 255.255.255.0

Although you might guess otherwise, the following command does not work properly due to the final .0:

bsd1# tcpdump net 205.153.60.0

Be sure to test your filters!

1.4.2.4.2. Protocol and port filtering.

It is possible to restrict capture to specific protocols such as IP, Appletalk, or TCP. You can also restrict capture to services built on top of these protocols, such as DNS or RIP. This type of capture can be done in three ways -- by using a few specific keywords known by tcpdump, by protocol using the proto keyword, or by service using the port keyword.

Several of these protocol names are recognized by tcpdump and can be identified by keyword. The following command restricts the traffic captured to IP traffic:

bsd1# tcpdump ip

Of course, IP traffic will include TCP traffic, UDP traffic, and so on.

To capture just TCP traffic, you would use:

bsd1# tcpdump tcp

Recognized keywords include ip, igmp, tcp, udp, and icmp.

There are many transport-level services that do not have recognized keywords. In this case, you can use the keywords proto or ip proto followed by either the name of the protocol found in the /etc/protocols file or the corresponding protocol number. For example, either of the following will look for OSPF packets:

bsd1# tcpdump ip proto ospf
bsd1# tcpdump ip proto 89

Of course, the first works only if there is an entry in /etc/protocols for OSPF.

Built-in keywords may cause problems. In these examples, the keyword tcp must either be escaped or the number must be used. For example, the following is fine:

bsd#1 tcpdump ip proto 6

On the other hand, you can't use tcp with proto.

bsd#1 tcpdump ip proto tcp

will generate an error.

For higher-level services, services built on top of the underlying protocols, you must use the keyword port. Either of the following will collect DNS traffic:

bsd#1 tcpdump port domain                                                 
bds#1 tcpdump port 53

In the former case, the keyword domain is resolved by looking in /etc/services. When there may be ambiguity between transport-layer protocols, you may further restrict ports to a particular protocol. Consider the command:

bsd#1 tcpdump udp port domain

This will capture DNS name lookups using UDP but not DNS zone transfers using TCP. The two previous commands would capture both.

1.4.2.4.3. Packet characteristics.

Filters can also be designed based on packet characteristics such as packet length or the contents of a particular field. These filters must include a relational operator. To use length, the keyword less or greater is used. Here is an example:

bsd1# tcpdump greater 200

This command collects packets longer than 200 bytes

Looking inside packets is a little more complicated in that you must understand the structure of the packet's header. But despite the complexity, or perhaps because of it, this technique gives you the greatest control over what is captured. (If you are charged with creating a firewall using a product that requires specifying offsets into headers, practicing with tcpdump could prove invaluable.)

The general syntax is proto [ expr : size ]. The field proto indicates which header to look into -- ip for the IP header, tcp for the TCP header, and so forth. The expr field gives an offset into the header indexed from 0. That is, the first byte in a header is number 0, the second byte is number 1, and so forth. Alternately, you can think of expr as the number of bytes in the header to skip over. The size field is optional. It specifies the number of bytes to use and can be 1, 2, or 4.

bsd1# tcpdump "ip[9] = 6"

looks into the IP header at the tenth byte, the protocol field, for a value of 6. Notice that this must be quoted. Either an apostrophe or double quotes should work, but a backquote will not work.

bsd1# tcpdump tcp

is an equivalent command since 6 is the protocol number for TCP.

This technique is frequently used with a mask to select specific bits. Values should be in hex. Comparisons are specified using the syntax & followed by a bit mask. The next example extracts the first byte from the Ethernet header (i.e., the first byte of the destination address), extracts the low-order bit, and makes sure the bit is not 0:[4]

[4]The astute reader will notice that this test could be more concisely written as =1 rather than !=0. While it doesn't matter for this example, using the second form simplifies testing in some cases and is a common idiom. In the next command, the syntax is simpler since you are testing to see if multiple bits are set.

bsd1# tcpdump 'ether[0] & 1 != 0'

This will match multicast and broadcast packets.

With both of these examples, there are better ways of matching the packets. For a more realistic example, consider the command:

bsd1# tcpdump "tcp[13] & 0x03 != 0"

This filter skips the first 13 bytes in the TCP header, extracting the flag byte. The mask 0x03 selects the first and second bits, which are the FIN and SYN bits. A packet is captured if either bit is set. This will capture setup or teardown packets for a TCP connection.

It is tempting to try to mix in relational operators with these logical operators. Unfortunately, expressions like tcp src port > 23 don't work. The best way of thinking about it is that the expression tcp src port returns a value of true or false, not a numerical value, so it can't be compared to a number. If you want to look for all TCP traffic with a source port with a value greater than 23, you must extract the port field from the header using syntax such as "tcp[0:2] & 0xffff > 0x0017".

1.4.2.4.4. Compound filters.

All the examples thus far have consisted of simple commands with a single test. Compound filters can be constructed in tcpdump using logical operator and, or, and not. These are often abbreviated &&, ||, and ! respectively. Negation has the highest precedence. Precedence is left to right in the absence of parentheses. While parentheses can be used to change precedence, remember that they must be escaped or quoted.

Earlier it was noted that the following will not limit capture to just IP traffic:

bsd1# tcpdump host 205.153.63.30

If you really only want IP traffic in this case, use the command:

bsd1# tcpdump host 205.153.63.30 and ip

On the other hand, if you want all traffic to the host except IP traffic, you could use:

bsd1# tcpdump host 205.153.63.30 and not ip

If you need to capture all traffic to and from the host and all non-IP traffic, replace the and with an or.

With complex expressions, you have to be careful of the precedence. Consider the two commands:

bsd1# tcpdump host lnx1 and udp or arp        
bsd1# tcpdump "host lnx1 and (udp or arp)"

The first will capture all UDP traffic to or from lnx1 and all ARP traffic. What you probably want is the second, which captures all UDP or ARP traffic to or from lxn1. But beware, this will also capture ARP broadcast traffic. To beat a dead horse, be sure to test your filters.

I mentioned earlier that running tcpdump on a remote station using telnet was one way to collect data across your network, except that the Telnet traffic itself would be captured. It should be clear now that the appropriate filter can be used to avoid this problem. To eliminate a specific TCP connection, you need four pieces of information -- the source and destination IP addresses and the source and destination port numbers. In practice, the two IP addresses and the well-known port number is often enough.

For example, suppose you are interested in capturing traffic on the host lnx1, you are logged onto the host bsd1, and you are using telnet to connect from bsd1 to lnx1. To capture all the traffic at lnx1, excluding the Telnet traffic between bsd1 and lnx1, the following command will probably work adequately in most cases:

lnx1# tcpdump -n "not (tcp port telnet and host lnx1 and host bsd1)"

We can't just exclude Telnet traffic since that would exclude all Telnet traffic between lnx1 and any host. We can't just exclude traffic to or from one of the hosts because that would exclude non-Telnet traffic as well. What we want to exclude is just traffic that is Telnet traffic, has lnx1 as a host, and has bsd1 as a host. So we take the negation of these three requirements to get everything else.

While this filter is usually adequate, this filter excludes all Telnet sessions between the two hosts, not just yours. If you really want to capture other Telnet traffic between lnx1 and bsd1, you would need to include a fourth term in the negation giving the ephemeral port assigned by telnet. You'll need to run tcpdump twice, first to discover the ephemeral port number for your current session since it will be different with every session, and then again with the full filter to capture the traffic you are interested in.

One other observation -- while we are not reporting the traffic, the traffic is still there. If you are investigating a bandwidth problem, you have just added to the traffic. You can, however, minimize this traffic during the capture if you write out your trace to a file on lnx1 using the -w option. This is true, however, only if you are using a local filesystem. Finally, note the use of the -n option. This is required to prevent name resolution. Otherwise, tcpdump would be creating additional network traffic in trying to resolve IP numbers into names as noted earlier.

Once you have mastered the basic syntax of tcpdump, you should run tcpdump on your own system without any filters. It is worthwhile to do this occasionally just to see what sorts of traffic you have on your network. There are likely to be a number of surprises. In particular, there may be router protocols, switch topology information exchange, or traffic from numerous PC-based protocols that you aren't expecting. It is very helpful to know that this is normal traffic so when you have problems you won't blame the problems on this strange traffic.

This has not been an exhaustive treatment of tcpdump, but I hope that it adequately covers the basics. The manpage for tcpdump contains a wealth of additional information, including several detailed examples with explanations. One issue I have avoided has been how to interpret tcpdump data. Unfortunately, this depends upon the protocol and is really beyond the scope of a book such as this. Ultimately, you must learn the details of the protocols. For TCP/IP, Richard W. Stevens' TCP/IP Illustrated, vol. 1, The Protocols has extensive examples using tcpdump. But the best way to learn is to use tcpdump to examine the behavior of working systems.

Next chapter