Viewing Packet Flows with tcpdump
The tcpdump command is one of the most popular packages for viewing the flow of packets through your Linux box's NIC card. It is installed by default on Red Hat/Fedora Linux and has very simple syntax, especially if you are doing simpler types of troubleshooting.
One of the most common uses of tcpdump is to determine whether you are getting basic two-way communication. Lack of communication could be due to the following:
Bad routing Faulty cables, interfaces of devices in the packet flow The server not listening on the port because the software isn't installed or started A network device in the packet path blocking traffic; common culprits are firewalls, routers with access control lists and even your Linux box running iptables
Analyzing tcpdump in much greater detail is beyond the scope of this section.
Like most Linux commands, tcpdump uses command-line switches to modify the output. Some of the more useful command-line switches are listed in Table 4.2.
Table 4.2. Possible tcpdump SwitchesTcpdump Command | Switch Description |
|---|
-c | Stop after viewing count packets. | -t | Don't print a timestamp at the beginning of each line. | -i | Listen on interface. If this is not specified, tcpdump uses the lowest numbered interface that is UP. | -w | Dump the output to a specially formatted tcpdump dump file. | -C | Specify the size the dump file must reach before a new one with a numeric extension is created. |
You can also add expressions after all the command-line switches. These act as filters to limit the volume of data presented on the screen. You can also use keywords such as and or or between expressions to further fine-tune your selection criteria. Some useful expressions are listed in Table 4.3.
Table 4.3. Useful tcpdump ExpressionsTcpdump Command Expression | Description |
|---|
host host-address | View packets from the IP address host-address. | icmp | View icmp packets. | tcp port port-number | View TCP packets with either a source or destination TCP port of port-number. | udp port port-number | View UDP packets with either a source or destination UDP port of port-number. |
The following is an example of tcpdump being used to view ICMP ping packets going through interface wlan0:
[root@bigboy tmp]# tcpdump -i wlan0 icmp
tcpdump: listening on wlan0
21:48:58.927091 smallfry > bigboy: icmp: echo request (DF)
21:48:58.927510 bigboy > smallfry: icmp: echo reply
21:48:58.928257 smallfry > bigboy.my-web-site.org: icmp: echo request (DF)
21:48:58.928365 bigboy. > smallfry: icmp: echo reply
21:48:58.943926 smallfry > bigboy.my-web-site.org: icmp: echo request (DF)
21:48:58.944034 bigboy > smallfry: icmp: echo reply
21:48:58.962244 bigboy > smallfry: icmp: echo reply
21:48:58.963966 bigboy > smallfry: icmp: echo reply
21:48:58.968556 bigboy > smallfry: icmp: echo reply
9 packets received by filter
0 packets dropped by kernel
[root@bigboy tmp]#
In this example:
The first column of data is a packet timestamp. The second column of data shows the packet source and then the destination IP address or server name of the packet. The third column shows the packet type. Two-way communication is occurring as each echo gets an echo reply.
The following example shows tcpdump being used to view packets on interface wlan0 to/from host 192.168.1.102 on TCP port 22 with no timestamps in the output (-t switch):
[root@bigboy tmp]# tcpdump -i wlan0 -t host 192.168.1.102 and tcp port
22
tcpdump: listening on wlan0
smallfry.32938 > bigboy.ssh: S 2013297020:2013297020(0) win 5840 <mss
1460,sackOK,timestamp 75227931 0,nop,wscale 0> (DF) [tos 0x10]
bigboy.ssh > smallfry.32938: R 0:0(0) ack 2013297021 win 0 (DF) [tos
0x10]
smallfry.32938 > bigboy.ssh: S 2013297020:2013297020(0) win 5840 <mss
1460,sackOK,timestamp 75227931 0,nop,wscale 0> (DF) [tos 0x10]
bigboy.ssh > smallfry.32938: R 0:0(0) ack 1 win 0 (DF) [tos 0x10]
smallfry.32938 > bigboy.ssh: S 2013297020:2013297020(0) win 5840 <mss
1460,sackOK,timestamp 75227931 0,nop,wscale 0> (DF) [tos 0x10]
7 packets received by filter
0 packets dropped by kernel
[root@bigboy tmp]#
In this example:
The first column of data shows the packet source and then the destination IP address or server name of the packet. The second column shows the TCP flags within the packet. The client named bigboy is using port 32938 to communicate with the server named smallfry on the TCP SSH port 22. Two-way communication is occurring.
Analyzing tcpdump files
By using the -w filename option you can send the entire Ethernet frame, not just brief IP information that normally goes to the screen, to a file. This can then be analyzed by graphical analysis tools such as Ethereal, which is available in both Windows and Linux, with customized filters, colorization of packet records based on criteria deemed interesting, and the capability of automatically highlighting certain error conditions such as data retransmissions:
tcpdump -i eth1 -w /tmp/packets.dump tcp port 22
Covering Ethereal is beyond the scope of this book, but that shouldn't discourage you from using it. The application is part of the Fedora RPM suite, and a Windows version is also available.
Common Problems with tcpdump
By default tcpdump will attempt to determine the DNS names of all the IP addresses it sees while logging data. This can slow down tcpdump so much that it appears not to be working at all. The -n switch stops DNS name lookups and makes tcpdump work more reliably.
The following are examples of how the -n switch affects the output.
Without the -n switch:
[root@bigboy tmp]# tcpdump -i eth1 tcp port 22
tcpdump: verbose output suppressed, use -v or -vv for full protocol
decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
02:24:34.818398 IP 192-168-1-242.my-web-site.org.1753 > bigboy-100.my-
web-site.org.ssh: . ack 318574223 win 65471
02:24:34.818478 IP bigboy-100.my-web-site.org.ssh > 192-168-1-242.my-
web-site.org.1753: P 1:165(164) ack 0 win 6432
02:24:35.019042 IP 192-168-1-242.my-web-site.org.1753 > bigboy-100.my-
web-site.org.ssh: . ack 165 win 65307
02:24:35.019118 IP bigboy-100.my-web-site.org.ssh > 192-168-1-242.my-
web-site.org.1753: P 165:401(236) ack 0 win 6432
02:24:35.176299 IP 192-168-1-242.my-web-site.org.1753 > bigboy-100.my-
web-site.org.ssh: P 0:20(20) ack 401 win 65071
02:24:35.176337 IP bigboy-100.my-web-site.org.ssh > 192-168-1-242.my-
web-site.org.1753: P 401:629(228) ack 20 win 6432
6 packets captured
7 packets received by filter
0 packets dropped by kernel
[root@bigboy tmp]#
With the -n switch:
[root@bigboy tmp]# tcpdump -i eth1 -n tcp port 22
tcpdump: verbose output suppressed, use -v or -vv for full protocol
decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
02:25:53.068511 IP 192.168.1.242.1753 > 192.168.1.100.ssh: . ack
318576011 win 65163
02:25:53.068606 IP 192.168.1.100.ssh > 192.168.1.242.1753: P
1:165(164) ack 0 win 6432
02:25:53.269152 IP 192.168.1.242.1753 > 192.168.1.100.ssh: . ack 165
win 64999
02:25:53.269205 IP 192.168.1.100.ssh > 192.168.1.242.1753: P
165:353(188) ack 0 win 6432
02:25:53.408556 IP 192.168.1.242.1753 > 192.168.1.100.ssh: P 0:20(20)
ack 353 win 64811
02:25:53.408589 IP 192.168.1.100.ssh > 192.168.1.242.1753: P
353:541(188) ack 20 win 6432
6 packets captured
7 packets received by filter
0 packets dropped by kernel
[root@bigboy tmp]#
 |