Hack 33. Watch Network Traffic
The tcpdump command-line packet-capture tool is invaluable for troubleshooting thorny network problems.
Practically all variations of Unix, Linux, and BSD ship with the tcpdump utility. Its deceptively simple interface hides a powerful and complex tool designed to capture data from a network interface, filter it, and print it out, so you can get a better grasp of what is really happening on your network.
Note that you need to be root to capture packets with tcpdump. The simplest way to start it is to run it while specifying the network device you would like to listen to:
# tcpdump -i eth0
If you are logged into a remote machine while doing this, you will see a flood of traffic fly by, even on an unloaded machine. This is because tcpdump is capturing your SSH session traffic and displaying it to your terminal, which generates more traffic, which is again displayed, in an endless loop of wasted bits. This is easily avoided by using a simple filter. For example, you could just ignore all SSH traffic, which uses port 22:
# tcpdump -i eth0 -n 'port ! 22'
That command specifies the -n switch, which tells tcpdump to skip DNS lookups for every host it encounters. When capturing network data, the name of the game is speed. If your machine is tied up with some other network function (such as looking up DNS names), it could miss packets as they fly past, particularly on a busy network. Skipping lookups speeds up capturing, but it means that you will be looking at IP addresses and port numbers instead of names and services.
One common use for tcpdump is to look for ping traffic when troubleshooting connectivity problems. To see ICMP traffic only, specify the protocol in a filter. Don't forget the backslash when specifying protocol names:
# tcpdump -i wlan0 'proto icmp' tcpdump: listening on eth0 16:34:33.842093 10.15.6.33 > www.google.com: icmp: echo request 16:34:33.873784 www.google.com > 10.15.6.33: icmp: echo reply 16:34:34.893981 10.15.6.33 > www.google.com: icmp: echo request 16:34:34.940997 www.google.com > 10.15.6.33: icmp: echo reply
Here, you can see a user sending echo requests (pings) to www.google.com, which then sends echo replies. If you see echo requests with no associated echo reply, this indicates problems somewhere further up the network. If you are sending pings and you don't even see the echo request on your router, you know that the problem is somewhere between your client and your router. Making educated guesses at where the problem might be, combined with judicious tcpdump filters, can quickly find the source of the trouble.
You can also capture all data from a particular host using tcpdump with the host directive:
# tcpdump -i wlan0 'host 10.15.6.88' tcpdump: listening on eth0 16:47:16.494447 10.15.6.88.1674 > florian.1900: udp 132 [ttl 1] 16:47:16.494524 florian > 10.15.6.88: icmp: florian udp port 1900 unreachable [tos 0xc0] 16:47:16.495831 10.15.6.88.1674 > florian.1900: udp 133 [ttl 1] 16:47:16.495926 florian > 10.15.6.88: icmp: florian udp port 1900 unreachable [tos 0xc0] 16:47:21.488711 arp who-has 10.15.6.88 tell florian 16:47:21.491861 arp reply 10.15.6.88 is-at 0:40:96:41:80:2c 16:47:28.293719 baym-cs197.msgr.hotmail.com.1863 > 10.15.6.88.1046: . ack 5 win 17128
This person is obviously using MSN Messenger, as evidenced by their connection to baym-cs197.msgr.hotmail.com port 1863, and by the UDP broadcasts to port 1900 as well. You can also see an ARP response that shows the user's MAC address starting with 0:40:96, indicating a Cisco card [Hack #39]. Without even resorting to Nmap [Hack #50] or another active scan, we could make a fair guess that this user is using a PC laptop running Windows. This information is revealed in just a few seconds, by observing a mere five or six packets.
Mac OS X is even chattier than Windows, revealing the user's name (and occasionally even their photo) in the form of iChat multicast broadcasts. Decoding this data is left as an exercise for the reader, but capturing it is simple enough:
# tcpdump -i wlan0 -X -s 0 -n -l 'port 5353'
This will show you a full dump of packets, both in hex and in ASCII, on only port 5353, which is used by iChat.
If you need to analyze large amounts of data, it is usually easier to use a graphical tool such as Ethereal [Hack #31] to pore over it. Since your access point probably isn't running Xwindows, you can use tcpdump to capture the actual data. Specifying the -w switch writes all packets to a file in pcap format, which many tools (such as Ethereal) will read:
# tcpdump -i wlan0 -n -w captured.pcap 'port 5353'
Now, just transfer the captured.pcap file to your local machine, and open it up in Ethereal.
For a command-line utility, tcpdump is a surprisingly complete packet-capture tool. It has a complex and powerful filter-expression language, and you can use it to capture precisely the data you are after. Be sure to read man tcpdump for many more details on what tcpdump can do for you.