This program is the workhorse for capturing network packets.
|
Note
|
If you need to capture traffic between two hosts that you don’t have easy ability to run software on but you have physical access, interject an old school hub between the hosts and put a 3rd host with decent Linux tools (running the capture) on that hub too. |
|
Note
|
tcpdump pretty much always likes you more if your UID is 0 (i.e. use sudo and run as root). If you can’t do this, see trick above. |
Useful Options
-
-U Flush on each packet instead of the arbitrary point when the buffer fills.
-
-w <file|-> Write packets to a file instead of parsing them and printing summary information about them. Use - for standard output.
-
-r <file>|- Read the packets from a file (maybe previously collected with -w) instead of a network source.
-
-i <interface> Specify the interface to listen to (eth0, etc.).
-
-s <val|0> Snapshot length is number of bytes per packet to look at. The default is 68 which may be enough to analyze the nature of traffic, but not enough to analyze the content of the packet. Set to 0 to capture the whole packet.
-
-tttt Print timestamp on each line of the dump.
Useful Examples
Dumping to Files
By default the packets are summarized and cleaned up and sent to stdout, but you can specify a file name for the actual raw packets captured. This file can then be used by tcpdump in the place of actual interfaces to see the summarized and cleaned up output. Writing:
# tcpdump -w /thenameofthefilehere.dump
Reading (perhaps to have a quick look at it):
# tcpdump -r /thenameofthefilehere.dump | less
Snapshot Length
This controls the snapshot length which on Linux seems to be 90 bytes even though the man page says 68. This means that it only thinks about and writes the first 90 bytes of each packet. That’s fine if you just want to see packet headers and get a sense of what’s going on, but if you want to guarantee that a particular content is or isn’t (e.g. clear text passwords) being transmitted, you might want to capture all bytes. Set this to 0 for all bytes in the packet to be captured. Example:
# tcpdump -i eth0 -s 0
Focusing On The Problem
Let’s say you’re trying to troubleshoot some particular problem. If, for example, you want to scrutinize a web page request, you want to focus on port 80. Here’s how:
$ sudo tcpdump -i eth0 -s 0 tcp port 80
Sometimes there is a bunch of chatter from chattery processes and equipment (routers are filled with STP - spanning tree protocol, ARP - address resolution protocol, DTP - dynamic trunking protocol, etc). Perhaps the worst offender for traffic you do not wish to keep an eye on is the SSH traffic that you’re using to log into the machine in the first place. To specifically exclude such unwanted traffic from consideration use something like this:
tcpdump -i eth0 -s 0 not tcp port 22 and not tcp port 53 and not tcp port 123 and not arp and not stp
Analyzing A Specific Type Of Traffic
In this example I’m trying to capture all of the packets associated with a secure LDAP connection. By capturing all of the data that was passed back and forth to the LDAP server, I can search through it and check to see if any passwords went over in the clear. First to get the data use this command:
sudo tcpdump -i eth0 -s 0 -w ldapcapture.dump tcp port 636
Then run wireshark ldapcapture.dump to start up the graphical analysis program Wireshark. Go to Edit->Find Packet (Ctrl-F) and do a string search for the password you’re looking for (or hoping you won’t find).
Analyzing Bandwidth
Let’s say you want to watch a connection and see what activities cause a big spike in network traffic. Here’s what I used to do that.
# tcpdump -U -s 0 -i eth0 -w - host example.xed.ch | ./bytecounter
The bytecounter program is a simple C program that spits out the current byte count as it is piped in:
#include <stdio.h> int main(int argc, char * argv[]) { int c, n=0; while ((c= getchar()) != EOF) { n++; if (n%100==0) { printf("\r<%d>",n); fflush(stdout); } } }
Simple Text Data
To analyze the communication between bots and the simulation in the Simulated Car Racing competition, I needed to eavesdrop on simple data transmitted locally over UDP. Here’s what worked well:
sudo tcpdump -A -nn -i lo -s 0 udp port 3010 # All traffic sudo tcpdump -A -nn -i lo -s 0 udp dst port 3010 # Driver Inputs sudo tcpdump -A -nn -i lo -s 0 udp src port 3010 # Car Feedback
Finding MAC Addresses
This technique is helpful when you’re dealing with devices who only reveal their MAC addresses to the network. An example is a Sony PlayStation3. If you have MAC address filtering on your router, this is how you can find out what that MAC address is.
Another good case for this technique is if you just installed a new cluster and you plugged everything in. You’d like to give the machines a DHCP lease based on MAC address but you don’t know the MAC address. You could power up each machine with a monitor plugged in and write it down as it POSTs. But that’s lame. Better to just power it up fresh and let its natural factory-set desire to get it’s OS with PXE do the work. Basically you’ll want to use another working machine on that network and watch as you power up each node while tcpdump records the nodes' futile attempts to find out who it is.
# tcpdump -tttt -i eth1 port bootps or port bootpc | tee MACs.dump
The -tttt is needed to timestamp packets so you can match it with when you power on the machines. If you power on the machines quicker than its PXE cycle then there will be confusion unless precautions are taken. Turn them on at 15 second intervals using a watch for accuracy and look for that first packet at that interval.