Tcpdump is a command-line tool for capturing and analyzing network packets in Linux. Basically its a packet sniffer that also breaks them down into easy to read format for human beings.
It can be a powerful tool for troubleshooting network connectivity issues by analyzing the network traffic on a system.
Tcpdump works by listening for packets on a network interface specified by the user. When a packet is received, tcpdump analyzes the packet according to the filter criteria indicated by the user.
Behind the scenes, tcpdump uses the libpcap library, which is installed as a dependency for capturing network traffic. If you are looking for a gui tool then Wireshark is an excellent choice which is also based on libpcap. Tshark is yet another command line tool for capturing network packets, but for the sake of sanity we shall be focusing just on tcpdump this article.
Some common applications of tcpdump are:
- Capturing network traffic including UDP, TCP, and ICMP traffic
- Filtering traffic to specific packets
- Diagnosing network problems such as packet loss
- Storing captured packets for further analysis
In order to use tcpdump to capture low level network traffic, "root" user or "sudo" privileges are required. That is how Linux works.
In this article, we'll cover some robust tcpdump commands that can be useful for analyzing network traffic together with examples.
Installation
Tcpdump comes preinstalled in most Linux distributions by default. You can check if tcpdump is present on your system by running:
tcpdump --version
You should get an output similar to the following if tcpdump is present:
tcpdump version 4.99.1 libpcap version 1.10.1 (with TPACKET_V3) OpenSSL 3.0.2 15 Mar 2022
However, if you don't have tcpdump installed, you can easily install it with either of the following commands, depending on your Linux distribution.
For Ubuntu and Debian-based Linux, run:
sudo apt install tcpdump
For CentOs, Fedora, and Red Hat, run:
sudo dnf install tcpdump
For Arch-based Linux, run:
sudo pacman -S tcpdump
Command Examples
Once tcpdump is installed on your system, its time to play with it. We shall be taking a look at some of the most basic commands that can be useful for system administrators in their regular tasks.
1. List of all Network Interfaces
We can get a list of the available network interfaces on the machine by adding the "-D"
or "--list-interfaces"
flag to the tcpdump command as shown below:
sudo tcpdump -D
The output shows a list of all the available network interfaces that packets can be captured from, according to the associated index.
1.enp0s3 [Up, Running, Connected] 2.any (Pseudo-device that captures on all interfaces) [Up, Running] 3.lo [Up, Running, Loopback] 4.bluetooth-monitor (Bluetooth Linux Monitor) [Wireless] 5.nflog (Linux netfilter log (NFLOG) interface) [none] 6.nfqueue (Linux netfilter queue (NFQUEUE) interface) [none] 7.dbus-system (D-Bus system bus) [none] 8.dbus-session (D-Bus session bus) [none]
From the output produced, the "any" interface is a special interface used to represent all the interfaces detected by tcpdump, used especially when capturing packets from all the interfaces.
2. Select interface and start capture
After listing the interfaces, we can specify the network interface from which tcpdump will capture packets by either using the "-i" or "--interface" flags.
sudo tcpdump -i any
Sample output:
tcpdump: data link type LINUX_SLL2 tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes 01:38:22.957542 enp0s3 B ARP, Request who-has 192.168.208.179 tell _gateway, length 46 01:38:23.043437 lo In IP localhost.47743 > localhost.domain: 62037+ [1au] PTR? 179.208.168.192.in-addr.arpa. (57) 01:38:23.044522 enp0s3 Out IP Ubuntu22.52997 > _gateway.domain: 10642+ PTR? 179.208.168.192.in-addr.arpa. (46) 01:38:23.051252 enp0s3 In IP _gateway.domain > Ubuntu22.52997: 10642 NXDomain 0/0/0 (46) 01:38:23.051788 lo In IP localhost.domain > localhost.47743: 62037 NXDomain 0/0/1 (57)
Note: Executing tcpdump without specifying an interface will capture packets on the first active indexed interface.
3. Limit the number of captured packets
After executing the command, tcpdump will continue to listen to packets in the interface until it's interrupted by pressing Ctrl + C. However, we can add the "-c" flag to specify the number of packets to be captured.
sudo tcpdump --interface any -c 6
The command above ensures that only six packets are captured, as seen in the following output:
tcpdump: data link type LINUX_SLL2 tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes 01:50:19.836119 enp0s3 B ARP, Request who-has 192.168.208.179 tell _gateway, length 46 01:50:19.932278 lo In IP localhost.51720 > localhost.domain: 49344+ [1au] PTR? 179.208.168.192.in-addr.arpa. (57) 01:50:19.934263 enp0s3 Out IP Ubuntu22.49760 > _gateway.domain: 14748+ PTR? 179.208.168.192.in-addr.arpa. (46) 01:50:19.940315 enp0s3 In IP _gateway.domain > Ubuntu22.49760: 14748 NXDomain 0/0/0 (46) 01:50:19.940726 lo In IP localhost.domain > localhost.51720: 49344 NXDomain 0/0/1 (57) 01:50:19.941310 lo In IP localhost.42093 > localhost.domain: 26341+ [1au] PTR? 178.208.168.192.in-addr.arpa. (57) 6 packets captured 23 packets received by filter 0 packets dropped by kernel
4. Understanding the tcpdump Output
tcpdump provides various information related to the captured packet, including the timestamp and the interface's name where a packet is captured from.
A typical output of a single captured packet looks like the following:
02:27:41.286650 enp0s3 Out IP 192.168.208.151.60690 > 185.125.190.48.80: Flags [P.], seq 1:88, ack 1, win 502, length 87: HTTP: GET / HTTP/1.1
The output shows the following information about the captured packet:
The timestamp: This denotes the precise time when the packet was captured.
The interface name: This shows the interface in which the packet was captured.
The packet flow: This indicates whether the packet is an "incoming" or "outgoing" packet. In the example above, "Out" represents an outgoing packet.
The packet protocol: This shows what protocol is being used by the packet. Here, it indicates IP (Internet Protocol version 4).
The source address and port: This shows the source address of the packet and the port, delimited with a dot (.).
The destination address and port: This shows the destination address of the packet and the port, delimited with a dot (.).
TCP flags: These are values in the TCP header used to control data flow between TCP endpoints. The flag field values can be one or a combination of the following:
- [.] - ACK (Acknowledge): Used to acknowledge receipt of data
- [P] - PSH (Push): Used to push data to the receiving end
- [R] - RST (Reset): Used to reset a TCP connection
- [S] - SYN (Synchronize): Used to synchronize a sequence of numbers for the beginning of a TCP connection
- URG (Urgent): Used to indicate that the data in the TCP segment should be processed before other data
- [F] - FIN (Finish): Used to indicate the end of the TCP connection
The number sequence range: This denotes the number of data present in the packet.
The acknowledgment number: This represents the byte expected by the other end of the connection.
The window size: This indicates the amount of data that can be transmitted before an acknowledgment is expected to be received.
Packet length: The length of the whole payload data.
5. Turning off DNS Resolution
By default, tcpdump tries to resolve IP addresses present in a packet to their corresponding domain names. However, this can potentially slow down packet capture, particularly when the DNS server is not functioning properly or thousands of packets need to be captured.
To address this issue, we can add the "-n" flag to tell tcpdump to skip DNS lookup and instead use the IP addresses in the output.
sudo tcpdump -n -i any
Sample output:
07:16:57.948197 enp0s3 In IP6 fe80::7134:2319:8425:d7d4.3702 > fe80::eee4:e463:3397:7ecd.44926: UDP, length 1243 07:16:58.124418 enp0s3 In IP6 fe80::7134:2319:8425:d7d4.3702 > fe80::eee4:e463:3397:7ecd.44926: UDP, length 1243 07:16:58.174259 enp0s3 In IP 192.168.208.179.3702 > 192.168.208.151.57685: UDP, length 1231 07:16:58.277839 enp0s3 In IP 192.168.208.179.3702 > 192.168.208.151.57685: UDP, length 1231 07:16:58.277899 enp0s3 Out IP 192.168.208.151 > 192.168.208.179: ICMP 192.168.208.151 udp port 57685 unreachable, length 556 07:16:58.490541 enp0s3 In IP6 fe80::7134:2319:8425:d7d4.3702 > fe80::eee4:e463:3397:7ecd.44926: UDP, length 1243
The output above shows both IPv4 and IPv6 addresses in the packets captured by tcpdump.
In addition, we can add a second "-n" flag as "-nn", which tells tcpdump to also ignore the port numbers.
6. Filter by host
Tcpdump provides different qualifiers that can be used to filter packets captured according to various criteria. When a filter is specified, tcpdump applies the filter to every incoming and outgoing packet and only captures the packets that match the indicated qualifier.
For example, when troubleshooting issues related to SSH traffic, we can filter all packets on port 22, which is the default port used by SSH.
To filter incoming and outgoing traffic related to a specific host, use the "host" qualifier:
sudo tcpdump -n -i any host 192.168.208.151
Sample output:
08:01:31.555410 enp0s3 Out IP 192.168.208.151.59472 > 91.189.91.49.80: Flags [.], ack 190, win 64051, length 0 08:01:31.555562 enp0s3 In IP 91.189.91.49.80 > 192.168.208.151.59472: Flags [F.], seq 190, ack 88, win 64913, length 0 08:01:31.555509 enp0s3 Out IP 192.168.208.151.59472 > 91.189.91.49.80: Flags [F.], seq 88, ack 191, win 64051, length 0 08:01:31.763313 enp0s3 In IP 91.189.91.49.80 > 192.168.208.151.59472: Flags [.], ack 89, win 64912, length 0
Alternatively, you can capture packets originating from a specific address or heading to a specific address using the "src" and "dst" qualifiers.
For instance, the following example shows how to capture packets originating from 192.168.208.178:
sudo tcpdump -n -i any src 192.168.208.178
Sample output:
08:14:10.729672 enp0s3 In IP 192.168.208.178.53 > 192.168.208.151.60455: 29747 0/1/0 (119) 08:14:26.539945 enp0s3 B ARP, Request who-has 192.168.208.179 tell 192.168.208.178, length 46 08:14:26.881156 enp0s3 In IP 192.168.208.178.53 > 192.168.208.151.56356: 13187 0/0/0 (34) 08:14:41.173182 enp0s3 B ARP, Request who-has 192.168.208.151 tell 192.168.208.178, length 46
In contrast, to capture packets going to 192.168.208.178, we use the following command:
sudo tcpdump -n -i any dst 192.168.208.178
Sample output:
08:13:30.666879 enp0s3 Out IP 192.168.208.151.68 > 192.168.208.178.67: BOOTP/DHCP, Request from 08:00:27:af:2a:8f, length 286 08:13:35.769629 enp0s3 Out ARP, Request who-has 192.168.208.178 tell 192.168.208.151, length 28 08:13:57.922229 enp0s3 Out IP 192.168.208.151.33277 > 192.168.208.178.53: 11781+ A? api.snapcraft.io. (34) 08:13:57.977637 enp0s3 Out IP 192.168.208.151.54464 > 192.168.208.178.53: 51816+ AAAA? api.snapcraft.io. (34)
7. Filter by protocol
To limit the packets captured to those using a specific protocol, you can use the "proto" qualifier.
For instance, to capture "ICMP" traffic, run:
sudo tcpdump -i any proto ICMP
Similarly, for UDP traffic, run:
sudo tcpdump -i any proto UDP
Sample output:
08:32:20.436024 lo In IP 127.0.0.1.51063 > 127.0.0.53.53: 54486+ [1au] PTR? 151.208.168.192.in-addr.arpa. (57) 08:32:20.437119 enp0s3 Out IP 192.168.208.151.57339 > 192.168.208.178.53: 46639+ [1au] PTR? 151.208.168.192.in-addr.arpa. (57) 08:32:20.443304 enp0s3 In IP 192.168.208.178.53 > 192.168.208.151.57339: 46639 NXDomain 0/0/0 (46) 08:32:20.444742 enp0s3 Out IP 192.168.208.151.57339 > 192.168.208.178.53: 3043+ PTR? 151.208.168.192.in-addr.arpa. (46) 08:32:20.451601 enp0s3 In IP 192.168.208.178.53 > 192.168.208.151.57339: 3043 NXDomain 0/0/0 (46)
Alternatively, you can specify the protocol number. For example, using "17" as shown in the command below will produce the same output above, as it represents the UDP protocol.
sudo tcpdump -n -i any proto 17
Common protocols and their corresponding numbers include:
- TCP: 6
- ICMP: 1
- UDP: 17
- FTP: 21
- HTTP: 80
8. Filter by Port
The "port" qualifier can be used to limit captured packets to those on a specific port.
For example, the following command captures packets related to SSH by listening to port 22:
sudo tcpdump -n -i any port 22
This command above produces the following output:
09:06:22.695718 enp0s3 Out IP 192.168.208.151.22 > 192.168.208.225.47782: Flags [.], ack 33, win 509, options [nop,nop,TS val 3486902457 ecr 2279433600], length 0 09:06:22.708095 enp0s3 Out IP 192.168.208.151.22 > 192.168.208.225.47782: Flags [P.], seq 1:42, ack 33, win 509, options [nop,nop,TS val 3486902469 ecr 2279433600], length 41: SSH: SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.1 09:06:22.709210 enp0s3 In IP 192.168.208.225.47782 > 192.168.208.151.22: Flags [.], ack 42, win 502, options [nop,nop,TS val 2279433614 ecr 3486902469], length 0
Alternatively, you can limit the traffic captured to either packets originating from the source port or packets going to the destination port by adding "src" and "dst" qualifiers, respectively.
For example, the command below captures packets originating in port 22 only:
sudo tcpdump -n -i any src port 22
Sample output:
10:10:11.646891 enp0s3 In IP 192.168.170.225.22 > 192.168.170.151.58628: Flags [P.], seq 124:192, ack 45, win 501, options [nop,nop,TS val 4276870210 ecr 3000912972], length 68 10:10:13.338238 enp0s3 In IP 192.168.170.225.22 > 192.168.170.151.58628: Flags [P.], seq 192:236, ack 81, win 501, options [nop,nop,TS val 4276871900 ecr 3000914662], length 44
In addition, we can specify a range of ports that tcpdump can listen to for packet capturing using the "portrange" qualifier.
sudo tcpdump -n -i any portrange 20-5000
Sample output:
10:19:39.166380 enp0s3 B IP 192.168.170.179.138 > 192.168.170.255.138: UDP, length 201 10:21:13.121464 enp0s3 Out IP 192.168.170.151.33602 > 192.168.170.252.53: 62482+ AAAA? connectivity-check.ubuntu.com. (47) 10:21:13.184926 enp0s3 In IP 192.168.170.252.53 > 192.168.170.151.33602: 62482 6/3/0 AAAA 2620:2d:4000:1::23, AAAA 2001:67c:1562::24, AAAA 2001:67c:1562::23, AAAA 2620:2d:4000:1::22, AAAA 2620:2d:4000:1::2b, AAAA 2620:2d:4000:1::2a (279)
Similarly, the "src" and "dst" qualifiers can be combined with the "portrange" qualifier to filter traffic originating from or going to a range of ports.
9. Filter by Network
tcpdump also supports filtering captured packets by networks. This is particularly useful for monitoring traffic within a specific network or subnet.
The "net" qualifier can be used to filter incoming and outgoing packets by a network. When using the "net" qualifier, the network address can be specified in two ways:
- Using the netmask.
- Using the CIDR notation.
The following examples show how to use both methods to filter captured packets to only those in a specific network:
sudo tcpdump -n -i any net 192.168.170.0/24
sudo tcpdump -n -i any net 192.168.170.0 mask 255.255.255.0
Sample output:
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes 10:53:01.863834 enp0s3 B ARP, Request who-has 192.168.170.179 tell 192.168.170.252, length 46 10:53:07.608933 enp0s3 Out IP 192.168.170.151.44538 > 185.125.190.56.123: NTPv4, Client, length 48 10:53:10.722187 enp0s3 In IP 185.125.190.56.123 > 192.168.170.151.44538: NTPv4, Server, length 48 10:53:12.834982 enp0s3 Out ARP, Request who-has 192.168.170.252 tell 192.168.170.151, length 28 10:53:12.838532 enp0s3 In ARP, Reply 192.168.170.252 is-at 86:1d:b1:4c:16:87, length 46
In the same fashion as the previous qualifiers, the "net" qualifier can be combined with the "src" and "dst" qualifiers to capture packets originating from and coming into the network.
10. Complex Filters
We have seen how to filter packets based on the host address, port numbers, network address, and protocol. However, tcpdump also supports more complex filter expressions that combine multiple qualifiers and operators to create advanced filtering rules.
tcpdump allows the use of the following operators to join multiple filters together:
- and (&&): This operator is used to combine two or more filters using the logical "AND".
- or (||): This operator combines two or more filters using the logical "OR".
- not (!): This operator is used to negate a filter expression.
- (): The parentheses operator is used to group filter expressions together.
Keep in mind when using special characters such as parentheses, single quotes should be used to wrap the expression, which allows tcpdump to parse the special characters.
For example, to filter incoming packets that are not SSH traffic from an IP address, the following command can be executed:
sudo tcpdump -n -i any src 192.168.170.252 and not port 22
Similarly, to filter packets with the UDP protocol originating from a source network and going to range of destination ports, we can use the following command:
sudo tcpdump -n -i any proto UDP and src net 192.168.170.0/24 and dst portrange 20-6000
The command above captures UDP traffic originating from the "192.168.170.0/24" network, with destination ports ranging from 20 to 6000.
Sample output:
11:46:14.641468 enp0s3 M IP 192.168.170.252.5353 > 224.0.0.251.5353: 0*- [0q] 1/0/0 PTR {"nm":"Redmi Note","as":"[8194]","ip":"252"}._mi-connect._udp.local. (95) 11:46:16.641677 enp0s3 M IP 192.168.170.252.5353 > 224.0.0.251.5353: 0*- [0q] 1/0/0 PTR {"nm":"Redmi Note","as":"[8194]","ip":"252"}._mi-connect._udp.local. (95) 11:46:21.957657 enp0s3 M IP 192.168.170.252.5353 > 224.0.0.251.5353: 0 [1n] ANY (QU)? {"nm":"Redmi Note","as":"[8194]","ip":"252"}._mi-connect._udp.local. (115) 11:46:22.206896 enp0s3 M IP 192.168.170.252.5353 > 224.0.0.251.5353: 0 [1n] ANY (QM)? {"nm":"Redmi Note","as":"[8194]","ip":"252"}._mi-connect._udp.local. (115) 11:46:22.457003 enp0s3 M IP 192.168.170.252.5353 > 224.0.0.251.5353: 0 [1n] ANY (QM)? {"nm":"Redmi Note","as":"[8194]","ip":"252"}._mi-connect._udp.local. (115)
In summary, by combining different operators and qualifiers, you can create advanced filtering rules to capture a specific subset of packets while troubleshooting.
11. Capture DNS Traffic
In the previous section, we've seen how to apply filters to capture specific packets. With this in mind, we can apply filters in capturing and analyzing DNS traffic.
Generally, DNS queries use the UDP protocol and a default port number of 53. Therefore, in order to capture DNS packets, we can tell tcpdump to listen for incoming and outgoing packets using the UDP protocol and port 53.
sudo tcpdump -n -v -i any -s 0 proto UDP and port 53
In the command above, we specify that only UDP packets on port 53 should be captured. In addition, we've added the "-s" flag, giving it a value of 0 to capture the full packet, and the "-v" flag to increase the verbosity of the output.
After executing the command, we can use a DNS querying tool such as "dig" to perform a query for the A records of a domain, as shown in the example below:
dig A google.com
tcpdump will then produce an output similar to the following:
01:41:53.342071 lo In IP (tos 0x0, ttl 64, id 62946, offset 0, flags [none], proto UDP (17), length 79) 127.0.0.1.54375 > 127.0.0.53.53: 840+ [1au] A? google.com. (51) 01:41:53.343333 lo In IP (tos 0x0, ttl 1, id 6668, offset 0, flags [DF], proto UDP (17), length 83) 127.0.0.53.53 > 127.0.0.1.54375: 840 1/0/1 google.com. A 216.58.223.238 (55)
In the output above, the first packet shows that a DNS query for A records was sent to the local DNS service for the domain "google.com". The second packet contains the response from the DNS service with a single A record for google.com.
12. Capture HTTP Traffic
To capture HTTP packets, we can tell tcpdump to listen for packets using the TCP protocol on port 80, which is the default HTTP port, and also perform some additional filtering on the TCP header.
For example, to capture packets with an HTTP GET request, you can execute the following command:
sudo tcpdump -n -i any -s 0 -A proto TCP and port 80 and 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'
Let's break down what the command above is doing:
- "-n -i any -s 0 -A proto TCP and port 80": We have seen these flags in previous sections. Here, we're telling tcpdump to listen for packets with the TCP protocol on port 80 in any interface and to display the fully captured packets in ASCII format without performing a reverse DNS lookup.
- "'tcp[((tcp[12:1] & 0xf0) >> 2):4]": In this part of the command, we're calculating the total bytes of the TCP header and retrieving the first 4 bytes after the whole header bytes, which is in the payload.
- "= 0x47455420": Here, we compare the data retrieved from the first 4 bytes of the payload to the hexadecimal value "0x47455420", which is equivalent to "GET" in ASCII.
After executing the command, you should get an output similar to the one below:
05:33:33.260256 enp0s3 In IP 192.168.181.225.44748 > 192.168.181.151.80: Flags [P.], seq 659:961, ack 7068, win 501, options [nop,nop,TS val 2504166022 ecr 3048394935], length 302: HTTP: GET /favicon.ico HTTP/1.1 E..b..@[email protected]............ .B......GET /favicon.ico HTTP/1.1 Host: 192.168.181.151 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/112.0 Accept: image/avif,image/webp,*/* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Referer: http://192.168.181.151/
Similarly, you can capture packets with HTTP POST requests using the following command:
sudo tcpdump -n -i any -s 0 -A proto TCP and port 80 and 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504F5354'
In the command above, the hexadecimal value "0x504F5354" is equivalent to "POST" in ASCII.
Sample output:
05:40:35.524814 enp0s3 In IP 192.168.181.225.34666 > 192.168.181.151.80: Flags [P.], seq 1765221554:1765221707, ack 1001593799, win 502, options [nop,nop,TS val 2504588494 ecr 3048817299], length 153: HTTP: POST / HTTP/1.1 E....S@[email protected]$.;.............. .H....B.POST / HTTP/1.1 Host: 192.168.181.151 User-Agent: curl/7.81.0 Accept: */* Content-Length: 5 Content-Type: application/x-www-form-urlencoded Hello
In addition, you can specify a source IP address to further filter the HTTP packets to those from a specific address.
13. Capture SMTP Traffic
To capture SMTP traffic, we can tell tcpdump to listen for packets with the TCP protocol on port 25, which is the well-known port for SMTP traffic as shown below:
sudo tcpdump -n -v -i any -s 0 -A proto TCP and port 25
14. Capture ARP Traffic
Address Resolution Protocol (ARP) facilitates communication in a network by allowing devices to query for the physical (MAC) address of a destination device.
tcpdump supports filtering captured packets using ARP, which is particularly useful for troubleshooting network connectivity issues.
To capture ARP-related packets, add "arp" when executing tcpdump as shown below:
sudo tcpdump -n -i any arp
Sample output:
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes 06:52:43.339898 enp0s3 B ARP, Request who-has 192.168.181.225 tell 192.168.181.252, length 46 06:53:01.771918 enp0s3 B ARP, Request who-has 192.168.181.179 tell 192.168.181.252, length 46 06:53:18.386462 enp0s3 Out ARP, Request who-has 192.168.181.252 tell 192.168.181.151, length 28 06:53:18.391004 enp0s3 In ARP, Reply 192.168.181.252 is-at 86:1d:b1:4c:16:87, length 46 06:53:18.666674 enp0s3 B ARP, Request who-has 192.168.181.151 tell 192.168.181.252, length 46
15. Save Captured Packets to File
tcpdump supports saving captured packets to a file. This is particularly useful when storing captured packets for subsequent analysis.
When saving packets with tcpdump, the "-w" flag is used to write the captured packets to a file with a .pcap (packet capture) file extension. This extension is the recommended file format for saving captured packets.
To begin writing captured packets to a file, add the "-w" flag and indicate the file name as shown in the following command:
sudo tcpdump -n -i any -w packets-data.pcap
After executing the above command, captured packets are continuously written to the file until the process is interrupted without displaying the captured packets on the shell output.
The data written to the file can only be read by packet analyzer tools like tcpdump and Wireshark. Consequently, text editors cannot be used to read the content of the file.
To read the packets captured in the file, we can use the "-r" flag followed by the name of the file as shown in the command below:
sudo tcpdump -r packets-data.pcap
Sample output:
reading from file packets-data.pcap, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 Warning: interface names might be incorrect 12:04:00.425149 enp0s3 B IP 0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 08:00:27:b9:99:60 (oui Unknown), length 287 12:04:00.438678 enp0s3 B IP _gateway.bootps > 255.255.255.255.bootpc: BOOTP/DHCP, Reply, length 314 12:04:00.489008 enp0s3 B ARP, Request who-has 192.168.170.225 tell 192.168.170.225, length 46 12:04:00.554996 enp0s3 B ARP, Request who-has _gateway tell 192.168.170.225, length 46
In addition, filters covered in the previous sections can be used to narrow the output to packets you're interested in.
Alternatively, if you intend to capture packets over a long period, the saved packets can be spread over various files by adding the "-W" and "-C" flags to the command as shown below:
sudo tcpdump -n -i any -W 5 -C 50 -w /tmp/packets.pcap
In the command above, the "-C" flag tells tcpdump to limit each file size to 50MB. Whereas, the "-W" flag tells tcpdump to create up to a maximum of five files. The naming sequence for each file will be "packets.pcap0", "packets.pcap1", "packets.pcap2", and so on. However, older files will be overwritten once the five files have been generated.
16. Inspect Packet Content
As we have seen so far, tcpdump only captures the packet headers by default. However, tcpdump also supports reading the content of the packet payload. This is particularly useful for inspecting the content of text-based protocols such as HTTP and SMTP.
Generally, the content of the packet payload can be read both in hexadecimal and ASCII forms by specifying the "-x" and "-A" flags, respectively.
To show the captured packet content in hexadecimal, you can add the "-x" flag, as shown in the command below:
sudo tcpdump -n -i any -x
The command above will produce an output similar to the following:
05:56:48.987686 enp0s3 B IP 192.168.181.179.57621 > 192.168.181.255.57621: UDP, length 44 0x0000: 4500 0048 9cd0 0000 8011 b0d0 c0a8 b5b3 0x0010: c0a8 b5ff e115 e115 0034 e336 5370 6f74 0x0020: 5564 7030 7392 1d83 4f7e 594c 0001 0004 0x0030: 4895 c203 ea60 971d ecba afbd e4a9 ad56
Similarly, the "-A" flag can be used to show the captured packet content in ASCII format.
sudo tcpdump -n -i any -A
Sample output:
05:57:58.687570 enp0s3 Out IP 192.168.181.151.80 > 192.168.181.225.52604: Flags [P.], seq 10379:13838, ack 1757, win 501, options [nop,nop,TS val 3049860462 ecr 2505632115], length 3459: HTTP: HTTP/1.1 200 OK E.....@[email protected].|=.V s,z......s..... ..-n.X.sHTTP/1.1 200 OK Date: Thurs, 04 May 2023 04:57:58 GMT Server: Apache/2.4.52 (Ubuntu) Last-Modified: Thurs, 04 May 2023 04:22:19 GMT ETag: "29af-5faeaa2891b60-gzip" Accept-Ranges: bytes Vary: Accept-Encoding Content-Encoding: gzip Content-Length: 3121 Keep-Alive: timeout=5, max=97 Connection: Keep-Alive Content-Type: text/html
Alternatively, we can use the "-X" flag to display the captured packet content in both hexadecimal and ASCII formats, as shown below:
sudo tcpdump -n -i any -X
Sample output:
06:01:19.401130 enp0s3 In IP 192.168.181.225.35094 > 192.168.181.151.80: Flags [P.], seq 1:440, ack 1, win 502, options [nop,nop,TS val 2505832820 ecr 3050061174], length 439: HTTP: GET / HTTP/1.1 0x0000: 4500 01eb 7144 4000 4006 dafe c0a8 b5e1 E...qD@.@....... 0x0010: c0a8 b597 8916 0050 07c2 f336 97d7 58ff .......P...6..X. 0x0020: 8018 01f6 3b70 0000 0101 080a 955b f974 ....;p.......[.t 0x0030: b5cc 3d76 4745 5420 2f20 4854 5450 2f31 ..=vGET./.HTTP/1 0x0040: 2e31 0d0a 486f 7374 3a20 3139 322e 3136 .1..Host:.192.16 0x0050: 382e 3138 312e 3135 310d 0a55 7365 722d 8.181.151..User- 0x0060: 4167 656e 743a 204d 6f7a 696c 6c61 2f35 Agent:.Mozilla/5 0x0070: 2e30 2028 5831 313b 2055 6275 6e74 753b .0.(X11;.Ubuntu; 0x0080: 204c 696e 7578 2078 3836 5f36 343b 2072 .Linux.x86_64;.r 0x0090: 763a 3130 392e 3029 2047 6563 6b6f 2f32 v:109.0).Gecko/2 0x00a0: 3031 3030 3130 3120 4669 7265 666f 782f 0100101.Firefox/ 0x00b0: 3131 322e 300d 0a41 6363 6570 743a 2074 112.0..Accept:.t 0x00c0: 6578 742f 6874 6d6c 2c61 7070 6c69 6361 ext/html,applica ..
Conclusion
Tcpdump is an essential tool that should be in the toolkit of any system administrator. It provides different options for troubleshooting and analyzing network issues.
Its advanced filtering capability lets narrow down captured packets to those they're interested in.
Its ability to write captured packets to files also allows users to perform analysis with other packet analysis tools. Knowing how to use tcpdump is a valuable skill, whether you're a system administrator, network analyst, or an everyday Linux user.