Learn tcpdump by example



Get tired of reading tcpdump man page? Here is an easy way to learn tcpdump by example

In order to use tcpdump, you must select CONFIG_PACKET in Network Option when you "make xconfig" to compile your kernel.


tcpdump is a very useful tool to dump the traffic on a network. It can dump not only TCP traffic, but also UDP, ICMP ... almost all kinds of traffic.

For the detail usage of tcpdump, please refer to tcpdump man page.

Here we just learn some cases that may be frequently used.

Let's use our experimental network as example. See diagram here

ALL tcpdump commands are used on DUBLIN.cs.unh.edu


1. To dump traffic on a specific interface.

By default, tcpdump will dump all packet it receives on all interfaces.
Use option  -i device_name, we can dump traffic on a specific interface.
e.g:
      #tcpdump -i eth1

2. To dump traffic of a specific network.

#tcpdump   net  192.168.1.0/24


[root@prague /root]# ping 192.168.1.2

On dublin, we get:

22:18:35.259408 eth1 < 192.168.2.2 > 192.168.1.2: icmp: echo request (DF)
22:18:35.259477 eth2 > 192.168.2.2 > 192.168.1.2: icmp: echo request (DF)
22:18:35.259561 eth2 < 192.168.1.2 > 192.168.2.2: icmp: echo reply
22:18:35.259580 eth1 > 192.168.1.2 > 192.168.2.2: icmp: echo reply
22:18:36.249756 eth1 < 192.168.2.2 > 192.168.1.2: icmp: echo request (DF)
22:18:36.249803 eth2 > 192.168.2.2 > 192.168.1.2: icmp: echo request (DF)
22:18:36.249887 eth2 < 192.168.1.2 > 192.168.2.2: icmp: echo reply
22:18:36.249904 eth1 > 192.168.1.2 > 192.168.2.2: icmp: echo reply


Note: Here if we don't specific the netmask number( in this case 24 ), tcpdump won't give error message but it won't work in the way you want. In this case, it won't print anything

3. Also, we can dump packets destined to or originated from a specific network

#tcpdump dst net 192.168.1.0/24

[root@prague /root]# ping 192.168.1.2

On dublin, we get:

22:21:13.411756 eth1 < 192.168.2.2 > 192.168.1.2: icmp: echo request (DF)
22:21:13.411819 eth2 > 192.168.2.2 > 192.168.1.2: icmp: echo request (DF)
22:21:14.409429 eth1 < 192.168.2.2 > 192.168.1.2: icmp: echo request (DF)
22:21:14.409477 eth2 > 192.168.2.2 > 192.168.1.2: icmp: echo request (DF)
22:21:18.406165 eth2 > arp who-has 192.168.1.2 tell 192.168.1.1 (0:c0:f0:6a:6d:c)
22:21:18.406241 eth2 < arp reply 192.168.1.2 is-at 0:c0:f0:6a:74:f1 (0:c0:f0:6a:6d:c)

[lin@madrid /etc]$ ping -c 2 192.168.2.2

On dublin, we get:

22:21:49.735595 eth1 < 192.168.2.2 > 192.168.1.2: icmp: echo reply
22:21:49.735607 eth2 > 192.168.2.2 > 192.168.1.2: icmp: echo reply
22:21:50.726727 eth1 < 192.168.2.2 > 192.168.1.2: icmp: echo reply
22:21:50.726738 eth2 > 192.168.2.2 > 192.168.1.2: icmp: echo reply

From here we can see ping packet passes network 192.168.1.0/24


Similarly, we can dump traffic originated from 192.168.1.0/24 as follows:


#tcpdump src net 192.168.1.0/24



4. To dump traffic relating to a specific host. Like that in network, tcpdump can specific source host, destination host, or just host( both )

#tcpdump [src|dst] host host_name

Here host_name can be numeric value or string value. Since the IP 192.168.*.* won't use DNS, here we use numberic value only.

e.g.

#tcpdump src host 192.168.2.2

[root@prague /root]# ping -c 2 192.168.1.2

On dublin, we get:

22:30:23.832502 eth1 B arp who-has 192.168.2.1 tell 192.168.2.2
22:30:23.832624 eth1 < 192.168.2.2 > 192.168.1.2: icmp: echo request (DF)
22:30:23.832786 eth2 > 192.168.2.2 > 192.168.1.2: icmp: echo request (DF)
22:30:24.828293 eth1 < 192.168.2.2 > 192.168.1.2: icmp: echo request (DF)
22:30:24.828332 eth2 > 192.168.2.2 > 192.168.1.2: icmp: echo request (DF)
22:30:28.826242 eth1 < arp reply 192.168.2.2 is-at 0:c0:f0:6a:6d:4e (0:c0:f0:6a:56:51)

#tcpdump dst host 192.168.1.2

[root@prague /root]# ping -c 2 192.168.1.2

On dublin, we get:

22:31:59.220237 eth1 < 192.168.2.2 > 192.168.1.2: icmp: echo request (DF)
22:31:59.220300 eth2 > 192.168.2.2 > 192.168.1.2: icmp: echo request (DF)
22:32:00.218097 eth1 < 192.168.2.2 > 192.168.1.2: icmp: echo request (DF)
22:32:00.218146 eth2 > 192.168.2.2 > 192.168.1.2: icmp: echo request (DF)
22:32:04.216165 eth2 > arp who-has 192.168.1.2 tell 192.168.1.1 (0:c0:f0:6a:6d:c)


5. tcpdump can dump traffic on a given port( src port, dst port, or both )

#tcpdump src port 21
[root@prague /root]# ftp 192.168.1.2

On dublin, we get:

22:35:46.735462 eth2 < 192.168.1.2.ftp > 192.168.2.2.32772: S 3447919818:3447919818(0) ack 3436609221 win 32120 <mss 1460,nop,nop,timestamp 16255856 3933870,nop,wscale 0> (DF)
22:35:46.735481 eth1 > 192.168.1.2.ftp > 192.168.2.2.32772: S 3447919818:3447919818(0) ack 3436609221 win 32120 <mss 1460,nop,nop,timestamp 16255856 3933870,nop,wscale 0> (DF)
22:35:49.861125 eth2 < 192.168.1.2.ftp > 192.168.2.2.32772: P 1:92(91) ack 1 win 32120 <nop,nop,timestamp 16256169 3933870> (DF) [tos 0x10]
22:35:49.861183 eth1 > 192.168.1.2.ftp > 192.168.2.2.32772: P 1:92(91) ack 1 win 32120 <nop,nop,timestamp 16256169 3933870> (DF) [tos 0x10]

[root@prague /root]# telnet 192.168.1.2

On dublin, we get nothing this time, because telnet use port 23.ftp uses port 21



6. tcpdump can dump traffic based on Ethernet address( src, dst, or both )

#tcpdump ether host 00:C0:F0:6A:74:F1     ( the MAC of madrid:eth1. 192.168.1.2/24)

[root@prague /root]# ping -c 2 192.168.1.2

On dublin, we get:

22:47:50.661442 eth2 < 192.168.1.2 > 192.168.2.2: icmp: echo reply
22:47:51.656204 eth2 < 192.168.1.2 > 192.168.2.2: icmp: echo reply
22:47:55.656248 eth2 < arp reply 192.168.1.2 is-at 0:c0:f0:6a:74:f1 (0:c0:f0:6a:6d:c)

[root@dublin /root]# tcpdump ether src 00:C0:F0:6A:74:F1
[root@prague /root]# ping -c 2 192.168.1.2

On dublin, we get:

22:49:52.689360 eth2 < 192.168.1.2 > 192.168.2.2: icmp: echo reply
22:49:53.685943 eth2 < 192.168.1.2 > 192.168.2.2: icmp: echo reply
22:49:57.680575 eth2 < arp who-has 192.168.1.1 tell 192.168.1.2

NOTE: When Dublin recieve ping packet from prague, it doesn't know the MAC address of 192.168.1.2(00:C0:F0:6A:74:F1 ). The echo reply packet from 192.168.1.2 has source MAC 00:C0:F0:6A:74:F1



7. tcpdump can dump traffic based on ip protocols

#tcpdump [ tcp | udp | icmp ]


8. tcpdump can dump traffice based on ethernet protocols:

#tcpdump [ ip | arp | rarp | decnet ]


9. You can also use Negation( '!' or 'not' ), Concatenation( '&&' or 'and' ) and
Alternation( '||' or 'or' ) to combine the above tcpdump expressions.

e.g. To dump TCP traffic originating from 192.168.2.2 port 23, we can use

#tcpdump src host 192.168.2.2 and tcp and port 23


[root@prague /root]# ftp 192.168.1.2

On dublin, we get nothing.


[root@prague /root]# telnet 192.168.1.2

On dublin, we get:

23:13:49.485236 eth1 < 192.168.2.2.32778 > 192.168.1.2.telnet: S [ECN-Echo,CWR] 1553997373:1553997373(0) win 5840 <mss 1460,sackOK,timestamp 4162146 0,nop,wscale 0> (DF)
23:13:49.485290 eth2 > 192.168.2.2.32778 > 192.168.1.2.telnet: S [ECN-Echo,CWR] 1553997373:1553997373(0) win 5840 <mss 1460,sackOK,timestamp 4162146 0,nop,wscale 0> (DF)
23:13:49.485478 eth1 < 192.168.2.2.32778 > 192.168.1.2.telnet: . 1553997374:1553997374(0) ack 1540040456 win 5840 <nop,nop,timestamp 4162146 16484131> (DF)
23:13:49.485491 eth2 > 192.168.2.2.32778 > 192.168.1.2.telnet: . 0:0(0) ack 1 win 5840 <nop,nop,timestamp 4162146 16484131> (DF)
23:13:49.485795 eth1 < 192.168.2.2.32778 > 192.168.1.2.telnet: P 0:27(27) ack 1 win 5840 <nop,nop,timestamp 4162146 16484131> (DF)
23:13:49.485817 eth2 > 192.168.2.2.32778 > 192.168.1.2.telnet: P 0:27(27) ack 1 win 5840 <nop,nop,timestamp 4162146 16484131> (DF)
23:13:49.493072 eth1 < 192.168.2.2.32778 > 192.168.1.2.telnet: . 27:27(0) ack 13 win 5840 <nop,nop,timestamp 4162147 16484131> (DF)
23:13:49.493084 eth2 > 192.168.2.2.32778 > 192.168.1.2.telnet: . 27:27(0) ack 13 win 5840 <nop,nop,timestamp 4162147 16484131> (DF)
23:13:49.493256 eth1 < 192.168.2.2.32778 > 192.168.1.2.telnet: . 27:27(0) ack 52 win 5840 <nop,nop,timestamp 4162147 16484131> (DF)
23:13:49.493268 eth2 > 192.168.2.2.32778 > 192.168.1.2.telnet: . 27:27(0) ack 52 win 5840 <nop,nop,timestamp 4162147 16484131> (DF)
23:13:49.493824 eth1 < 192.168.2.2.32778 > 192.168.1.2.telnet: P 27:121(94) ack 52 win 5840 <nop,nop,timestamp 4162147 16484131> (DF)
23:13:49.493849 eth2 > 192.168.2.2.32778 > 192.168.1.2.telnet: P 27:121(94) ack 52 win 5840 <nop,nop,timestamp 4162147 16484131> (DF)
23:13:49.501121 eth1 < 192.168.2.2.32778 > 192.168.1.2.telnet: P 121:124(3) ack 55 win 5840 <nop,nop,timestamp 4162147 16484132> (DF)
23:13:49.501131 eth2 > 192.168.2.2.32778 > 192.168.1.2.telnet: P 121:124(3) ack 55 win 5840 <nop,nop,timestamp 4162147 16484132> (DF)
23:13:49.502159 eth1 < 192.168.2.2.32778 > 192.168.1.2.telnet: P 124:127(3) ack 127 win 5840 <nop,nop,timestamp 4162147 16484132> (DF)
23:13:49.502169 eth2 > 192.168.2.2.32778 > 192.168.1.2.telnet: P 124:127(3) ack 127 win 5840 <nop,nop,timestamp 4162147 16484132> (DF)
23:13:49.532740 eth1 < 192.168.2.2.32778 > 192.168.1.2.telnet: . 127:127(0) ack 134 win 5840 <nop,nop,timestamp 4162151 16484132> (DF)
23:13:49.532751 eth2 > 192.168.2.2.32778 > 192.168.1.2.telnet: . 127:127(0) ack 134 win 5840 <nop,nop,timestamp 4162151 16484132> (DF)





10. Redirect to/from file.

tcpdump can use option -w filename to dump (raw) traffic to file. It can use -r to read input ( traffic ) from that file

Record the traffic on eth1 to file eth1.tc
#tcpdump -i eth1 -w eth1.tc

Get traffic originating from 192.168.2.2 from file eth1.tc
#tcpdump src host 192.168.2.2 -r eth1.tc


11. Customize your tcpdump output

    See man page