Last updated on March 31, 2021 by Dan Nanni
When it comes to network troubleshooting and monitoring, what types of tools you are using make a world of difference. While required tools may vary depending on the types of network problems you are dealing with, there are a set of essential tools that every network administrator must be familiar with, and tcpdump
is definitely one of them.
tcpdump
is a command-line tool packet sniffing that allows you to capture network packets based on packet filtering rules, interpret captured packet content, and display the result in a human-readable format. The main power of tcpdump
comes from its (1) flexible packet filtering rules and (2) versatile protocol dissection capability. Although GUI-based Wireshark provides equally powerful filtering/dissecting capabilities via a more user-friendly interface, its relatively high memory footprint (for buffering packets) and GUI-based operations make Wireshark unsuitable when you are troubleshooting directly from remote headless servers.
Using tcpdump
, you can troubleshoot a wide range of network issues including but not limited to:
The rest of the post provides a comprehensive tcpdump
cheat sheet, which illustrates different types of packet capture scenarios using actual tcpdump
examples.
When running tcpdump
, typically you specify, with -i
option, which network interface you want to monitor traffic on. If you do not specify a network interface, tcpdump
will listen on a default network interface, which is the lowest-number interface in the network interface list. tcpdump -D
will show the network interface list.
docker0
:$ sudo tcpdump -i docker0
Suppose there are multiple network interfaces on your system, and you want to capture traffic from all those interfaces simultaneously. Exactly for this purpose tcpdump
provides a special interface name called "any
". Thus, simply run tcpdump
with -i any
option to capture traffic from all available network interfaces.
$ sudo tcpdump -i any
$ sudo tcpdump -e
13:27:18.002070 9c:b6:d0:fe:4d:95 (oui Unknown) > 48:d6:e5:7b:81:70 (oui Unknown), ethertype IPv4 (0x0800), length 66: xxxx.xxxx.xxxx.33800 > xxxx.xxxx.xxxx.8009: Flags [.], ack 111, win 501, options [nop,nop,TS val 1624743259 ecr 4014866], length 0
$ sudo tcpdump -n
13:30:50.832688 IP 75.135.195.199.443 > 192.168.1.236.35267: UDP, length 45
$ sudo tcpdump -v $ sudo tcpdump -vv $ sudo tcpdump -vvv
8.8.8.8
:$ sudo tcpdump src 8.8.8.8
192.168.100.0/24
:$ sudo tcpdump src net 192.168.100.0/24
10.0.0.1
:$ sudo tcpdump dst 10.0.0.1
192.168.100.0/24
:$ sudo tcpdump dst net 192.168.100.0/24
10.10.0.1
to 192.168.100.54
:$ sudo tcpdump src 10.10.0.1 and dst 192.168.100.54
10.10.0.0/24
to destination network 192.168.100.0/24
:$ sudo tcpdump src net 10.10.0.0/24 and dst net 192.168.100.0/24
10.10.0.1
and 192.168.100.54
in both directions:$ sudo tcpdump host 10.10.0.1 and host 192.168.100.54
10.10.0.0/24
and 192.168.100.0./24
in both directions:sudo tcpdump net 10.10.0.0/24 and net 192.168.100.0/24
tcpdump
allows you to capture network traffic with a specific network protocol. For well-known layer-3 or layer-4 protocols, you just need to specify their names. For other types of transport protocols (e.g., DHCP, DNS, SSH), you can filter them based on their port numbers (shown next).
$ sudo tcpdump ip
$ sudo tcpdump icmp
$ sudo tcpdump arp
$ sudo tcpdump ip6
$ sudo tcpdump tcp
$ sudo tcpdump udp
$ sudo tcpdump tcp and host 10.10.0.1 and host 192.168.100.54
$ sudo tcpdump dst port 80
$ sudo tcpdump udp src port 4001
$ sudo tcpdump port 22
$ sudo tcpdump port 53
$ sudo tcpdump port 80 or port 8000
$ sudo tcpdump 'tcp port 80 or udp port 4001'
$ sudo tcpdump portrange 800-900
$ sudo tcpdump tcp dst portrange 8000-8010
If my SSH session is originating from 192.168.100.250
:
$ sudo tcpdump port not 22 and not host 192.168.100.250
$ sudo tcpdump -c 100 tcp
$ sudo tcpdump greater 200
$ sudo tcpdump tcp dst port 80 and less 200
Note that the greater
and less
operators check the length of an entire packet, including all headers (e.g., Ethernet, IP, TCP headers).
$ sudo tcpdump not less 200 and not greater 500
You can filter packets by MAC address with the ether
qualifier.
ff:ff:ff:ff:ff:ff
):$ sudo tcpdump ether dst ff:ff:ff:ff:ff:ff
e8:2b:88:ef:55:11
and 9c:b6:d0:ee:fd:90
in both directions:$ sudo tcpdump ether host e8:2b:88:ef:55:11 and ether host 9c:b6:d0:ee:fd:90
e8:2b:88:ef:55:11
:$ sudo tcpdump ether host e8:2b:88:ef:55:11
$ sudo tcpdump -A tcp
Printing packet payload in ASCII format can be useful to inspect (unencrypted) HTTP protocol headers. For example:
$ sudo tcpdump -X
trace.pcap
:$ sudo tcpdump -c 1000 -w trace.pcap
trace.pcap
:$ tcpdump -r trace.pcap tcp
When you dump captured packets to a file, the capture file can grow quickly depending on the rate of incoming packets. So you want to rotate capture files regularly.
$ sudo tcpdump -w /tmp/trace -W 24 -G 3600 -C 500
This will create 24 capture files (/tmp/trace00, /tmp/trace01, ..., /tmp/trace23) in 24 hours. After that, it will overwrite the files from the beginning.
$ sudo tcpdump -w /tmp/trace-%Y-%m-%d_%H-%M.pcap -G 1800
This will create a new trace file every 30 minutes with the following names.
/tmp/trace-2021-23-29_12-00.pcap /tmp/trace-2021-23-29_12-30.pcap /tmp/trace-2021-23-29_13-00.pcap /tmp/trace-2021-23-29_13-30.pcap . . .
By default tcpdump
use micro-second resolution for timestamping packets. However, tcpdump
version 4.6 or later supports nano-second resolution timestamp.
$ sudo tcpdump --time-stamp-precision nano
$ sudo tcpdump -tt
1617031894.463313 IP 192.168.1.236.35627 > 193.194.206.100.443: UDP, length 1350
$ sudo tcpdump -tttt
2021-03-29 11:33:57.181125 IP 192.168.1.236.52472 > 200.189.40.8.123: NTPv4, Client, length 48
$ sudo tcpdump -ttttt
00:00:00.000000 IP 192.168.1.228.49669 > 255.255.255.255.1947: UDP, length 40 00:00:00.205198 IP 185.199.206.189.443 > 192.168.1.236.35627: UDP, length 44 00:00:00.211631 IP 192.168.1.236.35627 > 173.194.206.189.443: UDP, length 33 00:00:02.356055 ARP, Request who-has 192.168.1.1 tell 192.168.1.204, length 46
tcpdump
prints packet timestamp in the default timezone of your Linux system. If you want to show timestamp in a different timezone, you can specify the timezone in TZ
environment variable before calling tcpdump
.
$ sudo TZ=America/New_York tcpdump $ sudo TZ=Europe/London tcpdump $ sudo TZ=Asia/Seoul tcpdump
tcpdump
's expressive filter allows you to check for any arbitrary byte ranges in a packet. Using this capability, for example, you can capture TCP packets with particular flags in their TCP headers.
$ sudo tcpdump "tcp[tcpflags] & (tcp-syn) != 0"
That's the end of the tcpdump
cheat sheet. As you have seen here, only the sky is the limit when it comes to packet-level monitoring with tcpdump
. If you want to share your own tcpdump
examples, feel free to post them in the comment.
This website is made possible by minimal ads and your gracious donation via PayPal (Credit Card) or Bitcoin (1M161JGAkz3oaHNvTiPFjNYkeABox8rb4g
).
Please note that this article is published by Xmodulo.com under a Creative Commons Attribution-ShareAlike 3.0 Unported License. If you would like to use the whole or any part of this article, you need to cite this web page at Xmodulo.com as the original source.
Xmodulo © 2021 ‒ About ‒ Write for Us ‒ Feed ‒ Powered by DigitalOcean