Without any options listed, tcpdump will dump all packets on all interfaces. This is not good. Even if no traffic is passing through the box, tcpdump will list the packets of your telnet session. Every packet listed to the screen will cause your telnet session to send another packet, which causes another packet to be listed to the screen, which... It's a vicious circle.
tcpdump -i vnd1025
This will only list traffic passing through (in or out) vnd1. This is good, since this is [generally] the "outside" interface of our system and will thus show the traffic passing through the system. It will actually show both sides of the conversation - if it is a conversation - since packets come in and replies go out vnd1.
When using tcpdump you may listen to all interfaces, or to a single interface. There is no way to list to both vnd1026 and vnd1026.
To listen on all interfaces, use the -i any option:
tcpdump -i any
Note that this can cause a LOT of output. Be prepared to filter this! (So below for filtering options.)
The above example may still show too much traffic, so you can limit the output to show any traffic coming from or going to a specific host:
tcpdump host 192.168.1.1
Using the "src" or "dst" keywords will limit the direction of the reporting:
tcpdump src host 192.168.1.1
You may wish to list only one protocol. Tcpdump understands TCP, UDP, ICMP, and ARP among others.
Tcpdump a single port
tcpdump port 80
You can also mix some options using the "and" keyword:
tcpdump host 192.168.1.1 and port 25
You can also use the "or" keyword:
tcpdump host 192.168.1.1 and tcp or udp
Tcpdump will run faster if hostname lookup is disable. Use the "-n" option:
tcpdump -n host 192.168.1.1 and tcp or udp
Using -nn will not only disable DNS lookups, but will also diable port names lookups. You'll see port numbers, like 80, rather than the service names, like www. This is highly recommended.
Simply pressing Control-C will exit tcpdump. But read below.
Tcpdump can produce a lot of output. Often the traffic will scroll fast than telnet or the craft port (at 9600 baud!) can send. If too much traffic is being listed then you Control-C may never seem to get to tcpdump. Or maybe it did, but 10,000 packets have to be sent to the screen before the Control-C can be interpreted.
One way to stop this is to limit the number of packets that tcpdump will capture by using the -c option:
tcpdump -c 100
This will have tcpdump capture 100 packets and then stop.
To reduce the above problem, or to simply save the output for further analysis, write the tcpdump packets to disk using the "-w" option:
tcpdump host 192.168.1.1 and tcp or udp -w tcpdump.out
This will write the output to a file called tcpdump.out. Nothing is sent to the screen, but you can then read it back in to tcpdump (using the -r option) to interpret. If it's a lot of packets, pipe through more to view a page at a time.
tcpdump -r tcpdump.out | more
You can apply filtering to this command, also:
tcpdump -r tcpdump.out port 80
The tcpdump output file can also be read by most sniffer packages, like EtherPeek or Sniffer Pro. Many open source packages, like Ethereal or TcpTrace can also read the output.
We can't we connect? Ping is a great test tool for connectivity, but remember that all IP relies on having the correct MAC address, so watching ARP is important, too. This is probably my most often-used tcpdump command when troubleshooting.
tcpdump -i vnd1026 icmp or arp –nn
Is HTTP traffic making it out of the box? Watching HTTP traffic may be overwhelming, since there will probably be a lot of it, so use -c to limit the number of packets captured. We're also looking for traffic with a destination port of 80 - we want to see if it's making it out, but don't care about replies.
tcpdump -i vnd1025 tcp dst port 80 -nn -c 100
Watch all Telnet from a particular host. This will match traffic to or from port 23, so you see both sides.
tcpdump -i any host 192.168.0.1 tcp port 23 –nn
Watch all FTP. FTP uses two ports, 20 and 21, so we watch both to make sure everything is working correctly.
tcpdump -i vnd1025 tcp port 20 or 21 -nn
Note: Watch your ANDs! You very rarely want AND - you probably want OR instead. I often think "I want to watch ports 20 and 21" and use the AND keyword. It's very doubtful that a packet will be going from port 20 and to port 21 - which is the only way to match the "port 20 and 21" command.
However, watching a conversation between two specific hosts is a good example of using AND:
tcpdump -i vnd1025 host 192.168.0.2 and host 172.16.99.99 –nn
All traffic between these two hosts will be captured.
You can also use AND to watch a particular conversation:
tcpdump -i vnd1025 tcp dst port 80 and src port 30295 –nn
As was mentioned above, interpreting tcpdump output can be an art form. This section will attempt to impart enough knowledge to make it a science. OK, it's really a science, but any unknown science is magic.
23:11:42.207288 eth0 < 192.168.0.1 > 10.1.1.12: icmp: echo request
23:11:42.207379 eth0 > 10.1.1.12 > 192.168.0.1: icmp: echo reply
This shows a single ping - ICMP echo request followed by the reply. The timestamp is shown in the first block, followed by the interface, eth0. The "<" indicates that the packet was coming in to eth0 (it points towards the interface). The next column lists the source address, ">" pointing to the destination address. The next two columns indicate that this packet was ICMP, and the type of ICMP packet - echo request and echo reply.
An ARP request and reply, with the timestamps removed to save space.
eth0 > arp who-has 192.168.0.1 tell 10.1.1.12 (0:10:5a:d1:12:d1)
eth0 < arp reply 192.168.0.1 is-at 0:c0:f0:1f:2a:3b (0:10:5a:d1:12:d1)
Example of a full TCP conversation:
1: eth0 < 192.168.0.1.3112 > 10.1.1.12.www: S 1256748838:1256748838(0) win 16384
<mss 1460,nop,nop,sackOK> (DF)
2: eth0 > 10.1.1.12.www > 192.168.0.1.3112: S 3961047523:3961047523(0) ack
1256748839 win 32120 <mss 1460,nop,nop,sackOK> (DF)
3: eth0 < 192.168.0.1.3112 > 10.1.1.12.www: . 1:1(0) ack 1 win 17520 (DF)
4: eth0 < 192.168.0.1.3112 > 10.1.1.12.www: P 1:15(14) ack 1 win 17520 (DF)
5: eth0 > 10.1.1.12.www > 192.168.0.1.3112: . 1:1(0) ack 15 win 32120 (DF)
6: eth0 > 10.1.1.12.www > 192.168.0.1.3112: P 1:397(396) ack 19 win 32120 (DF)
7: eth0 > 10.1.1.12.www > 192.168.0.1.3112: F 397:397(0) ack 19 win 32120 (DF)
8: eth0 < 192.168.0.1.3112 > 10.1.1.12.www: . 1:1(0) ack 398 win 17124 (DF)
9: eth0 < 192.168.0.1.3112 > 10.1.1.12.www: F 1:1(0) ack 398 win 17124 (DF)
10: eth0 > 10.1.1.12.www > 192.168.0.1.3112: . 398:398(0) ack 20 win 32120 (DF)
This shows a full conversation of a client system retrieving a single file from a web server. The timestamps have been removed, and lines 1 and 2 have been wrapped to the next line.
Note that the addresses have an extra field - the protocol. Common protocols are named, like www. (Though adding the -nn option will show the port number, not the name.)
The column after the destination address (where lines 1 and 2 show an S) are the TCP flags - well, some of them. Tcpdump reports only SYN, PUSH, RST, and FIN in this field, while displaying the ACK and URG bits later on the line (if they are set). If none of the first 4 flags are set then tcpdump displays a . in this field.
The next field on lines 1 and 2 show the absolute sequence numbers used for the conversation. In the following lines the relative sequence numbers are shown. The number in parentheses shows the number of bytes sent.
The next section, shown as "win 16384" in line 1, is the receiving buffer size of that host.
The next section shown in brackets ("mss 1460,nop,nop,sackOK" on line 1) shows some more TCP information, like Maximum Segment Size and the Selective ACK setting if enabled.
The "(DF)" in the last field indicates that the "Don't Fragment" bit is set.
To go through a interpretation of this output, by line number:
1) 192.168.0.1 initiates a conversation with 10.1.1.12 on port 80 (Note that SYN is set, but ACK is not)
2) 10.1.1.12 replies acknowledging the conversation request (SYN and ACK are set)
3) 192.168.0.1 acknowledges this with a single ACK. This ends the Three Way Handshake, and we now have an established connection between the two hosts.
4) 192.168.0.1 sends 14 bytes of data, which we could deduce is the GET request. Note that the PSH flag is set, which is expected when any host sends data.
5) 10.1.1.12 sends back an ACK of this packet
6) 10.1.1.12 sends 396 bytes - The results of the HTTP GET
7) 10.1.1.12 sends a FIN packet, closing the conversation
8) 192.168.0.1 acknowledges the FIN
9) 192.168.0.1 send it's FIN packet
10) 10.1.1.12 acknowledges this, and the conversation is officially complete